2 * Copyright (c) 2007-2008 The Florida State University
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * Authors: Stephen Hines
31 #include "arch/arm/isa_traits.hh"
32 #include "arch/arm/process.hh"
33 #include "arch/arm/types.hh"
34 #include "base/loader/elf_object.hh"
35 #include "base/loader/object_file.hh"
36 #include "base/misc.hh"
37 #include "cpu/thread_context.hh"
38 #include "mem/page_table.hh"
39 #include "mem/translating_port.hh"
40 #include "sim/process_impl.hh"
41 #include "sim/system.hh"
44 using namespace ArmISA
;
46 ArmLiveProcess::ArmLiveProcess(LiveProcessParams
* params
,
48 : LiveProcess(params
, objFile
)
50 stack_base
= 0xc0000000L
;
52 // Set pointer for next thread stack. Reserve 8M for main stack.
53 next_thread_stack_base
= stack_base
- (8 * 1024 * 1024);
55 // Set up break point (Top of Heap)
56 brk_point
= objFile
->dataBase() + objFile
->dataSize() + objFile
->bssSize();
57 brk_point
= roundUp(brk_point
, VMPageSize
);
59 // Set up region for mmaps. For now, start at bottom of kuseg space.
60 mmap_start
= mmap_end
= 0x70000000L
;
64 ArmLiveProcess::startup()
66 argsInit(MachineBytes
, VMPageSize
);
70 ArmLiveProcess::copyStringArray32(std::vector
<std::string
> &strings
,
71 Addr array_ptr
, Addr data_ptr
,
72 TranslatingPort
* memPort
)
75 for (int i
= 0; i
< strings
.size(); ++i
) {
76 data_ptr_swap
= htog(data_ptr
);
77 memPort
->writeBlob(array_ptr
, (uint8_t*)&data_ptr_swap
,
79 memPort
->writeString(data_ptr
, strings
[i
].c_str());
80 array_ptr
+= sizeof(uint32_t);
81 data_ptr
+= strings
[i
].size() + 1;
83 // add NULL terminator
86 memPort
->writeBlob(array_ptr
, (uint8_t*)&data_ptr
, sizeof(uint32_t));
90 ArmLiveProcess::argsInit(int intSize
, int pageSize
)
92 // Overloaded argsInit so that we can fine-tune for ARM architecture
95 // load object file into target memory
96 objFile
->loadSections(initVirtMem
);
98 // Calculate how much space we need for arg & env arrays.
99 int argv_array_size
= intSize
* (argv
.size() + 1);
100 int envp_array_size
= intSize
* (envp
.size() + 1);
101 int arg_data_size
= 0;
102 for (int i
= 0; i
< argv
.size(); ++i
) {
103 arg_data_size
+= argv
[i
].size() + 1;
105 int env_data_size
= 0;
106 for (int i
= 0; i
< envp
.size(); ++i
) {
107 env_data_size
+= envp
[i
].size() + 1;
111 argv_array_size
+ envp_array_size
+ arg_data_size
+ env_data_size
;
112 if (space_needed
< 16*1024)
113 space_needed
= 16*1024;
115 // set bottom of stack
116 stack_min
= stack_base
- space_needed
;
118 stack_min
= roundDown(stack_min
, pageSize
);
119 stack_size
= stack_base
- stack_min
;
121 pTable
->allocate(stack_min
, roundUp(stack_size
, pageSize
));
123 // map out initial stack contents
124 Addr argv_array_base
= stack_min
+ intSize
; // room for argc
125 Addr envp_array_base
= argv_array_base
+ argv_array_size
;
126 Addr arg_data_base
= envp_array_base
+ envp_array_size
;
127 Addr env_data_base
= arg_data_base
+ arg_data_size
;
129 // write contents to stack
130 uint64_t argc
= argv
.size();
132 argc
= htog((uint64_t)argc
);
133 else if (intSize
== 4)
134 argc
= htog((uint32_t)argc
);
136 panic("Unknown int size");
138 initVirtMem
->writeBlob(stack_min
, (uint8_t*)&argc
, intSize
);
140 copyStringArray32(argv
, argv_array_base
, arg_data_base
, initVirtMem
);
141 copyStringArray32(envp
, envp_array_base
, env_data_base
, initVirtMem
);
144 //uint8_t insns[] = {0xe5, 0x9f, 0x00, 0x08, 0xe1, 0xa0, 0xf0, 0x0e};
145 uint8_t insns[] = {0x08, 0x00, 0x9f, 0xe5, 0x0e, 0xf0, 0xa0, 0xe1};
147 initVirtMem->writeBlob(0xffff0fe0, insns, 8);
150 threadContexts
[0]->setIntReg(ArgumentReg1
, argc
);
151 threadContexts
[0]->setIntReg(ArgumentReg2
, argv_array_base
);
152 threadContexts
[0]->setIntReg(StackPointerReg
, stack_min
);
154 Addr prog_entry
= objFile
->entryPoint();
155 threadContexts
[0]->setPC(prog_entry
);
156 threadContexts
[0]->setNextPC(prog_entry
+ sizeof(MachInst
));