root / hw / moxie / moxiesim.c @ f487b677
History | View | Annotate | Download (5.6 kB)
1 | a360d965 | Anthony Green | /*
|
---|---|---|---|
2 | a360d965 | Anthony Green | * QEMU/moxiesim emulation
|
3 | a360d965 | Anthony Green | *
|
4 | 805a2505 | Stefan Weil | * Emulates a very simple machine model similar to the one used by the
|
5 | a360d965 | Anthony Green | * GDB moxie simulator.
|
6 | a360d965 | Anthony Green | *
|
7 | a360d965 | Anthony Green | * Copyright (c) 2008, 2009, 2010, 2013 Anthony Green
|
8 | a360d965 | Anthony Green | *
|
9 | a360d965 | Anthony Green | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
10 | a360d965 | Anthony Green | * of this software and associated documentation files (the "Software"), to deal
|
11 | a360d965 | Anthony Green | * in the Software without restriction, including without limitation the rights
|
12 | a360d965 | Anthony Green | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
13 | a360d965 | Anthony Green | * copies of the Software, and to permit persons to whom the Software is
|
14 | a360d965 | Anthony Green | * furnished to do so, subject to the following conditions:
|
15 | a360d965 | Anthony Green | *
|
16 | a360d965 | Anthony Green | * The above copyright notice and this permission notice shall be included in
|
17 | a360d965 | Anthony Green | * all copies or substantial portions of the Software.
|
18 | a360d965 | Anthony Green | *
|
19 | a360d965 | Anthony Green | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
20 | a360d965 | Anthony Green | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
21 | a360d965 | Anthony Green | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
22 | a360d965 | Anthony Green | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
23 | a360d965 | Anthony Green | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
24 | a360d965 | Anthony Green | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
25 | a360d965 | Anthony Green | * THE SOFTWARE.
|
26 | a360d965 | Anthony Green | */
|
27 | a360d965 | Anthony Green | #include "hw/sysbus.h" |
28 | a360d965 | Anthony Green | #include "hw/hw.h" |
29 | 0d09e41a | Paolo Bonzini | #include "hw/i386/pc.h" |
30 | 0d09e41a | Paolo Bonzini | #include "hw/isa/isa.h" |
31 | a360d965 | Anthony Green | #include "net/net.h" |
32 | a360d965 | Anthony Green | #include "sysemu/sysemu.h" |
33 | a360d965 | Anthony Green | #include "hw/boards.h" |
34 | a360d965 | Anthony Green | #include "hw/loader.h" |
35 | 0d09e41a | Paolo Bonzini | #include "hw/char/serial.h" |
36 | a360d965 | Anthony Green | #include "exec/address-spaces.h" |
37 | a360d965 | Anthony Green | |
38 | a360d965 | Anthony Green | #define PHYS_MEM_BASE 0x80000000 |
39 | a360d965 | Anthony Green | |
40 | a360d965 | Anthony Green | typedef struct { |
41 | a360d965 | Anthony Green | uint64_t ram_size; |
42 | a360d965 | Anthony Green | const char *kernel_filename; |
43 | a360d965 | Anthony Green | const char *kernel_cmdline; |
44 | a360d965 | Anthony Green | const char *initrd_filename; |
45 | a360d965 | Anthony Green | } LoaderParams; |
46 | a360d965 | Anthony Green | |
47 | a360d965 | Anthony Green | static void load_kernel(MoxieCPU *cpu, LoaderParams *loader_params) |
48 | a360d965 | Anthony Green | { |
49 | a360d965 | Anthony Green | uint64_t entry, kernel_low, kernel_high; |
50 | a360d965 | Anthony Green | long kernel_size;
|
51 | a360d965 | Anthony Green | long initrd_size;
|
52 | a360d965 | Anthony Green | ram_addr_t initrd_offset; |
53 | a360d965 | Anthony Green | |
54 | a360d965 | Anthony Green | kernel_size = load_elf(loader_params->kernel_filename, NULL, NULL, |
55 | a360d965 | Anthony Green | &entry, &kernel_low, &kernel_high, 1,
|
56 | a360d965 | Anthony Green | ELF_MACHINE, 0);
|
57 | a360d965 | Anthony Green | |
58 | a360d965 | Anthony Green | if (!kernel_size) {
|
59 | a360d965 | Anthony Green | fprintf(stderr, "qemu: could not load kernel '%s'\n",
|
60 | a360d965 | Anthony Green | loader_params->kernel_filename); |
61 | a360d965 | Anthony Green | exit(1);
|
62 | a360d965 | Anthony Green | } |
63 | a360d965 | Anthony Green | |
64 | a360d965 | Anthony Green | /* load initrd */
|
65 | a360d965 | Anthony Green | initrd_size = 0;
|
66 | a360d965 | Anthony Green | initrd_offset = 0;
|
67 | a360d965 | Anthony Green | if (loader_params->initrd_filename) {
|
68 | a360d965 | Anthony Green | initrd_size = get_image_size(loader_params->initrd_filename); |
69 | a360d965 | Anthony Green | if (initrd_size > 0) { |
70 | a360d965 | Anthony Green | initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) |
71 | a360d965 | Anthony Green | & TARGET_PAGE_MASK; |
72 | a360d965 | Anthony Green | if (initrd_offset + initrd_size > loader_params->ram_size) {
|
73 | a360d965 | Anthony Green | fprintf(stderr, |
74 | a360d965 | Anthony Green | "qemu: memory too small for initial ram disk '%s'\n",
|
75 | a360d965 | Anthony Green | loader_params->initrd_filename); |
76 | a360d965 | Anthony Green | exit(1);
|
77 | a360d965 | Anthony Green | } |
78 | a360d965 | Anthony Green | initrd_size = load_image_targphys(loader_params->initrd_filename, |
79 | a360d965 | Anthony Green | initrd_offset, |
80 | a360d965 | Anthony Green | ram_size); |
81 | a360d965 | Anthony Green | } |
82 | a360d965 | Anthony Green | if (initrd_size == (target_ulong)-1) { |
83 | a360d965 | Anthony Green | fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
|
84 | a360d965 | Anthony Green | loader_params->initrd_filename); |
85 | a360d965 | Anthony Green | exit(1);
|
86 | a360d965 | Anthony Green | } |
87 | a360d965 | Anthony Green | } |
88 | a360d965 | Anthony Green | } |
89 | a360d965 | Anthony Green | |
90 | a360d965 | Anthony Green | static void main_cpu_reset(void *opaque) |
91 | a360d965 | Anthony Green | { |
92 | a360d965 | Anthony Green | MoxieCPU *cpu = opaque; |
93 | a360d965 | Anthony Green | |
94 | a360d965 | Anthony Green | cpu_reset(CPU(cpu)); |
95 | a360d965 | Anthony Green | } |
96 | a360d965 | Anthony Green | |
97 | a360d965 | Anthony Green | static inline DeviceState * |
98 | a360d965 | Anthony Green | moxie_intc_create(hwaddr base, qemu_irq irq, int kind_of_intr)
|
99 | a360d965 | Anthony Green | { |
100 | a360d965 | Anthony Green | DeviceState *dev; |
101 | a360d965 | Anthony Green | |
102 | a360d965 | Anthony Green | dev = qdev_create(NULL, "moxie,intc"); |
103 | a360d965 | Anthony Green | qdev_prop_set_uint32(dev, "kind-of-intr", kind_of_intr);
|
104 | a360d965 | Anthony Green | qdev_init_nofail(dev); |
105 | a360d965 | Anthony Green | sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
|
106 | a360d965 | Anthony Green | sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
|
107 | a360d965 | Anthony Green | return dev;
|
108 | a360d965 | Anthony Green | } |
109 | a360d965 | Anthony Green | |
110 | a360d965 | Anthony Green | static void moxiesim_init(QEMUMachineInitArgs *args) |
111 | a360d965 | Anthony Green | { |
112 | a360d965 | Anthony Green | MoxieCPU *cpu = NULL;
|
113 | a360d965 | Anthony Green | ram_addr_t ram_size = args->ram_size; |
114 | a360d965 | Anthony Green | const char *cpu_model = args->cpu_model; |
115 | a360d965 | Anthony Green | const char *kernel_filename = args->kernel_filename; |
116 | a360d965 | Anthony Green | const char *kernel_cmdline = args->kernel_cmdline; |
117 | a360d965 | Anthony Green | const char *initrd_filename = args->initrd_filename; |
118 | a360d965 | Anthony Green | CPUMoxieState *env; |
119 | a360d965 | Anthony Green | MemoryRegion *address_space_mem = get_system_memory(); |
120 | a360d965 | Anthony Green | MemoryRegion *ram = g_new(MemoryRegion, 1);
|
121 | a360d965 | Anthony Green | MemoryRegion *rom = g_new(MemoryRegion, 1);
|
122 | a360d965 | Anthony Green | hwaddr ram_base = 0x200000;
|
123 | a360d965 | Anthony Green | LoaderParams loader_params; |
124 | a360d965 | Anthony Green | |
125 | a360d965 | Anthony Green | /* Init CPUs. */
|
126 | a360d965 | Anthony Green | if (cpu_model == NULL) { |
127 | a360d965 | Anthony Green | cpu_model = "MoxieLite-moxie-cpu";
|
128 | a360d965 | Anthony Green | } |
129 | a360d965 | Anthony Green | cpu = cpu_moxie_init(cpu_model); |
130 | a360d965 | Anthony Green | if (!cpu) {
|
131 | a360d965 | Anthony Green | fprintf(stderr, "Unable to find CPU definition\n");
|
132 | a360d965 | Anthony Green | exit(1);
|
133 | a360d965 | Anthony Green | } |
134 | a360d965 | Anthony Green | env = &cpu->env; |
135 | a360d965 | Anthony Green | |
136 | a360d965 | Anthony Green | qemu_register_reset(main_cpu_reset, cpu); |
137 | a360d965 | Anthony Green | |
138 | a360d965 | Anthony Green | /* Allocate RAM. */
|
139 | a360d965 | Anthony Green | memory_region_init_ram(ram, "moxiesim.ram", ram_size);
|
140 | a360d965 | Anthony Green | vmstate_register_ram_global(ram); |
141 | a360d965 | Anthony Green | memory_region_add_subregion(address_space_mem, ram_base, ram); |
142 | a360d965 | Anthony Green | |
143 | a360d965 | Anthony Green | memory_region_init_ram(rom, "moxie.rom", 128*0x1000); |
144 | a360d965 | Anthony Green | vmstate_register_ram_global(rom); |
145 | a360d965 | Anthony Green | memory_region_add_subregion(get_system_memory(), 0x1000, rom);
|
146 | a360d965 | Anthony Green | |
147 | a360d965 | Anthony Green | if (kernel_filename) {
|
148 | a360d965 | Anthony Green | loader_params.ram_size = ram_size; |
149 | a360d965 | Anthony Green | loader_params.kernel_filename = kernel_filename; |
150 | a360d965 | Anthony Green | loader_params.kernel_cmdline = kernel_cmdline; |
151 | a360d965 | Anthony Green | loader_params.initrd_filename = initrd_filename; |
152 | a360d965 | Anthony Green | load_kernel(cpu, &loader_params); |
153 | a360d965 | Anthony Green | } |
154 | a360d965 | Anthony Green | |
155 | a360d965 | Anthony Green | /* A single 16450 sits at offset 0x3f8. */
|
156 | a360d965 | Anthony Green | if (serial_hds[0]) { |
157 | a360d965 | Anthony Green | serial_mm_init(address_space_mem, 0x3f8, 0, env->irq[4], |
158 | a360d965 | Anthony Green | 8000000/16, serial_hds[0], DEVICE_LITTLE_ENDIAN); |
159 | a360d965 | Anthony Green | } |
160 | a360d965 | Anthony Green | } |
161 | a360d965 | Anthony Green | |
162 | a360d965 | Anthony Green | static QEMUMachine moxiesim_machine = {
|
163 | a360d965 | Anthony Green | .name = "moxiesim",
|
164 | a360d965 | Anthony Green | .desc = "Moxie simulator platform",
|
165 | a360d965 | Anthony Green | .init = moxiesim_init, |
166 | a360d965 | Anthony Green | .is_default = 1,
|
167 | a360d965 | Anthony Green | }; |
168 | a360d965 | Anthony Green | |
169 | a360d965 | Anthony Green | static void moxie_machine_init(void) |
170 | a360d965 | Anthony Green | { |
171 | a360d965 | Anthony Green | qemu_register_machine(&moxiesim_machine); |
172 | a360d965 | Anthony Green | } |
173 | a360d965 | Anthony Green | |
174 | a360d965 | Anthony Green | machine_init(moxie_machine_init) |