1 /*
2  *  Copyright (C) 2003-2020  Anders Gavare.  All rights reserved.
3  *
4  *  Redistribution and use in source and binary forms, with or without
5  *  modification, are permitted provided that the following conditions are met:
6  *
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. The name of the author may not be used to endorse or promote products
13  *     derived from this software without specific prior written permission.
14  *
15  *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  *  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  *  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  *  SUCH DAMAGE.
26  *
27  *
28  *  COMMENT: Silicon Graphics' MIPS-based machines
29  *
30  *  http://obsolete.majix.org/computers/sgi/iptable.shtml contains a
31  *  pretty detailed list of IP ("Inhouse Processor") model numbers.
32  *
33  *  See also: http://hardware.majix.org/computers/sgi/iptable.shtml
34  */
35 
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 
40 #include "arcbios.h"
41 #include "bus_pci.h"
42 #include "cpu.h"
43 #include "device.h"
44 #include "devices.h"
45 #include "diskimage.h"
46 #include "machine.h"
47 #include "memory.h"
48 #include "misc.h"
49 #include "net.h"
50 
51 #include "thirdparty/sgi_arcbios.h"
52 #include "thirdparty/crimereg.h"
53 
54 
55 #define ETHERNET_STRING_MAXLEN  	40
56 #define	MACHINE_NAME_MAXBUF		100
57 
58 
MACHINE_SETUP(sgi)59 MACHINE_SETUP(sgi)
60 {
61 	uint64_t sgi_ram_offset = 0;
62 	int arc_wordlen = sizeof(uint32_t);
63 	struct memory *mem = machine->memory;
64 	char tmpstr[1000];
65 	int i, j;
66 	unsigned char macaddr[6];
67 	char *machineName;
68 
69 	struct pci_data *pci_data = NULL;
70 
71 	CHECK_ALLOCATION(machineName = (char *) malloc(MACHINE_NAME_MAXBUF));
72 	machine->machine_name = machineName;
73 
74 	cpu->byte_order = EMUL_BIG_ENDIAN;
75 	snprintf(machineName, MACHINE_NAME_MAXBUF,
76 	    "SGI-IP%i", machine->machine_subtype);
77 
78 	sgi_ram_offset = 1048576 * machine->memory_offset_in_mb;
79 
80 	/*  Special cases for IP20,22,24,26 memory offset:  */
81 	if (machine->machine_subtype == 20 || machine->machine_subtype == 22 ||
82 	    machine->machine_subtype == 24 || machine->machine_subtype == 26) {
83 		dev_ram_init(machine, 0x00000000, 0x10000, DEV_RAM_MIRROR
84 		    | DEV_RAM_MIGHT_POINT_TO_DEVICES, sgi_ram_offset);
85 		dev_ram_init(machine, 0x00050000, sgi_ram_offset-0x50000,
86 		    DEV_RAM_MIRROR | DEV_RAM_MIGHT_POINT_TO_DEVICES,
87 		    sgi_ram_offset + 0x50000);
88 	}
89 
90 	/*  Special cases for IP28,30 memory offset:  */
91 	if (machine->machine_subtype == 28 || machine->machine_subtype == 30) {
92 		/*  TODO: length below should maybe not be 128MB?  */
93 		dev_ram_init(machine, 0x00000000, 128*1048576, DEV_RAM_MIRROR
94 		    | DEV_RAM_MIGHT_POINT_TO_DEVICES, sgi_ram_offset);
95 	}
96 
97 	net_generate_unique_mac(machine, macaddr);
98 
99 	char *eaddr_string;
100 	CHECK_ALLOCATION(eaddr_string = (char *) malloc(ETHERNET_STRING_MAXLEN));
101 
102 	switch (machine->machine_subtype) {
103 
104 	case 10:
105 		strlcat(machineName, " (4D/25)", MACHINE_NAME_MAXBUF);
106 		/*  TODO  */
107 		break;
108 
109 	case 12:
110 		strlcat(machineName, " (Iris Indigo IP12)", MACHINE_NAME_MAXBUF);
111 
112 		/*  TODO  */
113 		/*  33 MHz R3000, according to http://www.irisindigo.com/  */
114 		/*  "capable of addressing up to 96MB of memory."  */
115 
116 		break;
117 
118 	case 19:
119 		strlcat(machineName,
120 		    " (Everest IP19)", MACHINE_NAME_MAXBUF);
121 		machine->main_console_handle = (size_t)device_add(machine,
122 		    "z8530 addr=0x1fbd9830 irq=0 addr_mult=4");
123 
124 		fatal("TODO ip19 interrupt rewrite\n");
125 		abort();
126 		//dev_scc_init(machine, mem, 0x10086000, 0,
127 		//    machine->x11_md.in_use, 0, 8);	/*  serial? irix?  */
128 
129 		device_add(machine, "sgi_ip19 addr=0x18000000");
130 
131 		/*  Irix' <everest_du_init+0x130> reads this device:  */
132 		device_add(machine, "random addr=0x10006000 len=16");
133 
134 		/*  Irix' get_mpconf() looks for this:  (TODO)  */
135 		store_32bit_word(cpu, 0xa0000000 + 0x3000,
136 		    0xbaddeed2);
137 
138 		/*  Memory size, not 4096 byte pages, but 256 bytes?
139 		    (16 is size of kernel... approx)  */
140 		store_32bit_word(cpu, 0xa0000000 + 0x26d0, 30000);
141 		  /* (machine->physical_ram_in_mb - 16) * (1048576 / 256));  */
142 
143 		break;
144 
145 	case 20:
146 		strlcat(machineName, " (Indigo)", MACHINE_NAME_MAXBUF);
147 
148 		/*
149 		 *  Guesses based on NetBSD 2.0 beta, 20040606.
150 		 *
151 		 *  int0 at mainbus0 addr 0x1fb801c0: bus 1MHz, CPU 2MHz
152 		 *  imc0 at mainbus0 addr 0x1fa00000: revision 0
153 		 *  gio0 at imc0
154 		 *  unknown GIO card (product 0x00 revision 0x00)
155 		 *	at gio0 slot 0 addr 0x1f400000 not configured
156 		 *  unknown GIO card (product 0x00 revision 0x00)
157 		 *	at gio0 slot 1 addr 0x1f600000 not configured
158 		 *  unknown GIO card (product 0x00 revision 0x00)
159 		 *	at gio0 slot 2 addr 0x1f000000 not configured
160 		 *  hpc0 at gio0 addr 0x1fb80000: SGI HPC1
161 		 *  zsc0 at hpc0 offset 0xd10   (channels 0 and 1,
162 		 *				 channel 1 for console)
163 		 *  zsc1 at hpc0 offset 0xd00   (2 channels)
164 		 *  sq0 at hpc0 offset 0x100: SGI Seeq 80c03
165 		 *  wdsc0 at hpc0 offset 0x11f
166 		 *  dpclock0 at hpc0 offset 0xe00
167 		 */
168 
169 		/*  int0 at mainbus0 addr 0x1fb801c0  */
170 fatal("TODO: SGI legacy interrupt system rewrite!\n");
171 abort();
172 //		machine->md_int.sgi_ip20_data = dev_sgi_ip20_init(cpu, mem,
173 //		    DEV_SGI_IP20_BASE);
174 
175 		/*  imc0 at mainbus0 addr 0x1fa00000: revision 0:
176 		    TODO (or in dev_sgi_ip20?)  */
177 
178 		machine->main_console_handle = (size_t)device_add(machine,
179 		    "z8530 addr=0x1fbd9830 irq=0 addr_mult=4");
180 
181 		/*  This is the zsc0 reported by NetBSD:  TODO: irqs  */
182 		machine->main_console_handle = (size_t)device_add(machine,
183 		    "z8530 addr=0x1fb80d10 irq=0 addr_mult=4");
184 		machine->main_console_handle = (size_t)device_add(machine,
185 		    "z8530 addr=0x1fb80d00 irq=0 addr_mult=4");
186 
187 		/*  WDSC SCSI controller:  */
188 /*		dev_wdsc_init(machine, mem, 0x1fb8011f, 0, 0);  */
189 
190 		/*  Return memory read errors so that hpc1
191 		    and hpc2 are not detected:  */
192 		device_add(machine, "unreadable addr=0x1fb00000 len=0x10000");
193 		device_add(machine, "unreadable addr=0x1f980000 len=0x10000");
194 
195 		/*  Return nothing for gio slots 0, 1, and 2: */
196 		device_add(machine, "unreadable addr=0x1f400000 len=0x1000");
197 		device_add(machine, "unreadable addr=0x1f600000 len=0x1000");
198 		device_add(machine, "unreadable addr=0x1f000000 len=0x1000");
199 
200 		break;
201 
202 	case 21:
203 		strlcat(machineName,	/*  TODO  */
204 		    " (uknown SGI-IP21 ?)", MACHINE_NAME_MAXBUF);
205 		/*  NOTE:  Special case for arc_wordlen:  */
206 		arc_wordlen = sizeof(uint64_t);
207 
208 		device_add(machine, "random addr=0x418000200, len=0x20000");
209 
210 		break;
211 
212 	case 22:
213 	case 24:
214 		if (machine->machine_subtype == 22) {
215 			strlcat(machineName,
216 			    " (Indy, Indigo2, Challenge S; Full-house)",
217 			    MACHINE_NAME_MAXBUF);
218 fatal("TODO: SGI legacy interrupt system rewrite!\n");
219 abort();
220 //			machine->md_int.sgi_ip22_data =
221 //			    dev_sgi_ip22_init(machine, mem, 0x1fbd9000, 0);
222 		} else {
223 			strlcat(machineName,
224 			    " (Indy, Indigo2, Challenge S; Guiness)",
225 			    MACHINE_NAME_MAXBUF);
226 fatal("TODO: SGI legacy interrupt system rewrite!\n");
227 abort();
228 //			machine->md_int.sgi_ip22_data =
229 //			    dev_sgi_ip22_init(machine, mem, 0x1fbd9880, 1);
230 		}
231 
232 /*
233 Why is this here? TODO
234 		dev_ram_init(machine, 0x88000000ULL,
235 		    128 * 1048576, DEV_RAM_MIRROR, 0x08000000);
236 */
237 
238 fatal("TODO: Legacy rewrite\n");
239 abort();
240 //		machine->md_interrupt = sgi_ip22_interrupt;
241 
242 		/*
243 		 *  According to NetBSD 1.6.2:
244 		 *
245 		 *  imc0 at mainbus0 addr 0x1fa00000, Revision 0
246 		 *  gio0 at imc0
247 		 *  hpc0 at gio0 addr 0x1fb80000: SGI HPC3
248 		 *  zsc0 at hpc0 offset 0x59830
249 		 *  zstty0 at zsc0 channel 1 (console i/o)
250 		 *  zstty1 at zsc0 channel 0
251 		 *  sq0 at hpc0 offset 0x54000: SGI Seeq 80c03	(Ethernet)
252 		 *  wdsc0 at hpc0 offset 0x44000: WD33C93 SCSI, rev=0, target 7
253 		 *  scsibus2 at wdsc0: 8 targets, 8 luns per target
254 		 *  dsclock0 at hpc0 offset 0x60000
255 		 *
256 		 *  According to Linux/IP22:
257 		 *  tty00 at 0xbfbd9830 (irq = 45) is a Zilog8530
258 		 *  tty01 at 0xbfbd9838 (irq = 45) is a Zilog8530
259 		 *
260 		 *  and according to NetBSD 2.0_BETA (20040606):
261 		 *
262 		 *  haltwo0 at hpc0 offset 0x58000: HAL2 revision 0.0.0
263 		 *  audio0 at haltwo0: half duplex
264 		 *
265 		 *  IRQ numbers are of the form 8 + x, where x=0..31 for local0
266 		 *  interrupts, and 32..63 for local1.  + y*65 for "mappable".
267 		 */
268 
269 		/*  zsc0 serial console. 8 + 32 + 3 + 64*5 = 43+64*5 = 363 */
270 		i = (size_t)device_add(machine,
271 		    "z8530 addr=0x1fbd9830 irq=363 addr_mult=4");
272 
273 		/*  Not supported by NetBSD 1.6.2, but by 2.0_BETA:  */
274 fatal("TODO: legacy rewrite\n");
275 abort();
276 //		j = dev_pckbc_init(machine, mem, 0x1fbd9840, PCKBC_8242,
277 //		    0, 0, machine->x11_md.in_use, 0);  /*  TODO: irq numbers  */
278 j = 0;
279 
280 		if (machine->x11_md.in_use)
281 			machine->main_console_handle = j;
282 
283 		/*  sq0: Ethernet.  TODO:  This should have irq_nr = 8 + 3  */
284 		/*  dev_sq_init...  */
285 
286 		/*  wdsc0: SCSI  */
287 /*		dev_wdsc_init(machine, mem, 0x1fbc4000, 0, 8 + 1);  */
288 
289 		/*  wdsc1: SCSI  TODO: irq nr  */
290 /*		dev_wdsc_init(machine, mem, 0x1fbcc000, 1, 8 + 1);  */
291 
292 		/*  dsclock0: TODO:  possibly irq 8 + 33  */
293 
294 		/*  Return memory read errors so that hpc1 and hpc2 are
295 		    not detected:  */
296 		device_add(machine, "unreadable addr=0x1fb00000, len=0x10000");
297 		device_add(machine, "unreadable addr=0x1f980000, len=0x10000");
298 
299 		/*  Similarly for gio slots 0, 1, and 2:  */
300 		device_add(machine, "unreadable addr=0x1f400000, len=0x1000");
301 		device_add(machine, "unreadable addr=0x1f600000, len=0x1000");
302 		device_add(machine, "unreadable addr=0x1f000000, len=0x1000");
303 
304 		break;
305 
306 	case 25:
307 		/*  NOTE:  Special case for arc_wordlen:  */
308 		arc_wordlen = sizeof(uint64_t);
309 		strlcat(machineName, " (Everest IP25)", MACHINE_NAME_MAXBUF);
310 
311 		 /*  serial? irix?  */
312 		fatal("TODO ip25 interrupt rewrite\n");
313 		abort();
314 		//dev_scc_init(machine, mem,
315 		//    0x400086000ULL, 0, machine->x11_md.in_use, 0, 8);
316 
317 		/*  NOTE: ip19! (perhaps not really the same  */
318 		device_add(machine, "sgi_ip19 addr=0x18000000");
319 
320 		/*
321 		 *  Memory size, not 4096 byte pages, but 256
322 		 *  bytes?  (16 is size of kernel... approx)
323 		 */
324 		store_32bit_word(cpu, 0xa0000000ULL + 0x26d0,
325 		    30000);  /* (machine->physical_ram_in_mb - 16)
326 				 * (1048576 / 256));  */
327 
328 		break;
329 
330 	case 26:
331 		/*  NOTE:  Special case for arc_wordlen:  */
332 		arc_wordlen = sizeof(uint64_t);
333 		strlcat(machineName, " (uknown SGI-IP26 ?)",
334 		    MACHINE_NAME_MAXBUF);	/*  TODO  */
335 		machine->main_console_handle = (size_t)device_add(machine,
336 		    "z8530 addr=0x1fbd9830 irq=0 addr_mult=4");
337 		break;
338 
339 	case 27:
340 		strlcat(machineName, " (Origin 200/2000, Onyx2)",
341 		    MACHINE_NAME_MAXBUF);
342 		arc_wordlen = sizeof(uint64_t);
343 		/*  2 cpus per node  */
344 
345 		machine->main_console_handle = (size_t)device_add(machine,
346 		    "z8530 addr=0x1fbd9830 irq=0 addr_mult=4");
347 		break;
348 
349 	case 28:
350 		/*  NOTE:  Special case for arc_wordlen:  */
351 		arc_wordlen = sizeof(uint64_t);
352 		strlcat(machineName, " (Impact Indigo2 ?)", MACHINE_NAME_MAXBUF);
353 
354 		device_add(machine, "random addr=0x1fbe0000, len=1");
355 
356 		/*  Something at paddr 0x1880fb0000.  */
357 
358 		break;
359 
360 	case 30:
361 		/*  NOTE:  Special case for arc_wordlen:  */
362 		arc_wordlen = sizeof(uint64_t);
363 		strlcat(machineName, " (Octane)",
364 		    MACHINE_NAME_MAXBUF);
365 
366 		// TODO: Interrupts!
367 		snprintf(tmpstr, sizeof(tmpstr),
368 		    "sgi_ip30 addr=0x0ff00000");
369 		device_add(machine, tmpstr);
370 
371 		dev_ram_init(machine, 0xa0000000ULL, 128 * 1048576,
372 		    DEV_RAM_MIRROR | DEV_RAM_MIGHT_POINT_TO_DEVICES,
373 		    0x00000000);
374 
375 		dev_ram_init(machine,    0x80000000ULL,
376 		    32 * 1048576, DEV_RAM_RAM, 0x00000000);
377 
378 		/*
379 		 *  Something at paddr=1f022004: TODO
380 		 *  Something at paddr=813f0510 - paddr=813f0570 ?
381 		 *  Something at paddr=813f04b8
382 		 *  Something at paddr=f8000003c  used by Linux/Octane
383 		 *
384 		 *  16550 serial port at paddr=1f620178, addr mul 1
385 		 *  (Error messages are printed to this serial port by
386 		 *  the PROM.)
387 		 *
388 		 *  There seems to also be a serial port at 1f620170. The
389 		 *  "symmon" program dumps something there, but it doesn't
390 		 *  look like readable text.  (TODO)
391 		 */
392 
393 		/*  TODO: irq!  */
394 		snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=%s.cpu[%i].2 addr="
395 		    "0x1f620170 name2=tty0 in_use=%i",
396 		    machine->path, machine->bootstrap_cpu,
397 		    machine->x11_md.in_use? 0 : 1);
398 		machine->main_console_handle = (size_t)device_add(machine,
399 		    tmpstr);
400 		snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=%s.cpu[%i].2 addr="
401 		    "0x1f620178 name2=tty1 in_use=0",
402 		    machine->path, machine->bootstrap_cpu);
403 		device_add(machine, tmpstr);
404 
405 		/*  MardiGras graphics:  */
406 		device_add(machine, "sgi_mardigras addr=0x1c000000");
407 
408 		break;
409 
410 	case 32:
411 		strlcat(machineName, " (O2)", MACHINE_NAME_MAXBUF);
412 
413 		/*
414 		 *  The IP32 prom probes "bank 0" with the following
415 		 *  TLB entries:
416 		 *
417 		 *  00: vaddr=0000000000000000 (global):  p0=0x040000000 D p1=0x041000000 D (16MB)
418 		 *  01: vaddr=0000000002000000 (global):  p0=0x042000000 D p1=0x043000000 D (16MB)
419 		 *  02: vaddr=0000000004000000 (global):  p0=0x044000000 D p1=0x045000000 D (16MB)
420 		 *  03: vaddr=0000000006000000 (global):  p0=0x046000000 D p1=0x047000000 D (16MB)
421 		 *
422 		 *  In other words, it uses real memory at 0x40000000 and up.
423 		 *  However, it is _also_ accessible at physical address 0x0.
424 		 *
425 		 *  Max amount of RAM in an O2 is 1 GB. However, devices start at
426 		 *  0x14000000 (or below that), so 256 MB is the most that the legacy GXemul
427 		 *  framework can handle. Memory above that must be accessed from 0x40000000 and up.
428  		 */
429 
430 		if (machine->physical_ram_in_mb > 1024) {
431 			fatal("SGI O2 cannot have more than 1 GB of RAM.\n");
432 			exit(1);
433 		}
434 
435 		/*  In the new framework, this would be the other way around :-), i.e.
436 		    actual memory at 0x40000000 and the first 256 MB would be mirrored
437 		    to address 0.  */
438 		{
439 			int mirrorInMB = machine->physical_ram_in_mb < 256 ? machine->physical_ram_in_mb : 256;
440 			dev_ram_init(machine, 0x40000000ULL, mirrorInMB * 1048576, DEV_RAM_MIRROR, 0);
441 			if (machine->physical_ram_in_mb > 256)
442 				dev_ram_init(machine, 0x50000000ULL, (machine->physical_ram_in_mb - 256) * 1048576, DEV_RAM_RAM, 0);
443 		}
444 
445 		/*  Connect CRIME (Interrupt Controller) to MIPS irq 2:  */
446 		snprintf(tmpstr, sizeof(tmpstr), "%s.cpu[%i].2",
447 		    machine->path, machine->bootstrap_cpu);
448 		dev_crime_init(machine, mem, 0x14000000, tmpstr, machine->x11_md.in_use);
449 
450 		/*  Rendering Engine  */
451 		dev_sgi_re_init(machine, mem, 0x15000000);
452 
453 		/*  Graphics Back End  */
454 		dev_sgi_gbe_init(machine, mem, 0x16000000);
455 
456 		/*
457 		 *  A combination of NetBSD and Linux info:
458 		 *
459 		 *	14000000	crime (interrupt/memory controller?)
460 		 *	15000000	drawing engine, memory transfer engine, rendering engine
461 		 *	16000000	gbe (graphics), crm framebuffer control
462 		 *      17000000	vice (Video Image Compression Engine)
463 		 *	18000000	pci (?)
464 		 *	1f000000	mace
465 		 *	1f080000	macepci
466 		 *	1f100000	vin1
467 		 *	1f180000	vin2
468 		 *	1f200000	vout
469 		 *	1f280000	enet (mec0, MAC-110 Ethernet)
470 		 *	1f300000	perif:
471 		 *	  1f300000	  audio ("a3"?)
472 		 *	  1f310000	  isa
473 		 *	    1f318000	    (unknown, accessed by Irix' pciio_pio_write64 and by the PROM during bootup)
474 		 *	    1f31c000	    (unknown, accessed by the PROM during bootup)
475 		 *	  1f320000	  kbdms
476 		 *	  1f330000	  i2c
477 		 *	  1f340000	  ust
478 		 *	1f380000	isa ext
479 		 * 	  1f390000	  com0 (serial)
480 		 * 	  1f398000	  com1 (serial)
481 		 * 	  1f3a0000	  mcclock0
482 		 */
483 
484 		/*
485 		 *  IRQ mapping is really ugly.  TODO: fix
486 		 *
487 		 *  com0 at mace0 offset 0x390000 intr 4 intrmask
488 		 *	0x3f00000: ns16550a, working fifo
489 		 *  com1 at mace0 offset 0x398000 intr 4 intrmask
490 		 *	0xfc000000: ns16550a, working fifo
491 		 *  pckbc0 at mace0 offset 0x320000 intr 5 intrmask 0x0
492 		 *  mcclock0 at mace0 offset 0x3a0000 intrmask 0x0
493 		 *  macepci0 at mace0 offset 0x80000 intr 7 intrmask 0x0: rev 1
494 		 *
495 		 *  intr 4 = CRIME_INT_PERIPH_SERIAL
496 		 *  intr 5 = CRIME_INT_PERIPH_MISC
497 		 *  intr 7 = CRIME_INT_PCI_BRIDGE
498 		 */
499 
500 		snprintf(eaddr_string, ETHERNET_STRING_MAXLEN,
501 		    "%02x:%02x:%02x:%02x:%02x:%02x",
502 		    macaddr[0], macaddr[1], macaddr[2],
503 		    macaddr[3], macaddr[4], macaddr[5]);
504 
505 		snprintf(tmpstr, sizeof(tmpstr), "%s.cpu[%i].2.crime.0x%x",
506 		    machine->path, machine->bootstrap_cpu, CRIME_INT_ETHERNET);
507 		dev_sgi_mec_init(machine, mem, 0x1f280000,
508 		    tmpstr, macaddr);
509 
510 		dev_sgi_ust_init(mem, 0x1f340000);  /*  ust?  */
511 
512 		snprintf(tmpstr, sizeof(tmpstr),
513 		    "ns16550 irq=%s.cpu[%i].2.crime.0x%x.mace.%i addr="
514 		    "0x1f390000 addr_mult=0x100 in_use=%i name2=tty0",
515 		    machine->path, machine->bootstrap_cpu,
516 		    CRIME_INT_PERIPH_SERIAL, 20, machine->x11_md.in_use? 0 : 1);
517 		j = (size_t)device_add(machine, tmpstr);
518 		snprintf(tmpstr, sizeof(tmpstr),
519 		    "ns16550 irq=%s.cpu[%i].2.crime.0x%x.mace.%i addr="
520 		    "0x1f398000 addr_mult=0x100 in_use=%i name2=tty1",
521 		    machine->path, machine->bootstrap_cpu,
522 		    CRIME_INT_PERIPH_SERIAL, 26, 0);
523 		device_add(machine, tmpstr);
524 
525 		machine->main_console_handle = j;
526 
527 		{
528 			/*  keyb+mouse (mace irq numbers)  */
529 			char tmpstr1[1000];
530 			char tmpstr2[1000];
531 			snprintf(tmpstr1, sizeof(tmpstr1),
532 			    "%s.cpu[%i].2.crime.0x%x.mace.%i",
533 			    machine->path, machine->bootstrap_cpu,
534 			    CRIME_INT_PERIPH_MISC, 9);
535 
536 			snprintf(tmpstr2, sizeof(tmpstr2),
537 			    "%s.cpu[%i].2.crime.0x%x.mace.%i",
538 			    machine->path, machine->bootstrap_cpu,
539 			    CRIME_INT_PERIPH_MISC, 11);
540 
541 			i = dev_pckbc_init(machine, mem, 0x1f320000,
542 			    PCKBC_8242, tmpstr1,
543 			    tmpstr2, machine->x11_md.in_use,
544 			    0);
545 
546 			if (machine->x11_md.in_use)
547 				machine->main_console_handle = i;
548 		}
549 
550 		snprintf(tmpstr, sizeof(tmpstr),
551 		    "%s.cpu[%i].2.crime.0x%x.mace.%i",
552 		    machine->path, machine->bootstrap_cpu,
553 		    CRIME_INT_PERIPH_MISC, 8);
554 		dev_mc146818_init(machine, mem, 0x1f3a0000, tmpstr,
555 		    MC146818_SGI, 0x40);  /*  mcclock0  */
556 
557 		/*
558 		 *  PCI devices:   (according to NetBSD's GENERIC
559 		 *  config file for sgimips)
560 		 *
561 		 *	ne*             at pci? dev ? function ?
562 		 *	ahc0            at pci0 dev 1 function ?
563 		 *	ahc1            at pci0 dev 2 function ?
564 		 */
565 
566 		snprintf(tmpstr, sizeof(tmpstr),
567 		    "%s.cpu[%i].2.crime.0x%x", machine->path,
568 		    machine->bootstrap_cpu, CRIME_INT_PCI_BRIDGE);
569 		pci_data = dev_macepci_init(machine, mem, 0x1f080000,
570 		    tmpstr);		/*  macepci0  */
571 		/*  bus_pci_add(machine, pci_data, mem, 0, 0, 0,
572 		    "ne2000");  TODO  */
573 
574 		/*
575 		 *  OpenBSD accesses the SCSI controller at paddr=0x2800010xx.
576 		 *  Note that the 2 is above 32-bit range.
577 		 *
578 		 *  TODO: Investigate what this actually means. Possibly
579 		 *  a bug in GXemul's 64-bit instructions? Or perhaps it really
580 		 *  is correct.
581 		 */
582 		dev_ram_init(machine, 0x280000000ULL, 0x01000000, DEV_RAM_MIRROR, 0x18000000);
583 
584 
585 		// ahc0:
586 		/*  TODO: Make it possible to add the controller, regardless of
587 			the existence of disks!  */
588 		if (diskimage_exist(machine, 0, DISKIMAGE_SCSI) ||
589 		    diskimage_exist(machine, 1, DISKIMAGE_SCSI) ||
590 		    diskimage_exist(machine, 2, DISKIMAGE_SCSI) ||
591 		    diskimage_exist(machine, 3, DISKIMAGE_SCSI) ||
592 		    diskimage_exist(machine, 4, DISKIMAGE_SCSI) ||
593 		    diskimage_exist(machine, 5, DISKIMAGE_SCSI) ||
594 		    diskimage_exist(machine, 6, DISKIMAGE_SCSI) ||
595 		    diskimage_exist(machine, 7, DISKIMAGE_SCSI))
596 			bus_pci_add(machine, pci_data, mem, 0, 1, 0, "ahc");
597 
598 		// ahc1:
599 		// bus_pci_add(machine, pci_data, mem, 0, 2, 0, "ahc");
600 
601 		break;
602 
603 	case 35:
604 		strlcat(machineName, " (Origin 3000)", MACHINE_NAME_MAXBUF);
605 		/*  4 cpus per node  */
606 
607 		// TODO: Correct Interrupt!
608 		snprintf(tmpstr, sizeof(tmpstr), "z8530 addr=0x1fbd9830 irq=%s.cpu[%i].2",
609 		    machine->path, machine->bootstrap_cpu);
610 		machine->main_console_handle = (size_t)device_add(machine, tmpstr);
611 
612 		break;
613 
614 	case 53:
615 		strlcat(machineName, " (Origin 350)",
616 		    MACHINE_NAME_MAXBUF);
617 
618 		/*
619 		 *  According to http://kumba.drachentekh.net/xml/myguide.html
620 		 *  Origin 350, Tezro IP53 R16000
621 		 */
622 		break;
623 
624 	default:
625 		fatal("unimplemented SGI machine type IP%i\n",
626 		    machine->machine_subtype);
627 		exit(1);
628 	}
629 
630 	if (!machine->prom_emulation)
631 		return;
632 
633 	arcbios_init(machine, arc_wordlen == sizeof(uint64_t), sgi_ram_offset,
634 	    eaddr_string, macaddr);
635 }
636 
637 
MACHINE_DEFAULT_CPU(sgi)638 MACHINE_DEFAULT_CPU(sgi)
639 {
640 	if (machine->machine_subtype <= 12)
641 	        machine->cpu_name = strdup("R3000");
642 	if (machine->cpu_name == NULL && machine->machine_subtype == 35)
643 	        machine->cpu_name = strdup("R12000");
644 	if (machine->cpu_name == NULL && (machine->machine_subtype == 25 ||
645 	    machine->machine_subtype == 27 || machine->machine_subtype == 28 ||
646 	    machine->machine_subtype == 30 || machine->machine_subtype == 32))
647 	        machine->cpu_name = strdup("R10000");
648 	if (machine->cpu_name == NULL && (machine->machine_subtype == 21 ||
649 	    machine->machine_subtype == 26))
650 	        machine->cpu_name = strdup("R8000");
651 	if (machine->cpu_name == NULL && machine->machine_subtype == 24)
652 	        machine->cpu_name = strdup("R5000");
653 
654 	/*  Other SGIs should probably work with
655 	    R4000, R4400 or R5000 or similar:  */
656 	if (machine->cpu_name == NULL)
657 	        machine->cpu_name = strdup("R4400");
658 }
659 
660 
MACHINE_DEFAULT_RAM(sgi)661 MACHINE_DEFAULT_RAM(sgi)
662 {
663 	// Self-compilation fails with OpenBSD/sgi 6.3 with as low as 128 MB
664 	// RAM, so 256 would be better. But my O2 has 128 MB, so this is kept
665 	// as 128 to simplify comparison between the real machine and the
666 	// emulator.
667 	machine->physical_ram_in_mb = 128;
668 }
669 
670 
MACHINE_REGISTER(sgi)671 MACHINE_REGISTER(sgi)
672 {
673 	MR_DEFAULT(sgi, "SGI", ARCH_MIPS, MACHINE_SGI);
674 
675 	me->set_default_ram = machine_default_ram_sgi;
676 
677 	machine_entry_add_alias(me, "silicon graphics");
678 	machine_entry_add_alias(me, "sgi");
679 
680 	machine_entry_add_subtype(me, "IP12", 12, "ip12", NULL);
681 
682 	machine_entry_add_subtype(me, "IP19", 19, "ip19", NULL);
683 
684 	machine_entry_add_subtype(me, "IP20", 20, "ip20", NULL);
685 
686 	machine_entry_add_subtype(me, "IP22", 22, "ip22", "indy", NULL);
687 
688 	machine_entry_add_subtype(me, "IP24", 24, "ip24", NULL);
689 
690 	machine_entry_add_subtype(me, "IP27", 27,
691 	    "ip27", "origin 200", "origin 2000", NULL);
692 
693 	machine_entry_add_subtype(me, "IP28", 28, "ip28", NULL);
694 
695 	machine_entry_add_subtype(me, "IP30", 30, "ip30", "octane", NULL);
696 
697 	machine_entry_add_subtype(me, "IP32", 32, "ip32", "o2", NULL);
698 
699 	machine_entry_add_subtype(me, "IP35", 35, "ip35", NULL);
700 }
701 
702