machine_test.cc Source File

Back to the index.

machine_test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2018 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. 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  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *
28  * COMMENT: Various test machines
29  *
30  * Generally, the machines are as follows:
31  *
32  * bareXYZ: A bare machine using an XYZ processor.
33  *
34  * testXYZ: A machine with an XYZ processor, and some experimental
35  * devices connected to it.
36  *
37  * The experimental devices in the test machines are:
38  *
39  * cons A serial I/O console device.
40  * disk A device for reading/writing (emulated) disk sectors.
41  * ether An ethernet device, for sending/receiving ethernet
42  * frames on an emulated network.
43  * fb Framebuffer (24-bit RGB per pixel).
44  * irqc A generic interrupt controller.
45  * mp A multiprocessor controller.
46  * rtc A real-time clock device.
47  */
48 
49 #include <stdio.h>
50 #include <string.h>
51 
52 #include "cpu.h"
53 #include "device.h"
54 #include "devices.h"
55 #include "machine.h"
56 #include "memory.h"
57 #include "misc.h"
58 
60 
61 #include "testmachine/dev_cons.h"
62 #include "testmachine/dev_disk.h"
63 #include "testmachine/dev_ether.h"
64 #include "testmachine/dev_fb.h"
65 #include "testmachine/dev_irqc.h"
66 #include "testmachine/dev_mp.h"
67 #include "testmachine/dev_rtc.h"
68 
69 
70 /*
71  * default_test():
72  *
73  * Initializes devices for most test machines. (Note: MIPS is different,
74  * because of legacy reasons.)
75  */
76 static void default_test(struct machine *machine, struct cpu *cpu)
77 {
78  char tmpstr[2000];
79  char base_irq[1000];
80  char end_of_base_irq[50];
81 
82  /*
83  * First add the interrupt controller. Most processor architectures
84  * in GXemul have only 1 interrupt pin on the CPU, and it is simply
85  * called "machine[y].cpu[z]".
86  *
87  * MIPS is an exception, dealt with in a separate setup function.
88  * ARM and SH are dealt with here.
89  */
90 
91  switch (machine->arch) {
92 
93  case ARCH_ARM:
94  snprintf(end_of_base_irq, sizeof(end_of_base_irq), ".irq");
95  break;
96 
97  case ARCH_SH:
98  snprintf(end_of_base_irq, sizeof(end_of_base_irq),
99  ".irq[0x%x]", SH4_INTEVT_IRQ15);
100  break;
101 
102  default:
103  end_of_base_irq[0] = '\0';
104  }
105 
106  snprintf(base_irq, sizeof(base_irq), "%s.cpu[%i]%s",
107  machine->path, machine->bootstrap_cpu, end_of_base_irq);
108 
109  snprintf(tmpstr, sizeof(tmpstr), "irqc addr=0x%" PRIx64" irq=%s",
110  (uint64_t) DEV_IRQC_ADDRESS, base_irq);
111  device_add(machine, tmpstr);
112 
113 
114  /* Now, add the other devices: */
115 
116  snprintf(tmpstr, sizeof(tmpstr), "cons addr=0x%" PRIx64
117  " irq=%s.irqc.2 in_use=%i",
118  (uint64_t) DEV_CONS_ADDRESS, base_irq, machine->arch != ARCH_SH);
119  machine->main_console_handle = (size_t)device_add(machine, tmpstr);
120 
121  snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%" PRIx64" irq=%s%sirqc.6",
122  (uint64_t) DEV_MP_ADDRESS,
123  end_of_base_irq[0]? end_of_base_irq + 1 : "",
124  end_of_base_irq[0]? "." : "");
125  device_add(machine, tmpstr);
126 
127  snprintf(tmpstr, sizeof(tmpstr), "fbctrl addr=0x%" PRIx64,
128  (uint64_t) DEV_FBCTRL_ADDRESS);
129  device_add(machine, tmpstr);
130 
131  snprintf(tmpstr, sizeof(tmpstr), "disk addr=0x%" PRIx64,
132  (uint64_t) DEV_DISK_ADDRESS);
133  device_add(machine, tmpstr);
134 
135  snprintf(tmpstr, sizeof(tmpstr), "ether addr=0x%" PRIx64" irq=%s.irqc.3",
136  (uint64_t) DEV_ETHER_ADDRESS, base_irq);
137  device_add(machine, tmpstr);
138 
139  snprintf(tmpstr, sizeof(tmpstr), "rtc addr=0x%" PRIx64" irq=%s.irqc.4",
140  (uint64_t) DEV_RTC_ADDRESS, base_irq);
141  device_add(machine, tmpstr);
142 }
143 
144 
146 {
147  machine->machine_name = strdup("Generic \"bare\" ARM machine");
148 
149 #if 1
150  // An experiment with running a particular firmware image on a device;
151  // move some other place when/if it works?
153 
154  dev_ram_init(machine, 0xa0000000, 128 * 1048576, DEV_RAM_MIRROR
155  | DEV_RAM_MIGHT_POINT_TO_DEVICES, 0x00000000, "ram_mirror");
156 #endif
157 }
158 
159 
161 {
162  machine->machine_name = strdup("ARM test machine");
163 
164  default_test(machine, cpu);
165 
166  /*
167  * Place a tiny stub at end of memory, and set the link register to
168  * point to it. This stub halts the machine (making it easy to try
169  * out simple stand-alone C functions).
170  */
171  cpu->cd.arm.r[ARM_SP] = machine->physical_ram_in_mb * 1048576 - 4096;
172  cpu->cd.arm.r[ARM_LR] = cpu->cd.arm.r[ARM_SP] + 32;
173  store_32bit_word(cpu, cpu->cd.arm.r[ARM_LR] + 0, 0xe3a00201);
174  store_32bit_word(cpu, cpu->cd.arm.r[ARM_LR] + 4, 0xe5c00010);
175  store_32bit_word(cpu, cpu->cd.arm.r[ARM_LR] + 8, 0xeafffffe);
176 }
177 
178 
180 {
181  machine->cpu_name = strdup("SA1110");
182 }
183 
184 
186 {
187  machine->cpu_name = strdup("SA1110");
188 }
189 
190 
192 {
193  MR_DEFAULT(barearm, "Generic \"bare\" ARM machine",
195 
196  machine_entry_add_alias(me, "barearm");
197 }
198 
199 
201 {
202  MR_DEFAULT(testarm, "Test-machine for ARM", ARCH_ARM, MACHINE_TESTARM);
203 
204  machine_entry_add_alias(me, "testarm");
205 }
206 
207 
208 
209 MACHINE_SETUP(barem88k)
210 {
211  machine->machine_name = strdup("Generic \"bare\" M88K machine");
212 }
213 
214 
215 MACHINE_SETUP(oldtestm88k)
216 {
217  machine->machine_name = strdup("M88K test machine");
218 
219  default_test(machine, cpu);
220 }
221 
222 
224 {
225  machine->cpu_name = strdup("88110");
226 }
227 
228 
230 {
231  machine->cpu_name = strdup("88110");
232 }
233 
234 
236 {
237  MR_DEFAULT(barem88k, "Generic \"bare\" M88K machine",
239 
240  machine_entry_add_alias(me, "barem88k");
241 }
242 
243 
244 MACHINE_REGISTER(oldtestm88k)
245 {
246  MR_DEFAULT(oldtestm88k, "Test-machine for M88K",
248 
249  machine_entry_add_alias(me, "oldtestm88k");
250 }
251 
252 
253 MACHINE_SETUP(baremips)
254 {
255  machine->machine_name = strdup("Generic \"bare\" MIPS machine");
257 }
258 
259 
260 MACHINE_SETUP(oldtestmips)
261 {
262  /*
263  * A MIPS test machine. Originally, this was created as a way for
264  * me to test my master's thesis code; since then it has both
265  * evolved to support new things, and suffered bit rot so that it
266  * no longer can run my thesis code. Well, well...
267  *
268  * IRQ map:
269  * 7 CPU counter
270  * 6 SMP IPIs
271  * 5 not used yet
272  * 4 rtc
273  * 3 ethernet
274  * 2 serial console
275  */
276 
277  char tmpstr[300];
278 
279  machine->machine_name = strdup("MIPS test machine");
281 
282  snprintf(tmpstr, sizeof(tmpstr), "cons addr=0x%" PRIx64" irq=%s."
283  "cpu[%i].2", (uint64_t) DEV_CONS_ADDRESS, machine->path,
285  machine->main_console_handle = (size_t)device_add(machine, tmpstr);
286 
287  snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%" PRIx64" irq=6",
288  (uint64_t) DEV_MP_ADDRESS);
289  device_add(machine, tmpstr);
290 
291  snprintf(tmpstr, sizeof(tmpstr), "fbctrl addr=0x%" PRIx64,
292  (uint64_t) DEV_FBCTRL_ADDRESS);
293  device_add(machine, tmpstr);
294 
295  snprintf(tmpstr, sizeof(tmpstr), "disk addr=0x%" PRIx64,
296  (uint64_t) DEV_DISK_ADDRESS);
297  device_add(machine, tmpstr);
298 
299  snprintf(tmpstr, sizeof(tmpstr), "ether addr=0x%" PRIx64" irq=%s."
300  "cpu[%i].3", (uint64_t) DEV_ETHER_ADDRESS, machine->path,
302  device_add(machine, tmpstr);
303 
304  snprintf(tmpstr, sizeof(tmpstr), "rtc addr=0x%" PRIx64" irq=%s."
305  "cpu[%i].4", (uint64_t) DEV_RTC_ADDRESS, machine->path,
307  device_add(machine, tmpstr);
308 }
309 
310 
312 {
313  machine->cpu_name = strdup("5KE");
314 }
315 
316 
318 {
319  machine->cpu_name = strdup("5KE");
320 }
321 
322 
324 {
325  MR_DEFAULT(baremips, "Generic \"bare\" MIPS machine",
327 
328  machine_entry_add_alias(me, "baremips");
329 }
330 
331 
332 MACHINE_REGISTER(oldtestmips)
333 {
334  MR_DEFAULT(oldtestmips, "Test-machine for MIPS",
336 
337  machine_entry_add_alias(me, "oldtestmips");
338 }
339 
340 
342 {
343  machine->machine_name = strdup("Generic \"bare\" PPC machine");
344 }
345 
346 
348 {
349  machine->machine_name = strdup("PPC test machine");
350 
351  default_test(machine, cpu);
352 }
353 
354 
356 {
357  machine->cpu_name = strdup("PPC970");
358 }
359 
360 
362 {
363  machine->cpu_name = strdup("PPC970");
364 }
365 
366 
368 {
369  MR_DEFAULT(bareppc, "Generic \"bare\" PPC machine",
371 
372  machine_entry_add_alias(me, "bareppc");
373 }
374 
375 
377 {
378  MR_DEFAULT(testppc, "Test-machine for PPC", ARCH_PPC, MACHINE_TESTPPC);
379 
380  machine_entry_add_alias(me, "testppc");
381 }
382 
383 
385 {
386  machine->machine_name = strdup("Generic \"bare\" SH machine");
387 }
388 
389 
391 {
392  machine->machine_name = strdup("SH test machine");
393 
394  default_test(machine, cpu);
395 }
396 
397 
399 {
400  machine->cpu_name = strdup("SH7750");
401 }
402 
403 
405 {
406  machine->cpu_name = strdup("SH7750");
407 }
408 
409 
411 {
412  MR_DEFAULT(baresh, "Generic \"bare\" SH machine",
414 
415  machine_entry_add_alias(me, "baresh");
416 }
417 
418 
420 {
421  MR_DEFAULT(testsh, "Test-machine for SH", ARCH_SH, MACHINE_TESTSH);
422 
423  machine_entry_add_alias(me, "testsh");
424 }
425 
426 
427 
DEV_FBCTRL_ADDRESS
#define DEV_FBCTRL_ADDRESS
Definition: dev_fb.h:15
machine::bootstrap_cpu
int bootstrap_cpu
Definition: machine.h:136
ARCH_PPC
#define ARCH_PPC
Definition: machine.h:204
dev_cons.h
DEV_MP_ADDRESS
#define DEV_MP_ADDRESS
Definition: dev_mp.h:22
MACHINE_TESTPPC
#define MACHINE_TESTPPC
Definition: machine.h:226
MACHINE_TESTM88K
#define MACHINE_TESTM88K
Definition: machine.h:257
machine::physical_ram_in_mb
int physical_ram_in_mb
Definition: machine.h:147
MACHINE_REGISTER
MACHINE_REGISTER(barearm)
Definition: machine_test.cc:191
DEV_ETHER_ADDRESS
#define DEV_ETHER_ADDRESS
Definition: dev_ether.h:11
DEV_RAM_MIRROR
#define DEV_RAM_MIRROR
Definition: devices.h:365
dev_fb.h
cpu::byte_order
uint8_t byte_order
Definition: cpu.h:347
EMUL_BIG_ENDIAN
#define EMUL_BIG_ENDIAN
Definition: misc.h:165
device.h
MACHINE_TESTMIPS
#define MACHINE_TESTMIPS
Definition: machine.h:212
DEV_CONS_ADDRESS
#define DEV_CONS_ADDRESS
Definition: dev_cons.h:11
ARCH_M88K
#define ARCH_M88K
Definition: machine.h:208
MACHINE_DEFAULT_CPU
MACHINE_DEFAULT_CPU(barearm)
Definition: machine_test.cc:179
dev_disk.h
DEV_IRQC_ADDRESS
#define DEV_IRQC_ADDRESS
Definition: dev_irqc.h:10
ARCH_MIPS
#define ARCH_MIPS
Definition: machine.h:203
machine::cpu_name
char * cpu_name
Definition: machine.h:133
MACHINE_TESTARM
#define MACHINE_TESTARM
Definition: machine.h:239
misc.h
DEV_DISK_ADDRESS
#define DEV_DISK_ADDRESS
Definition: dev_disk.h:11
dev_irqc.h
cpu::cd
union cpu::@1 cd
device_add
void * device_add(struct machine *machine, const char *name_and_params)
Definition: device.cc:252
machine.h
machine
Definition: machine.h:97
machine::main_console_handle
int main_console_handle
Definition: machine.h:128
ARCH_SH
#define ARCH_SH
Definition: machine.h:207
ARM_LR
#define ARM_LR
Definition: cpu_arm.h:55
MR_DEFAULT
#define MR_DEFAULT(x, name, arch, type)
Definition: machine.h:370
dev_mp.h
arm_cpu::r
uint32_t r[N_ARM_REGS]
Definition: cpu_arm.h:155
MACHINE_TESTSH
#define MACHINE_TESTSH
Definition: machine.h:250
SH4_INTEVT_IRQ15
#define SH4_INTEVT_IRQ15
Definition: sh4_exception.h:157
cpu.h
machine::path
char * path
Definition: machine.h:108
MACHINE_BAREMIPS
#define MACHINE_BAREMIPS
Definition: machine.h:211
sh4_exception.h
dev_rtc.h
MACHINE_BAREM88K
#define MACHINE_BAREM88K
Definition: machine.h:256
DEV_RTC_ADDRESS
#define DEV_RTC_ADDRESS
Definition: dev_rtc.h:11
DEV_RAM_MIGHT_POINT_TO_DEVICES
#define DEV_RAM_MIGHT_POINT_TO_DEVICES
Definition: devices.h:366
MACHINE_BARESH
#define MACHINE_BARESH
Definition: machine.h:249
cpu::arm
struct arm_cpu arm
Definition: cpu.h:441
store_32bit_word
int store_32bit_word(struct cpu *cpu, uint64_t addr, uint64_t data32)
Definition: memory.cc:783
ARCH_ARM
#define ARCH_ARM
Definition: machine.h:206
MACHINE_BAREARM
#define MACHINE_BAREARM
Definition: machine.h:238
MACHINE_BAREPPC
#define MACHINE_BAREPPC
Definition: machine.h:225
devices.h
machine::machine_name
const char * machine_name
Definition: machine.h:115
cpu
Definition: cpu.h:326
machine_entry_add_alias
void machine_entry_add_alias(struct machine_entry *me, const char *name)
Definition: machine.cc:697
ARM_SP
#define ARM_SP
Definition: cpu_arm.h:54
machine::arch
int arch
Definition: machine.h:110
dev_ram_init
void dev_ram_init(struct machine *machine, uint64_t baseaddr, uint64_t length, int mode, uint64_t otheraddress, const char *name)
Definition: dev_ram.cc:134
memory.h
MACHINE_SETUP
MACHINE_SETUP(barearm)
Definition: machine_test.cc:145
dev_ether.h

Generated on Tue Mar 24 2020 14:04:48 for GXemul by doxygen 1.8.17