|
1 /* |
|
2 * QEMU Sun4m & Sun4d & Sun4c System Emulator |
|
3 * |
|
4 * Copyright (c) 2003-2005 Fabrice Bellard |
|
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 #include "hw.h" |
|
25 #include "qemu-timer.h" |
|
26 #include "sun4m.h" |
|
27 #include "nvram.h" |
|
28 #include "sparc32_dma.h" |
|
29 #include "fdc.h" |
|
30 #include "sysemu.h" |
|
31 #include "net.h" |
|
32 #include "boards.h" |
|
33 #include "firmware_abi.h" |
|
34 #include "scsi.h" |
|
35 #include "pc.h" |
|
36 #include "isa.h" |
|
37 #include "fw_cfg.h" |
|
38 |
|
39 //#define DEBUG_IRQ |
|
40 |
|
41 /* |
|
42 * Sun4m architecture was used in the following machines: |
|
43 * |
|
44 * SPARCserver 6xxMP/xx |
|
45 * SPARCclassic (SPARCclassic Server)(SPARCstation LC) (4/15), |
|
46 * SPARCclassic X (4/10) |
|
47 * SPARCstation LX/ZX (4/30) |
|
48 * SPARCstation Voyager |
|
49 * SPARCstation 10/xx, SPARCserver 10/xx |
|
50 * SPARCstation 5, SPARCserver 5 |
|
51 * SPARCstation 20/xx, SPARCserver 20 |
|
52 * SPARCstation 4 |
|
53 * |
|
54 * Sun4d architecture was used in the following machines: |
|
55 * |
|
56 * SPARCcenter 2000 |
|
57 * SPARCserver 1000 |
|
58 * |
|
59 * Sun4c architecture was used in the following machines: |
|
60 * SPARCstation 1/1+, SPARCserver 1/1+ |
|
61 * SPARCstation SLC |
|
62 * SPARCstation IPC |
|
63 * SPARCstation ELC |
|
64 * SPARCstation IPX |
|
65 * |
|
66 * See for example: http://www.sunhelp.org/faq/sunref1.html |
|
67 */ |
|
68 |
|
69 #ifdef DEBUG_IRQ |
|
70 #define DPRINTF(fmt, args...) \ |
|
71 do { printf("CPUIRQ: " fmt , ##args); } while (0) |
|
72 #else |
|
73 #define DPRINTF(fmt, args...) |
|
74 #endif |
|
75 |
|
76 #define KERNEL_LOAD_ADDR 0x00004000 |
|
77 #define CMDLINE_ADDR 0x007ff000 |
|
78 #define INITRD_LOAD_ADDR 0x00800000 |
|
79 #define PROM_SIZE_MAX (1024 * 1024) |
|
80 #define PROM_VADDR 0xffd00000 |
|
81 #define PROM_FILENAME "openbios-sparc32" |
|
82 #define CFG_ADDR 0xd00000510ULL |
|
83 #define FW_CFG_SUN4M_DEPTH (FW_CFG_ARCH_LOCAL + 0x00) |
|
84 |
|
85 // Control plane, 8-bit and 24-bit planes |
|
86 #define TCX_SIZE (9 * 1024 * 1024) |
|
87 |
|
88 #define MAX_CPUS 16 |
|
89 #define MAX_PILS 16 |
|
90 |
|
91 struct sun4m_hwdef { |
|
92 target_phys_addr_t iommu_base, slavio_base; |
|
93 target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base; |
|
94 target_phys_addr_t serial_base, fd_base; |
|
95 target_phys_addr_t idreg_base, dma_base, esp_base, le_base; |
|
96 target_phys_addr_t tcx_base, cs_base, apc_base, aux1_base, aux2_base; |
|
97 target_phys_addr_t ecc_base; |
|
98 uint32_t ecc_version; |
|
99 long vram_size, nvram_size; |
|
100 // IRQ numbers are not PIL ones, but master interrupt controller |
|
101 // register bit numbers |
|
102 int esp_irq, le_irq, clock_irq, clock1_irq; |
|
103 int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq, ecc_irq; |
|
104 uint8_t nvram_machine_id; |
|
105 uint16_t machine_id; |
|
106 uint32_t iommu_version; |
|
107 uint32_t intbit_to_level[32]; |
|
108 uint64_t max_mem; |
|
109 const char * const default_cpu_model; |
|
110 }; |
|
111 |
|
112 #define MAX_IOUNITS 5 |
|
113 |
|
114 struct sun4d_hwdef { |
|
115 target_phys_addr_t iounit_bases[MAX_IOUNITS], slavio_base; |
|
116 target_phys_addr_t counter_base, nvram_base, ms_kb_base; |
|
117 target_phys_addr_t serial_base; |
|
118 target_phys_addr_t espdma_base, esp_base; |
|
119 target_phys_addr_t ledma_base, le_base; |
|
120 target_phys_addr_t tcx_base; |
|
121 target_phys_addr_t sbi_base; |
|
122 unsigned long vram_size, nvram_size; |
|
123 // IRQ numbers are not PIL ones, but SBI register bit numbers |
|
124 int esp_irq, le_irq, clock_irq, clock1_irq; |
|
125 int ser_irq, ms_kb_irq, me_irq; |
|
126 uint8_t nvram_machine_id; |
|
127 uint16_t machine_id; |
|
128 uint32_t iounit_version; |
|
129 uint64_t max_mem; |
|
130 const char * const default_cpu_model; |
|
131 }; |
|
132 |
|
133 struct sun4c_hwdef { |
|
134 target_phys_addr_t iommu_base, slavio_base; |
|
135 target_phys_addr_t intctl_base, counter_base, nvram_base, ms_kb_base; |
|
136 target_phys_addr_t serial_base, fd_base; |
|
137 target_phys_addr_t idreg_base, dma_base, esp_base, le_base; |
|
138 target_phys_addr_t tcx_base, aux1_base; |
|
139 long vram_size, nvram_size; |
|
140 // IRQ numbers are not PIL ones, but master interrupt controller |
|
141 // register bit numbers |
|
142 int esp_irq, le_irq, clock_irq, clock1_irq; |
|
143 int ser_irq, ms_kb_irq, fd_irq, me_irq; |
|
144 uint8_t nvram_machine_id; |
|
145 uint16_t machine_id; |
|
146 uint32_t iommu_version; |
|
147 uint32_t intbit_to_level[32]; |
|
148 uint64_t max_mem; |
|
149 const char * const default_cpu_model; |
|
150 }; |
|
151 |
|
152 int DMA_get_channel_mode (int nchan) |
|
153 { |
|
154 return 0; |
|
155 } |
|
156 int DMA_read_memory (int nchan, void *buf, int pos, int size) |
|
157 { |
|
158 return 0; |
|
159 } |
|
160 int DMA_write_memory (int nchan, void *buf, int pos, int size) |
|
161 { |
|
162 return 0; |
|
163 } |
|
164 void DMA_hold_DREQ (int nchan) {} |
|
165 void DMA_release_DREQ (int nchan) {} |
|
166 void DMA_schedule(int nchan) {} |
|
167 void DMA_init (int high_page_enable) {} |
|
168 void DMA_register_channel (int nchan, |
|
169 DMA_transfer_handler transfer_handler, |
|
170 void *opaque) |
|
171 { |
|
172 } |
|
173 |
|
174 static int nvram_boot_set(void *opaque, const char *boot_device) |
|
175 { |
|
176 unsigned int i; |
|
177 uint8_t image[sizeof(ohwcfg_v3_t)]; |
|
178 ohwcfg_v3_t *header = (ohwcfg_v3_t *)ℑ |
|
179 m48t59_t *nvram = (m48t59_t *)opaque; |
|
180 |
|
181 for (i = 0; i < sizeof(image); i++) |
|
182 image[i] = m48t59_read(nvram, i) & 0xff; |
|
183 |
|
184 pstrcpy((char *)header->boot_devices, sizeof(header->boot_devices), |
|
185 boot_device); |
|
186 header->nboot_devices = strlen(boot_device) & 0xff; |
|
187 header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8)); |
|
188 |
|
189 for (i = 0; i < sizeof(image); i++) |
|
190 m48t59_write(nvram, i, image[i]); |
|
191 |
|
192 return 0; |
|
193 } |
|
194 |
|
195 static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline, |
|
196 const char *boot_devices, ram_addr_t RAM_size, |
|
197 uint32_t kernel_size, |
|
198 int width, int height, int depth, |
|
199 int nvram_machine_id, const char *arch) |
|
200 { |
|
201 unsigned int i; |
|
202 uint32_t start, end; |
|
203 uint8_t image[0x1ff0]; |
|
204 ohwcfg_v3_t *header = (ohwcfg_v3_t *)ℑ |
|
205 struct sparc_arch_cfg *sparc_header; |
|
206 struct OpenBIOS_nvpart_v1 *part_header; |
|
207 |
|
208 memset(image, '\0', sizeof(image)); |
|
209 |
|
210 // Try to match PPC NVRAM |
|
211 pstrcpy((char *)header->struct_ident, sizeof(header->struct_ident), |
|
212 "QEMU_BIOS"); |
|
213 header->struct_version = cpu_to_be32(3); /* structure v3 */ |
|
214 |
|
215 header->nvram_size = cpu_to_be16(0x2000); |
|
216 header->nvram_arch_ptr = cpu_to_be16(sizeof(ohwcfg_v3_t)); |
|
217 header->nvram_arch_size = cpu_to_be16(sizeof(struct sparc_arch_cfg)); |
|
218 pstrcpy((char *)header->arch, sizeof(header->arch), arch); |
|
219 header->nb_cpus = smp_cpus & 0xff; |
|
220 header->RAM0_base = 0; |
|
221 header->RAM0_size = cpu_to_be64((uint64_t)RAM_size); |
|
222 pstrcpy((char *)header->boot_devices, sizeof(header->boot_devices), |
|
223 boot_devices); |
|
224 header->nboot_devices = strlen(boot_devices) & 0xff; |
|
225 header->kernel_image = cpu_to_be64((uint64_t)KERNEL_LOAD_ADDR); |
|
226 header->kernel_size = cpu_to_be64((uint64_t)kernel_size); |
|
227 if (cmdline) { |
|
228 pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, cmdline); |
|
229 header->cmdline = cpu_to_be64((uint64_t)CMDLINE_ADDR); |
|
230 header->cmdline_size = cpu_to_be64((uint64_t)strlen(cmdline)); |
|
231 } |
|
232 // XXX add initrd_image, initrd_size |
|
233 header->width = cpu_to_be16(width); |
|
234 header->height = cpu_to_be16(height); |
|
235 header->depth = cpu_to_be16(depth); |
|
236 if (nographic) |
|
237 header->graphic_flags = cpu_to_be16(OHW_GF_NOGRAPHICS); |
|
238 |
|
239 header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8)); |
|
240 |
|
241 // Architecture specific header |
|
242 start = sizeof(ohwcfg_v3_t); |
|
243 sparc_header = (struct sparc_arch_cfg *)&image[start]; |
|
244 sparc_header->valid = 0; |
|
245 start += sizeof(struct sparc_arch_cfg); |
|
246 |
|
247 // OpenBIOS nvram variables |
|
248 // Variable partition |
|
249 part_header = (struct OpenBIOS_nvpart_v1 *)&image[start]; |
|
250 part_header->signature = OPENBIOS_PART_SYSTEM; |
|
251 pstrcpy(part_header->name, sizeof(part_header->name), "system"); |
|
252 |
|
253 end = start + sizeof(struct OpenBIOS_nvpart_v1); |
|
254 for (i = 0; i < nb_prom_envs; i++) |
|
255 end = OpenBIOS_set_var(image, end, prom_envs[i]); |
|
256 |
|
257 // End marker |
|
258 image[end++] = '\0'; |
|
259 |
|
260 end = start + ((end - start + 15) & ~15); |
|
261 OpenBIOS_finish_partition(part_header, end - start); |
|
262 |
|
263 // free partition |
|
264 start = end; |
|
265 part_header = (struct OpenBIOS_nvpart_v1 *)&image[start]; |
|
266 part_header->signature = OPENBIOS_PART_FREE; |
|
267 pstrcpy(part_header->name, sizeof(part_header->name), "free"); |
|
268 |
|
269 end = 0x1fd0; |
|
270 OpenBIOS_finish_partition(part_header, end - start); |
|
271 |
|
272 Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr, |
|
273 nvram_machine_id); |
|
274 |
|
275 for (i = 0; i < sizeof(image); i++) |
|
276 m48t59_write(nvram, i, image[i]); |
|
277 |
|
278 qemu_register_boot_set(nvram_boot_set, nvram); |
|
279 } |
|
280 |
|
281 static void *slavio_intctl; |
|
282 |
|
283 void pic_info(void) |
|
284 { |
|
285 if (slavio_intctl) |
|
286 slavio_pic_info(slavio_intctl); |
|
287 } |
|
288 |
|
289 void irq_info(void) |
|
290 { |
|
291 if (slavio_intctl) |
|
292 slavio_irq_info(slavio_intctl); |
|
293 } |
|
294 |
|
295 void cpu_check_irqs(CPUState *env) |
|
296 { |
|
297 if (env->pil_in && (env->interrupt_index == 0 || |
|
298 (env->interrupt_index & ~15) == TT_EXTINT)) { |
|
299 unsigned int i; |
|
300 |
|
301 for (i = 15; i > 0; i--) { |
|
302 if (env->pil_in & (1 << i)) { |
|
303 int old_interrupt = env->interrupt_index; |
|
304 |
|
305 env->interrupt_index = TT_EXTINT | i; |
|
306 if (old_interrupt != env->interrupt_index) { |
|
307 DPRINTF("Set CPU IRQ %d\n", i); |
|
308 cpu_interrupt(env, CPU_INTERRUPT_HARD); |
|
309 } |
|
310 break; |
|
311 } |
|
312 } |
|
313 } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) { |
|
314 DPRINTF("Reset CPU IRQ %d\n", env->interrupt_index & 15); |
|
315 env->interrupt_index = 0; |
|
316 cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); |
|
317 } |
|
318 } |
|
319 |
|
320 static void cpu_set_irq(void *opaque, int irq, int level) |
|
321 { |
|
322 CPUState *env = opaque; |
|
323 |
|
324 if (level) { |
|
325 DPRINTF("Raise CPU IRQ %d\n", irq); |
|
326 env->halted = 0; |
|
327 env->pil_in |= 1 << irq; |
|
328 cpu_check_irqs(env); |
|
329 } else { |
|
330 DPRINTF("Lower CPU IRQ %d\n", irq); |
|
331 env->pil_in &= ~(1 << irq); |
|
332 cpu_check_irqs(env); |
|
333 } |
|
334 } |
|
335 |
|
336 static void dummy_cpu_set_irq(void *opaque, int irq, int level) |
|
337 { |
|
338 } |
|
339 |
|
340 static void *slavio_misc; |
|
341 |
|
342 void qemu_system_powerdown(void) |
|
343 { |
|
344 slavio_set_power_fail(slavio_misc, 1); |
|
345 } |
|
346 |
|
347 static void main_cpu_reset(void *opaque) |
|
348 { |
|
349 CPUState *env = opaque; |
|
350 |
|
351 cpu_reset(env); |
|
352 env->halted = 0; |
|
353 } |
|
354 |
|
355 static void secondary_cpu_reset(void *opaque) |
|
356 { |
|
357 CPUState *env = opaque; |
|
358 |
|
359 cpu_reset(env); |
|
360 env->halted = 1; |
|
361 } |
|
362 |
|
363 static void cpu_halt_signal(void *opaque, int irq, int level) |
|
364 { |
|
365 if (level && cpu_single_env) |
|
366 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HALT); |
|
367 } |
|
368 |
|
369 static unsigned long sun4m_load_kernel(const char *kernel_filename, |
|
370 const char *initrd_filename, |
|
371 ram_addr_t RAM_size) |
|
372 { |
|
373 int linux_boot; |
|
374 unsigned int i; |
|
375 long initrd_size, kernel_size; |
|
376 |
|
377 linux_boot = (kernel_filename != NULL); |
|
378 |
|
379 kernel_size = 0; |
|
380 if (linux_boot) { |
|
381 kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL, |
|
382 NULL); |
|
383 if (kernel_size < 0) |
|
384 kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR, |
|
385 RAM_size - KERNEL_LOAD_ADDR); |
|
386 if (kernel_size < 0) |
|
387 kernel_size = load_image_targphys(kernel_filename, |
|
388 KERNEL_LOAD_ADDR, |
|
389 RAM_size - KERNEL_LOAD_ADDR); |
|
390 if (kernel_size < 0) { |
|
391 fprintf(stderr, "qemu: could not load kernel '%s'\n", |
|
392 kernel_filename); |
|
393 exit(1); |
|
394 } |
|
395 |
|
396 /* load initrd */ |
|
397 initrd_size = 0; |
|
398 if (initrd_filename) { |
|
399 initrd_size = load_image_targphys(initrd_filename, |
|
400 INITRD_LOAD_ADDR, |
|
401 RAM_size - INITRD_LOAD_ADDR); |
|
402 if (initrd_size < 0) { |
|
403 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", |
|
404 initrd_filename); |
|
405 exit(1); |
|
406 } |
|
407 } |
|
408 if (initrd_size > 0) { |
|
409 for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) { |
|
410 if (ldl_phys(KERNEL_LOAD_ADDR + i) == 0x48647253) { // HdrS |
|
411 stl_phys(KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR); |
|
412 stl_phys(KERNEL_LOAD_ADDR + i + 20, initrd_size); |
|
413 break; |
|
414 } |
|
415 } |
|
416 } |
|
417 } |
|
418 return kernel_size; |
|
419 } |
|
420 |
|
421 static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size, |
|
422 const char *boot_device, |
|
423 DisplayState *ds, const char *kernel_filename, |
|
424 const char *kernel_cmdline, |
|
425 const char *initrd_filename, const char *cpu_model) |
|
426 |
|
427 { |
|
428 CPUState *env, *envs[MAX_CPUS]; |
|
429 unsigned int i; |
|
430 void *iommu, *espdma, *ledma, *main_esp, *nvram; |
|
431 qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq, |
|
432 *espdma_irq, *ledma_irq; |
|
433 qemu_irq *esp_reset, *le_reset; |
|
434 qemu_irq *fdc_tc; |
|
435 qemu_irq *cpu_halt; |
|
436 ram_addr_t ram_offset, prom_offset, tcx_offset, idreg_offset; |
|
437 unsigned long kernel_size; |
|
438 int ret; |
|
439 char buf[1024]; |
|
440 BlockDriverState *fd[MAX_FD]; |
|
441 int drive_index; |
|
442 void *fw_cfg; |
|
443 |
|
444 /* init CPUs */ |
|
445 if (!cpu_model) |
|
446 cpu_model = hwdef->default_cpu_model; |
|
447 |
|
448 for(i = 0; i < smp_cpus; i++) { |
|
449 env = cpu_init(cpu_model); |
|
450 if (!env) { |
|
451 fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n"); |
|
452 exit(1); |
|
453 } |
|
454 cpu_sparc_set_id(env, i); |
|
455 envs[i] = env; |
|
456 if (i == 0) { |
|
457 qemu_register_reset(main_cpu_reset, env); |
|
458 } else { |
|
459 qemu_register_reset(secondary_cpu_reset, env); |
|
460 env->halted = 1; |
|
461 } |
|
462 cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS); |
|
463 env->prom_addr = hwdef->slavio_base; |
|
464 } |
|
465 |
|
466 for (i = smp_cpus; i < MAX_CPUS; i++) |
|
467 cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS); |
|
468 |
|
469 |
|
470 /* allocate RAM */ |
|
471 if ((uint64_t)RAM_size > hwdef->max_mem) { |
|
472 fprintf(stderr, |
|
473 "qemu: Too much memory for this machine: %d, maximum %d\n", |
|
474 (unsigned int)(RAM_size / (1024 * 1024)), |
|
475 (unsigned int)(hwdef->max_mem / (1024 * 1024))); |
|
476 exit(1); |
|
477 } |
|
478 ram_offset = qemu_ram_alloc(RAM_size); |
|
479 cpu_register_physical_memory(0, RAM_size, ram_offset); |
|
480 |
|
481 /* load boot prom */ |
|
482 prom_offset = qemu_ram_alloc(PROM_SIZE_MAX); |
|
483 cpu_register_physical_memory(hwdef->slavio_base, |
|
484 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & |
|
485 TARGET_PAGE_MASK, |
|
486 prom_offset | IO_MEM_ROM); |
|
487 |
|
488 if (bios_name == NULL) |
|
489 bios_name = PROM_FILENAME; |
|
490 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); |
|
491 ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL); |
|
492 if (ret < 0 || ret > PROM_SIZE_MAX) |
|
493 ret = load_image_targphys(buf, hwdef->slavio_base, PROM_SIZE_MAX); |
|
494 if (ret < 0 || ret > PROM_SIZE_MAX) { |
|
495 fprintf(stderr, "qemu: could not load prom '%s'\n", |
|
496 buf); |
|
497 exit(1); |
|
498 } |
|
499 |
|
500 /* set up devices */ |
|
501 slavio_intctl = slavio_intctl_init(hwdef->intctl_base, |
|
502 hwdef->intctl_base + 0x10000ULL, |
|
503 &hwdef->intbit_to_level[0], |
|
504 &slavio_irq, &slavio_cpu_irq, |
|
505 cpu_irqs, |
|
506 hwdef->clock_irq); |
|
507 |
|
508 if (hwdef->idreg_base != (target_phys_addr_t)-1) { |
|
509 static const uint8_t idreg_data[] = { 0xfe, 0x81, 0x01, 0x03 }; |
|
510 |
|
511 idreg_offset = qemu_ram_alloc(sizeof(idreg_data)); |
|
512 cpu_register_physical_memory(hwdef->idreg_base, sizeof(idreg_data), |
|
513 idreg_offset | IO_MEM_ROM); |
|
514 cpu_physical_memory_write_rom(hwdef->idreg_base, idreg_data, |
|
515 sizeof(idreg_data)); |
|
516 } |
|
517 |
|
518 iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version, |
|
519 slavio_irq[hwdef->me_irq]); |
|
520 |
|
521 espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq], |
|
522 iommu, &espdma_irq, &esp_reset); |
|
523 |
|
524 ledma = sparc32_dma_init(hwdef->dma_base + 16ULL, |
|
525 slavio_irq[hwdef->le_irq], iommu, &ledma_irq, |
|
526 &le_reset); |
|
527 |
|
528 if (graphic_depth != 8 && graphic_depth != 24) { |
|
529 fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth); |
|
530 exit (1); |
|
531 } |
|
532 tcx_offset = qemu_ram_alloc(hwdef->vram_size); |
|
533 tcx_init(ds, hwdef->tcx_base, phys_ram_base + tcx_offset, tcx_offset, |
|
534 hwdef->vram_size, graphic_width, graphic_height, graphic_depth); |
|
535 |
|
536 if (nd_table[0].model == NULL |
|
537 || strcmp(nd_table[0].model, "lance") == 0) { |
|
538 lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset); |
|
539 } else if (strcmp(nd_table[0].model, "?") == 0) { |
|
540 fprintf(stderr, "qemu: Supported NICs: lance\n"); |
|
541 exit (1); |
|
542 } else { |
|
543 fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model); |
|
544 exit (1); |
|
545 } |
|
546 |
|
547 nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, |
|
548 hwdef->nvram_size, 8); |
|
549 |
|
550 slavio_timer_init_all(hwdef->counter_base, slavio_irq[hwdef->clock1_irq], |
|
551 slavio_cpu_irq, smp_cpus); |
|
552 |
|
553 slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq], |
|
554 nographic); |
|
555 // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device |
|
556 // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device |
|
557 slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq], |
|
558 serial_hds[1], serial_hds[0]); |
|
559 |
|
560 cpu_halt = qemu_allocate_irqs(cpu_halt_signal, NULL, 1); |
|
561 slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->apc_base, |
|
562 hwdef->aux1_base, hwdef->aux2_base, |
|
563 slavio_irq[hwdef->me_irq], cpu_halt[0], |
|
564 &fdc_tc); |
|
565 |
|
566 if (hwdef->fd_base != (target_phys_addr_t)-1) { |
|
567 /* there is zero or one floppy drive */ |
|
568 memset(fd, 0, sizeof(fd)); |
|
569 drive_index = drive_get_index(IF_FLOPPY, 0, 0); |
|
570 if (drive_index != -1) |
|
571 fd[0] = drives_table[drive_index].bdrv; |
|
572 |
|
573 sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd, |
|
574 fdc_tc); |
|
575 } |
|
576 |
|
577 if (drive_get_max_bus(IF_SCSI) > 0) { |
|
578 fprintf(stderr, "qemu: too many SCSI bus\n"); |
|
579 exit(1); |
|
580 } |
|
581 |
|
582 main_esp = esp_init(hwdef->esp_base, 2, |
|
583 espdma_memory_read, espdma_memory_write, |
|
584 espdma, *espdma_irq, esp_reset); |
|
585 |
|
586 for (i = 0; i < ESP_MAX_DEVS; i++) { |
|
587 drive_index = drive_get_index(IF_SCSI, 0, i); |
|
588 if (drive_index == -1) |
|
589 continue; |
|
590 esp_scsi_attach(main_esp, drives_table[drive_index].bdrv, i); |
|
591 } |
|
592 |
|
593 if (hwdef->cs_base != (target_phys_addr_t)-1) |
|
594 cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl); |
|
595 |
|
596 kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename, |
|
597 RAM_size); |
|
598 |
|
599 nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, |
|
600 boot_device, RAM_size, kernel_size, graphic_width, |
|
601 graphic_height, graphic_depth, hwdef->nvram_machine_id, |
|
602 "Sun4m"); |
|
603 |
|
604 if (hwdef->ecc_base != (target_phys_addr_t)-1) |
|
605 ecc_init(hwdef->ecc_base, slavio_irq[hwdef->ecc_irq], |
|
606 hwdef->ecc_version); |
|
607 |
|
608 fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2); |
|
609 fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); |
|
610 fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); |
|
611 fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id); |
|
612 fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_DEPTH, graphic_depth); |
|
613 } |
|
614 |
|
615 enum { |
|
616 ss2_id = 0, |
|
617 ss5_id = 32, |
|
618 vger_id, |
|
619 lx_id, |
|
620 ss4_id, |
|
621 scls_id, |
|
622 sbook_id, |
|
623 ss10_id = 64, |
|
624 ss20_id, |
|
625 ss600mp_id, |
|
626 ss1000_id = 96, |
|
627 ss2000_id, |
|
628 }; |
|
629 |
|
630 static const struct sun4m_hwdef sun4m_hwdefs[] = { |
|
631 /* SS-5 */ |
|
632 { |
|
633 .iommu_base = 0x10000000, |
|
634 .tcx_base = 0x50000000, |
|
635 .cs_base = 0x6c000000, |
|
636 .slavio_base = 0x70000000, |
|
637 .ms_kb_base = 0x71000000, |
|
638 .serial_base = 0x71100000, |
|
639 .nvram_base = 0x71200000, |
|
640 .fd_base = 0x71400000, |
|
641 .counter_base = 0x71d00000, |
|
642 .intctl_base = 0x71e00000, |
|
643 .idreg_base = 0x78000000, |
|
644 .dma_base = 0x78400000, |
|
645 .esp_base = 0x78800000, |
|
646 .le_base = 0x78c00000, |
|
647 .apc_base = 0x6a000000, |
|
648 .aux1_base = 0x71900000, |
|
649 .aux2_base = 0x71910000, |
|
650 .ecc_base = -1, |
|
651 .vram_size = 0x00100000, |
|
652 .nvram_size = 0x2000, |
|
653 .esp_irq = 18, |
|
654 .le_irq = 16, |
|
655 .clock_irq = 7, |
|
656 .clock1_irq = 19, |
|
657 .ms_kb_irq = 14, |
|
658 .ser_irq = 15, |
|
659 .fd_irq = 22, |
|
660 .me_irq = 30, |
|
661 .cs_irq = 5, |
|
662 .nvram_machine_id = 0x80, |
|
663 .machine_id = ss5_id, |
|
664 .iommu_version = 0x05000000, |
|
665 .intbit_to_level = { |
|
666 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12, |
|
667 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0, |
|
668 }, |
|
669 .max_mem = 0x10000000, |
|
670 .default_cpu_model = "Fujitsu MB86904", |
|
671 }, |
|
672 /* SS-10 */ |
|
673 { |
|
674 .iommu_base = 0xfe0000000ULL, |
|
675 .tcx_base = 0xe20000000ULL, |
|
676 .cs_base = -1, |
|
677 .slavio_base = 0xff0000000ULL, |
|
678 .ms_kb_base = 0xff1000000ULL, |
|
679 .serial_base = 0xff1100000ULL, |
|
680 .nvram_base = 0xff1200000ULL, |
|
681 .fd_base = 0xff1700000ULL, |
|
682 .counter_base = 0xff1300000ULL, |
|
683 .intctl_base = 0xff1400000ULL, |
|
684 .idreg_base = 0xef0000000ULL, |
|
685 .dma_base = 0xef0400000ULL, |
|
686 .esp_base = 0xef0800000ULL, |
|
687 .le_base = 0xef0c00000ULL, |
|
688 .apc_base = 0xefa000000ULL, // XXX should not exist |
|
689 .aux1_base = 0xff1800000ULL, |
|
690 .aux2_base = 0xff1a01000ULL, |
|
691 .ecc_base = 0xf00000000ULL, |
|
692 .ecc_version = 0x10000000, // version 0, implementation 1 |
|
693 .vram_size = 0x00100000, |
|
694 .nvram_size = 0x2000, |
|
695 .esp_irq = 18, |
|
696 .le_irq = 16, |
|
697 .clock_irq = 7, |
|
698 .clock1_irq = 19, |
|
699 .ms_kb_irq = 14, |
|
700 .ser_irq = 15, |
|
701 .fd_irq = 22, |
|
702 .me_irq = 30, |
|
703 .cs_irq = -1, |
|
704 .ecc_irq = 28, |
|
705 .nvram_machine_id = 0x72, |
|
706 .machine_id = ss10_id, |
|
707 .iommu_version = 0x03000000, |
|
708 .intbit_to_level = { |
|
709 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12, |
|
710 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0, |
|
711 }, |
|
712 .max_mem = 0xf00000000ULL, |
|
713 .default_cpu_model = "TI SuperSparc II", |
|
714 }, |
|
715 /* SS-600MP */ |
|
716 { |
|
717 .iommu_base = 0xfe0000000ULL, |
|
718 .tcx_base = 0xe20000000ULL, |
|
719 .cs_base = -1, |
|
720 .slavio_base = 0xff0000000ULL, |
|
721 .ms_kb_base = 0xff1000000ULL, |
|
722 .serial_base = 0xff1100000ULL, |
|
723 .nvram_base = 0xff1200000ULL, |
|
724 .fd_base = -1, |
|
725 .counter_base = 0xff1300000ULL, |
|
726 .intctl_base = 0xff1400000ULL, |
|
727 .idreg_base = -1, |
|
728 .dma_base = 0xef0081000ULL, |
|
729 .esp_base = 0xef0080000ULL, |
|
730 .le_base = 0xef0060000ULL, |
|
731 .apc_base = 0xefa000000ULL, // XXX should not exist |
|
732 .aux1_base = 0xff1800000ULL, |
|
733 .aux2_base = 0xff1a01000ULL, // XXX should not exist |
|
734 .ecc_base = 0xf00000000ULL, |
|
735 .ecc_version = 0x00000000, // version 0, implementation 0 |
|
736 .vram_size = 0x00100000, |
|
737 .nvram_size = 0x2000, |
|
738 .esp_irq = 18, |
|
739 .le_irq = 16, |
|
740 .clock_irq = 7, |
|
741 .clock1_irq = 19, |
|
742 .ms_kb_irq = 14, |
|
743 .ser_irq = 15, |
|
744 .fd_irq = 22, |
|
745 .me_irq = 30, |
|
746 .cs_irq = -1, |
|
747 .ecc_irq = 28, |
|
748 .nvram_machine_id = 0x71, |
|
749 .machine_id = ss600mp_id, |
|
750 .iommu_version = 0x01000000, |
|
751 .intbit_to_level = { |
|
752 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12, |
|
753 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0, |
|
754 }, |
|
755 .max_mem = 0xf00000000ULL, |
|
756 .default_cpu_model = "TI SuperSparc II", |
|
757 }, |
|
758 /* SS-20 */ |
|
759 { |
|
760 .iommu_base = 0xfe0000000ULL, |
|
761 .tcx_base = 0xe20000000ULL, |
|
762 .cs_base = -1, |
|
763 .slavio_base = 0xff0000000ULL, |
|
764 .ms_kb_base = 0xff1000000ULL, |
|
765 .serial_base = 0xff1100000ULL, |
|
766 .nvram_base = 0xff1200000ULL, |
|
767 .fd_base = 0xff1700000ULL, |
|
768 .counter_base = 0xff1300000ULL, |
|
769 .intctl_base = 0xff1400000ULL, |
|
770 .idreg_base = 0xef0000000ULL, |
|
771 .dma_base = 0xef0400000ULL, |
|
772 .esp_base = 0xef0800000ULL, |
|
773 .le_base = 0xef0c00000ULL, |
|
774 .apc_base = 0xefa000000ULL, // XXX should not exist |
|
775 .aux1_base = 0xff1800000ULL, |
|
776 .aux2_base = 0xff1a01000ULL, |
|
777 .ecc_base = 0xf00000000ULL, |
|
778 .ecc_version = 0x20000000, // version 0, implementation 2 |
|
779 .vram_size = 0x00100000, |
|
780 .nvram_size = 0x2000, |
|
781 .esp_irq = 18, |
|
782 .le_irq = 16, |
|
783 .clock_irq = 7, |
|
784 .clock1_irq = 19, |
|
785 .ms_kb_irq = 14, |
|
786 .ser_irq = 15, |
|
787 .fd_irq = 22, |
|
788 .me_irq = 30, |
|
789 .cs_irq = -1, |
|
790 .ecc_irq = 28, |
|
791 .nvram_machine_id = 0x72, |
|
792 .machine_id = ss20_id, |
|
793 .iommu_version = 0x13000000, |
|
794 .intbit_to_level = { |
|
795 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12, |
|
796 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0, |
|
797 }, |
|
798 .max_mem = 0xf00000000ULL, |
|
799 .default_cpu_model = "TI SuperSparc II", |
|
800 }, |
|
801 /* Voyager */ |
|
802 { |
|
803 .iommu_base = 0x10000000, |
|
804 .tcx_base = 0x50000000, |
|
805 .cs_base = -1, |
|
806 .slavio_base = 0x70000000, |
|
807 .ms_kb_base = 0x71000000, |
|
808 .serial_base = 0x71100000, |
|
809 .nvram_base = 0x71200000, |
|
810 .fd_base = 0x71400000, |
|
811 .counter_base = 0x71d00000, |
|
812 .intctl_base = 0x71e00000, |
|
813 .idreg_base = 0x78000000, |
|
814 .dma_base = 0x78400000, |
|
815 .esp_base = 0x78800000, |
|
816 .le_base = 0x78c00000, |
|
817 .apc_base = 0x71300000, // pmc |
|
818 .aux1_base = 0x71900000, |
|
819 .aux2_base = 0x71910000, |
|
820 .ecc_base = -1, |
|
821 .vram_size = 0x00100000, |
|
822 .nvram_size = 0x2000, |
|
823 .esp_irq = 18, |
|
824 .le_irq = 16, |
|
825 .clock_irq = 7, |
|
826 .clock1_irq = 19, |
|
827 .ms_kb_irq = 14, |
|
828 .ser_irq = 15, |
|
829 .fd_irq = 22, |
|
830 .me_irq = 30, |
|
831 .cs_irq = -1, |
|
832 .nvram_machine_id = 0x80, |
|
833 .machine_id = vger_id, |
|
834 .iommu_version = 0x05000000, |
|
835 .intbit_to_level = { |
|
836 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12, |
|
837 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0, |
|
838 }, |
|
839 .max_mem = 0x10000000, |
|
840 .default_cpu_model = "Fujitsu MB86904", |
|
841 }, |
|
842 /* LX */ |
|
843 { |
|
844 .iommu_base = 0x10000000, |
|
845 .tcx_base = 0x50000000, |
|
846 .cs_base = -1, |
|
847 .slavio_base = 0x70000000, |
|
848 .ms_kb_base = 0x71000000, |
|
849 .serial_base = 0x71100000, |
|
850 .nvram_base = 0x71200000, |
|
851 .fd_base = 0x71400000, |
|
852 .counter_base = 0x71d00000, |
|
853 .intctl_base = 0x71e00000, |
|
854 .idreg_base = 0x78000000, |
|
855 .dma_base = 0x78400000, |
|
856 .esp_base = 0x78800000, |
|
857 .le_base = 0x78c00000, |
|
858 .apc_base = -1, |
|
859 .aux1_base = 0x71900000, |
|
860 .aux2_base = 0x71910000, |
|
861 .ecc_base = -1, |
|
862 .vram_size = 0x00100000, |
|
863 .nvram_size = 0x2000, |
|
864 .esp_irq = 18, |
|
865 .le_irq = 16, |
|
866 .clock_irq = 7, |
|
867 .clock1_irq = 19, |
|
868 .ms_kb_irq = 14, |
|
869 .ser_irq = 15, |
|
870 .fd_irq = 22, |
|
871 .me_irq = 30, |
|
872 .cs_irq = -1, |
|
873 .nvram_machine_id = 0x80, |
|
874 .machine_id = lx_id, |
|
875 .iommu_version = 0x04000000, |
|
876 .intbit_to_level = { |
|
877 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12, |
|
878 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0, |
|
879 }, |
|
880 .max_mem = 0x10000000, |
|
881 .default_cpu_model = "TI MicroSparc I", |
|
882 }, |
|
883 /* SS-4 */ |
|
884 { |
|
885 .iommu_base = 0x10000000, |
|
886 .tcx_base = 0x50000000, |
|
887 .cs_base = 0x6c000000, |
|
888 .slavio_base = 0x70000000, |
|
889 .ms_kb_base = 0x71000000, |
|
890 .serial_base = 0x71100000, |
|
891 .nvram_base = 0x71200000, |
|
892 .fd_base = 0x71400000, |
|
893 .counter_base = 0x71d00000, |
|
894 .intctl_base = 0x71e00000, |
|
895 .idreg_base = 0x78000000, |
|
896 .dma_base = 0x78400000, |
|
897 .esp_base = 0x78800000, |
|
898 .le_base = 0x78c00000, |
|
899 .apc_base = 0x6a000000, |
|
900 .aux1_base = 0x71900000, |
|
901 .aux2_base = 0x71910000, |
|
902 .ecc_base = -1, |
|
903 .vram_size = 0x00100000, |
|
904 .nvram_size = 0x2000, |
|
905 .esp_irq = 18, |
|
906 .le_irq = 16, |
|
907 .clock_irq = 7, |
|
908 .clock1_irq = 19, |
|
909 .ms_kb_irq = 14, |
|
910 .ser_irq = 15, |
|
911 .fd_irq = 22, |
|
912 .me_irq = 30, |
|
913 .cs_irq = 5, |
|
914 .nvram_machine_id = 0x80, |
|
915 .machine_id = ss4_id, |
|
916 .iommu_version = 0x05000000, |
|
917 .intbit_to_level = { |
|
918 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12, |
|
919 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0, |
|
920 }, |
|
921 .max_mem = 0x10000000, |
|
922 .default_cpu_model = "Fujitsu MB86904", |
|
923 }, |
|
924 /* SPARCClassic */ |
|
925 { |
|
926 .iommu_base = 0x10000000, |
|
927 .tcx_base = 0x50000000, |
|
928 .cs_base = -1, |
|
929 .slavio_base = 0x70000000, |
|
930 .ms_kb_base = 0x71000000, |
|
931 .serial_base = 0x71100000, |
|
932 .nvram_base = 0x71200000, |
|
933 .fd_base = 0x71400000, |
|
934 .counter_base = 0x71d00000, |
|
935 .intctl_base = 0x71e00000, |
|
936 .idreg_base = 0x78000000, |
|
937 .dma_base = 0x78400000, |
|
938 .esp_base = 0x78800000, |
|
939 .le_base = 0x78c00000, |
|
940 .apc_base = 0x6a000000, |
|
941 .aux1_base = 0x71900000, |
|
942 .aux2_base = 0x71910000, |
|
943 .ecc_base = -1, |
|
944 .vram_size = 0x00100000, |
|
945 .nvram_size = 0x2000, |
|
946 .esp_irq = 18, |
|
947 .le_irq = 16, |
|
948 .clock_irq = 7, |
|
949 .clock1_irq = 19, |
|
950 .ms_kb_irq = 14, |
|
951 .ser_irq = 15, |
|
952 .fd_irq = 22, |
|
953 .me_irq = 30, |
|
954 .cs_irq = -1, |
|
955 .nvram_machine_id = 0x80, |
|
956 .machine_id = scls_id, |
|
957 .iommu_version = 0x05000000, |
|
958 .intbit_to_level = { |
|
959 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12, |
|
960 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0, |
|
961 }, |
|
962 .max_mem = 0x10000000, |
|
963 .default_cpu_model = "TI MicroSparc I", |
|
964 }, |
|
965 /* SPARCbook */ |
|
966 { |
|
967 .iommu_base = 0x10000000, |
|
968 .tcx_base = 0x50000000, // XXX |
|
969 .cs_base = -1, |
|
970 .slavio_base = 0x70000000, |
|
971 .ms_kb_base = 0x71000000, |
|
972 .serial_base = 0x71100000, |
|
973 .nvram_base = 0x71200000, |
|
974 .fd_base = 0x71400000, |
|
975 .counter_base = 0x71d00000, |
|
976 .intctl_base = 0x71e00000, |
|
977 .idreg_base = 0x78000000, |
|
978 .dma_base = 0x78400000, |
|
979 .esp_base = 0x78800000, |
|
980 .le_base = 0x78c00000, |
|
981 .apc_base = 0x6a000000, |
|
982 .aux1_base = 0x71900000, |
|
983 .aux2_base = 0x71910000, |
|
984 .ecc_base = -1, |
|
985 .vram_size = 0x00100000, |
|
986 .nvram_size = 0x2000, |
|
987 .esp_irq = 18, |
|
988 .le_irq = 16, |
|
989 .clock_irq = 7, |
|
990 .clock1_irq = 19, |
|
991 .ms_kb_irq = 14, |
|
992 .ser_irq = 15, |
|
993 .fd_irq = 22, |
|
994 .me_irq = 30, |
|
995 .cs_irq = -1, |
|
996 .nvram_machine_id = 0x80, |
|
997 .machine_id = sbook_id, |
|
998 .iommu_version = 0x05000000, |
|
999 .intbit_to_level = { |
|
1000 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12, |
|
1001 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0, |
|
1002 }, |
|
1003 .max_mem = 0x10000000, |
|
1004 .default_cpu_model = "TI MicroSparc I", |
|
1005 }, |
|
1006 }; |
|
1007 |
|
1008 /* SPARCstation 5 hardware initialisation */ |
|
1009 static void ss5_init(ram_addr_t RAM_size, int vga_ram_size, |
|
1010 const char *boot_device, DisplayState *ds, |
|
1011 const char *kernel_filename, const char *kernel_cmdline, |
|
1012 const char *initrd_filename, const char *cpu_model) |
|
1013 { |
|
1014 sun4m_hw_init(&sun4m_hwdefs[0], RAM_size, boot_device, ds, kernel_filename, |
|
1015 kernel_cmdline, initrd_filename, cpu_model); |
|
1016 } |
|
1017 |
|
1018 /* SPARCstation 10 hardware initialisation */ |
|
1019 static void ss10_init(ram_addr_t RAM_size, int vga_ram_size, |
|
1020 const char *boot_device, DisplayState *ds, |
|
1021 const char *kernel_filename, const char *kernel_cmdline, |
|
1022 const char *initrd_filename, const char *cpu_model) |
|
1023 { |
|
1024 sun4m_hw_init(&sun4m_hwdefs[1], RAM_size, boot_device, ds, kernel_filename, |
|
1025 kernel_cmdline, initrd_filename, cpu_model); |
|
1026 } |
|
1027 |
|
1028 /* SPARCserver 600MP hardware initialisation */ |
|
1029 static void ss600mp_init(ram_addr_t RAM_size, int vga_ram_size, |
|
1030 const char *boot_device, DisplayState *ds, |
|
1031 const char *kernel_filename, |
|
1032 const char *kernel_cmdline, |
|
1033 const char *initrd_filename, const char *cpu_model) |
|
1034 { |
|
1035 sun4m_hw_init(&sun4m_hwdefs[2], RAM_size, boot_device, ds, kernel_filename, |
|
1036 kernel_cmdline, initrd_filename, cpu_model); |
|
1037 } |
|
1038 |
|
1039 /* SPARCstation 20 hardware initialisation */ |
|
1040 static void ss20_init(ram_addr_t RAM_size, int vga_ram_size, |
|
1041 const char *boot_device, DisplayState *ds, |
|
1042 const char *kernel_filename, const char *kernel_cmdline, |
|
1043 const char *initrd_filename, const char *cpu_model) |
|
1044 { |
|
1045 sun4m_hw_init(&sun4m_hwdefs[3], RAM_size, boot_device, ds, kernel_filename, |
|
1046 kernel_cmdline, initrd_filename, cpu_model); |
|
1047 } |
|
1048 |
|
1049 /* SPARCstation Voyager hardware initialisation */ |
|
1050 static void vger_init(ram_addr_t RAM_size, int vga_ram_size, |
|
1051 const char *boot_device, DisplayState *ds, |
|
1052 const char *kernel_filename, const char *kernel_cmdline, |
|
1053 const char *initrd_filename, const char *cpu_model) |
|
1054 { |
|
1055 sun4m_hw_init(&sun4m_hwdefs[4], RAM_size, boot_device, ds, kernel_filename, |
|
1056 kernel_cmdline, initrd_filename, cpu_model); |
|
1057 } |
|
1058 |
|
1059 /* SPARCstation LX hardware initialisation */ |
|
1060 static void ss_lx_init(ram_addr_t RAM_size, int vga_ram_size, |
|
1061 const char *boot_device, DisplayState *ds, |
|
1062 const char *kernel_filename, const char *kernel_cmdline, |
|
1063 const char *initrd_filename, const char *cpu_model) |
|
1064 { |
|
1065 sun4m_hw_init(&sun4m_hwdefs[5], RAM_size, boot_device, ds, kernel_filename, |
|
1066 kernel_cmdline, initrd_filename, cpu_model); |
|
1067 } |
|
1068 |
|
1069 /* SPARCstation 4 hardware initialisation */ |
|
1070 static void ss4_init(ram_addr_t RAM_size, int vga_ram_size, |
|
1071 const char *boot_device, DisplayState *ds, |
|
1072 const char *kernel_filename, const char *kernel_cmdline, |
|
1073 const char *initrd_filename, const char *cpu_model) |
|
1074 { |
|
1075 sun4m_hw_init(&sun4m_hwdefs[6], RAM_size, boot_device, ds, kernel_filename, |
|
1076 kernel_cmdline, initrd_filename, cpu_model); |
|
1077 } |
|
1078 |
|
1079 /* SPARCClassic hardware initialisation */ |
|
1080 static void scls_init(ram_addr_t RAM_size, int vga_ram_size, |
|
1081 const char *boot_device, DisplayState *ds, |
|
1082 const char *kernel_filename, const char *kernel_cmdline, |
|
1083 const char *initrd_filename, const char *cpu_model) |
|
1084 { |
|
1085 sun4m_hw_init(&sun4m_hwdefs[7], RAM_size, boot_device, ds, kernel_filename, |
|
1086 kernel_cmdline, initrd_filename, cpu_model); |
|
1087 } |
|
1088 |
|
1089 /* SPARCbook hardware initialisation */ |
|
1090 static void sbook_init(ram_addr_t RAM_size, int vga_ram_size, |
|
1091 const char *boot_device, DisplayState *ds, |
|
1092 const char *kernel_filename, const char *kernel_cmdline, |
|
1093 const char *initrd_filename, const char *cpu_model) |
|
1094 { |
|
1095 sun4m_hw_init(&sun4m_hwdefs[8], RAM_size, boot_device, ds, kernel_filename, |
|
1096 kernel_cmdline, initrd_filename, cpu_model); |
|
1097 } |
|
1098 |
|
1099 QEMUMachine ss5_machine = { |
|
1100 .name = "SS-5", |
|
1101 .desc = "Sun4m platform, SPARCstation 5", |
|
1102 .init = ss5_init, |
|
1103 .ram_require = PROM_SIZE_MAX + TCX_SIZE, |
|
1104 .nodisk_ok = 1, |
|
1105 .use_scsi = 1, |
|
1106 }; |
|
1107 |
|
1108 QEMUMachine ss10_machine = { |
|
1109 .name = "SS-10", |
|
1110 .desc = "Sun4m platform, SPARCstation 10", |
|
1111 .init = ss10_init, |
|
1112 .ram_require = PROM_SIZE_MAX + TCX_SIZE, |
|
1113 .nodisk_ok = 1, |
|
1114 .use_scsi = 1, |
|
1115 .max_cpus = 4, |
|
1116 }; |
|
1117 |
|
1118 QEMUMachine ss600mp_machine = { |
|
1119 .name = "SS-600MP", |
|
1120 .desc = "Sun4m platform, SPARCserver 600MP", |
|
1121 .init = ss600mp_init, |
|
1122 .ram_require = PROM_SIZE_MAX + TCX_SIZE, |
|
1123 .nodisk_ok = 1, |
|
1124 .use_scsi = 1, |
|
1125 .max_cpus = 4, |
|
1126 }; |
|
1127 |
|
1128 QEMUMachine ss20_machine = { |
|
1129 .name = "SS-20", |
|
1130 .desc = "Sun4m platform, SPARCstation 20", |
|
1131 .init = ss20_init, |
|
1132 .ram_require = PROM_SIZE_MAX + TCX_SIZE, |
|
1133 .nodisk_ok = 1, |
|
1134 .use_scsi = 1, |
|
1135 .max_cpus = 4, |
|
1136 }; |
|
1137 |
|
1138 QEMUMachine voyager_machine = { |
|
1139 .name = "Voyager", |
|
1140 .desc = "Sun4m platform, SPARCstation Voyager", |
|
1141 .init = vger_init, |
|
1142 .ram_require = PROM_SIZE_MAX + TCX_SIZE, |
|
1143 .nodisk_ok = 1, |
|
1144 .use_scsi = 1, |
|
1145 }; |
|
1146 |
|
1147 QEMUMachine ss_lx_machine = { |
|
1148 .name = "LX", |
|
1149 .desc = "Sun4m platform, SPARCstation LX", |
|
1150 .init = ss_lx_init, |
|
1151 .ram_require = PROM_SIZE_MAX + TCX_SIZE, |
|
1152 .nodisk_ok = 1, |
|
1153 .use_scsi = 1, |
|
1154 }; |
|
1155 |
|
1156 QEMUMachine ss4_machine = { |
|
1157 .name = "SS-4", |
|
1158 .desc = "Sun4m platform, SPARCstation 4", |
|
1159 .init = ss4_init, |
|
1160 .ram_require = PROM_SIZE_MAX + TCX_SIZE, |
|
1161 .nodisk_ok = 1, |
|
1162 .use_scsi = 1, |
|
1163 }; |
|
1164 |
|
1165 QEMUMachine scls_machine = { |
|
1166 .name = "SPARCClassic", |
|
1167 .desc = "Sun4m platform, SPARCClassic", |
|
1168 .init = scls_init, |
|
1169 .ram_require = PROM_SIZE_MAX + TCX_SIZE, |
|
1170 .nodisk_ok = 1, |
|
1171 .use_scsi = 1, |
|
1172 }; |
|
1173 |
|
1174 QEMUMachine sbook_machine = { |
|
1175 .name = "SPARCbook", |
|
1176 .desc = "Sun4m platform, SPARCbook", |
|
1177 .init = sbook_init, |
|
1178 .ram_require = PROM_SIZE_MAX + TCX_SIZE, |
|
1179 .nodisk_ok = 1, |
|
1180 .use_scsi = 1, |
|
1181 }; |
|
1182 |
|
1183 static const struct sun4d_hwdef sun4d_hwdefs[] = { |
|
1184 /* SS-1000 */ |
|
1185 { |
|
1186 .iounit_bases = { |
|
1187 0xfe0200000ULL, |
|
1188 0xfe1200000ULL, |
|
1189 0xfe2200000ULL, |
|
1190 0xfe3200000ULL, |
|
1191 -1, |
|
1192 }, |
|
1193 .tcx_base = 0x820000000ULL, |
|
1194 .slavio_base = 0xf00000000ULL, |
|
1195 .ms_kb_base = 0xf00240000ULL, |
|
1196 .serial_base = 0xf00200000ULL, |
|
1197 .nvram_base = 0xf00280000ULL, |
|
1198 .counter_base = 0xf00300000ULL, |
|
1199 .espdma_base = 0x800081000ULL, |
|
1200 .esp_base = 0x800080000ULL, |
|
1201 .ledma_base = 0x800040000ULL, |
|
1202 .le_base = 0x800060000ULL, |
|
1203 .sbi_base = 0xf02800000ULL, |
|
1204 .vram_size = 0x00100000, |
|
1205 .nvram_size = 0x2000, |
|
1206 .esp_irq = 3, |
|
1207 .le_irq = 4, |
|
1208 .clock_irq = 14, |
|
1209 .clock1_irq = 10, |
|
1210 .ms_kb_irq = 12, |
|
1211 .ser_irq = 12, |
|
1212 .nvram_machine_id = 0x80, |
|
1213 .machine_id = ss1000_id, |
|
1214 .iounit_version = 0x03000000, |
|
1215 .max_mem = 0xf00000000ULL, |
|
1216 .default_cpu_model = "TI SuperSparc II", |
|
1217 }, |
|
1218 /* SS-2000 */ |
|
1219 { |
|
1220 .iounit_bases = { |
|
1221 0xfe0200000ULL, |
|
1222 0xfe1200000ULL, |
|
1223 0xfe2200000ULL, |
|
1224 0xfe3200000ULL, |
|
1225 0xfe4200000ULL, |
|
1226 }, |
|
1227 .tcx_base = 0x820000000ULL, |
|
1228 .slavio_base = 0xf00000000ULL, |
|
1229 .ms_kb_base = 0xf00240000ULL, |
|
1230 .serial_base = 0xf00200000ULL, |
|
1231 .nvram_base = 0xf00280000ULL, |
|
1232 .counter_base = 0xf00300000ULL, |
|
1233 .espdma_base = 0x800081000ULL, |
|
1234 .esp_base = 0x800080000ULL, |
|
1235 .ledma_base = 0x800040000ULL, |
|
1236 .le_base = 0x800060000ULL, |
|
1237 .sbi_base = 0xf02800000ULL, |
|
1238 .vram_size = 0x00100000, |
|
1239 .nvram_size = 0x2000, |
|
1240 .esp_irq = 3, |
|
1241 .le_irq = 4, |
|
1242 .clock_irq = 14, |
|
1243 .clock1_irq = 10, |
|
1244 .ms_kb_irq = 12, |
|
1245 .ser_irq = 12, |
|
1246 .nvram_machine_id = 0x80, |
|
1247 .machine_id = ss2000_id, |
|
1248 .iounit_version = 0x03000000, |
|
1249 .max_mem = 0xf00000000ULL, |
|
1250 .default_cpu_model = "TI SuperSparc II", |
|
1251 }, |
|
1252 }; |
|
1253 |
|
1254 static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size, |
|
1255 const char *boot_device, |
|
1256 DisplayState *ds, const char *kernel_filename, |
|
1257 const char *kernel_cmdline, |
|
1258 const char *initrd_filename, const char *cpu_model) |
|
1259 { |
|
1260 CPUState *env, *envs[MAX_CPUS]; |
|
1261 unsigned int i; |
|
1262 void *iounits[MAX_IOUNITS], *espdma, *ledma, *main_esp, *nvram, *sbi; |
|
1263 qemu_irq *cpu_irqs[MAX_CPUS], *sbi_irq, *sbi_cpu_irq, |
|
1264 *espdma_irq, *ledma_irq; |
|
1265 qemu_irq *esp_reset, *le_reset; |
|
1266 ram_addr_t ram_offset, prom_offset, tcx_offset; |
|
1267 unsigned long kernel_size; |
|
1268 int ret; |
|
1269 char buf[1024]; |
|
1270 int drive_index; |
|
1271 void *fw_cfg; |
|
1272 |
|
1273 /* init CPUs */ |
|
1274 if (!cpu_model) |
|
1275 cpu_model = hwdef->default_cpu_model; |
|
1276 |
|
1277 for (i = 0; i < smp_cpus; i++) { |
|
1278 env = cpu_init(cpu_model); |
|
1279 if (!env) { |
|
1280 fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n"); |
|
1281 exit(1); |
|
1282 } |
|
1283 cpu_sparc_set_id(env, i); |
|
1284 envs[i] = env; |
|
1285 if (i == 0) { |
|
1286 qemu_register_reset(main_cpu_reset, env); |
|
1287 } else { |
|
1288 qemu_register_reset(secondary_cpu_reset, env); |
|
1289 env->halted = 1; |
|
1290 } |
|
1291 cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS); |
|
1292 env->prom_addr = hwdef->slavio_base; |
|
1293 } |
|
1294 |
|
1295 for (i = smp_cpus; i < MAX_CPUS; i++) |
|
1296 cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS); |
|
1297 |
|
1298 /* allocate RAM */ |
|
1299 if ((uint64_t)RAM_size > hwdef->max_mem) { |
|
1300 fprintf(stderr, |
|
1301 "qemu: Too much memory for this machine: %d, maximum %d\n", |
|
1302 (unsigned int)(RAM_size / (1024 * 1024)), |
|
1303 (unsigned int)(hwdef->max_mem / (1024 * 1024))); |
|
1304 exit(1); |
|
1305 } |
|
1306 ram_offset = qemu_ram_alloc(RAM_size); |
|
1307 cpu_register_physical_memory(0, RAM_size, ram_offset); |
|
1308 |
|
1309 /* load boot prom */ |
|
1310 prom_offset = qemu_ram_alloc(PROM_SIZE_MAX); |
|
1311 cpu_register_physical_memory(hwdef->slavio_base, |
|
1312 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & |
|
1313 TARGET_PAGE_MASK, |
|
1314 prom_offset | IO_MEM_ROM); |
|
1315 |
|
1316 if (bios_name == NULL) |
|
1317 bios_name = PROM_FILENAME; |
|
1318 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); |
|
1319 ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL); |
|
1320 if (ret < 0 || ret > PROM_SIZE_MAX) |
|
1321 ret = load_image_targphys(buf, hwdef->slavio_base, PROM_SIZE_MAX); |
|
1322 if (ret < 0 || ret > PROM_SIZE_MAX) { |
|
1323 fprintf(stderr, "qemu: could not load prom '%s'\n", |
|
1324 buf); |
|
1325 exit(1); |
|
1326 } |
|
1327 |
|
1328 /* set up devices */ |
|
1329 sbi = sbi_init(hwdef->sbi_base, &sbi_irq, &sbi_cpu_irq, cpu_irqs); |
|
1330 |
|
1331 for (i = 0; i < MAX_IOUNITS; i++) |
|
1332 if (hwdef->iounit_bases[i] != (target_phys_addr_t)-1) |
|
1333 iounits[i] = iommu_init(hwdef->iounit_bases[i], |
|
1334 hwdef->iounit_version, |
|
1335 sbi_irq[hwdef->me_irq]); |
|
1336 |
|
1337 espdma = sparc32_dma_init(hwdef->espdma_base, sbi_irq[hwdef->esp_irq], |
|
1338 iounits[0], &espdma_irq, &esp_reset); |
|
1339 |
|
1340 ledma = sparc32_dma_init(hwdef->ledma_base, sbi_irq[hwdef->le_irq], |
|
1341 iounits[0], &ledma_irq, &le_reset); |
|
1342 |
|
1343 if (graphic_depth != 8 && graphic_depth != 24) { |
|
1344 fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth); |
|
1345 exit (1); |
|
1346 } |
|
1347 tcx_offset = qemu_ram_alloc(hwdef->vram_size); |
|
1348 tcx_init(ds, hwdef->tcx_base, phys_ram_base + tcx_offset, tcx_offset, |
|
1349 hwdef->vram_size, graphic_width, graphic_height, graphic_depth); |
|
1350 |
|
1351 if (nd_table[0].model == NULL |
|
1352 || strcmp(nd_table[0].model, "lance") == 0) { |
|
1353 lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset); |
|
1354 } else if (strcmp(nd_table[0].model, "?") == 0) { |
|
1355 fprintf(stderr, "qemu: Supported NICs: lance\n"); |
|
1356 exit (1); |
|
1357 } else { |
|
1358 fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model); |
|
1359 exit (1); |
|
1360 } |
|
1361 |
|
1362 nvram = m48t59_init(sbi_irq[0], hwdef->nvram_base, 0, |
|
1363 hwdef->nvram_size, 8); |
|
1364 |
|
1365 slavio_timer_init_all(hwdef->counter_base, sbi_irq[hwdef->clock1_irq], |
|
1366 sbi_cpu_irq, smp_cpus); |
|
1367 |
|
1368 slavio_serial_ms_kbd_init(hwdef->ms_kb_base, sbi_irq[hwdef->ms_kb_irq], |
|
1369 nographic); |
|
1370 // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device |
|
1371 // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device |
|
1372 slavio_serial_init(hwdef->serial_base, sbi_irq[hwdef->ser_irq], |
|
1373 serial_hds[1], serial_hds[0]); |
|
1374 |
|
1375 if (drive_get_max_bus(IF_SCSI) > 0) { |
|
1376 fprintf(stderr, "qemu: too many SCSI bus\n"); |
|
1377 exit(1); |
|
1378 } |
|
1379 |
|
1380 main_esp = esp_init(hwdef->esp_base, 2, |
|
1381 espdma_memory_read, espdma_memory_write, |
|
1382 espdma, *espdma_irq, esp_reset); |
|
1383 |
|
1384 for (i = 0; i < ESP_MAX_DEVS; i++) { |
|
1385 drive_index = drive_get_index(IF_SCSI, 0, i); |
|
1386 if (drive_index == -1) |
|
1387 continue; |
|
1388 esp_scsi_attach(main_esp, drives_table[drive_index].bdrv, i); |
|
1389 } |
|
1390 |
|
1391 kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename, |
|
1392 RAM_size); |
|
1393 |
|
1394 nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, |
|
1395 boot_device, RAM_size, kernel_size, graphic_width, |
|
1396 graphic_height, graphic_depth, hwdef->nvram_machine_id, |
|
1397 "Sun4d"); |
|
1398 |
|
1399 fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2); |
|
1400 fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); |
|
1401 fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); |
|
1402 fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id); |
|
1403 } |
|
1404 |
|
1405 /* SPARCserver 1000 hardware initialisation */ |
|
1406 static void ss1000_init(ram_addr_t RAM_size, int vga_ram_size, |
|
1407 const char *boot_device, DisplayState *ds, |
|
1408 const char *kernel_filename, const char *kernel_cmdline, |
|
1409 const char *initrd_filename, const char *cpu_model) |
|
1410 { |
|
1411 sun4d_hw_init(&sun4d_hwdefs[0], RAM_size, boot_device, ds, kernel_filename, |
|
1412 kernel_cmdline, initrd_filename, cpu_model); |
|
1413 } |
|
1414 |
|
1415 /* SPARCcenter 2000 hardware initialisation */ |
|
1416 static void ss2000_init(ram_addr_t RAM_size, int vga_ram_size, |
|
1417 const char *boot_device, DisplayState *ds, |
|
1418 const char *kernel_filename, const char *kernel_cmdline, |
|
1419 const char *initrd_filename, const char *cpu_model) |
|
1420 { |
|
1421 sun4d_hw_init(&sun4d_hwdefs[1], RAM_size, boot_device, ds, kernel_filename, |
|
1422 kernel_cmdline, initrd_filename, cpu_model); |
|
1423 } |
|
1424 |
|
1425 QEMUMachine ss1000_machine = { |
|
1426 .name = "SS-1000", |
|
1427 .desc = "Sun4d platform, SPARCserver 1000", |
|
1428 .init = ss1000_init, |
|
1429 .ram_require = PROM_SIZE_MAX + TCX_SIZE, |
|
1430 .nodisk_ok = 1, |
|
1431 .use_scsi = 1, |
|
1432 .max_cpus = 8, |
|
1433 }; |
|
1434 |
|
1435 QEMUMachine ss2000_machine = { |
|
1436 .name = "SS-2000", |
|
1437 .desc = "Sun4d platform, SPARCcenter 2000", |
|
1438 .init = ss2000_init, |
|
1439 .ram_require = PROM_SIZE_MAX + TCX_SIZE, |
|
1440 .nodisk_ok = 1, |
|
1441 .use_scsi = 1, |
|
1442 .max_cpus = 20, |
|
1443 }; |
|
1444 |
|
1445 static const struct sun4c_hwdef sun4c_hwdefs[] = { |
|
1446 /* SS-2 */ |
|
1447 { |
|
1448 .iommu_base = 0xf8000000, |
|
1449 .tcx_base = 0xfe000000, |
|
1450 .slavio_base = 0xf6000000, |
|
1451 .intctl_base = 0xf5000000, |
|
1452 .counter_base = 0xf3000000, |
|
1453 .ms_kb_base = 0xf0000000, |
|
1454 .serial_base = 0xf1000000, |
|
1455 .nvram_base = 0xf2000000, |
|
1456 .fd_base = 0xf7200000, |
|
1457 .dma_base = 0xf8400000, |
|
1458 .esp_base = 0xf8800000, |
|
1459 .le_base = 0xf8c00000, |
|
1460 .aux1_base = 0xf7400003, |
|
1461 .vram_size = 0x00100000, |
|
1462 .nvram_size = 0x800, |
|
1463 .esp_irq = 2, |
|
1464 .le_irq = 3, |
|
1465 .clock_irq = 5, |
|
1466 .clock1_irq = 7, |
|
1467 .ms_kb_irq = 1, |
|
1468 .ser_irq = 1, |
|
1469 .fd_irq = 1, |
|
1470 .me_irq = 1, |
|
1471 .nvram_machine_id = 0x55, |
|
1472 .machine_id = ss2_id, |
|
1473 .max_mem = 0x10000000, |
|
1474 .default_cpu_model = "Cypress CY7C601", |
|
1475 }, |
|
1476 }; |
|
1477 |
|
1478 static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size, |
|
1479 const char *boot_device, |
|
1480 DisplayState *ds, const char *kernel_filename, |
|
1481 const char *kernel_cmdline, |
|
1482 const char *initrd_filename, const char *cpu_model) |
|
1483 { |
|
1484 CPUState *env; |
|
1485 unsigned int i; |
|
1486 void *iommu, *espdma, *ledma, *main_esp, *nvram; |
|
1487 qemu_irq *cpu_irqs, *slavio_irq, *espdma_irq, *ledma_irq; |
|
1488 qemu_irq *esp_reset, *le_reset; |
|
1489 qemu_irq *fdc_tc; |
|
1490 ram_addr_t ram_offset, prom_offset, tcx_offset; |
|
1491 unsigned long kernel_size; |
|
1492 int ret; |
|
1493 char buf[1024]; |
|
1494 BlockDriverState *fd[MAX_FD]; |
|
1495 int drive_index; |
|
1496 void *fw_cfg; |
|
1497 |
|
1498 /* init CPU */ |
|
1499 if (!cpu_model) |
|
1500 cpu_model = hwdef->default_cpu_model; |
|
1501 |
|
1502 env = cpu_init(cpu_model); |
|
1503 if (!env) { |
|
1504 fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n"); |
|
1505 exit(1); |
|
1506 } |
|
1507 |
|
1508 cpu_sparc_set_id(env, 0); |
|
1509 |
|
1510 qemu_register_reset(main_cpu_reset, env); |
|
1511 cpu_irqs = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS); |
|
1512 env->prom_addr = hwdef->slavio_base; |
|
1513 |
|
1514 /* allocate RAM */ |
|
1515 if ((uint64_t)RAM_size > hwdef->max_mem) { |
|
1516 fprintf(stderr, |
|
1517 "qemu: Too much memory for this machine: %d, maximum %d\n", |
|
1518 (unsigned int)(RAM_size / (1024 * 1024)), |
|
1519 (unsigned int)(hwdef->max_mem / (1024 * 1024))); |
|
1520 exit(1); |
|
1521 } |
|
1522 ram_offset = qemu_ram_alloc(RAM_size); |
|
1523 cpu_register_physical_memory(0, RAM_size, ram_offset); |
|
1524 |
|
1525 /* load boot prom */ |
|
1526 prom_offset = qemu_ram_alloc(PROM_SIZE_MAX); |
|
1527 cpu_register_physical_memory(hwdef->slavio_base, |
|
1528 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & |
|
1529 TARGET_PAGE_MASK, |
|
1530 prom_offset | IO_MEM_ROM); |
|
1531 |
|
1532 if (bios_name == NULL) |
|
1533 bios_name = PROM_FILENAME; |
|
1534 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); |
|
1535 ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL); |
|
1536 if (ret < 0 || ret > PROM_SIZE_MAX) |
|
1537 ret = load_image_targphys(buf, hwdef->slavio_base, PROM_SIZE_MAX); |
|
1538 if (ret < 0 || ret > PROM_SIZE_MAX) { |
|
1539 fprintf(stderr, "qemu: could not load prom '%s'\n", |
|
1540 buf); |
|
1541 exit(1); |
|
1542 } |
|
1543 |
|
1544 /* set up devices */ |
|
1545 slavio_intctl = sun4c_intctl_init(hwdef->intctl_base, |
|
1546 &slavio_irq, cpu_irqs); |
|
1547 |
|
1548 iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version, |
|
1549 slavio_irq[hwdef->me_irq]); |
|
1550 |
|
1551 espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq], |
|
1552 iommu, &espdma_irq, &esp_reset); |
|
1553 |
|
1554 ledma = sparc32_dma_init(hwdef->dma_base + 16ULL, |
|
1555 slavio_irq[hwdef->le_irq], iommu, &ledma_irq, |
|
1556 &le_reset); |
|
1557 |
|
1558 if (graphic_depth != 8 && graphic_depth != 24) { |
|
1559 fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth); |
|
1560 exit (1); |
|
1561 } |
|
1562 tcx_offset = qemu_ram_alloc(hwdef->vram_size); |
|
1563 tcx_init(ds, hwdef->tcx_base, phys_ram_base + tcx_offset, tcx_offset, |
|
1564 hwdef->vram_size, graphic_width, graphic_height, graphic_depth); |
|
1565 |
|
1566 if (nd_table[0].model == NULL |
|
1567 || strcmp(nd_table[0].model, "lance") == 0) { |
|
1568 lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset); |
|
1569 } else if (strcmp(nd_table[0].model, "?") == 0) { |
|
1570 fprintf(stderr, "qemu: Supported NICs: lance\n"); |
|
1571 exit (1); |
|
1572 } else { |
|
1573 fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model); |
|
1574 exit (1); |
|
1575 } |
|
1576 |
|
1577 nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, |
|
1578 hwdef->nvram_size, 2); |
|
1579 |
|
1580 slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq], |
|
1581 nographic); |
|
1582 // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device |
|
1583 // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device |
|
1584 slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq], |
|
1585 serial_hds[1], serial_hds[0]); |
|
1586 |
|
1587 slavio_misc = slavio_misc_init(0, -1, hwdef->aux1_base, -1, |
|
1588 slavio_irq[hwdef->me_irq], NULL, &fdc_tc); |
|
1589 |
|
1590 if (hwdef->fd_base != (target_phys_addr_t)-1) { |
|
1591 /* there is zero or one floppy drive */ |
|
1592 memset(fd, 0, sizeof(fd)); |
|
1593 drive_index = drive_get_index(IF_FLOPPY, 0, 0); |
|
1594 if (drive_index != -1) |
|
1595 fd[0] = drives_table[drive_index].bdrv; |
|
1596 |
|
1597 sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd, |
|
1598 fdc_tc); |
|
1599 } |
|
1600 |
|
1601 if (drive_get_max_bus(IF_SCSI) > 0) { |
|
1602 fprintf(stderr, "qemu: too many SCSI bus\n"); |
|
1603 exit(1); |
|
1604 } |
|
1605 |
|
1606 main_esp = esp_init(hwdef->esp_base, 2, |
|
1607 espdma_memory_read, espdma_memory_write, |
|
1608 espdma, *espdma_irq, esp_reset); |
|
1609 |
|
1610 for (i = 0; i < ESP_MAX_DEVS; i++) { |
|
1611 drive_index = drive_get_index(IF_SCSI, 0, i); |
|
1612 if (drive_index == -1) |
|
1613 continue; |
|
1614 esp_scsi_attach(main_esp, drives_table[drive_index].bdrv, i); |
|
1615 } |
|
1616 |
|
1617 kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename, |
|
1618 RAM_size); |
|
1619 |
|
1620 nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, |
|
1621 boot_device, RAM_size, kernel_size, graphic_width, |
|
1622 graphic_height, graphic_depth, hwdef->nvram_machine_id, |
|
1623 "Sun4c"); |
|
1624 |
|
1625 fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2); |
|
1626 fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); |
|
1627 fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); |
|
1628 fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id); |
|
1629 } |
|
1630 |
|
1631 /* SPARCstation 2 hardware initialisation */ |
|
1632 static void ss2_init(ram_addr_t RAM_size, int vga_ram_size, |
|
1633 const char *boot_device, DisplayState *ds, |
|
1634 const char *kernel_filename, const char *kernel_cmdline, |
|
1635 const char *initrd_filename, const char *cpu_model) |
|
1636 { |
|
1637 sun4c_hw_init(&sun4c_hwdefs[0], RAM_size, boot_device, ds, kernel_filename, |
|
1638 kernel_cmdline, initrd_filename, cpu_model); |
|
1639 } |
|
1640 |
|
1641 QEMUMachine ss2_machine = { |
|
1642 .name = "SS-2", |
|
1643 .desc = "Sun4c platform, SPARCstation 2", |
|
1644 .init = ss2_init, |
|
1645 .ram_require = PROM_SIZE_MAX + TCX_SIZE, |
|
1646 .nodisk_ok = 1, |
|
1647 .use_scsi = 1, |
|
1648 }; |