Merge remote-tracking branch 'remotes/riscv/tags/riscv-for-master-3.1-sf0' into staging
[qemu.git] / hw / lm32 / lm32_boards.c
1 /*
2  *  QEMU models for LatticeMico32 uclinux and evr32 boards.
3  *
4  *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "qemu/osdep.h"
21 #include "qemu/units.h"
22 #include "qemu/error-report.h"
23 #include "qemu-common.h"
24 #include "cpu.h"
25 #include "hw/sysbus.h"
26 #include "hw/hw.h"
27 #include "hw/block/flash.h"
28 #include "hw/devices.h"
29 #include "hw/boards.h"
30 #include "hw/loader.h"
31 #include "elf.h"
32 #include "lm32_hwsetup.h"
33 #include "lm32.h"
34 #include "exec/address-spaces.h"
35 #include "sysemu/sysemu.h"
36
37 typedef struct {
38     LM32CPU *cpu;
39     hwaddr bootstrap_pc;
40     hwaddr flash_base;
41     hwaddr hwsetup_base;
42     hwaddr initrd_base;
43     size_t initrd_size;
44     hwaddr cmdline_base;
45 } ResetInfo;
46
47 static void cpu_irq_handler(void *opaque, int irq, int level)
48 {
49     LM32CPU *cpu = opaque;
50     CPUState *cs = CPU(cpu);
51
52     if (level) {
53         cpu_interrupt(cs, CPU_INTERRUPT_HARD);
54     } else {
55         cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
56     }
57 }
58
59 static void main_cpu_reset(void *opaque)
60 {
61     ResetInfo *reset_info = opaque;
62     CPULM32State *env = &reset_info->cpu->env;
63
64     cpu_reset(CPU(reset_info->cpu));
65
66     /* init defaults */
67     env->pc = (uint32_t)reset_info->bootstrap_pc;
68     env->regs[R_R1] = (uint32_t)reset_info->hwsetup_base;
69     env->regs[R_R2] = (uint32_t)reset_info->cmdline_base;
70     env->regs[R_R3] = (uint32_t)reset_info->initrd_base;
71     env->regs[R_R4] = (uint32_t)(reset_info->initrd_base +
72         reset_info->initrd_size);
73     env->eba = reset_info->flash_base;
74     env->deba = reset_info->flash_base;
75 }
76
77 static void lm32_evr_init(MachineState *machine)
78 {
79     const char *kernel_filename = machine->kernel_filename;
80     LM32CPU *cpu;
81     CPULM32State *env;
82     DriveInfo *dinfo;
83     MemoryRegion *address_space_mem =  get_system_memory();
84     MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
85     qemu_irq irq[32];
86     ResetInfo *reset_info;
87     int i;
88
89     /* memory map */
90     hwaddr flash_base  = 0x04000000;
91     size_t flash_sector_size       = 256 * KiB;
92     size_t flash_size              = 32 * MiB;
93     hwaddr ram_base    = 0x08000000;
94     size_t ram_size                = 64 * MiB;
95     hwaddr timer0_base = 0x80002000;
96     hwaddr uart0_base  = 0x80006000;
97     hwaddr timer1_base = 0x8000a000;
98     int uart0_irq                  = 0;
99     int timer0_irq                 = 1;
100     int timer1_irq                 = 3;
101
102     reset_info = g_malloc0(sizeof(ResetInfo));
103
104     cpu = LM32_CPU(cpu_create(machine->cpu_type));
105
106     env = &cpu->env;
107     reset_info->cpu = cpu;
108
109     reset_info->flash_base = flash_base;
110
111     memory_region_allocate_system_memory(phys_ram, NULL, "lm32_evr.sdram",
112                                          ram_size);
113     memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
114
115     dinfo = drive_get(IF_PFLASH, 0, 0);
116     /* Spansion S29NS128P */
117     pflash_cfi02_register(flash_base, NULL, "lm32_evr.flash", flash_size,
118                           dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
119                           flash_sector_size, flash_size / flash_sector_size,
120                           1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
121
122     /* create irq lines */
123     env->pic_state = lm32_pic_init(qemu_allocate_irq(cpu_irq_handler, cpu, 0));
124     for (i = 0; i < 32; i++) {
125         irq[i] = qdev_get_gpio_in(env->pic_state, i);
126     }
127
128     lm32_uart_create(uart0_base, irq[uart0_irq], serial_hd(0));
129     sysbus_create_simple("lm32-timer", timer0_base, irq[timer0_irq]);
130     sysbus_create_simple("lm32-timer", timer1_base, irq[timer1_irq]);
131
132     /* make sure juart isn't the first chardev */
133     env->juart_state = lm32_juart_init(serial_hd(1));
134
135     reset_info->bootstrap_pc = flash_base;
136
137     if (kernel_filename) {
138         uint64_t entry;
139         int kernel_size;
140
141         kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL,
142                                1, EM_LATTICEMICO32, 0, 0);
143         reset_info->bootstrap_pc = entry;
144
145         if (kernel_size < 0) {
146             kernel_size = load_image_targphys(kernel_filename, ram_base,
147                                               ram_size);
148             reset_info->bootstrap_pc = ram_base;
149         }
150
151         if (kernel_size < 0) {
152             error_report("could not load kernel '%s'", kernel_filename);
153             exit(1);
154         }
155     }
156
157     qemu_register_reset(main_cpu_reset, reset_info);
158 }
159
160 static void lm32_uclinux_init(MachineState *machine)
161 {
162     const char *kernel_filename = machine->kernel_filename;
163     const char *kernel_cmdline = machine->kernel_cmdline;
164     const char *initrd_filename = machine->initrd_filename;
165     LM32CPU *cpu;
166     CPULM32State *env;
167     DriveInfo *dinfo;
168     MemoryRegion *address_space_mem =  get_system_memory();
169     MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
170     qemu_irq irq[32];
171     HWSetup *hw;
172     ResetInfo *reset_info;
173     int i;
174
175     /* memory map */
176     hwaddr flash_base   = 0x04000000;
177     size_t flash_sector_size        = 256 * KiB;
178     size_t flash_size               = 32 * MiB;
179     hwaddr ram_base     = 0x08000000;
180     size_t ram_size                 = 64 * MiB;
181     hwaddr uart0_base   = 0x80000000;
182     hwaddr timer0_base  = 0x80002000;
183     hwaddr timer1_base  = 0x80010000;
184     hwaddr timer2_base  = 0x80012000;
185     int uart0_irq                   = 0;
186     int timer0_irq                  = 1;
187     int timer1_irq                  = 20;
188     int timer2_irq                  = 21;
189     hwaddr hwsetup_base = 0x0bffe000;
190     hwaddr cmdline_base = 0x0bfff000;
191     hwaddr initrd_base  = 0x08400000;
192     size_t initrd_max               = 0x01000000;
193
194     reset_info = g_malloc0(sizeof(ResetInfo));
195
196     cpu = LM32_CPU(cpu_create(machine->cpu_type));
197
198     env = &cpu->env;
199     reset_info->cpu = cpu;
200
201     reset_info->flash_base = flash_base;
202
203     memory_region_allocate_system_memory(phys_ram, NULL,
204                                          "lm32_uclinux.sdram", ram_size);
205     memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
206
207     dinfo = drive_get(IF_PFLASH, 0, 0);
208     /* Spansion S29NS128P */
209     pflash_cfi02_register(flash_base, NULL, "lm32_uclinux.flash", flash_size,
210                           dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
211                           flash_sector_size, flash_size / flash_sector_size,
212                           1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
213
214     /* create irq lines */
215     env->pic_state = lm32_pic_init(qemu_allocate_irq(cpu_irq_handler, env, 0));
216     for (i = 0; i < 32; i++) {
217         irq[i] = qdev_get_gpio_in(env->pic_state, i);
218     }
219
220     lm32_uart_create(uart0_base, irq[uart0_irq], serial_hd(0));
221     sysbus_create_simple("lm32-timer", timer0_base, irq[timer0_irq]);
222     sysbus_create_simple("lm32-timer", timer1_base, irq[timer1_irq]);
223     sysbus_create_simple("lm32-timer", timer2_base, irq[timer2_irq]);
224
225     /* make sure juart isn't the first chardev */
226     env->juart_state = lm32_juart_init(serial_hd(1));
227
228     reset_info->bootstrap_pc = flash_base;
229
230     if (kernel_filename) {
231         uint64_t entry;
232         int kernel_size;
233
234         kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL,
235                                1, EM_LATTICEMICO32, 0, 0);
236         reset_info->bootstrap_pc = entry;
237
238         if (kernel_size < 0) {
239             kernel_size = load_image_targphys(kernel_filename, ram_base,
240                                               ram_size);
241             reset_info->bootstrap_pc = ram_base;
242         }
243
244         if (kernel_size < 0) {
245             error_report("could not load kernel '%s'", kernel_filename);
246             exit(1);
247         }
248     }
249
250     /* generate a rom with the hardware description */
251     hw = hwsetup_init();
252     hwsetup_add_cpu(hw, "LM32", 75000000);
253     hwsetup_add_flash(hw, "flash", flash_base, flash_size);
254     hwsetup_add_ddr_sdram(hw, "ddr_sdram", ram_base, ram_size);
255     hwsetup_add_timer(hw, "timer0", timer0_base, timer0_irq);
256     hwsetup_add_timer(hw, "timer1_dev_only", timer1_base, timer1_irq);
257     hwsetup_add_timer(hw, "timer2_dev_only", timer2_base, timer2_irq);
258     hwsetup_add_uart(hw, "uart", uart0_base, uart0_irq);
259     hwsetup_add_trailer(hw);
260     hwsetup_create_rom(hw, hwsetup_base);
261     hwsetup_free(hw);
262
263     reset_info->hwsetup_base = hwsetup_base;
264
265     if (kernel_cmdline && strlen(kernel_cmdline)) {
266         pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE,
267                 kernel_cmdline);
268         reset_info->cmdline_base = cmdline_base;
269     }
270
271     if (initrd_filename) {
272         size_t initrd_size;
273         initrd_size = load_image_targphys(initrd_filename, initrd_base,
274                 initrd_max);
275         reset_info->initrd_base = initrd_base;
276         reset_info->initrd_size = initrd_size;
277     }
278
279     qemu_register_reset(main_cpu_reset, reset_info);
280 }
281
282 static void lm32_evr_class_init(ObjectClass *oc, void *data)
283 {
284     MachineClass *mc = MACHINE_CLASS(oc);
285
286     mc->desc = "LatticeMico32 EVR32 eval system";
287     mc->init = lm32_evr_init;
288     mc->is_default = 1;
289     mc->default_cpu_type = LM32_CPU_TYPE_NAME("lm32-full");
290 }
291
292 static const TypeInfo lm32_evr_type = {
293     .name = MACHINE_TYPE_NAME("lm32-evr"),
294     .parent = TYPE_MACHINE,
295     .class_init = lm32_evr_class_init,
296 };
297
298 static void lm32_uclinux_class_init(ObjectClass *oc, void *data)
299 {
300     MachineClass *mc = MACHINE_CLASS(oc);
301
302     mc->desc = "lm32 platform for uClinux and u-boot by Theobroma Systems";
303     mc->init = lm32_uclinux_init;
304     mc->is_default = 0;
305     mc->default_cpu_type = LM32_CPU_TYPE_NAME("lm32-full");
306 }
307
308 static const TypeInfo lm32_uclinux_type = {
309     .name = MACHINE_TYPE_NAME("lm32-uclinux"),
310     .parent = TYPE_MACHINE,
311     .class_init = lm32_uclinux_class_init,
312 };
313
314 static void lm32_machine_init(void)
315 {
316     type_register_static(&lm32_evr_type);
317     type_register_static(&lm32_uclinux_type);
318 }
319
320 type_init(lm32_machine_init)
This page took 0.041769 seconds and 4 git commands to generate.