|
|
1.1 root 1: /*
2: * QEMU MIPS Jazz support
3: *
4: * Copyright (c) 2007-2008 Hervé Poussineau
5: *
6: * Permission is hereby granted, free of charge, to any person obtaining a copy
7: * of this software and associated documentation files (the "Software"), to deal
8: * in the Software without restriction, including without limitation the rights
9: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10: * copies of the Software, and to permit persons to whom the Software is
11: * furnished to do so, subject to the following conditions:
12: *
13: * The above copyright notice and this permission notice shall be included in
14: * all copies or substantial portions of the Software.
15: *
16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22: * THE SOFTWARE.
23: */
24:
25: #include "hw.h"
26: #include "mips.h"
1.1.1.4 ! root 27: #include "mips_cpudevs.h"
1.1 root 28: #include "pc.h"
29: #include "isa.h"
30: #include "fdc.h"
31: #include "sysemu.h"
32: #include "audio/audio.h"
33: #include "boards.h"
34: #include "net.h"
1.1.1.3 root 35: #include "esp.h"
1.1.1.2 root 36: #include "mips-bios.h"
1.1.1.3 root 37: #include "loader.h"
1.1.1.4 ! root 38: #include "mc146818rtc.h"
1.1 root 39:
40: enum jazz_model_e
41: {
42: JAZZ_MAGNUM,
43: JAZZ_PICA61,
44: };
45:
46: static void main_cpu_reset(void *opaque)
47: {
48: CPUState *env = opaque;
49: cpu_reset(env);
50: }
51:
52: static uint32_t rtc_readb(void *opaque, target_phys_addr_t addr)
53: {
1.1.1.3 root 54: return cpu_inw(0x71);
1.1 root 55: }
56:
57: static void rtc_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
58: {
1.1.1.3 root 59: cpu_outw(0x71, val & 0xff);
1.1 root 60: }
61:
1.1.1.3 root 62: static CPUReadMemoryFunc * const rtc_read[3] = {
1.1 root 63: rtc_readb,
64: rtc_readb,
65: rtc_readb,
66: };
67:
1.1.1.3 root 68: static CPUWriteMemoryFunc * const rtc_write[3] = {
1.1 root 69: rtc_writeb,
70: rtc_writeb,
71: rtc_writeb,
72: };
73:
74: static void dma_dummy_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
75: {
76: /* Nothing to do. That is only to ensure that
77: * the current DMA acknowledge cycle is completed. */
78: }
79:
1.1.1.3 root 80: static CPUReadMemoryFunc * const dma_dummy_read[3] = {
1.1 root 81: NULL,
82: NULL,
83: NULL,
84: };
85:
1.1.1.3 root 86: static CPUWriteMemoryFunc * const dma_dummy_write[3] = {
1.1 root 87: dma_dummy_writeb,
88: dma_dummy_writeb,
89: dma_dummy_writeb,
90: };
91:
92: static void audio_init(qemu_irq *pic)
93: {
94: struct soundhw *c;
95: int audio_enabled = 0;
96:
97: for (c = soundhw; !audio_enabled && c->name; ++c) {
98: audio_enabled = c->enabled;
99: }
100:
101: if (audio_enabled) {
1.1.1.2 root 102: for (c = soundhw; c->name; ++c) {
103: if (c->enabled) {
104: if (c->isa) {
105: c->init.init_isa(pic);
1.1 root 106: }
107: }
108: }
109: }
110: }
111:
112: #define MAGNUM_BIOS_SIZE_MAX 0x7e000
113: #define MAGNUM_BIOS_SIZE (BIOS_SIZE < MAGNUM_BIOS_SIZE_MAX ? BIOS_SIZE : MAGNUM_BIOS_SIZE_MAX)
114:
1.1.1.4 ! root 115: static void cpu_request_exit(void *opaque, int irq, int level)
! 116: {
! 117: CPUState *env = cpu_single_env;
! 118:
! 119: if (env && level) {
! 120: cpu_exit(env);
! 121: }
! 122: }
! 123:
1.1 root 124: static
1.1.1.2 root 125: void mips_jazz_init (ram_addr_t ram_size,
1.1 root 126: const char *cpu_model,
127: enum jazz_model_e jazz_model)
128: {
1.1.1.2 root 129: char *filename;
1.1 root 130: int bios_size, n;
131: CPUState *env;
132: qemu_irq *rc4030, *i8259;
133: rc4030_dma *dmas;
1.1.1.2 root 134: void* rc4030_opaque;
1.1 root 135: int s_rtc, s_dma_dummy;
1.1.1.2 root 136: NICInfo *nd;
1.1 root 137: PITState *pit;
1.1.1.3 root 138: DriveInfo *fds[MAX_FD];
1.1 root 139: qemu_irq esp_reset;
1.1.1.4 ! root 140: qemu_irq *cpu_exit_irq;
1.1.1.2 root 141: ram_addr_t ram_offset;
142: ram_addr_t bios_offset;
1.1 root 143:
144: /* init CPUs */
145: if (cpu_model == NULL) {
146: #ifdef TARGET_MIPS64
147: cpu_model = "R4000";
148: #else
149: /* FIXME: All wrong, this maybe should be R3000 for the older JAZZs. */
150: cpu_model = "24Kf";
151: #endif
152: }
153: env = cpu_init(cpu_model);
154: if (!env) {
155: fprintf(stderr, "Unable to find CPU definition\n");
156: exit(1);
157: }
158: qemu_register_reset(main_cpu_reset, env);
159:
160: /* allocate RAM */
1.1.1.4 ! root 161: ram_offset = qemu_ram_alloc(NULL, "mips_jazz.ram", ram_size);
1.1.1.2 root 162: cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
163:
1.1.1.4 ! root 164: bios_offset = qemu_ram_alloc(NULL, "mips_jazz.bios", MAGNUM_BIOS_SIZE);
1.1.1.2 root 165: cpu_register_physical_memory(0x1fc00000LL,
166: MAGNUM_BIOS_SIZE, bios_offset | IO_MEM_ROM);
167: cpu_register_physical_memory(0xfff00000LL,
168: MAGNUM_BIOS_SIZE, bios_offset | IO_MEM_ROM);
1.1 root 169:
170: /* load the BIOS image. */
171: if (bios_name == NULL)
172: bios_name = BIOS_FILENAME;
1.1.1.2 root 173: filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
174: if (filename) {
175: bios_size = load_image_targphys(filename, 0xfff00000LL,
176: MAGNUM_BIOS_SIZE);
177: qemu_free(filename);
178: } else {
179: bios_size = -1;
180: }
1.1 root 181: if (bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE) {
182: fprintf(stderr, "qemu: Could not load MIPS bios '%s'\n",
1.1.1.2 root 183: bios_name);
1.1 root 184: exit(1);
185: }
186:
187: /* Init CPU internal devices */
188: cpu_mips_irq_init_cpu(env);
189: cpu_mips_clock_init(env);
190:
191: /* Chipset */
1.1.1.2 root 192: rc4030_opaque = rc4030_init(env->irq[6], env->irq[3], &rc4030, &dmas);
193: s_dma_dummy = cpu_register_io_memory(dma_dummy_read, dma_dummy_write, NULL);
1.1 root 194: cpu_register_physical_memory(0x8000d000, 0x00001000, s_dma_dummy);
195:
196: /* ISA devices */
197: i8259 = i8259_init(env->irq[4]);
1.1.1.3 root 198: isa_bus_new(NULL);
199: isa_bus_irqs(i8259);
1.1.1.4 ! root 200: cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
! 201: DMA_init(0, cpu_exit_irq);
1.1 root 202: pit = pit_init(0x40, i8259[0]);
203: pcspk_init(pit);
204:
205: /* ISA IO space at 0x90000000 */
1.1.1.4 ! root 206: #ifdef TARGET_WORDS_BIGENDIAN
! 207: isa_mmio_init(0x90000000, 0x01000000, 1);
! 208: #else
! 209: isa_mmio_init(0x90000000, 0x01000000, 0);
! 210: #endif
! 211:
1.1 root 212: isa_mem_base = 0x11000000;
213:
214: /* Video card */
215: switch (jazz_model) {
216: case JAZZ_MAGNUM:
1.1.1.2 root 217: g364fb_mm_init(0x40000000, 0x60000000, 0, rc4030[3]);
1.1 root 218: break;
219: case JAZZ_PICA61:
1.1.1.2 root 220: isa_vga_mm_init(0x40000000, 0x60000000, 0);
1.1 root 221: break;
222: default:
223: break;
224: }
225:
226: /* Network controller */
1.1.1.2 root 227: for (n = 0; n < nb_nics; n++) {
228: nd = &nd_table[n];
229: if (!nd->model)
1.1.1.3 root 230: nd->model = qemu_strdup("dp83932");
1.1.1.2 root 231: if (strcmp(nd->model, "dp83932") == 0) {
232: dp83932_init(nd, 0x80001000, 2, rc4030[4],
233: rc4030_opaque, rc4030_dma_memory_rw);
234: break;
235: } else if (strcmp(nd->model, "?") == 0) {
236: fprintf(stderr, "qemu: Supported NICs: dp83932\n");
237: exit(1);
238: } else {
239: fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model);
240: exit(1);
1.1 root 241: }
242: }
243:
1.1.1.2 root 244: /* SCSI adapter */
245: esp_init(0x80002000, 0,
246: rc4030_dma_read, rc4030_dma_write, dmas[0],
247: rc4030[5], &esp_reset);
248:
1.1 root 249: /* Floppy */
250: if (drive_get_max_bus(IF_FLOPPY) >= MAX_FD) {
251: fprintf(stderr, "qemu: too many floppy drives\n");
252: exit(1);
253: }
254: for (n = 0; n < MAX_FD; n++) {
1.1.1.3 root 255: fds[n] = drive_get(IF_FLOPPY, 0, n);
1.1 root 256: }
1.1.1.3 root 257: fdctrl_init_sysbus(rc4030[1], 0, 0x80003000, fds);
1.1 root 258:
259: /* Real time clock */
1.1.1.4 ! root 260: rtc_init(1980, NULL);
1.1.1.3 root 261: s_rtc = cpu_register_io_memory(rtc_read, rtc_write, NULL);
1.1 root 262: cpu_register_physical_memory(0x80004000, 0x00001000, s_rtc);
263:
264: /* Keyboard (i8042) */
265: i8042_mm_init(rc4030[6], rc4030[7], 0x80005000, 0x1000, 0x1);
266:
267: /* Serial ports */
1.1.1.4 ! root 268: if (serial_hds[0]) {
! 269: #ifdef TARGET_WORDS_BIGENDIAN
! 270: serial_mm_init(0x80006000, 0, rc4030[8], 8000000/16, serial_hds[0], 1, 1);
! 271: #else
! 272: serial_mm_init(0x80006000, 0, rc4030[8], 8000000/16, serial_hds[0], 1, 0);
! 273: #endif
! 274: }
! 275: if (serial_hds[1]) {
! 276: #ifdef TARGET_WORDS_BIGENDIAN
! 277: serial_mm_init(0x80007000, 0, rc4030[9], 8000000/16, serial_hds[1], 1, 1);
! 278: #else
! 279: serial_mm_init(0x80007000, 0, rc4030[9], 8000000/16, serial_hds[1], 1, 0);
! 280: #endif
! 281: }
1.1 root 282:
283: /* Parallel port */
284: if (parallel_hds[0])
285: parallel_mm_init(0x80008000, 0, rc4030[0], parallel_hds[0]);
286:
287: /* Sound card */
288: /* FIXME: missing Jazz sound at 0x8000c000, rc4030[2] */
289: audio_init(i8259);
290:
291: /* NVRAM: Unprotected at 0x9000, Protected at 0xa000, Read only at 0xb000 */
292: ds1225y_init(0x80009000, "nvram");
293:
294: /* LED indicator */
295: jazz_led_init(0x8000f000);
296: }
297:
298: static
1.1.1.2 root 299: void mips_magnum_init (ram_addr_t ram_size,
1.1 root 300: const char *boot_device,
301: const char *kernel_filename, const char *kernel_cmdline,
302: const char *initrd_filename, const char *cpu_model)
303: {
1.1.1.2 root 304: mips_jazz_init(ram_size, cpu_model, JAZZ_MAGNUM);
1.1 root 305: }
306:
307: static
1.1.1.2 root 308: void mips_pica61_init (ram_addr_t ram_size,
1.1 root 309: const char *boot_device,
310: const char *kernel_filename, const char *kernel_cmdline,
311: const char *initrd_filename, const char *cpu_model)
312: {
1.1.1.2 root 313: mips_jazz_init(ram_size, cpu_model, JAZZ_PICA61);
1.1 root 314: }
315:
1.1.1.2 root 316: static QEMUMachine mips_magnum_machine = {
1.1 root 317: .name = "magnum",
318: .desc = "MIPS Magnum",
319: .init = mips_magnum_init,
320: .use_scsi = 1,
321: };
322:
1.1.1.2 root 323: static QEMUMachine mips_pica61_machine = {
1.1 root 324: .name = "pica61",
325: .desc = "Acer Pica 61",
326: .init = mips_pica61_init,
327: .use_scsi = 1,
328: };
1.1.1.2 root 329:
330: static void mips_jazz_machine_init(void)
331: {
332: qemu_register_machine(&mips_magnum_machine);
333: qemu_register_machine(&mips_pica61_machine);
334: }
335:
336: machine_init(mips_jazz_machine_init);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.