1 |
/* |
/* |
2 |
* Copyright (C) 2003-2006 Anders Gavare. All rights reserved. |
* Copyright (C) 2003-2007 Anders Gavare. All rights reserved. |
3 |
* |
* |
4 |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
5 |
* modification, are permitted provided that the following conditions are met: |
* modification, are permitted provided that the following conditions are met: |
25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: machine_sgi.c,v 1.5 2006/06/30 20:22:54 debug Exp $ |
* $Id: machine_sgi.c,v 1.23 2007/06/16 14:39:18 debug Exp $ |
29 |
* |
* |
30 |
* Machine descriptions for Silicon Graphics' MIPS-based machines. |
* COMMENT: Silicon Graphics' MIPS-based machines |
31 |
* |
* |
32 |
* http://obsolete.majix.org/computers/sgi/iptable.shtml contains a |
* http://obsolete.majix.org/computers/sgi/iptable.shtml contains a |
33 |
* pretty detailed list of IP ("Inhouse Processor") model numbers. |
* pretty detailed list of IP ("Inhouse Processor") model numbers. |
46 |
#include "devices.h" |
#include "devices.h" |
47 |
#include "diskimage.h" |
#include "diskimage.h" |
48 |
#include "machine.h" |
#include "machine.h" |
|
#include "machine_interrupts.h" |
|
49 |
#include "memory.h" |
#include "memory.h" |
50 |
#include "misc.h" |
#include "misc.h" |
51 |
#include "net.h" |
#include "net.h" |
70 |
|
|
71 |
struct pci_data *pci_data = NULL; |
struct pci_data *pci_data = NULL; |
72 |
|
|
73 |
machine->machine_name = malloc(MACHINE_NAME_MAXBUF); |
CHECK_ALLOCATION(machine->machine_name = malloc(MACHINE_NAME_MAXBUF)); |
|
if (machine->machine_name == NULL) { |
|
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
74 |
|
|
75 |
cpu->byte_order = EMUL_BIG_ENDIAN; |
cpu->byte_order = EMUL_BIG_ENDIAN; |
76 |
snprintf(machine->machine_name, MACHINE_NAME_MAXBUF, |
snprintf(machine->machine_name, MACHINE_NAME_MAXBUF, |
96 |
} |
} |
97 |
|
|
98 |
net_generate_unique_mac(machine, macaddr); |
net_generate_unique_mac(machine, macaddr); |
99 |
eaddr_string = malloc(ETHERNET_STRING_MAXLEN); |
CHECK_ALLOCATION(eaddr_string = malloc(ETHERNET_STRING_MAXLEN)); |
100 |
|
|
101 |
switch (machine->machine_subtype) { |
switch (machine->machine_subtype) { |
102 |
|
|
120 |
" (Everest IP19)", MACHINE_NAME_MAXBUF); |
" (Everest IP19)", MACHINE_NAME_MAXBUF); |
121 |
machine->main_console_handle = (size_t)device_add(machine, |
machine->main_console_handle = (size_t)device_add(machine, |
122 |
"z8530 addr=0x1fbd9830 irq=0 addr_mult=4"); |
"z8530 addr=0x1fbd9830 irq=0 addr_mult=4"); |
123 |
dev_scc_init(machine, mem, 0x10086000, 0, machine->use_x11, |
dev_scc_init(machine, mem, 0x10086000, 0, |
124 |
0, 8); /* serial? irix? */ |
machine->x11_md.in_use, 0, 8); /* serial? irix? */ |
125 |
|
|
126 |
device_add(machine, "sgi_ip19 addr=0x18000000"); |
device_add(machine, "sgi_ip19 addr=0x18000000"); |
127 |
|
|
165 |
*/ |
*/ |
166 |
|
|
167 |
/* int0 at mainbus0 addr 0x1fb801c0 */ |
/* int0 at mainbus0 addr 0x1fb801c0 */ |
168 |
machine->md_int.sgi_ip20_data = dev_sgi_ip20_init(cpu, mem, |
fatal("TODO: SGI legacy interrupt system rewrite!\n"); |
169 |
DEV_SGI_IP20_BASE); |
abort(); |
170 |
|
// machine->md_int.sgi_ip20_data = dev_sgi_ip20_init(cpu, mem, |
171 |
|
// DEV_SGI_IP20_BASE); |
172 |
|
|
173 |
/* imc0 at mainbus0 addr 0x1fa00000: revision 0: |
/* imc0 at mainbus0 addr 0x1fa00000: revision 0: |
174 |
TODO (or in dev_sgi_ip20?) */ |
TODO (or in dev_sgi_ip20?) */ |
183 |
"z8530 addr=0x1fb80d00 irq=0 addr_mult=4"); |
"z8530 addr=0x1fb80d00 irq=0 addr_mult=4"); |
184 |
|
|
185 |
/* WDSC SCSI controller: */ |
/* WDSC SCSI controller: */ |
186 |
dev_wdsc_init(machine, mem, 0x1fb8011f, 0, 0); |
/* dev_wdsc_init(machine, mem, 0x1fb8011f, 0, 0); */ |
187 |
|
|
188 |
/* Return memory read errors so that hpc1 |
/* Return memory read errors so that hpc1 |
189 |
and hpc2 are not detected: */ |
and hpc2 are not detected: */ |
213 |
strlcat(machine->machine_name, |
strlcat(machine->machine_name, |
214 |
" (Indy, Indigo2, Challenge S; Full-house)", |
" (Indy, Indigo2, Challenge S; Full-house)", |
215 |
MACHINE_NAME_MAXBUF); |
MACHINE_NAME_MAXBUF); |
216 |
machine->md_int.sgi_ip22_data = |
fatal("TODO: SGI legacy interrupt system rewrite!\n"); |
217 |
dev_sgi_ip22_init(machine, mem, 0x1fbd9000, 0); |
abort(); |
218 |
|
// machine->md_int.sgi_ip22_data = |
219 |
|
// dev_sgi_ip22_init(machine, mem, 0x1fbd9000, 0); |
220 |
} else { |
} else { |
221 |
strlcat(machine->machine_name, |
strlcat(machine->machine_name, |
222 |
" (Indy, Indigo2, Challenge S; Guiness)", |
" (Indy, Indigo2, Challenge S; Guiness)", |
223 |
MACHINE_NAME_MAXBUF); |
MACHINE_NAME_MAXBUF); |
224 |
machine->md_int.sgi_ip22_data = |
fatal("TODO: SGI legacy interrupt system rewrite!\n"); |
225 |
dev_sgi_ip22_init(machine, mem, 0x1fbd9880, 1); |
abort(); |
226 |
|
// machine->md_int.sgi_ip22_data = |
227 |
|
// dev_sgi_ip22_init(machine, mem, 0x1fbd9880, 1); |
228 |
} |
} |
229 |
|
|
230 |
/* |
/* |
232 |
dev_ram_init(machine, 0x88000000ULL, |
dev_ram_init(machine, 0x88000000ULL, |
233 |
128 * 1048576, DEV_RAM_MIRROR, 0x08000000); |
128 * 1048576, DEV_RAM_MIRROR, 0x08000000); |
234 |
*/ |
*/ |
235 |
machine->md_interrupt = sgi_ip22_interrupt; |
|
236 |
|
fatal("TODO: Legacy rewrite\n"); |
237 |
|
abort(); |
238 |
|
// machine->md_interrupt = sgi_ip22_interrupt; |
239 |
|
|
240 |
/* |
/* |
241 |
* According to NetBSD 1.6.2: |
* According to NetBSD 1.6.2: |
269 |
"z8530 addr=0x1fbd9830 irq=363 addr_mult=4"); |
"z8530 addr=0x1fbd9830 irq=363 addr_mult=4"); |
270 |
|
|
271 |
/* Not supported by NetBSD 1.6.2, but by 2.0_BETA: */ |
/* Not supported by NetBSD 1.6.2, but by 2.0_BETA: */ |
272 |
j = dev_pckbc_init(machine, mem, 0x1fbd9840, PCKBC_8242, |
fatal("TODO: legacy rewrite\n"); |
273 |
0, 0, machine->use_x11, 0); /* TODO: irq numbers */ |
abort(); |
274 |
|
// j = dev_pckbc_init(machine, mem, 0x1fbd9840, PCKBC_8242, |
275 |
|
// 0, 0, machine->x11_md.in_use, 0); /* TODO: irq numbers */ |
276 |
|
j = 0; |
277 |
|
|
278 |
if (machine->use_x11) |
if (machine->x11_md.in_use) |
279 |
machine->main_console_handle = j; |
machine->main_console_handle = j; |
280 |
|
|
281 |
/* sq0: Ethernet. TODO: This should have irq_nr = 8 + 3 */ |
/* sq0: Ethernet. TODO: This should have irq_nr = 8 + 3 */ |
282 |
/* dev_sq_init... */ |
/* dev_sq_init... */ |
283 |
|
|
284 |
/* wdsc0: SCSI */ |
/* wdsc0: SCSI */ |
285 |
dev_wdsc_init(machine, mem, 0x1fbc4000, 0, 8 + 1); |
/* dev_wdsc_init(machine, mem, 0x1fbc4000, 0, 8 + 1); */ |
286 |
|
|
287 |
/* wdsc1: SCSI TODO: irq nr */ |
/* wdsc1: SCSI TODO: irq nr */ |
288 |
dev_wdsc_init(machine, mem, 0x1fbcc000, 1, 8 + 1); |
/* dev_wdsc_init(machine, mem, 0x1fbcc000, 1, 8 + 1); */ |
289 |
|
|
290 |
/* dsclock0: TODO: possibly irq 8 + 33 */ |
/* dsclock0: TODO: possibly irq 8 + 33 */ |
291 |
|
|
309 |
|
|
310 |
/* serial? irix? */ |
/* serial? irix? */ |
311 |
dev_scc_init(machine, mem, |
dev_scc_init(machine, mem, |
312 |
0x400086000ULL, 0, machine->use_x11, 0, 8); |
0x400086000ULL, 0, machine->x11_md.in_use, 0, 8); |
313 |
|
|
314 |
/* NOTE: ip19! (perhaps not really the same */ |
/* NOTE: ip19! (perhaps not really the same */ |
315 |
device_add(machine, "sgi_ip19 addr=0x18000000"); |
device_add(machine, "sgi_ip19 addr=0x18000000"); |
361 |
strlcat(machine->machine_name, " (Octane)", |
strlcat(machine->machine_name, " (Octane)", |
362 |
MACHINE_NAME_MAXBUF); |
MACHINE_NAME_MAXBUF); |
363 |
|
|
364 |
machine->md_int.sgi_ip30_data = |
fatal("TODO: SGI legacy interrupt system rewrite!\n"); |
365 |
dev_sgi_ip30_init(machine, mem, 0x0ff00000); |
abort(); |
366 |
machine->md_interrupt = sgi_ip30_interrupt; |
// machine->md_int.sgi_ip30_data = |
367 |
|
// dev_sgi_ip30_init(machine, mem, 0x0ff00000); |
368 |
|
|
369 |
|
fatal("TODO: Legacy rewrite\n"); |
370 |
|
abort(); |
371 |
|
// machine->md_interrupt = sgi_ip30_interrupt; |
372 |
|
|
373 |
dev_ram_init(machine, 0xa0000000ULL, 128 * 1048576, |
dev_ram_init(machine, 0xa0000000ULL, 128 * 1048576, |
374 |
DEV_RAM_MIRROR | DEV_RAM_MIGHT_POINT_TO_DEVICES, |
DEV_RAM_MIRROR | DEV_RAM_MIGHT_POINT_TO_DEVICES, |
394 |
|
|
395 |
/* TODO: irq! */ |
/* TODO: irq! */ |
396 |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=0 addr=" |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=0 addr=" |
397 |
"0x1f620170 name2=tty0 in_use=%i", machine->use_x11? 0 : 1); |
"0x1f620170 name2=tty0 in_use=%i", |
398 |
|
machine->x11_md.in_use? 0 : 1); |
399 |
machine->main_console_handle = (size_t)device_add(machine, |
machine->main_console_handle = (size_t)device_add(machine, |
400 |
tmpstr); |
tmpstr); |
401 |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=0 addr=" |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=0 addr=" |
409 |
|
|
410 |
case 32: |
case 32: |
411 |
strlcat(machine->machine_name, " (O2)", MACHINE_NAME_MAXBUF); |
strlcat(machine->machine_name, " (O2)", MACHINE_NAME_MAXBUF); |
|
machine->stable = 1; |
|
412 |
|
|
413 |
/* TODO: Find out where the phys ram is actually located. */ |
/* TODO: Find out where the phys ram is actually located. */ |
414 |
dev_ram_init(machine, 0x07ffff00ULL, 256, |
dev_ram_init(machine, 0x07ffff00ULL, 256, |
426 |
dev_ram_init(machine, 0x40000000ULL, 128 * 1048576, |
dev_ram_init(machine, 0x40000000ULL, 128 * 1048576, |
427 |
DEV_RAM_MIRROR, 0x10000000); |
DEV_RAM_MIRROR, 0x10000000); |
428 |
|
|
429 |
machine->md_int.ip32.crime_data = dev_crime_init(machine, |
/* Connect CRIME (Interrupt Controller) to MIPS irq 2: */ |
430 |
mem, 0x14000000, 2, machine->use_x11); /* crime0 */ |
snprintf(tmpstr, sizeof(tmpstr), "%s.cpu[%i].2", |
431 |
|
machine->path, machine->bootstrap_cpu); |
432 |
|
dev_crime_init(machine, mem, 0x14000000, tmpstr, |
433 |
|
machine->x11_md.in_use); /* crime0 */ |
434 |
dev_sgi_mte_init(mem, 0x15000000); /* mte ??? */ |
dev_sgi_mte_init(mem, 0x15000000); /* mte ??? */ |
435 |
dev_sgi_gbe_init(machine, mem, 0x16000000); /* gbe? */ |
dev_sgi_gbe_init(machine, mem, 0x16000000); /* gbe? */ |
436 |
|
|
458 |
* 1f3a0000 mcclock0 |
* 1f3a0000 mcclock0 |
459 |
*/ |
*/ |
460 |
|
|
|
machine->md_int.ip32.mace_data = |
|
|
dev_mace_init(mem, 0x1f310000, 2); |
|
|
machine->md_interrupt = sgi_ip32_interrupt; |
|
|
|
|
461 |
/* |
/* |
462 |
* IRQ mapping is really ugly. TODO: fix |
* IRQ mapping is really ugly. TODO: fix |
463 |
* |
* |
474 |
* intr 7 = MACE_PCI_BRIDGE |
* intr 7 = MACE_PCI_BRIDGE |
475 |
*/ |
*/ |
476 |
|
|
|
if (eaddr_string == NULL) { |
|
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
477 |
snprintf(eaddr_string, ETHERNET_STRING_MAXLEN, |
snprintf(eaddr_string, ETHERNET_STRING_MAXLEN, |
478 |
"eaddr=%02x:%02x:%02x:%02x:%02x:%02x", |
"eaddr=%02x:%02x:%02x:%02x:%02x:%02x", |
479 |
macaddr[0], macaddr[1], macaddr[2], |
macaddr[0], macaddr[1], macaddr[2], |
480 |
macaddr[3], macaddr[4], macaddr[5]); |
macaddr[3], macaddr[4], macaddr[5]); |
481 |
|
|
482 |
|
snprintf(tmpstr, sizeof(tmpstr), "%s.cpu[%i].2.crime.0x%x", |
483 |
|
machine->path, machine->bootstrap_cpu, MACE_ETHERNET); |
484 |
dev_sgi_mec_init(machine, mem, 0x1f280000, |
dev_sgi_mec_init(machine, mem, 0x1f280000, |
485 |
MACE_ETHERNET, macaddr); |
tmpstr, macaddr); |
486 |
|
|
487 |
dev_sgi_ust_init(mem, 0x1f340000); /* ust? */ |
dev_sgi_ust_init(mem, 0x1f340000); /* ust? */ |
488 |
|
|
489 |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=%i addr=" |
snprintf(tmpstr, sizeof(tmpstr), |
490 |
|
"ns16550 irq=%s.cpu[%i].2.crime.0x%x.mace.%i addr=" |
491 |
"0x1f390000 addr_mult=0x100 in_use=%i name2=tty0", |
"0x1f390000 addr_mult=0x100 in_use=%i name2=tty0", |
492 |
(1<<20) + MACE_PERIPH_SERIAL, machine->use_x11? 0 : 1); |
machine->path, machine->bootstrap_cpu, |
493 |
|
MACE_PERIPH_SERIAL, 20, machine->x11_md.in_use? 0 : 1); |
494 |
j = (size_t)device_add(machine, tmpstr); |
j = (size_t)device_add(machine, tmpstr); |
495 |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=%i addr=" |
snprintf(tmpstr, sizeof(tmpstr), |
496 |
|
"ns16550 irq=%s.cpu[%i].2.crime.0x%x.mace.%i addr=" |
497 |
"0x1f398000 addr_mult=0x100 in_use=%i name2=tty1", |
"0x1f398000 addr_mult=0x100 in_use=%i name2=tty1", |
498 |
(1<<26) + MACE_PERIPH_SERIAL, 0); |
machine->path, machine->bootstrap_cpu, |
499 |
|
MACE_PERIPH_SERIAL, 26, 0); |
500 |
device_add(machine, tmpstr); |
device_add(machine, tmpstr); |
501 |
|
|
502 |
machine->main_console_handle = j; |
machine->main_console_handle = j; |
503 |
|
|
504 |
/* TODO: Once this works, it should be enabled |
/* TODO: Once this works, it should be enabled |
505 |
always, not just when using X! */ |
always, not just when using X! */ |
506 |
if (machine->use_x11) { |
#if 0 |
507 |
|
fatal("TODO: legacy SGI rewrite\n"); |
508 |
|
abort(); |
509 |
|
if (machine->x11_md.in_use) { |
510 |
i = dev_pckbc_init(machine, mem, 0x1f320000, |
i = dev_pckbc_init(machine, mem, 0x1f320000, |
511 |
PCKBC_8242, 0x200 + MACE_PERIPH_MISC, |
PCKBC_8242, 0x200 + MACE_PERIPH_MISC, |
512 |
0x800 + MACE_PERIPH_MISC, machine->use_x11, 0); |
0x800 + MACE_PERIPH_MISC, machine->x11_md.in_use, |
513 |
|
0); |
514 |
/* keyb+mouse (mace irq numbers) */ |
/* keyb+mouse (mace irq numbers) */ |
515 |
machine->main_console_handle = i; |
machine->main_console_handle = i; |
516 |
} |
} |
517 |
|
#endif |
518 |
|
|
519 |
dev_mc146818_init(machine, mem, 0x1f3a0000, (1<<8) + |
snprintf(tmpstr, sizeof(tmpstr), |
520 |
MACE_PERIPH_MISC, MC146818_SGI, 0x40); /* mcclock0 */ |
"%s.cpu[%i].2.crime.0x%x.mace.%i", |
521 |
machine->main_console_handle = (size_t)device_add(machine, |
machine->path, machine->bootstrap_cpu, |
522 |
"z8530 addr=0x1fbd9830 irq=0 addr_mult=4"); |
MACE_PERIPH_MISC, 8); |
523 |
|
dev_mc146818_init(machine, mem, 0x1f3a0000, tmpstr, |
524 |
|
MC146818_SGI, 0x40); /* mcclock0 */ |
525 |
|
|
526 |
|
/* TODO: _WHERE_ does the z8530 interrupt? */ |
527 |
|
snprintf(tmpstr, sizeof(tmpstr), "z8530 addr=0x1fbd9830 " |
528 |
|
"irq=%s.cpu[%i].2 addr_mult=4", |
529 |
|
machine->path, machine->bootstrap_cpu); |
530 |
|
machine->main_console_handle = (size_t) |
531 |
|
device_add(machine, tmpstr); |
532 |
|
|
533 |
/* |
/* |
534 |
* PCI devices: (according to NetBSD's GENERIC |
* PCI devices: (according to NetBSD's GENERIC |
539 |
* ahc1 at pci0 dev 2 function ? |
* ahc1 at pci0 dev 2 function ? |
540 |
*/ |
*/ |
541 |
|
|
542 |
|
snprintf(tmpstr, sizeof(tmpstr), |
543 |
|
"%s.cpu[%i].2.crime.0x%x", machine->path, |
544 |
|
machine->bootstrap_cpu, MACE_PCI_BRIDGE); |
545 |
pci_data = dev_macepci_init(machine, mem, 0x1f080000, |
pci_data = dev_macepci_init(machine, mem, 0x1f080000, |
546 |
MACE_PCI_BRIDGE); /* macepci0 */ |
tmpstr); /* macepci0 */ |
547 |
/* bus_pci_add(machine, pci_data, mem, 0, 0, 0, |
/* bus_pci_add(machine, pci_data, mem, 0, 0, 0, |
548 |
"ne2000"); TODO */ |
"ne2000"); TODO */ |
549 |
|
|
561 |
/* TODO: second ahc */ |
/* TODO: second ahc */ |
562 |
/* bus_pci_add(machine, pci_data, mem, 0, 2, 0, "ahc"); */ |
/* bus_pci_add(machine, pci_data, mem, 0, 2, 0, "ahc"); */ |
563 |
|
|
564 |
|
/* |
565 |
|
* An additional PCI IDE controller, for NetBSD/sgimips |
566 |
|
* experiments: (Not found in a regular O2.) |
567 |
|
*/ |
568 |
|
bus_pci_add(machine, pci_data, mem, 0, 3, 0, "symphony_82c105"); |
569 |
|
|
570 |
break; |
break; |
571 |
|
|
572 |
case 35: |
case 35: |