Commit 36cd921035c1469f8d953c47132925ac5da7f02e
1 parent
8a08f9a8
Reorganise Sun4m to allow other machine types
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2570 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
135 additions
and
64 deletions
hw/sun4m.c
... | ... | @@ -23,43 +23,44 @@ |
23 | 23 | */ |
24 | 24 | #include "vl.h" |
25 | 25 | |
26 | +/* | |
27 | + * Sun4m architecture was used in the following machines: | |
28 | + * | |
29 | + * SPARCserver 6xxMP/xx | |
30 | + * SPARCclassic (SPARCclassic Server)(SPARCstation LC) (4/15), SPARCclassic X (4/10) | |
31 | + * SPARCstation LX/ZX (4/30) | |
32 | + * SPARCstation Voyager | |
33 | + * SPARCstation 10/xx, SPARCserver 10/xx | |
34 | + * SPARCstation 5, SPARCserver 5 | |
35 | + * SPARCstation 20/xx, SPARCserver 20 | |
36 | + * SPARCstation 4 | |
37 | + * | |
38 | + * See for example: http://www.sunhelp.org/faq/sunref1.html | |
39 | + */ | |
40 | + | |
26 | 41 | #define KERNEL_LOAD_ADDR 0x00004000 |
27 | 42 | #define CMDLINE_ADDR 0x007ff000 |
28 | 43 | #define INITRD_LOAD_ADDR 0x00800000 |
29 | 44 | #define PROM_SIZE_MAX (256 * 1024) |
30 | 45 | #define PROM_ADDR 0xffd00000 |
31 | 46 | #define PROM_FILENAME "openbios-sparc32" |
32 | -#define PHYS_JJ_EEPROM 0x71200000 /* m48t08 */ | |
33 | -#define PHYS_JJ_IDPROM_OFF 0x1FD8 | |
34 | -#define PHYS_JJ_EEPROM_SIZE 0x2000 | |
35 | -// IRQs are not PIL ones, but master interrupt controller register | |
36 | -// bits | |
37 | -#define PHYS_JJ_IOMMU 0x10000000 /* I/O MMU */ | |
38 | -#define PHYS_JJ_TCX_FB 0x50000000 /* TCX frame buffer */ | |
39 | -#define PHYS_JJ_SLAVIO 0x70000000 /* Slavio base */ | |
40 | -#define PHYS_JJ_DMA 0x78400000 /* DMA controller */ | |
41 | -#define PHYS_JJ_ESP 0x78800000 /* ESP SCSI */ | |
42 | -#define PHYS_JJ_ESP_IRQ 18 | |
43 | -#define PHYS_JJ_LE 0x78C00000 /* Lance ethernet */ | |
44 | -#define PHYS_JJ_LE_IRQ 16 | |
45 | -#define PHYS_JJ_CLOCK 0x71D00000 /* Per-CPU timer/counter, L14 */ | |
46 | -#define PHYS_JJ_CLOCK_IRQ 7 | |
47 | -#define PHYS_JJ_CLOCK1 0x71D10000 /* System timer/counter, L10 */ | |
48 | -#define PHYS_JJ_CLOCK1_IRQ 19 | |
49 | -#define PHYS_JJ_INTR0 0x71E00000 /* Per-CPU interrupt control registers */ | |
50 | -#define PHYS_JJ_INTR_G 0x71E10000 /* Master interrupt control registers */ | |
51 | -#define PHYS_JJ_MS_KBD 0x71000000 /* Mouse and keyboard */ | |
52 | -#define PHYS_JJ_MS_KBD_IRQ 14 | |
53 | -#define PHYS_JJ_SER 0x71100000 /* Serial */ | |
54 | -#define PHYS_JJ_SER_IRQ 15 | |
55 | -#define PHYS_JJ_FDC 0x71400000 /* Floppy */ | |
56 | -#define PHYS_JJ_FLOPPY_IRQ 22 | |
57 | -#define PHYS_JJ_ME_IRQ 30 /* Module error, power fail */ | |
58 | -#define PHYS_JJ_CS 0x6c000000 /* Crystal CS4231 */ | |
59 | -#define PHYS_JJ_CS_IRQ 5 | |
60 | 47 | |
61 | 48 | #define MAX_CPUS 16 |
62 | 49 | |
50 | +struct hwdef { | |
51 | + target_ulong iommu_base, slavio_base; | |
52 | + target_ulong intctl_base, counter_base, nvram_base, ms_kb_base, serial_base; | |
53 | + target_ulong fd_base; | |
54 | + target_ulong dma_base, esp_base, le_base; | |
55 | + target_ulong tcx_base, cs_base; | |
56 | + long vram_size, nvram_size; | |
57 | + // IRQ numbers are not PIL ones, but master interrupt controller register | |
58 | + // bit numbers | |
59 | + int intctl_g_intr, esp_irq, le_irq, cpu_irq, clock_irq, clock1_irq; | |
60 | + int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq; | |
61 | + int machine_id; // For NVRAM | |
62 | +}; | |
63 | + | |
63 | 64 | /* TSC handling */ |
64 | 65 | |
65 | 66 | uint64_t cpu_get_tsc() |
... | ... | @@ -122,7 +123,8 @@ extern int nographic; |
122 | 123 | static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline, |
123 | 124 | int boot_device, uint32_t RAM_size, |
124 | 125 | uint32_t kernel_size, |
125 | - int width, int height, int depth) | |
126 | + int width, int height, int depth, | |
127 | + int machine_id) | |
126 | 128 | { |
127 | 129 | unsigned char tmp = 0; |
128 | 130 | int i, j; |
... | ... | @@ -151,7 +153,7 @@ static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline, |
151 | 153 | // Sun4m specific use |
152 | 154 | i = 0x1fd8; |
153 | 155 | m48t59_write(nvram, i++, 0x01); |
154 | - m48t59_write(nvram, i++, 0x80); /* Sun4m OBP */ | |
156 | + m48t59_write(nvram, i++, machine_id); | |
155 | 157 | j = 0; |
156 | 158 | m48t59_write(nvram, i++, macaddr[j++]); |
157 | 159 | m48t59_write(nvram, i++, macaddr[j++]); |
... | ... | @@ -207,25 +209,16 @@ static void main_cpu_reset(void *opaque) |
207 | 209 | cpu_reset(env); |
208 | 210 | } |
209 | 211 | |
210 | -/* Sun4m hardware initialisation */ | |
211 | -static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, | |
212 | - DisplayState *ds, const char **fd_filename, int snapshot, | |
213 | - const char *kernel_filename, const char *kernel_cmdline, | |
214 | - const char *initrd_filename, const char *cpu_model) | |
212 | +static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size, | |
213 | + DisplayState *ds, const char *cpu_model) | |
214 | + | |
215 | 215 | { |
216 | 216 | CPUState *env, *envs[MAX_CPUS]; |
217 | - char buf[1024]; | |
218 | - int ret, linux_boot; | |
219 | 217 | unsigned int i; |
220 | - long vram_size = 0x100000, prom_offset, initrd_size, kernel_size; | |
221 | 218 | void *iommu, *dma, *main_esp, *main_lance = NULL; |
222 | 219 | const sparc_def_t *def; |
223 | 220 | |
224 | - linux_boot = (kernel_filename != NULL); | |
225 | - | |
226 | 221 | /* init CPUs */ |
227 | - if (cpu_model == NULL) | |
228 | - cpu_model = "Fujitsu MB86904"; | |
229 | 222 | sparc_find_by_name(cpu_model, &def); |
230 | 223 | if (def == NULL) { |
231 | 224 | fprintf(stderr, "Unable to find Sparc CPU definition\n"); |
... | ... | @@ -243,34 +236,40 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, |
243 | 236 | /* allocate RAM */ |
244 | 237 | cpu_register_physical_memory(0, ram_size, 0); |
245 | 238 | |
246 | - iommu = iommu_init(PHYS_JJ_IOMMU); | |
247 | - slavio_intctl = slavio_intctl_init(PHYS_JJ_INTR0, PHYS_JJ_INTR_G); | |
239 | + iommu = iommu_init(hwdef->iommu_base); | |
240 | + slavio_intctl = slavio_intctl_init(hwdef->intctl_base, | |
241 | + hwdef->intctl_base + 0x10000); | |
248 | 242 | for(i = 0; i < smp_cpus; i++) { |
249 | 243 | slavio_intctl_set_cpu(slavio_intctl, i, envs[i]); |
250 | 244 | } |
251 | - dma = sparc32_dma_init(PHYS_JJ_DMA, PHYS_JJ_ESP_IRQ, PHYS_JJ_LE_IRQ, iommu, slavio_intctl); | |
245 | + dma = sparc32_dma_init(hwdef->dma_base, hwdef->esp_irq, | |
246 | + hwdef->le_irq, iommu, slavio_intctl); | |
252 | 247 | |
253 | - tcx_init(ds, PHYS_JJ_TCX_FB, phys_ram_base + ram_size, ram_size, vram_size, graphic_width, graphic_height); | |
248 | + tcx_init(ds, hwdef->tcx_base, phys_ram_base + ram_size, ram_size, | |
249 | + hwdef->vram_size, graphic_width, graphic_height); | |
254 | 250 | if (nd_table[0].vlan) { |
255 | 251 | if (nd_table[0].model == NULL |
256 | 252 | || strcmp(nd_table[0].model, "lance") == 0) { |
257 | - main_lance = lance_init(&nd_table[0], PHYS_JJ_LE, dma); | |
253 | + main_lance = lance_init(&nd_table[0], hwdef->le_base, dma); | |
258 | 254 | } else { |
259 | 255 | fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model); |
260 | 256 | exit (1); |
261 | 257 | } |
262 | 258 | } |
263 | - nvram = m48t59_init(0, PHYS_JJ_EEPROM, 0, PHYS_JJ_EEPROM_SIZE, 8); | |
259 | + nvram = m48t59_init(0, hwdef->nvram_base, 0, hwdef->nvram_size, 8); | |
264 | 260 | for (i = 0; i < MAX_CPUS; i++) { |
265 | - slavio_timer_init(PHYS_JJ_CLOCK + i * TARGET_PAGE_SIZE, PHYS_JJ_CLOCK_IRQ, 0, i); | |
261 | + slavio_timer_init(hwdef->counter_base + i * TARGET_PAGE_SIZE, | |
262 | + hwdef->clock_irq, 0, i); | |
266 | 263 | } |
267 | - slavio_timer_init(PHYS_JJ_CLOCK1, PHYS_JJ_CLOCK1_IRQ, 2, (unsigned int)-1); | |
268 | - slavio_serial_ms_kbd_init(PHYS_JJ_MS_KBD, PHYS_JJ_MS_KBD_IRQ); | |
264 | + slavio_timer_init(hwdef->counter_base + 0x10000, hwdef->clock1_irq, 2, | |
265 | + (unsigned int)-1); | |
266 | + slavio_serial_ms_kbd_init(hwdef->ms_kb_base, hwdef->ms_kb_irq); | |
269 | 267 | // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device |
270 | 268 | // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device |
271 | - slavio_serial_init(PHYS_JJ_SER, PHYS_JJ_SER_IRQ, serial_hds[1], serial_hds[0]); | |
272 | - fdctrl_init(PHYS_JJ_FLOPPY_IRQ, 0, 1, PHYS_JJ_FDC, fd_table); | |
273 | - main_esp = esp_init(bs_table, PHYS_JJ_ESP, dma); | |
269 | + slavio_serial_init(hwdef->serial_base, hwdef->ser_irq, | |
270 | + serial_hds[1], serial_hds[0]); | |
271 | + fdctrl_init(hwdef->fd_irq, 0, 1, hwdef->fd_base, fd_table); | |
272 | + main_esp = esp_init(bs_table, hwdef->esp_base, dma); | |
274 | 273 | |
275 | 274 | for (i = 0; i < MAX_DISKS; i++) { |
276 | 275 | if (bs_table[i]) { |
... | ... | @@ -278,9 +277,23 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, |
278 | 277 | } |
279 | 278 | } |
280 | 279 | |
281 | - slavio_misc = slavio_misc_init(PHYS_JJ_SLAVIO, PHYS_JJ_ME_IRQ); | |
282 | - cs_init(PHYS_JJ_CS, PHYS_JJ_CS_IRQ, slavio_intctl); | |
280 | + slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->me_irq); | |
281 | + cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl); | |
283 | 282 | sparc32_dma_set_reset_data(dma, main_esp, main_lance); |
283 | +} | |
284 | + | |
285 | +static void sun4m_load_kernel(long vram_size, int ram_size, int boot_device, | |
286 | + const char *kernel_filename, | |
287 | + const char *kernel_cmdline, | |
288 | + const char *initrd_filename, | |
289 | + int machine_id) | |
290 | +{ | |
291 | + int ret, linux_boot; | |
292 | + char buf[1024]; | |
293 | + unsigned int i; | |
294 | + long prom_offset, initrd_size, kernel_size; | |
295 | + | |
296 | + linux_boot = (kernel_filename != NULL); | |
284 | 297 | |
285 | 298 | prom_offset = ram_size + vram_size; |
286 | 299 | cpu_register_physical_memory(PROM_ADDR, |
... | ... | @@ -329,11 +342,69 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, |
329 | 342 | } |
330 | 343 | } |
331 | 344 | } |
332 | - nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, boot_device, ram_size, kernel_size, graphic_width, graphic_height, graphic_depth); | |
345 | + nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, | |
346 | + boot_device, ram_size, kernel_size, graphic_width, | |
347 | + graphic_height, graphic_depth, machine_id); | |
348 | +} | |
349 | + | |
350 | +static const struct hwdef hwdefs[] = { | |
351 | + /* SS-5 */ | |
352 | + { | |
353 | + .iommu_base = 0x10000000, | |
354 | + .tcx_base = 0x50000000, | |
355 | + .cs_base = 0x6c000000, | |
356 | + .slavio_base = 0x71000000, | |
357 | + .ms_kb_base = 0x71000000, | |
358 | + .serial_base = 0x71100000, | |
359 | + .nvram_base = 0x71200000, | |
360 | + .fd_base = 0x71400000, | |
361 | + .counter_base = 0x71d00000, | |
362 | + .intctl_base = 0x71e00000, | |
363 | + .dma_base = 0x78400000, | |
364 | + .esp_base = 0x78800000, | |
365 | + .le_base = 0x78c00000, | |
366 | + .vram_size = 0x00100000, | |
367 | + .nvram_size = 0x2000, | |
368 | + .esp_irq = 18, | |
369 | + .le_irq = 16, | |
370 | + .clock_irq = 7, | |
371 | + .clock1_irq = 19, | |
372 | + .ms_kb_irq = 14, | |
373 | + .ser_irq = 15, | |
374 | + .fd_irq = 22, | |
375 | + .me_irq = 30, | |
376 | + .cs_irq = 5, | |
377 | + .machine_id = 0x80, | |
378 | + }, | |
379 | +}; | |
380 | + | |
381 | +static void sun4m_common_init(int ram_size, int boot_device, DisplayState *ds, | |
382 | + const char *kernel_filename, const char *kernel_cmdline, | |
383 | + const char *initrd_filename, const char *cpu_model, | |
384 | + unsigned int machine) | |
385 | +{ | |
386 | + sun4m_hw_init(&hwdefs[machine], ram_size, ds, cpu_model); | |
387 | + | |
388 | + sun4m_load_kernel(hwdefs[machine].vram_size, ram_size, boot_device, | |
389 | + kernel_filename, kernel_cmdline, initrd_filename, | |
390 | + hwdefs[machine].machine_id); | |
391 | +} | |
392 | + | |
393 | +/* SPARCstation 5 hardware initialisation */ | |
394 | +static void ss5_init(int ram_size, int vga_ram_size, int boot_device, | |
395 | + DisplayState *ds, const char **fd_filename, int snapshot, | |
396 | + const char *kernel_filename, const char *kernel_cmdline, | |
397 | + const char *initrd_filename, const char *cpu_model) | |
398 | +{ | |
399 | + if (cpu_model == NULL) | |
400 | + cpu_model = "Fujitsu MB86904"; | |
401 | + sun4m_common_init(ram_size, boot_device, ds, kernel_filename, | |
402 | + kernel_cmdline, initrd_filename, cpu_model, | |
403 | + 0); | |
333 | 404 | } |
334 | 405 | |
335 | -QEMUMachine sun4m_machine = { | |
336 | - "sun4m", | |
337 | - "Sun4m platform", | |
338 | - sun4m_init, | |
406 | +QEMUMachine ss5_machine = { | |
407 | + "SS-5", | |
408 | + "Sun4m platform, SPARCstation 5", | |
409 | + ss5_init, | |
339 | 410 | }; | ... | ... |
vl.c
... | ... | @@ -6690,7 +6690,7 @@ void register_machines(void) |
6690 | 6690 | #ifdef TARGET_SPARC64 |
6691 | 6691 | qemu_register_machine(&sun4u_machine); |
6692 | 6692 | #else |
6693 | - qemu_register_machine(&sun4m_machine); | |
6693 | + qemu_register_machine(&ss5_machine); | |
6694 | 6694 | #endif |
6695 | 6695 | #elif defined(TARGET_ARM) |
6696 | 6696 | qemu_register_machine(&integratorcp_machine); | ... | ... |
vl.h
... | ... | @@ -1143,7 +1143,7 @@ extern CPUReadMemoryFunc *PPC_io_read[]; |
1143 | 1143 | void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val); |
1144 | 1144 | |
1145 | 1145 | /* sun4m.c */ |
1146 | -extern QEMUMachine sun4m_machine; | |
1146 | +extern QEMUMachine ss5_machine; | |
1147 | 1147 | void pic_set_irq_cpu(int irq, int level, unsigned int cpu); |
1148 | 1148 | |
1149 | 1149 | /* iommu.c */ |
... | ... | @@ -1169,7 +1169,7 @@ void tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base, |
1169 | 1169 | unsigned long vram_offset, int vram_size, int width, int height); |
1170 | 1170 | |
1171 | 1171 | /* slavio_intctl.c */ |
1172 | -void *slavio_intctl_init(); | |
1172 | +void *slavio_intctl_init(uint32_t addr, uint32_t addrg); | |
1173 | 1173 | void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env); |
1174 | 1174 | void slavio_pic_info(void *opaque); |
1175 | 1175 | void slavio_irq_info(void *opaque); | ... | ... |