/[gxemul]/trunk/src/machine.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/src/machine.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (show annotations)
Mon Oct 8 16:18:38 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 174291 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.905 2005/08/16 09:16:24 debug Exp $
20050628	Continuing the work on the ARM translation engine. end_of_page
		works. Experimenting with load/store translation caches
		(virtual -> physical -> host).
20050629	More ARM stuff (memory access translation cache, mostly). This
		might break a lot of stuff elsewhere, probably some MIPS-
		related translation things.
20050630	Many load/stores are now automatically generated and included
		into cpu_arm_instr.c; 1024 functions in total (!).
		Fixes based on feedback from Alec Voropay: only print 8 hex
		digits instead of 16 in some cases when emulating 32-bit
		machines; similar 8 vs 16 digit fix for breakpoint addresses;
		4Kc has 16 TLB entries, not 48; the MIPS config select1
		register is now printed with "reg ,0".
		Also changing many other occurances of 16 vs 8 digit output.
		Adding cache associativity fields to mips_cpu_types.h; updating
		some other cache fields; making the output of
		mips_cpu_dumpinfo() look nicer.
		Generalizing the bintrans stuff for device accesses to also
		work with the new translation system. (This might also break
		some MIPS things.)
		Adding multi-load/store instructions to the ARM disassembler
		and the translator, and some optimizations of various kinds.
20050701	Adding a simple dev_disk (it can read/write sectors from
		disk images).
20050712	Adding dev_ether (a simple ethernet send/receive device).
		Debugger command "ninstrs" for toggling show_nr_of_instructions
		during runtime.
		Removing the framebuffer logo.
20050713	Continuing on dev_ether.
		Adding a dummy cpu_alpha (again).
20050714	More work on cpu_alpha.
20050715	More work on cpu_alpha. Many instructions work, enough to run
		a simple framebuffer fill test (similar to the ARM test).
20050716	More Alpha stuff.
20050717	Minor updates (Alpha stuff).
20050718	Minor updates (Alpha stuff).
20050719	Generalizing some Alpha instructions.
20050720	More Alpha-related updates.
20050721	Continuing on cpu_alpha. Importing rpb.h from NetBSD/alpha.
20050722	Alpha-related updates: userland stuff (Hello World using
		write() compiled statically for FreeBSD/Alpha runs fine), and
		more instructions are now implemented.
20050723	Fixing ldq_u and stq_u.
		Adding more instructions (conditional moves, masks, extracts,
		shifts).
20050724	More FreeBSD/Alpha userland stuff, and adding some more
		instructions (inserts).
20050725	Continuing on the Alpha stuff. (Adding dummy ldt/stt.)
		Adding a -A command line option to turn off alignment checks
		in some cases (for translated code).
		Trying to remove the old bintrans code which updated the pc
		and nr_of_executed_instructions for every instruction.
20050726	Making another attempt att removing the pc/nr of instructions
		code. This time it worked, huge performance increase for
		artificial test code, but performance loss for real-world
		code :-( so I'm scrapping that code for now.
		Tiny performance increase on Alpha (by using ret instead of
		jmp, to play nice with the Alpha's branch prediction) for the
		old MIPS bintrans backend.
20050727	Various minor fixes and cleanups.
20050728	Switching from a 2-level virtual to host/physical translation
		system for ARM emulation, to a 1-level translation.
		Trying to switch from 2-level to 1-level for the MIPS bintrans
		system as well (Alpha only, so far), but there is at least one
		problem: caches and/or how they work with device mappings.
20050730	Doing the 2-level to 1-level conversion for the i386 backend.
		The cache/device bug is still there for R2K/3K :(
		Various other minor updates (Malta etc).
		The mc146818 clock now updates the UIP bit in a way which works
		better with Linux for at least sgimips and Malta emulation.
		Beginning the work on refactoring the dyntrans system.
20050731	Continuing the dyntrans refactoring.
		Fixing a small but serious host alignment bug in memory_rw.
		Adding support for big-endian load/stores to the i386 bintrans
		backend.
		Another minor i386 bintrans backend update: stores from the
		zero register are now one (or two) loads shorter.
		The slt and sltu instructions were incorrectly implemented for
		the i386 backend; only using them for 32-bit mode for now.
20050801	Continuing the dyntrans refactoring.
		Cleanup of the ns16550 serial controller (removing unnecessary
		code).
		Bugfix (memory corruption bug) in dev_gt, and a patch/hack from
		Alec Voropay for Linux/Malta.
20050802	More cleanup/refactoring of the dyntrans subsystem: adding
		phys_page pointers to the lookup tables, for quick jumps
		between translated pages.
		Better fix for the ns16550 device (but still no real FIFO
		functionality).
		Converting cpu_ppc to the new dyntrans system. This means that
		I will have to start from scratch with implementing each
		instruction, and figure out how to implement dual 64/32-bit
		modes etc.
		Removing the URISC CPU family, because it was useless.
20050803	When selecting a machine type, the main type can now be omitted
		if the subtype name is unique. (I.e. -E can be omitted.)
		Fixing a dyntrans/device update bug. (Writes to offset 0 of
		a device could sometimes go unnoticed.)
		Adding an experimental "instruction combination" hack for
		ARM for memset-like byte fill loops.
20050804	Minor progress on cpu_alpha and related things.
		Finally fixing the MIPS dmult/dmultu bugs.
		Fixing some minor TODOs.
20050805	Generalizing the 8259 PIC. It now also works with Cobalt
		and evbmips emulation, in addition to the x86 hack.
		Finally converting the ns16550 device to use devinit.
		Continuing the work on the dyntrans system. Thinking about
		how to add breakpoints.
20050806	More dyntrans updates. Breakpoints seem to work now.
20050807	Minor updates: cpu_alpha and related things; removing
		dev_malta (as it isn't used any more).
		Dyntrans: working on general "show trace tree" support.
		The trace tree stuff now works with both the old MIPS code and
		with newer dyntrans modes. :)
		Continuing on Alpha-related stuff (trying to get *BSD to boot
		a bit further, adding more instructions, etc).
20050808	Adding a dummy IA64 cpu family, and continuing the refactoring
		of the dyntrans system.
		Removing the regression test stuff, because it was more or
		less useless.
		Adding loadlinked/storeconditional type instructions to the
		Alpha emulation. (Needed for Linux/alpha. Not very well tested
		yet.)
20050809	The function call trace tree now prints a per-function nr of
		arguments. (Semi-meaningless, since that data isn't read yet
		from the ELFs; some hardcoded symbols such as memcpy() and
		strlen() work fine, though.)
		More dyntrans refactoring; taking out more of the things that
		are common to all cpu families.
20050810	Working on adding support for "dual mode" for PPC dyntrans
		(i.e. both 64-bit and 32-bit modes).
		(Re)adding some simple PPC instructions.
20050811	Adding a dummy M68K cpu family. The dyntrans system isn't ready
		for variable-length ISAs yet, so it's completely bogus so far.
		Re-adding more PPC instructions.
		Adding a hack to src/file.c which allows OpenBSD/mac68k a.out
		kernels to be loaded.
		Beginning to add PPC loads/stores. So far they only work in
		32-bit mode.
20050812	The configure file option "add_remote" now accepts symbolic
		host names, in addition to numeric IPv4 addresses.
		Re-adding more PPC instructions.
20050814	Continuing to port back more PPC instructions.
		Found and fixed the cache/device write-update bug for 32-bit
		MIPS bintrans. :-)
		Triggered a really weird and annoying bug in Compaq's C
		compiler; ccc sometimes outputs code which loads from an
		address _before_ checking whether the pointer was NULL or not.
		(I'm not sure how to handle this problem.)
20050815	Removing all of the old x86 instruction execution code; adding
		a new (dummy) dyntrans module for x86.
		Taking the first steps to extend the dyntrans system to support
		variable-length instructions.
		Slowly preparing for the next release.
20050816	Adding a dummy SPARC cpu module.
		Minor updates (documentation etc) for the release.

==============  RELEASE 0.3.5  ==============


1 /*
2 * Copyright (C) 2003-2005 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 * $Id: machine.c,v 1.515 2005/08/16 09:16:26 debug Exp $
29 *
30 * Emulation of specific machines.
31 *
32 * This module is quite large. Hopefully it is still clear enough to be
33 * easily understood. The main parts are:
34 *
35 * Helper functions.
36 *
37 * Machine specific Interrupt routines.
38 *
39 * Machine specific Initialization routines.
40 */
41
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <stdarg.h>
45 #ifdef SOLARIS
46 #include <strings.h>
47 #else
48 #include <string.h>
49 #endif
50 #include <time.h>
51 #include <unistd.h>
52
53 #include "arcbios.h"
54 #include "bus_pci.h"
55 #include "cpu.h"
56 #include "device.h"
57 #include "devices.h"
58 #include "diskimage.h"
59 #include "emul.h"
60 #include "machine.h"
61 #include "memory.h"
62 #include "misc.h"
63 #include "mp.h"
64 #include "net.h"
65 #include "symbol.h"
66
67 /* For Alpha emulation: */
68 #include "alpha_rpb.h"
69
70 /* For SGI and ARC emulation: */
71 #include "sgi_arcbios.h"
72 #include "crimereg.h"
73
74 /* For evbmips emulation: */
75 #include "maltareg.h"
76
77 /* For DECstation emulation: */
78 #include "dec_prom.h"
79 #include "dec_bootinfo.h"
80 #include "dec_5100.h"
81 #include "dec_kn01.h"
82 #include "dec_kn02.h"
83 #include "dec_kn03.h"
84 #include "dec_kmin.h"
85 #include "dec_maxine.h"
86
87 /* HPC: */
88 #include "hpc_bootinfo.h"
89 #include "vripreg.h"
90
91 #define BOOTSTR_BUFLEN 1000
92 #define BOOTARG_BUFLEN 2000
93 #define ETHERNET_STRING_MAXLEN 40
94
95 struct machine_entry_subtype {
96 int machine_subtype;/* Old-style subtype */
97 const char *name; /* Official name */
98 int n_aliases;
99 char **aliases; /* Aliases */
100 };
101
102 struct machine_entry {
103 struct machine_entry *next;
104
105 /* Machine type: */
106 int arch;
107 int machine_type; /* Old-style type */
108 const char *name; /* Official name */
109 int n_aliases;
110 char **aliases; /* Aliases */
111
112 /* Machine subtypes: */
113 int n_subtypes;
114 struct machine_entry_subtype **subtype;
115 };
116
117
118 /* See main.c: */
119 extern int quiet_mode;
120
121
122 /* This is initialized by machine_init(): */
123 static struct machine_entry *first_machine_entry = NULL;
124
125
126 /*
127 * machine_new():
128 *
129 * Returns a reasonably initialized struct machine.
130 */
131 struct machine *machine_new(char *name, struct emul *emul)
132 {
133 struct machine *m;
134 m = malloc(sizeof(struct machine));
135 if (m == NULL) {
136 fprintf(stderr, "machine_new(): out of memory\n");
137 exit(1);
138 }
139
140 memset(m, 0, sizeof(struct machine));
141
142 /* Back pointer: */
143 m->emul = emul;
144
145 m->name = strdup(name);
146
147 /* Sane default values: */
148 m->serial_nr = 1;
149 m->machine_type = MACHINE_NONE;
150 m->machine_subtype = MACHINE_NONE;
151 #ifdef BINTRANS
152 m->bintrans_enable = 1;
153 m->old_bintrans_enable = 1;
154 #endif
155 m->arch_pagesize = 4096; /* Should be overriden in
156 emul.c for other pagesizes. */
157 m->dyntrans_alignment_check = 1;
158 m->prom_emulation = 1;
159 m->speed_tricks = 1;
160 m->byte_order_override = NO_BYTE_ORDER_OVERRIDE;
161 m->boot_kernel_filename = "";
162 m->boot_string_argument = NULL;
163 m->automatic_clock_adjustment = 1;
164 m->x11_scaledown = 1;
165 m->n_gfx_cards = 1;
166 m->dbe_on_nonexistant_memaccess = 1;
167 m->show_symbolic_register_names = 1;
168 m->bintrans_size = DEFAULT_BINTRANS_SIZE_IN_MB * 1048576;
169 symbol_init(&m->symbol_context);
170
171 return m;
172 }
173
174
175 /*
176 * machine_name_to_type():
177 *
178 * Take a type and a subtype as strings, and convert them into numeric
179 * values used internally throughout the code.
180 *
181 * Return value is 1 on success, 0 if there was no match.
182 * Also, any errors/warnings are printed using fatal()/debug().
183 */
184 int machine_name_to_type(char *stype, char *ssubtype,
185 int *type, int *subtype, int *arch)
186 {
187 struct machine_entry *me;
188 int i, j, k, nmatches = 0;
189
190 *type = MACHINE_NONE;
191 *subtype = 0;
192
193 /* Check stype, and optionally ssubtype: */
194 me = first_machine_entry;
195 while (me != NULL) {
196 for (i=0; i<me->n_aliases; i++)
197 if (strcasecmp(me->aliases[i], stype) == 0) {
198 /* Found a type: */
199 *type = me->machine_type;
200 *arch = me->arch;
201
202 if (me->n_subtypes == 0)
203 return 1;
204
205 /* Check for subtype: */
206 for (j=0; j<me->n_subtypes; j++)
207 for (k=0; k<me->subtype[j]->n_aliases;
208 k++)
209 if (strcasecmp(ssubtype,
210 me->subtype[j]->aliases[k]
211 ) == 0) {
212 *subtype = me->subtype[
213 j]->machine_subtype;
214 return 1;
215 }
216
217 fatal("Unknown subtype '%s' for emulation"
218 " '%s'\n", ssubtype, stype);
219 if (!ssubtype[0])
220 fatal("(Maybe you forgot the -e"
221 " command line option?)\n");
222 exit(1);
223 }
224
225 me = me->next;
226 }
227
228 /* Not found? Then just check ssubtype: */
229 me = first_machine_entry;
230 while (me != NULL) {
231 if (me->n_subtypes == 0) {
232 me = me->next;
233 continue;
234 }
235
236 /* Check for subtype: */
237 for (j=0; j<me->n_subtypes; j++)
238 for (k=0; k<me->subtype[j]->n_aliases; k++)
239 if (strcasecmp(ssubtype, me->subtype[j]->
240 aliases[k]) == 0) {
241 *type = me->machine_type;
242 *arch = me->arch;
243 *subtype = me->subtype[j]->
244 machine_subtype;
245 nmatches ++;
246 }
247
248 me = me->next;
249 }
250
251 switch (nmatches) {
252 case 0: fatal("\nSorry, emulation \"%s\"", stype);
253 if (ssubtype != NULL && ssubtype[0] != '\0')
254 fatal(" (subtype \"%s\")", ssubtype);
255 fatal(" is unknown.\n");
256 break;
257 case 1: return 1;
258 default:fatal("\nSorry, multiple matches for \"%s\"", stype);
259 if (ssubtype != NULL && ssubtype[0] != '\0')
260 fatal(" (subtype \"%s\")", ssubtype);
261 fatal(".\n");
262 }
263
264 *type = MACHINE_NONE;
265 *subtype = 0;
266
267 fatal("Use the -H command line option to get a list of "
268 "available types and subtypes.\n\n");
269
270 return 0;
271 }
272
273
274 /*
275 * machine_add_tickfunction():
276 *
277 * Adds a tick function (a function called every now and then, depending on
278 * clock cycle count) to a machine.
279 */
280 void machine_add_tickfunction(struct machine *machine, void (*func)
281 (struct cpu *, void *), void *extra, int clockshift)
282 {
283 int n = machine->n_tick_entries;
284
285 if (n >= MAX_TICK_FUNCTIONS) {
286 fprintf(stderr, "machine_add_tickfunction(): too "
287 "many tick functions\n");
288 exit(1);
289 }
290
291 /* Don't use too low clockshifts, that would be too inefficient
292 with bintrans. */
293 if (clockshift < N_SAFE_BINTRANS_LIMIT_SHIFT)
294 fatal("WARNING! clockshift = %i, less than "
295 "N_SAFE_BINTRANS_LIMIT_SHIFT (%i)\n",
296 clockshift, N_SAFE_BINTRANS_LIMIT_SHIFT);
297
298 machine->ticks_till_next[n] = 0;
299 machine->ticks_reset_value[n] = 1 << clockshift;
300 machine->tick_func[n] = func;
301 machine->tick_extra[n] = extra;
302
303 machine->n_tick_entries ++;
304 }
305
306
307 /****************************************************************************
308 * *
309 * Helper functions *
310 * *
311 ****************************************************************************/
312
313
314 int int_to_bcd(int i)
315 {
316 return (i/10) * 16 + (i % 10);
317 }
318
319
320 /*
321 * dump_mem_string():
322 *
323 * Dump the contents of emulated RAM as readable text. Bytes that aren't
324 * readable are dumped in [xx] notation, where xx is in hexadecimal.
325 * Dumping ends after DUMP_MEM_STRING_MAX bytes, or when a terminating
326 * zero byte is found.
327 */
328 #define DUMP_MEM_STRING_MAX 45
329 void dump_mem_string(struct cpu *cpu, uint64_t addr)
330 {
331 int i;
332 for (i=0; i<DUMP_MEM_STRING_MAX; i++) {
333 unsigned char ch = '\0';
334
335 cpu->memory_rw(cpu, cpu->mem, addr + i, &ch, sizeof(ch),
336 MEM_READ, CACHE_DATA | NO_EXCEPTIONS);
337 if (ch == '\0')
338 return;
339 if (ch >= ' ' && ch < 126)
340 debug("%c", ch);
341 else
342 debug("[%02x]", ch);
343 }
344 }
345
346
347 /*
348 * store_byte():
349 *
350 * Stores a byte in emulated ram. (Helper function.)
351 */
352 void store_byte(struct cpu *cpu, uint64_t addr, uint8_t data)
353 {
354 if ((addr >> 32) == 0)
355 addr = (int64_t)(int32_t)addr;
356 cpu->memory_rw(cpu, cpu->mem,
357 addr, &data, sizeof(data), MEM_WRITE, CACHE_DATA);
358 }
359
360
361 /*
362 * store_string():
363 *
364 * Stores chars into emulated RAM until a zero byte (string terminating
365 * character) is found. The zero byte is also copied.
366 * (strcpy()-like helper function, host-RAM-to-emulated-RAM.)
367 */
368 void store_string(struct cpu *cpu, uint64_t addr, char *s)
369 {
370 do {
371 store_byte(cpu, addr++, *s);
372 } while (*s++);
373 }
374
375
376 /*
377 * add_environment_string():
378 *
379 * Like store_string(), but advances the pointer afterwards. The most
380 * obvious use is to place a number of strings (such as environment variable
381 * strings) after one-another in emulated memory.
382 */
383 void add_environment_string(struct cpu *cpu, char *s, uint64_t *addr)
384 {
385 store_string(cpu, *addr, s);
386 (*addr) += strlen(s) + 1;
387 }
388
389
390 /*
391 * add_environment_string_dual():
392 *
393 * Add "dual" environment strings, one for the variable name and one for the
394 * value, and update pointers afterwards.
395 */
396 void add_environment_string_dual(struct cpu *cpu,
397 uint64_t *ptrp, uint64_t *addrp, char *s1, char *s2)
398 {
399 uint64_t ptr = *ptrp, addr = *addrp;
400
401 store_32bit_word(cpu, ptr, addr);
402 ptr += sizeof(uint32_t);
403 if (addr != 0) {
404 store_string(cpu, addr, s1);
405 addr += strlen(s1) + 1;
406 }
407 store_32bit_word(cpu, ptr, addr);
408 ptr += sizeof(uint32_t);
409 if (addr != 0) {
410 store_string(cpu, addr, s2);
411 addr += strlen(s2) + 1;
412 }
413
414 *ptrp = ptr;
415 *addrp = addr;
416 }
417
418
419 /*
420 * store_64bit_word():
421 *
422 * Stores a 64-bit word in emulated RAM. Byte order is taken into account.
423 * Helper function.
424 */
425 int store_64bit_word(struct cpu *cpu, uint64_t addr, uint64_t data64)
426 {
427 unsigned char data[8];
428 if ((addr >> 32) == 0)
429 addr = (int64_t)(int32_t)addr;
430 data[0] = (data64 >> 56) & 255;
431 data[1] = (data64 >> 48) & 255;
432 data[2] = (data64 >> 40) & 255;
433 data[3] = (data64 >> 32) & 255;
434 data[4] = (data64 >> 24) & 255;
435 data[5] = (data64 >> 16) & 255;
436 data[6] = (data64 >> 8) & 255;
437 data[7] = (data64) & 255;
438 if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
439 int tmp = data[0]; data[0] = data[7]; data[7] = tmp;
440 tmp = data[1]; data[1] = data[6]; data[6] = tmp;
441 tmp = data[2]; data[2] = data[5]; data[5] = tmp;
442 tmp = data[3]; data[3] = data[4]; data[4] = tmp;
443 }
444 return cpu->memory_rw(cpu, cpu->mem,
445 addr, data, sizeof(data), MEM_WRITE, CACHE_DATA);
446 }
447
448
449 /*
450 * store_32bit_word():
451 *
452 * Stores a 32-bit word in emulated RAM. Byte order is taken into account.
453 * (This function takes a 64-bit word as argument, to suppress some
454 * warnings, but only the lowest 32 bits are used.)
455 */
456 int store_32bit_word(struct cpu *cpu, uint64_t addr, uint64_t data32)
457 {
458 unsigned char data[4];
459 if ((addr >> 32) == 0)
460 addr = (int64_t)(int32_t)addr;
461 data[0] = (data32 >> 24) & 255;
462 data[1] = (data32 >> 16) & 255;
463 data[2] = (data32 >> 8) & 255;
464 data[3] = (data32) & 255;
465 if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
466 int tmp = data[0]; data[0] = data[3]; data[3] = tmp;
467 tmp = data[1]; data[1] = data[2]; data[2] = tmp;
468 }
469 return cpu->memory_rw(cpu, cpu->mem,
470 addr, data, sizeof(data), MEM_WRITE, CACHE_DATA);
471 }
472
473
474 /*
475 * store_16bit_word():
476 *
477 * Stores a 16-bit word in emulated RAM. Byte order is taken into account.
478 * (This function takes a 64-bit word as argument, to suppress some
479 * warnings, but only the lowest 16 bits are used.)
480 */
481 int store_16bit_word(struct cpu *cpu, uint64_t addr, uint64_t data16)
482 {
483 unsigned char data[2];
484 if ((addr >> 32) == 0)
485 addr = (int64_t)(int32_t)addr;
486 data[0] = (data16 >> 8) & 255;
487 data[1] = (data16) & 255;
488 if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
489 int tmp = data[0]; data[0] = data[1]; data[1] = tmp;
490 }
491 return cpu->memory_rw(cpu, cpu->mem,
492 addr, data, sizeof(data), MEM_WRITE, CACHE_DATA);
493 }
494
495
496 /*
497 * store_buf():
498 *
499 * memcpy()-like helper function, from host RAM to emulated RAM.
500 */
501 void store_buf(struct cpu *cpu, uint64_t addr, char *s, size_t len)
502 {
503 int psize = 1024; /* 1024 256 64 16 4 1 */
504
505 if ((addr >> 32) == 0)
506 addr = (int64_t)(int32_t)addr;
507
508 while (len != 0) {
509 if ((addr & (psize-1)) == 0) {
510 while (len >= psize) {
511 cpu->memory_rw(cpu, cpu->mem, addr,
512 (unsigned char *)s, psize, MEM_WRITE,
513 CACHE_DATA);
514 addr += psize;
515 s += psize;
516 len -= psize;
517 }
518 }
519 psize >>= 2;
520 }
521
522 while (len-- != 0)
523 store_byte(cpu, addr++, *s++);
524 }
525
526
527 /*
528 * store_pointer_and_advance():
529 *
530 * Stores a 32-bit or 64-bit pointer in emulated RAM, and advances the
531 * target address. (Used by ARC and SGI initialization.)
532 */
533 void store_pointer_and_advance(struct cpu *cpu, uint64_t *addrp,
534 uint64_t data, int flag64)
535 {
536 uint64_t addr = *addrp;
537 if (flag64) {
538 store_64bit_word(cpu, addr, data);
539 addr += 8;
540 } else {
541 store_32bit_word(cpu, addr, data);
542 addr += 4;
543 }
544 *addrp = addr;
545 }
546
547
548 /*
549 * load_32bit_word():
550 *
551 * Helper function. Prints a warning and returns 0, if the read failed.
552 * Emulated byte order is taken into account.
553 */
554 uint32_t load_32bit_word(struct cpu *cpu, uint64_t addr)
555 {
556 unsigned char data[4];
557
558 if ((addr >> 32) == 0)
559 addr = (int64_t)(int32_t)addr;
560 cpu->memory_rw(cpu, cpu->mem,
561 addr, data, sizeof(data), MEM_READ, CACHE_DATA);
562
563 if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
564 int tmp = data[0]; data[0] = data[3]; data[3] = tmp;
565 tmp = data[1]; data[1] = data[2]; data[2] = tmp;
566 }
567
568 return (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
569 }
570
571
572 /*
573 * load_16bit_word():
574 *
575 * Helper function. Prints a warning and returns 0, if the read failed.
576 * Emulated byte order is taken into account.
577 */
578 uint16_t load_16bit_word(struct cpu *cpu, uint64_t addr)
579 {
580 unsigned char data[2];
581
582 if ((addr >> 32) == 0)
583 addr = (int64_t)(int32_t)addr;
584 cpu->memory_rw(cpu, cpu->mem,
585 addr, data, sizeof(data), MEM_READ, CACHE_DATA);
586
587 if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
588 int tmp = data[0]; data[0] = data[1]; data[1] = tmp;
589 }
590
591 return (data[0] << 8) + data[1];
592 }
593
594
595 /*
596 * store_64bit_word_in_host():
597 *
598 * Stores a 64-bit word in the _host's_ RAM. Emulated byte order is taken
599 * into account. This is useful when building structs in the host's RAM
600 * which will later be copied into emulated RAM.
601 */
602 void store_64bit_word_in_host(struct cpu *cpu,
603 unsigned char *data, uint64_t data64)
604 {
605 data[0] = (data64 >> 56) & 255;
606 data[1] = (data64 >> 48) & 255;
607 data[2] = (data64 >> 40) & 255;
608 data[3] = (data64 >> 32) & 255;
609 data[4] = (data64 >> 24) & 255;
610 data[5] = (data64 >> 16) & 255;
611 data[6] = (data64 >> 8) & 255;
612 data[7] = (data64) & 255;
613 if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
614 int tmp = data[0]; data[0] = data[7]; data[7] = tmp;
615 tmp = data[1]; data[1] = data[6]; data[6] = tmp;
616 tmp = data[2]; data[2] = data[5]; data[5] = tmp;
617 tmp = data[3]; data[3] = data[4]; data[4] = tmp;
618 }
619 }
620
621
622 /*
623 * store_32bit_word_in_host():
624 *
625 * See comment for store_64bit_word_in_host().
626 *
627 * (Note: The data32 parameter is a uint64_t. This is done to suppress
628 * some warnings.)
629 */
630 void store_32bit_word_in_host(struct cpu *cpu,
631 unsigned char *data, uint64_t data32)
632 {
633 data[0] = (data32 >> 24) & 255;
634 data[1] = (data32 >> 16) & 255;
635 data[2] = (data32 >> 8) & 255;
636 data[3] = (data32) & 255;
637 if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
638 int tmp = data[0]; data[0] = data[3]; data[3] = tmp;
639 tmp = data[1]; data[1] = data[2]; data[2] = tmp;
640 }
641 }
642
643
644 /*
645 * store_16bit_word_in_host():
646 *
647 * See comment for store_64bit_word_in_host().
648 */
649 void store_16bit_word_in_host(struct cpu *cpu,
650 unsigned char *data, uint16_t data16)
651 {
652 data[0] = (data16 >> 8) & 255;
653 data[1] = (data16) & 255;
654 if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
655 int tmp = data[0]; data[0] = data[1]; data[1] = tmp;
656 }
657 }
658
659
660 /****************************************************************************
661 * *
662 * Machine dependant Interrupt routines *
663 * *
664 ****************************************************************************/
665
666
667 /*
668 * DECstation KN02 interrupts:
669 */
670 void kn02_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, int assrt)
671 {
672 int current;
673
674 irq_nr -= 8;
675 irq_nr &= 0xff;
676
677 if (assrt) {
678 /* OR in the irq_nr into the CSR: */
679 m->md_int.kn02_csr->csr[0] |= irq_nr;
680 } else {
681 /* AND out the irq_nr from the CSR: */
682 m->md_int.kn02_csr->csr[0] &= ~irq_nr;
683 }
684
685 current = m->md_int.kn02_csr->csr[0] & m->md_int.kn02_csr->csr[2];
686 if (current == 0)
687 cpu_interrupt_ack(cpu, 2);
688 else
689 cpu_interrupt(cpu, 2);
690 }
691
692
693 /*
694 * DECstation KMIN interrupts:
695 *
696 * TC slot 3 = system slot.
697 */
698 void kmin_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, int assrt)
699 {
700 irq_nr -= 8;
701 /* debug("kmin_interrupt(): irq_nr=%i assrt=%i\n", irq_nr, assrt); */
702
703 if (assrt)
704 m->md_int.dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START) / 0x10] |= irq_nr;
705 else
706 m->md_int.dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START) / 0x10] &= ~irq_nr;
707
708 if (m->md_int.dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START) / 0x10]
709 & m->md_int.dec_ioasic_data->reg[(IOASIC_IMSK - IOASIC_SLOT_1_START) / 0x10])
710 cpu_interrupt(cpu, KMIN_INT_TC3);
711 else
712 cpu_interrupt_ack(cpu, KMIN_INT_TC3);
713 }
714
715
716 /*
717 * DECstation KN03 interrupts:
718 */
719 void kn03_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, int assrt)
720 {
721 irq_nr -= 8;
722 /* debug("kn03_interrupt(): irq_nr=0x%x assrt=%i\n", irq_nr, assrt); */
723
724 if (assrt)
725 m->md_int.dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START) / 0x10] |= irq_nr;
726 else
727 m->md_int.dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START) / 0x10] &= ~irq_nr;
728
729 if (m->md_int.dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START) / 0x10]
730 & m->md_int.dec_ioasic_data->reg[(IOASIC_IMSK - IOASIC_SLOT_1_START) / 0x10])
731 cpu_interrupt(cpu, KN03_INT_ASIC);
732 else
733 cpu_interrupt_ack(cpu, KN03_INT_ASIC);
734 }
735
736
737 /*
738 * DECstation MAXINE interrupts:
739 */
740 void maxine_interrupt(struct machine *m, struct cpu *cpu,
741 int irq_nr, int assrt)
742 {
743 irq_nr -= 8;
744 debug("maxine_interrupt(): irq_nr=0x%x assrt=%i\n", irq_nr, assrt);
745
746 if (assrt)
747 m->md_int.dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START)
748 / 0x10] |= irq_nr;
749 else
750 m->md_int.dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START)
751 / 0x10] &= ~irq_nr;
752
753 if (m->md_int.dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START) / 0x10]
754 & m->md_int.dec_ioasic_data->reg[(IOASIC_IMSK - IOASIC_SLOT_1_START)
755 / 0x10])
756 cpu_interrupt(cpu, XINE_INT_TC3);
757 else
758 cpu_interrupt_ack(cpu, XINE_INT_TC3);
759 }
760
761
762 /*
763 * DECstation KN230 interrupts:
764 */
765 void kn230_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, int assrt)
766 {
767 int r2 = 0;
768
769 m->md_int.kn230_csr->csr |= irq_nr;
770
771 switch (irq_nr) {
772 case KN230_CSR_INTR_SII:
773 case KN230_CSR_INTR_LANCE:
774 r2 = 3;
775 break;
776 case KN230_CSR_INTR_DZ0:
777 case KN230_CSR_INTR_OPT0:
778 case KN230_CSR_INTR_OPT1:
779 r2 = 2;
780 break;
781 default:
782 fatal("kn230_interrupt(): irq_nr = %i ?\n", irq_nr);
783 }
784
785 if (assrt) {
786 /* OR in the irq_nr mask into the CSR: */
787 m->md_int.kn230_csr->csr |= irq_nr;
788
789 /* Assert MIPS interrupt 2 or 3: */
790 cpu_interrupt(cpu, r2);
791 } else {
792 /* AND out the irq_nr mask from the CSR: */
793 m->md_int.kn230_csr->csr &= ~irq_nr;
794
795 /* If the CSR interrupt bits are all zero,
796 clear the bit in the cause register as well. */
797 if (r2 == 2) {
798 /* irq 2: */
799 if ((m->md_int.kn230_csr->csr & (KN230_CSR_INTR_DZ0
800 | KN230_CSR_INTR_OPT0 | KN230_CSR_INTR_OPT1)) == 0)
801 cpu_interrupt_ack(cpu, r2);
802 } else {
803 /* irq 3: */
804 if ((m->md_int.kn230_csr->csr & (KN230_CSR_INTR_SII |
805 KN230_CSR_INTR_LANCE)) == 0)
806 cpu_interrupt_ack(cpu, r2);
807 }
808 }
809 }
810
811
812 /*
813 * Jazz interrupts (for Acer PICA-61 etc):
814 *
815 * 0..7 MIPS interrupts
816 * 8 + x, where x = 0..15 Jazz interrupts
817 * 8 + x, where x = 16..31 ISA interrupt (irq nr + 16)
818 */
819 void jazz_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, int assrt)
820 {
821 uint32_t irq;
822 int isa = 0;
823
824 irq_nr -= 8;
825
826 /* debug("jazz_interrupt() irq_nr = %i, assrt = %i\n",
827 irq_nr, assrt); */
828
829 if (irq_nr >= 16) {
830 isa = 1;
831 irq_nr -= 16;
832 }
833
834 irq = 1 << irq_nr;
835
836 if (isa) {
837 if (assrt)
838 m->md_int.jazz_data->isa_int_asserted |= irq;
839 else
840 m->md_int.jazz_data->isa_int_asserted &= ~irq;
841 } else {
842 if (assrt)
843 m->md_int.jazz_data->int_asserted |= irq;
844 else
845 m->md_int.jazz_data->int_asserted &= ~irq;
846 }
847
848 /* debug(" %08x %08x\n", m->md_int.jazz_data->int_asserted,
849 m->md_int.jazz_data->int_enable_mask); */
850 /* debug(" %08x %08x\n", m->md_int.jazz_data->isa_int_asserted,
851 m->md_int.jazz_data->isa_int_enable_mask); */
852
853 if (m->md_int.jazz_data->int_asserted
854 /* & m->md_int.jazz_data->int_enable_mask */ & ~0x8000 )
855 cpu_interrupt(cpu, 3);
856 else
857 cpu_interrupt_ack(cpu, 3);
858
859 if (m->md_int.jazz_data->isa_int_asserted &
860 m->md_int.jazz_data->isa_int_enable_mask)
861 cpu_interrupt(cpu, 4);
862 else
863 cpu_interrupt_ack(cpu, 4);
864
865 /* TODO: this "15" (0x8000) is the timer... fix this? */
866 if (m->md_int.jazz_data->int_asserted & 0x8000)
867 cpu_interrupt(cpu, 6);
868 else
869 cpu_interrupt_ack(cpu, 6);
870 }
871
872
873 /*
874 * VR41xx interrupt routine:
875 *
876 * irq_nr = 8 + x
877 * x = 0..15 for level1
878 * x = 16..31 for level2
879 * x = 32+y for GIU interrupt y
880 */
881 void vr41xx_interrupt(struct machine *m, struct cpu *cpu,
882 int irq_nr, int assrt)
883 {
884 int giu_irq = 0;
885
886 irq_nr -= 8;
887 if (irq_nr >= 32) {
888 giu_irq = irq_nr - 32;
889
890 if (assrt)
891 m->md_int.vr41xx_data->giuint |= (1 << giu_irq);
892 else
893 m->md_int.vr41xx_data->giuint &= ~(1 << giu_irq);
894 }
895
896 /* TODO: This is wrong. What about GIU bit 8? */
897
898 if (irq_nr != 8) {
899 /* If any GIU bit is asserted, then assert the main
900 GIU interrupt: */
901 if (m->md_int.vr41xx_data->giuint &
902 m->md_int.vr41xx_data->giumask)
903 vr41xx_interrupt(m, cpu, 8 + 8, 1);
904 else
905 vr41xx_interrupt(m, cpu, 8 + 8, 0);
906 }
907
908 /* debug("vr41xx_interrupt(): irq_nr=%i assrt=%i\n",
909 irq_nr, assrt); */
910
911 if (irq_nr < 16) {
912 if (assrt)
913 m->md_int.vr41xx_data->sysint1 |= (1 << irq_nr);
914 else
915 m->md_int.vr41xx_data->sysint1 &= ~(1 << irq_nr);
916 } else if (irq_nr < 32) {
917 irq_nr -= 16;
918 if (assrt)
919 m->md_int.vr41xx_data->sysint2 |= (1 << irq_nr);
920 else
921 m->md_int.vr41xx_data->sysint2 &= ~(1 << irq_nr);
922 }
923
924 /* TODO: Which hardware interrupt pin? */
925
926 /* debug(" sysint1=%04x mask=%04x, sysint2=%04x mask=%04x\n",
927 m->md_int.vr41xx_data->sysint1, m->md_int.vr41xx_data->msysint1,
928 m->md_int.vr41xx_data->sysint2, m->md_int.vr41xx_data->msysint2); */
929
930 if ((m->md_int.vr41xx_data->sysint1 & m->md_int.vr41xx_data->msysint1) |
931 (m->md_int.vr41xx_data->sysint2 & m->md_int.vr41xx_data->msysint2))
932 cpu_interrupt(cpu, 2);
933 else
934 cpu_interrupt_ack(cpu, 2);
935 }
936
937
938 /*
939 * Playstation 2 interrupt routine:
940 *
941 * irq_nr = 8 + x normal irq x
942 * 8 + 16 + y dma irq y
943 * 8 + 32 + 0 sbus irq 0 (pcmcia)
944 * 8 + 32 + 1 sbus irq 1 (usb)
945 */
946 void ps2_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, int assrt)
947 {
948 irq_nr -= 8;
949 debug("ps2_interrupt(): irq_nr=0x%x assrt=%i\n", irq_nr, assrt);
950
951 if (irq_nr >= 32) {
952 int msk = 0;
953 switch (irq_nr - 32) {
954 case 0: /* PCMCIA: */
955 msk = 0x100;
956 break;
957 case 1: /* USB: */
958 msk = 0x400;
959 break;
960 default:
961 fatal("ps2_interrupt(): bad irq_nr %i\n", irq_nr);
962 }
963
964 if (assrt)
965 m->md_int.ps2_data->sbus_smflg |= msk;
966 else
967 m->md_int.ps2_data->sbus_smflg &= ~msk;
968
969 if (m->md_int.ps2_data->sbus_smflg != 0)
970 cpu_interrupt(cpu, 8 + 1);
971 else
972 cpu_interrupt_ack(cpu, 8 + 1);
973 return;
974 }
975
976 if (assrt) {
977 /* OR into the INTR: */
978 if (irq_nr < 16)
979 m->md_int.ps2_data->intr |= (1 << irq_nr);
980 else
981 m->md_int.ps2_data->dmac_reg[0x601] |=
982 (1 << (irq_nr-16));
983 } else {
984 /* AND out of the INTR: */
985 if (irq_nr < 16)
986 m->md_int.ps2_data->intr &= ~(1 << irq_nr);
987 else
988 m->md_int.ps2_data->dmac_reg[0x601] &=
989 ~(1 << (irq_nr-16));
990 }
991
992 /* TODO: Hm? How about the mask? */
993 if (m->md_int.ps2_data->intr /* & m->md_int.ps2_data->imask */ )
994 cpu_interrupt(cpu, 2);
995 else
996 cpu_interrupt_ack(cpu, 2);
997
998 /* TODO: mask? */
999 if (m->md_int.ps2_data->dmac_reg[0x601] & 0xffff)
1000 cpu_interrupt(cpu, 3);
1001 else
1002 cpu_interrupt_ack(cpu, 3);
1003 }
1004
1005
1006 /*
1007 * SGI "IP22" interrupt routine:
1008 */
1009 void sgi_ip22_interrupt(struct machine *m, struct cpu *cpu,
1010 int irq_nr, int assrt)
1011 {
1012 /*
1013 * SGI-IP22 specific interrupt stuff:
1014 *
1015 * irq_nr should be 8 + x, where x = 0..31 for local0,
1016 * and 32..63 for local1 interrupts.
1017 * Add 64*y for "mappable" interrupts, where 1<<y is
1018 * the mappable interrupt bitmask. TODO: this misses 64*0 !
1019 */
1020
1021 uint32_t newmask;
1022 uint32_t stat, mask;
1023
1024 irq_nr -= 8;
1025 newmask = 1 << (irq_nr & 31);
1026
1027 if (irq_nr >= 64) {
1028 int ms = irq_nr / 64;
1029 uint32_t new = 1 << ms;
1030 if (assrt)
1031 m->md_int.sgi_ip22_data->reg[4] |= new;
1032 else
1033 m->md_int.sgi_ip22_data->reg[4] &= ~new;
1034 /* TODO: is this enough? */
1035 irq_nr &= 63;
1036 }
1037
1038 if (irq_nr < 32) {
1039 if (assrt)
1040 m->md_int.sgi_ip22_data->reg[0] |= newmask;
1041 else
1042 m->md_int.sgi_ip22_data->reg[0] &= ~newmask;
1043 } else {
1044 if (assrt)
1045 m->md_int.sgi_ip22_data->reg[2] |= newmask;
1046 else
1047 m->md_int.sgi_ip22_data->reg[2] &= ~newmask;
1048 }
1049
1050 /* Read stat and mask for local0: */
1051 stat = m->md_int.sgi_ip22_data->reg[0];
1052 mask = m->md_int.sgi_ip22_data->reg[1];
1053 if ((stat & mask) == 0)
1054 cpu_interrupt_ack(cpu, 2);
1055 else
1056 cpu_interrupt(cpu, 2);
1057
1058 /* Read stat and mask for local1: */
1059 stat = m->md_int.sgi_ip22_data->reg[2];
1060 mask = m->md_int.sgi_ip22_data->reg[3];
1061 if ((stat & mask) == 0)
1062 cpu_interrupt_ack(cpu, 3);
1063 else
1064 cpu_interrupt(cpu, 3);
1065 }
1066
1067
1068 /*
1069 * SGI "IP30" interrupt routine:
1070 *
1071 * irq_nr = 8 + 1 + nr, where nr is:
1072 * 0..49 HEART irqs hardware irq 2,3,4
1073 * 50 HEART timer hardware irq 5
1074 * 51..63 HEART errors hardware irq 6
1075 *
1076 * according to Linux/IP30.
1077 */
1078 void sgi_ip30_interrupt(struct machine *m, struct cpu *cpu,
1079 int irq_nr, int assrt)
1080 {
1081 uint64_t newmask;
1082 uint64_t stat, mask;
1083
1084 irq_nr -= 8;
1085 if (irq_nr == 0)
1086 goto just_assert_and_such;
1087 irq_nr --;
1088
1089 newmask = (int64_t)1 << irq_nr;
1090
1091 if (assrt)
1092 m->md_int.sgi_ip30_data->isr |= newmask;
1093 else
1094 m->md_int.sgi_ip30_data->isr &= ~newmask;
1095
1096 just_assert_and_such:
1097
1098 cpu_interrupt_ack(cpu, 2);
1099 cpu_interrupt_ack(cpu, 3);
1100 cpu_interrupt_ack(cpu, 4);
1101 cpu_interrupt_ack(cpu, 5);
1102 cpu_interrupt_ack(cpu, 6);
1103
1104 stat = m->md_int.sgi_ip30_data->isr;
1105 mask = m->md_int.sgi_ip30_data->imask0;
1106
1107 if ((stat & mask) & 0x000000000000ffffULL)
1108 cpu_interrupt(cpu, 2);
1109 if ((stat & mask) & 0x00000000ffff0000ULL)
1110 cpu_interrupt(cpu, 3);
1111 if ((stat & mask) & 0x0003ffff00000000ULL)
1112 cpu_interrupt(cpu, 4);
1113 if ((stat & mask) & 0x0004000000000000ULL)
1114 cpu_interrupt(cpu, 5);
1115 if ((stat & mask) & 0xfff8000000000000ULL)
1116 cpu_interrupt(cpu, 6);
1117 }
1118
1119
1120 /*
1121 * SGI "IP32" interrupt routine:
1122 */
1123 void sgi_ip32_interrupt(struct machine *m, struct cpu *cpu,
1124 int irq_nr, int assrt)
1125 {
1126 /*
1127 * The 64-bit word at crime offset 0x10 is CRIME_INTSTAT,
1128 * which contains the current interrupt bits. CRIME_INTMASK
1129 * contains a mask of which bits are actually in use.
1130 *
1131 * crime hardcoded at 0x14000000, for SGI-IP32.
1132 * If any of these bits are asserted, then physical MIPS
1133 * interrupt 2 should be asserted.
1134 *
1135 * TODO: how should all this be done nicely?
1136 */
1137
1138 uint64_t crime_addr = CRIME_INTSTAT;
1139 uint64_t mace_addr = 0x10;
1140 uint64_t crime_interrupts, crime_interrupts_mask;
1141 uint64_t mace_interrupts, mace_interrupt_mask;
1142 unsigned int i;
1143 unsigned char x[8];
1144
1145 /* Read current MACE interrupt assertions: */
1146 memcpy(x, m->md_int.ip32.mace_data->reg + mace_addr,
1147 sizeof(uint64_t));
1148 mace_interrupts = 0;
1149 for (i=0; i<sizeof(uint64_t); i++) {
1150 mace_interrupts <<= 8;
1151 mace_interrupts |= x[i];
1152 }
1153
1154 /* Read current MACE interrupt mask: */
1155 memcpy(x, m->md_int.ip32.mace_data->reg + mace_addr + 8,
1156 sizeof(uint64_t));
1157 mace_interrupt_mask = 0;
1158 for (i=0; i<sizeof(uint64_t); i++) {
1159 mace_interrupt_mask <<= 8;
1160 mace_interrupt_mask |= x[i];
1161 }
1162
1163 /*
1164 * This mapping of both MACE and CRIME interrupts into the same
1165 * 'int' is really ugly.
1166 *
1167 * If MACE_PERIPH_MISC or MACE_PERIPH_SERIAL is set, then mask
1168 * that bit out and treat the rest of the word as the mace interrupt
1169 * bitmask.
1170 *
1171 * TODO: fix.
1172 */
1173 if (irq_nr & MACE_PERIPH_SERIAL) {
1174 if (assrt)
1175 mace_interrupts |= (irq_nr & ~MACE_PERIPH_SERIAL);
1176 else
1177 mace_interrupts &= ~(irq_nr & ~MACE_PERIPH_SERIAL);
1178
1179 irq_nr = MACE_PERIPH_SERIAL;
1180 if ((mace_interrupts & mace_interrupt_mask) == 0)
1181 assrt = 0;
1182 else
1183 assrt = 1;
1184 }
1185
1186 /* Hopefully _MISC and _SERIAL will not be both on at the same time. */
1187 if (irq_nr & MACE_PERIPH_MISC) {
1188 if (assrt)
1189 mace_interrupts |= (irq_nr & ~MACE_PERIPH_MISC);
1190 else
1191 mace_interrupts &= ~(irq_nr & ~MACE_PERIPH_MISC);
1192
1193 irq_nr = MACE_PERIPH_MISC;
1194 if ((mace_interrupts & mace_interrupt_mask) == 0)
1195 assrt = 0;
1196 else
1197 assrt = 1;
1198 }
1199
1200 /* Write back MACE interrupt assertions: */
1201 for (i=0; i<sizeof(uint64_t); i++)
1202 x[7-i] = mace_interrupts >> (i*8);
1203 memcpy(m->md_int.ip32.mace_data->reg + mace_addr, x, sizeof(uint64_t));
1204
1205 /* Read CRIME_INTSTAT: */
1206 memcpy(x, m->md_int.ip32.crime_data->reg + crime_addr,
1207 sizeof(uint64_t));
1208 crime_interrupts = 0;
1209 for (i=0; i<sizeof(uint64_t); i++) {
1210 crime_interrupts <<= 8;
1211 crime_interrupts |= x[i];
1212 }
1213
1214 if (assrt)
1215 crime_interrupts |= irq_nr;
1216 else
1217 crime_interrupts &= ~irq_nr;
1218
1219 /* Write back CRIME_INTSTAT: */
1220 for (i=0; i<sizeof(uint64_t); i++)
1221 x[7-i] = crime_interrupts >> (i*8);
1222 memcpy(m->md_int.ip32.crime_data->reg + crime_addr, x,
1223 sizeof(uint64_t));
1224
1225 /* Read CRIME_INTMASK: */
1226 memcpy(x, m->md_int.ip32.crime_data->reg + CRIME_INTMASK,
1227 sizeof(uint64_t));
1228 crime_interrupts_mask = 0;
1229 for (i=0; i<sizeof(uint64_t); i++) {
1230 crime_interrupts_mask <<= 8;
1231 crime_interrupts_mask |= x[i];
1232 }
1233
1234 if ((crime_interrupts & crime_interrupts_mask) == 0)
1235 cpu_interrupt_ack(cpu, 2);
1236 else
1237 cpu_interrupt(cpu, 2);
1238
1239 /* printf("sgi_crime_machine_irq(%i,%i): new interrupts = 0x%08x\n",
1240 assrt, irq_nr, crime_interrupts); */
1241 }
1242
1243
1244 /*
1245 * Au1x00 interrupt routine:
1246 *
1247 * TODO: This is just bogus so far. For more info, read this:
1248 * http://www.meshcube.org/cgi-bin/viewcvs.cgi/kernel/linux/arch/mips/au1000/common/
1249 *
1250 * CPU int 2 = IC 0, request 0
1251 * CPU int 3 = IC 0, request 1
1252 * CPU int 4 = IC 1, request 0
1253 * CPU int 5 = IC 1, request 1
1254 *
1255 * Interrupts 0..31 are on interrupt controller 0, interrupts 32..63 are
1256 * on controller 1.
1257 *
1258 * Special case: if irq_nr == 64+8, then this just updates the CPU
1259 * interrupt assertions.
1260 */
1261 void au1x00_interrupt(struct machine *m, struct cpu *cpu,
1262 int irq_nr, int assrt)
1263 {
1264 uint32_t ms;
1265
1266 irq_nr -= 8;
1267 debug("au1x00_interrupt(): irq_nr=%i assrt=%i\n", irq_nr, assrt);
1268
1269 if (irq_nr < 64) {
1270 ms = 1 << (irq_nr & 31);
1271
1272 if (assrt)
1273 m->md_int.au1x00_ic_data->request0_int |= ms;
1274 else
1275 m->md_int.au1x00_ic_data->request0_int &= ~ms;
1276
1277 /* TODO: Controller 1 */
1278 }
1279
1280 if ((m->md_int.au1x00_ic_data->request0_int &
1281 m->md_int.au1x00_ic_data->mask) != 0)
1282 cpu_interrupt(cpu, 2);
1283 else
1284 cpu_interrupt_ack(cpu, 2);
1285
1286 /* TODO: What _is_ request1? */
1287
1288 /* TODO: Controller 1 */
1289 }
1290
1291
1292 /*
1293 * Malta (evbmips) interrupts:
1294 *
1295 * ISA interrupts.
1296 * (irq_nr = 16+8 can be used to just reassert/deassert interrupts.)
1297 */
1298 void malta_interrupt(struct machine *m, struct cpu *cpu, int irq_nr,
1299 int assrt)
1300 {
1301 int mask;
1302
1303 irq_nr -= 8;
1304 mask = 1 << (irq_nr & 7);
1305
1306 if (irq_nr < 8) {
1307 if (assrt)
1308 m->md_int.isa_pic_data.pic1->irr |= mask;
1309 else
1310 m->md_int.isa_pic_data.pic1->irr &= ~mask;
1311 } else if (irq_nr < 16) {
1312 if (assrt)
1313 m->md_int.isa_pic_data.pic2->irr |= mask;
1314 else
1315 m->md_int.isa_pic_data.pic2->irr &= ~mask;
1316 }
1317
1318 /* Any interrupt assertions on PIC2 go to irq 2 on PIC1 */
1319 /* (TODO: don't hardcode this here) */
1320 if (m->md_int.isa_pic_data.pic2->irr &
1321 ~m->md_int.isa_pic_data.pic2->ier)
1322 m->md_int.isa_pic_data.pic1->irr |= 0x04;
1323 else
1324 m->md_int.isa_pic_data.pic1->irr &= ~0x04;
1325
1326 /* Now, PIC1: */
1327 if (m->md_int.isa_pic_data.pic1->irr &
1328 ~m->md_int.isa_pic_data.pic1->ier)
1329 cpu_interrupt(cpu, 2);
1330 else
1331 cpu_interrupt_ack(cpu, 2);
1332
1333 /* printf("MALTA: pic1.irr=0x%02x ier=0x%02x pic2.irr=0x%02x "
1334 "ier=0x%02x\n", m->md_int.isa_pic_data.pic1->irr,
1335 m->md_int.isa_pic_data.pic1->ier,
1336 m->md_int.isa_pic_data.pic2->irr,
1337 m->md_int.isa_pic_data.pic2->ier); */
1338 }
1339
1340
1341 /*
1342 * Cobalt interrupts:
1343 *
1344 * (irq_nr = 8 + 16 can be used to just reassert/deassert interrupts.)
1345 */
1346 void cobalt_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, int assrt)
1347 {
1348 int mask;
1349
1350 irq_nr -= 8;
1351 mask = 1 << (irq_nr & 7);
1352
1353 if (irq_nr < 8) {
1354 if (assrt)
1355 m->md_int.isa_pic_data.pic1->irr |= mask;
1356 else
1357 m->md_int.isa_pic_data.pic1->irr &= ~mask;
1358 } else if (irq_nr < 16) {
1359 if (assrt)
1360 m->md_int.isa_pic_data.pic2->irr |= mask;
1361 else
1362 m->md_int.isa_pic_data.pic2->irr &= ~mask;
1363 }
1364
1365 /* Any interrupt assertions on PIC2 go to irq 2 on PIC1 */
1366 /* (TODO: don't hardcode this here) */
1367 if (m->md_int.isa_pic_data.pic2->irr &
1368 ~m->md_int.isa_pic_data.pic2->ier)
1369 m->md_int.isa_pic_data.pic1->irr |= 0x04;
1370 else
1371 m->md_int.isa_pic_data.pic1->irr &= ~0x04;
1372
1373 /* Now, PIC1: */
1374 if (m->md_int.isa_pic_data.pic1->irr &
1375 ~m->md_int.isa_pic_data.pic1->ier)
1376 cpu_interrupt(cpu, 6);
1377 else
1378 cpu_interrupt_ack(cpu, 6);
1379
1380 /* printf("COBALT: pic1.irr=0x%02x ier=0x%02x pic2.irr=0x%02x "
1381 "ier=0x%02x\n", m->md_int.isa_pic_data.pic1->irr,
1382 m->md_int.isa_pic_data.pic1->ier,
1383 m->md_int.isa_pic_data.pic2->irr,
1384 m->md_int.isa_pic_data.pic2->ier); */
1385 }
1386
1387
1388 /*
1389 * x86 (PC) interrupts:
1390 *
1391 * (irq_nr = 16 can be used to just reassert/deassert interrupts.)
1392 */
1393 void x86_pc_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, int assrt)
1394 {
1395 int mask = 1 << (irq_nr & 7);
1396
1397 if (irq_nr < 8) {
1398 if (assrt)
1399 m->md.pc.pic1->irr |= mask;
1400 else
1401 m->md.pc.pic1->irr &= ~mask;
1402 } else if (irq_nr < 16) {
1403 if (m->md.pc.pic2 == NULL) {
1404 fatal("x86_pc_interrupt(): pic2 used (irq_nr = %i), "
1405 "but we are emulating an XT?\n", irq_nr);
1406 return;
1407 }
1408 if (assrt)
1409 m->md.pc.pic2->irr |= mask;
1410 else
1411 m->md.pc.pic2->irr &= ~mask;
1412 }
1413
1414 if (m->md.pc.pic2 != NULL) {
1415 /* Any interrupt assertions on PIC2 go to irq 2 on PIC1 */
1416 /* (TODO: don't hardcode this here) */
1417 if (m->md.pc.pic2->irr & ~m->md.pc.pic2->ier)
1418 m->md.pc.pic1->irr |= 0x04;
1419 else
1420 m->md.pc.pic1->irr &= ~0x04;
1421 }
1422
1423 /* Now, PIC1: */
1424 if (m->md.pc.pic1->irr & ~m->md.pc.pic1->ier)
1425 cpu->cd.x86.interrupt_asserted = 1;
1426 else
1427 cpu->cd.x86.interrupt_asserted = 0;
1428 }
1429
1430
1431 /****************************************************************************
1432 * *
1433 * Machine dependant Initialization routines *
1434 * *
1435 ****************************************************************************/
1436
1437
1438 /*
1439 * machine_setup():
1440 *
1441 * This (rather large) function initializes memory, registers, and/or devices
1442 * required by specific machine emulations.
1443 */
1444 void machine_setup(struct machine *machine)
1445 {
1446 uint64_t addr, addr2;
1447 int i, j;
1448 struct memory *mem;
1449 char tmpstr[1000];
1450 struct cons_data *cons_data;
1451
1452 /* DECstation: */
1453 char *framebuffer_console_name, *serial_console_name;
1454 int color_fb_flag;
1455 int boot_scsi_boardnumber = 3, boot_net_boardnumber = 3;
1456 char *turbochannel_default_gfx_card = "PMAG-BA";
1457 /* PMAG-AA, -BA, -CA/DA/EA/FA, -JA, -RO, PMAGB-BA */
1458
1459 /* HPCmips: */
1460 struct xx {
1461 struct btinfo_magic a;
1462 struct btinfo_bootpath b;
1463 struct btinfo_symtab c;
1464 } xx;
1465 struct hpc_bootinfo hpc_bootinfo;
1466 uint64_t hpcmips_fb_addr = 0;
1467 int hpcmips_fb_bits = 0, hpcmips_fb_encoding = 0;
1468 int hpcmips_fb_xsize = 0;
1469 int hpcmips_fb_ysize = 0;
1470 int hpcmips_fb_xsize_mem = 0;
1471 int hpcmips_fb_ysize_mem = 0;
1472
1473 /* ARCBIOS stuff: */
1474 uint64_t sgi_ram_offset = 0;
1475 int arc_wordlen = sizeof(uint32_t);
1476 char *eaddr_string = "eaddr=10:20:30:40:50:60"; /* nonsense */
1477 unsigned char macaddr[6];
1478
1479 /* Generic bootstring stuff: */
1480 int bootdev_type = 0;
1481 int bootdev_id;
1482 char *bootstr = NULL;
1483 char *bootarg = NULL;
1484 char *init_bootpath;
1485
1486 /* PCI stuff: */
1487 struct pci_data *pci_data;
1488
1489 /* Framebuffer stuff: */
1490 struct vfb_data *fb;
1491
1492 /* Abreviation: :-) */
1493 struct cpu *cpu = machine->cpus[machine->bootstrap_cpu];
1494
1495
1496 bootdev_id = diskimage_bootdev(machine, &bootdev_type);
1497
1498 mem = cpu->mem;
1499 machine->machine_name = NULL;
1500
1501 /* TODO: Move this somewhere else? */
1502 if (machine->boot_string_argument == NULL) {
1503 switch (machine->machine_type) {
1504 case MACHINE_ARC:
1505 machine->boot_string_argument = "-aN";
1506 break;
1507 case MACHINE_DEC:
1508 machine->boot_string_argument = "-a";
1509 break;
1510 default:
1511 /* Important, because boot_string_argument should
1512 not be set to NULL: */
1513 machine->boot_string_argument = "";
1514 }
1515 }
1516
1517 switch (machine->machine_type) {
1518
1519 case MACHINE_NONE:
1520 printf("\nNo emulation type specified.\n");
1521 exit(1);
1522
1523 #ifdef ENABLE_MIPS
1524 case MACHINE_BAREMIPS:
1525 /*
1526 * A "bare" MIPS test machine.
1527 *
1528 * NOTE: NO devices at all.
1529 */
1530 cpu->byte_order = EMUL_BIG_ENDIAN;
1531 machine->machine_name = "\"Bare\" MIPS machine";
1532 break;
1533
1534 case MACHINE_TESTMIPS:
1535 /*
1536 * A MIPS test machine (which happens to work with the
1537 * code in my master's thesis). :-)
1538 *
1539 * IRQ map:
1540 * 7 CPU counter
1541 * 6 SMP IPIs
1542 * 5 not used yet
1543 * 4 not used yet
1544 * 3 ethernet
1545 * 2 serial console
1546 */
1547 cpu->byte_order = EMUL_BIG_ENDIAN;
1548 machine->machine_name = "MIPS test machine";
1549
1550 snprintf(tmpstr, sizeof(tmpstr), "cons addr=0x%llx irq=2",
1551 (long long)DEV_CONS_ADDRESS);
1552 cons_data = device_add(machine, tmpstr);
1553 machine->main_console_handle = cons_data->console_handle;
1554
1555 snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%llx",
1556 (long long)DEV_MP_ADDRESS);
1557 device_add(machine, tmpstr);
1558
1559 fb = dev_fb_init(machine, mem, DEV_FB_ADDRESS, VFB_GENERIC,
1560 640,480, 640,480, 24, "testmips generic");
1561
1562 snprintf(tmpstr, sizeof(tmpstr), "disk addr=0x%llx",
1563 (long long)DEV_DISK_ADDRESS);
1564 device_add(machine, tmpstr);
1565
1566 snprintf(tmpstr, sizeof(tmpstr), "ether addr=0x%llx irq=3",
1567 (long long)DEV_ETHER_ADDRESS);
1568 device_add(machine, tmpstr);
1569
1570 break;
1571
1572 case MACHINE_DEC:
1573 cpu->byte_order = EMUL_LITTLE_ENDIAN;
1574
1575 /* An R2020 or R3220 memory thingy: */
1576 cpu->cd.mips.coproc[3] = mips_coproc_new(cpu, 3);
1577
1578 /* There aren't really any good standard values... */
1579 framebuffer_console_name = "osconsole=0,3";
1580 serial_console_name = "osconsole=1";
1581
1582 switch (machine->machine_subtype) {
1583 case MACHINE_DEC_PMAX_3100: /* type 1, KN01 */
1584 /* Supposed to have 12MHz or 16.67MHz R2000 CPU, R2010 FPC, R2020 Memory coprocessor */
1585 machine->machine_name = "DEC PMAX 3100 (KN01)";
1586
1587 /* 12 MHz for 2100, 16.67 MHz for 3100 */
1588 if (machine->emulated_hz == 0)
1589 machine->emulated_hz = 16670000;
1590
1591 if (machine->physical_ram_in_mb > 24)
1592 fprintf(stderr, "WARNING! Real DECstation 3100 machines cannot have more than 24MB RAM. Continuing anyway.\n");
1593
1594 if ((machine->physical_ram_in_mb % 4) != 0)
1595 fprintf(stderr, "WARNING! Real DECstation 3100 machines have an integer multiple of 4 MBs of RAM. Continuing anyway.\n");
1596
1597 color_fb_flag = 1; /* 1 for color, 0 for mono. TODO: command line option? */
1598
1599 /*
1600 * According to NetBSD/pmax:
1601 *
1602 * pm0 at ibus0 addr 0xfc00000: 1024x864x1 (or x8 for color)
1603 * dc0 at ibus0 addr 0x1c000000
1604 * le0 at ibus0 addr 0x18000000: address 00:00:00:00:00:00
1605 * sii0 at ibus0 addr 0x1a000000
1606 * mcclock0 at ibus0 addr 0x1d000000: mc146818 or compatible
1607 * 0x1e000000 = system status and control register
1608 */
1609 fb = dev_fb_init(machine, mem, KN01_PHYS_FBUF_START,
1610 color_fb_flag? VFB_DEC_VFB02 : VFB_DEC_VFB01,
1611 0,0,0,0,0, color_fb_flag? "VFB02":"VFB01");
1612 dev_colorplanemask_init(mem, KN01_PHYS_COLMASK_START, &fb->color_plane_mask);
1613 dev_vdac_init(mem, KN01_SYS_VDAC, fb->rgb_palette, color_fb_flag);
1614 dev_le_init(machine, mem, KN01_SYS_LANCE, KN01_SYS_LANCE_B_START, KN01_SYS_LANCE_B_END, KN01_INT_LANCE, 4*1048576);
1615 dev_sii_init(machine, mem, KN01_SYS_SII, KN01_SYS_SII_B_START, KN01_SYS_SII_B_END, KN01_INT_SII);
1616 dev_dc7085_init(machine, mem, KN01_SYS_DZ, KN01_INT_DZ, machine->use_x11);
1617 dev_mc146818_init(machine, mem, KN01_SYS_CLOCK, KN01_INT_CLOCK, MC146818_DEC, 1);
1618 dev_kn01_csr_init(mem, KN01_SYS_CSR, color_fb_flag);
1619
1620 framebuffer_console_name = "osconsole=0,3"; /* fb,keyb */
1621 serial_console_name = "osconsole=3"; /* 3 */
1622 break;
1623
1624 case MACHINE_DEC_3MAX_5000: /* type 2, KN02 */
1625 /* Supposed to have 25MHz R3000 CPU, R3010 FPC, */
1626 /* and a R3220 Memory coprocessor */
1627 machine->machine_name = "DECstation 5000/200 (3MAX, KN02)";
1628
1629 if (machine->emulated_hz == 0)
1630 machine->emulated_hz = 25000000;
1631
1632 if (machine->physical_ram_in_mb < 8)
1633 fprintf(stderr, "WARNING! Real KN02 machines do not have less than 8MB RAM. Continuing anyway.\n");
1634 if (machine->physical_ram_in_mb > 480)
1635 fprintf(stderr, "WARNING! Real KN02 machines cannot have more than 480MB RAM. Continuing anyway.\n");
1636
1637 /* An R3220 memory thingy: */
1638 cpu->cd.mips.coproc[3] = mips_coproc_new(cpu, 3);
1639
1640 /*
1641 * According to NetBSD/pmax:
1642 * asc0 at tc0 slot 5 offset 0x0
1643 * le0 at tc0 slot 6 offset 0x0
1644 * ibus0 at tc0 slot 7 offset 0x0
1645 * dc0 at ibus0 addr 0x1fe00000
1646 * mcclock0 at ibus0 addr 0x1fe80000: mc146818
1647 *
1648 * kn02 shared irq numbers (IP) are offset by +8
1649 * in the emulator
1650 */
1651
1652 /* KN02 interrupts: */
1653 machine->md_interrupt = kn02_interrupt;
1654
1655 /*
1656 * TURBOchannel slots 0, 1, and 2 are free for
1657 * option cards. Let's put in zero or more graphics
1658 * boards:
1659 *
1660 * TODO: It's also possible to have larger graphics
1661 * cards that occupy several slots. How to solve
1662 * this nicely?
1663 */
1664 dev_turbochannel_init(machine, mem, 0,
1665 KN02_PHYS_TC_0_START, KN02_PHYS_TC_0_END,
1666 machine->n_gfx_cards >= 1?
1667 turbochannel_default_gfx_card : "",
1668 KN02_IP_SLOT0 +8);
1669
1670 dev_turbochannel_init(machine, mem, 1,
1671 KN02_PHYS_TC_1_START, KN02_PHYS_TC_1_END,
1672 machine->n_gfx_cards >= 2?
1673 turbochannel_default_gfx_card : "",
1674 KN02_IP_SLOT1 +8);
1675
1676 dev_turbochannel_init(machine, mem, 2,
1677 KN02_PHYS_TC_2_START, KN02_PHYS_TC_2_END,
1678 machine->n_gfx_cards >= 3?
1679 turbochannel_default_gfx_card : "",
1680 KN02_IP_SLOT2 +8);
1681
1682 /* TURBOchannel slots 3 and 4 are reserved. */
1683
1684 /* TURBOchannel slot 5 is PMAZ-AA ("asc" SCSI). */
1685 dev_turbochannel_init(machine, mem, 5,
1686 KN02_PHYS_TC_5_START, KN02_PHYS_TC_5_END,
1687 "PMAZ-AA", KN02_IP_SCSI +8);
1688
1689 /* TURBOchannel slot 6 is PMAD-AA ("le" ethernet). */
1690 dev_turbochannel_init(machine, mem, 6,
1691 KN02_PHYS_TC_6_START, KN02_PHYS_TC_6_END,
1692 "PMAD-AA", KN02_IP_LANCE +8);
1693
1694 /* TURBOchannel slot 7 is system stuff. */
1695 machine->main_console_handle =
1696 dev_dc7085_init(machine, mem,
1697 KN02_SYS_DZ, KN02_IP_DZ +8, machine->use_x11);
1698 dev_mc146818_init(machine, mem,
1699 KN02_SYS_CLOCK, KN02_INT_CLOCK, MC146818_DEC, 1);
1700
1701 machine->md_int.kn02_csr =
1702 dev_kn02_init(cpu, mem, KN02_SYS_CSR);
1703
1704 framebuffer_console_name = "osconsole=0,7";
1705 /* fb,keyb */
1706 serial_console_name = "osconsole=2";
1707 boot_scsi_boardnumber = 5;
1708 boot_net_boardnumber = 6; /* TODO: 3? */
1709 break;
1710
1711 case MACHINE_DEC_3MIN_5000: /* type 3, KN02BA */
1712 machine->machine_name = "DECstation 5000/112 or 145 (3MIN, KN02BA)";
1713 if (machine->emulated_hz == 0)
1714 machine->emulated_hz = 33000000;
1715 if (machine->physical_ram_in_mb > 128)
1716 fprintf(stderr, "WARNING! Real 3MIN machines cannot have more than 128MB RAM. Continuing anyway.\n");
1717
1718 /* KMIN interrupts: */
1719 machine->md_interrupt = kmin_interrupt;
1720
1721 /*
1722 * tc0 at mainbus0: 12.5 MHz clock (0x10000000, slotsize = 64MB)
1723 * tc slot 1: 0x14000000
1724 * tc slot 2: 0x18000000
1725 * ioasic0 at tc0 slot 3 offset 0x0 (0x1c000000) slot 0
1726 * asic regs (0x1c040000) slot 1
1727 * station's ether address (0x1c080000) slot 2
1728 * le0 at ioasic0 offset 0xc0000: address 00:00:00:00:00:00 (0x1c0c0000) slot 3
1729 * scc0 at ioasic0 offset 0x100000 (0x1c100000) slot 4
1730 * scc1 at ioasic0 offset 0x180000: console (0x1c180000) slot 6
1731 * mcclock0 at ioasic0 offset 0x200000: mc146818 or compatible (0x1c200000) slot 8
1732 * asc0 at ioasic0 offset 0x300000: NCR53C94, 25MHz, SCSI ID 7 (0x1c300000) slot 12
1733 * dma for asc0 (0x1c380000) slot 14
1734 */
1735 machine->md_int.dec_ioasic_data = dev_dec_ioasic_init(cpu, mem, 0x1c000000, 0);
1736 dev_le_init(machine, mem, 0x1c0c0000, 0, 0, KMIN_INTR_LANCE +8, 4*65536);
1737 dev_scc_init(machine, mem, 0x1c100000, KMIN_INTR_SCC_0 +8, machine->use_x11, 0, 1);
1738 dev_scc_init(machine, mem, 0x1c180000, KMIN_INTR_SCC_1 +8, machine->use_x11, 1, 1);
1739 dev_mc146818_init(machine, mem, 0x1c200000, KMIN_INTR_CLOCK +8, MC146818_DEC, 1);
1740 dev_asc_init(machine, mem, 0x1c300000, KMIN_INTR_SCSI +8,
1741 NULL, DEV_ASC_DEC, NULL, NULL);
1742
1743 /*
1744 * TURBOchannel slots 0, 1, and 2 are free for
1745 * option cards. These are by default filled with
1746 * zero or more graphics boards.
1747 *
1748 * TODO: irqs
1749 */
1750 dev_turbochannel_init(machine, mem, 0,
1751 0x10000000, 0x103fffff,
1752 machine->n_gfx_cards >= 1?
1753 turbochannel_default_gfx_card : "",
1754 KMIN_INT_TC0);
1755
1756 dev_turbochannel_init(machine, mem, 1,
1757 0x14000000, 0x143fffff,
1758 machine->n_gfx_cards >= 2?
1759 turbochannel_default_gfx_card : "",
1760 KMIN_INT_TC1);
1761
1762 dev_turbochannel_init(machine, mem, 2,
1763 0x18000000, 0x183fffff,
1764 machine->n_gfx_cards >= 3?
1765 turbochannel_default_gfx_card : "",
1766 KMIN_INT_TC2);
1767
1768 /* (kmin shared irq numbers (IP) are offset by +8 in the emulator) */
1769 /* kmin_csr = dev_kmin_init(cpu, mem, KMIN_REG_INTR); */
1770
1771 framebuffer_console_name = "osconsole=0,3"; /* fb, keyb (?) */
1772 serial_console_name = "osconsole=3"; /* ? */
1773 break;
1774
1775 case MACHINE_DEC_3MAXPLUS_5000: /* type 4, KN03 */
1776 machine->machine_name = "DECsystem 5900 or 5000 (3MAX+) (KN03)";
1777
1778 /* 5000/240 (KN03-GA, R3000): 40 MHz */
1779 /* 5000/260 (KN05-NB, R4000): 60 MHz */
1780 /* TODO: are both these type 4? */
1781 if (machine->emulated_hz == 0)
1782 machine->emulated_hz = 40000000;
1783 if (machine->physical_ram_in_mb > 480)
1784 fprintf(stderr, "WARNING! Real KN03 machines cannot have more than 480MB RAM. Continuing anyway.\n");
1785
1786 /* KN03 interrupts: */
1787 machine->md_interrupt = kn03_interrupt;
1788
1789 /*
1790 * tc0 at mainbus0: 25 MHz clock (slot 0) (0x1e000000)
1791 * tc0 slot 1 (0x1e800000)
1792 * tc0 slot 2 (0x1f000000)
1793 * ioasic0 at tc0 slot 3 offset 0x0 (0x1f800000)
1794 * something that has to do with interrupts? (?) (0x1f840000 ?)
1795 * le0 at ioasic0 offset 0xc0000 (0x1f8c0000)
1796 * scc0 at ioasic0 offset 0x100000 (0x1f900000)
1797 * scc1 at ioasic0 offset 0x180000: console (0x1f980000)
1798 * mcclock0 at ioasic0 offset 0x200000: mc146818 or compatible (0x1fa00000)
1799 * asc0 at ioasic0 offset 0x300000: NCR53C94, 25MHz, SCSI ID 7 (0x1fb00000)
1800 */
1801 machine->md_int.dec_ioasic_data = dev_dec_ioasic_init(cpu, mem, 0x1f800000, 0);
1802
1803 dev_le_init(machine, mem, KN03_SYS_LANCE, 0, 0, KN03_INTR_LANCE +8, 4*65536);
1804
1805 machine->md_int.dec_ioasic_data->dma_func[3] = dev_scc_dma_func;
1806 machine->md_int.dec_ioasic_data->dma_func_extra[2] = dev_scc_init(machine, mem, KN03_SYS_SCC_0, KN03_INTR_SCC_0 +8, machine->use_x11, 0, 1);
1807 machine->md_int.dec_ioasic_data->dma_func[2] = dev_scc_dma_func;
1808 machine->md_int.dec_ioasic_data->dma_func_extra[3] = dev_scc_init(machine, mem, KN03_SYS_SCC_1, KN03_INTR_SCC_1 +8, machine->use_x11, 1, 1);
1809
1810 dev_mc146818_init(machine, mem, KN03_SYS_CLOCK, KN03_INT_RTC, MC146818_DEC, 1);
1811 dev_asc_init(machine, mem, KN03_SYS_SCSI,
1812 KN03_INTR_SCSI +8, NULL, DEV_ASC_DEC, NULL, NULL);
1813
1814 /*
1815 * TURBOchannel slots 0, 1, and 2 are free for
1816 * option cards. These are by default filled with
1817 * zero or more graphics boards.
1818 *
1819 * TODO: irqs
1820 */
1821 dev_turbochannel_init(machine, mem, 0,
1822 KN03_PHYS_TC_0_START, KN03_PHYS_TC_0_END,
1823 machine->n_gfx_cards >= 1?
1824 turbochannel_default_gfx_card : "",
1825 KN03_INTR_TC_0 +8);
1826
1827 dev_turbochannel_init(machine, mem, 1,
1828 KN03_PHYS_TC_1_START, KN03_PHYS_TC_1_END,
1829 machine->n_gfx_cards >= 2?
1830 turbochannel_default_gfx_card : "",
1831 KN03_INTR_TC_1 +8);
1832
1833 dev_turbochannel_init(machine, mem, 2,
1834 KN03_PHYS_TC_2_START, KN03_PHYS_TC_2_END,
1835 machine->n_gfx_cards >= 3?
1836 turbochannel_default_gfx_card : "",
1837 KN03_INTR_TC_2 +8);
1838
1839 /* TODO: interrupts */
1840 /* shared (turbochannel) interrupts are +8 */
1841
1842 framebuffer_console_name = "osconsole=0,3"; /* fb, keyb (?) */
1843 serial_console_name = "osconsole=3"; /* ? */
1844 break;
1845
1846 case MACHINE_DEC_5800: /* type 5, KN5800 */
1847 machine->machine_name = "DECsystem 5800";
1848
1849 /* TODO: this is incorrect, banks multiply by 8 etc */
1850 if (machine->physical_ram_in_mb < 48)
1851 fprintf(stderr, "WARNING! 5800 will probably not run with less than 48MB RAM. Continuing anyway.\n");
1852
1853 /*
1854 * According to http://www2.no.netbsd.org/Ports/pmax/models.html,
1855 * the 5800-series is based on VAX 6000/300.
1856 */
1857
1858 /*
1859 * Ultrix might support SMP on this machine type.
1860 *
1861 * Something at 0x10000000.
1862 * ssc serial console at 0x10140000, interrupt 2 (shared with XMI?).
1863 * xmi 0 at address 0x11800000 (node x at offset x*0x80000)
1864 * Clock uses interrupt 3 (shared with XMI?).
1865 */
1866
1867 machine->md_int.dec5800_csr = dev_dec5800_init(machine, mem, 0x10000000);
1868 dev_decbi_init(mem, 0x10000000);
1869 dev_ssc_init(machine, mem, 0x10140000, 2, machine->use_x11, &machine->md_int.dec5800_csr->csr);
1870 dev_decxmi_init(mem, 0x11800000);
1871 dev_deccca_init(mem, DEC_DECCCA_BASEADDR);
1872
1873 break;
1874
1875 case MACHINE_DEC_5400: /* type 6, KN210 */
1876 machine->machine_name = "DECsystem 5400 (KN210)";
1877 /*
1878 * Misc. info from the KN210 manual:
1879 *
1880 * Interrupt lines:
1881 * irq5 fpu
1882 * irq4 halt
1883 * irq3 pwrfl -> mer1 -> mer0 -> wear
1884 * irq2 100 Hz -> birq7
1885 * irq1 dssi -> ni -> birq6
1886 * irq0 birq5 -> console -> timers -> birq4
1887 *
1888 * Interrupt status register at 0x10048000.
1889 * Main memory error status register at 0x1008140.
1890 * Interval Timer Register (ITR) at 0x10084010.
1891 * Q22 stuff at 0x10088000 - 0x1008ffff.
1892 * TODR at 0x1014006c.
1893 * TCR0 (timer control register 0) 0x10140100.
1894 * TIR0 (timer interval register 0) 0x10140104.
1895 * TCR1 (timer control register 1) 0x10140110.
1896 * TIR1 (timer interval register 1) 0x10140114.
1897 * VRR0 (Vector Read Register 0) at 0x16000050.
1898 * VRR1 (Vector Read Register 1) at 0x16000054.
1899 * VRR2 (Vector Read Register 2) at 0x16000058.
1900 * VRR3 (Vector Read Register 3) at 0x1600005c.
1901 */
1902 /* ln (ethernet) at 0x10084x00 ? and 0x10120000 ? */
1903 /* error registers (?) at 0x17000000 and 0x10080000 */
1904 device_add(machine, "kn210 addr=0x10080000");
1905 dev_ssc_init(machine, mem, 0x10140000, 0, machine->use_x11, NULL); /* TODO: not irq 0 */
1906 break;
1907
1908 case MACHINE_DEC_MAXINE_5000: /* type 7, KN02CA */
1909 machine->machine_name = "Personal DECstation 5000/xxx (MAXINE) (KN02CA)";
1910 if (machine->emulated_hz == 0)
1911 machine->emulated_hz = 33000000;
1912
1913 if (machine->physical_ram_in_mb < 8)
1914 fprintf(stderr, "WARNING! Real KN02CA machines do not have less than 8MB RAM. Continuing anyway.\n");
1915 if (machine->physical_ram_in_mb > 40)
1916 fprintf(stderr, "WARNING! Real KN02CA machines cannot have more than 40MB RAM. Continuing anyway.\n");
1917
1918 /* Maxine interrupts: */
1919 machine->md_interrupt = maxine_interrupt;
1920
1921 /*
1922 * Something at address 0xca00000. (?)
1923 * Something at address 0xe000000. (?)
1924 * tc0 slot 0 (0x10000000)
1925 * tc0 slot 1 (0x14000000)
1926 * (tc0 slot 2 used by the framebuffer)
1927 * ioasic0 at tc0 slot 3 offset 0x0 (0x1c000000)
1928 * le0 at ioasic0 offset 0xc0000: address 00:00:00:00:00:00 (0x1c0c0000)
1929 * scc0 at ioasic0 offset 0x100000: console <-- serial (0x1c100000)
1930 * mcclock0 at ioasic0 offset 0x200000: mc146818 (0x1c200000)
1931 * isdn at ioasic0 offset 0x240000 not configured (0x1c240000)
1932 * bba0 at ioasic0 offset 0x240000 (audio0 at bba0) <--- which one of isdn and bba0?
1933 * dtop0 at ioasic0 offset 0x280000 (0x1c280000)
1934 * fdc at ioasic0 offset 0x2c0000 not configured <-- floppy (0x1c2c0000)
1935 * asc0 at ioasic0 offset 0x300000: NCR53C94, 25MHz, SCSI ID 7 (0x1c300000)
1936 * xcfb0 at tc0 slot 2 offset 0x0: 1024x768x8 built-in framebuffer (0xa000000)
1937 */
1938 machine->md_int.dec_ioasic_data = dev_dec_ioasic_init(cpu, mem, 0x1c000000, 0);
1939
1940 /* TURBOchannel slots (0 and 1): */
1941 dev_turbochannel_init(machine, mem, 0,
1942 0x10000000, 0x103fffff,
1943 machine->n_gfx_cards >= 2?
1944 turbochannel_default_gfx_card : "",
1945 XINE_INTR_TC_0 +8);
1946 dev_turbochannel_init(machine, mem, 1,
1947 0x14000000, 0x143fffff,
1948 machine->n_gfx_cards >= 3?
1949 turbochannel_default_gfx_card : "",
1950 XINE_INTR_TC_1 +8);
1951
1952 /*
1953 * TURBOchannel slot 2 is hardwired to be used by
1954 * the framebuffer: (NOTE: 0x8000000, not 0x18000000)
1955 */
1956 dev_turbochannel_init(machine, mem, 2,
1957 0x8000000, 0xbffffff, "PMAG-DV", 0);
1958
1959 /*
1960 * TURBOchannel slot 3: fixed, ioasic
1961 * (the system stuff), 0x1c000000
1962 */
1963 dev_le_init(machine, mem, 0x1c0c0000, 0, 0, XINE_INTR_LANCE +8, 4*65536);
1964 dev_scc_init(machine, mem, 0x1c100000,
1965 XINE_INTR_SCC_0 +8, machine->use_x11, 0, 1);
1966 dev_mc146818_init(machine, mem, 0x1c200000,
1967 XINE_INT_TOY, MC146818_DEC, 1);
1968 dev_asc_init(machine, mem, 0x1c300000,
1969 XINE_INTR_SCSI +8, NULL, DEV_ASC_DEC, NULL, NULL);
1970
1971 framebuffer_console_name = "osconsole=3,2"; /* keyb,fb ?? */
1972 serial_console_name = "osconsole=3";
1973 break;
1974
1975 case MACHINE_DEC_5500: /* type 11, KN220 */
1976 machine->machine_name = "DECsystem 5500 (KN220)";
1977
1978 /*
1979 * According to NetBSD's pmax ports page:
1980 * KN220-AA is a "30 MHz R3000 CPU with R3010 FPU"
1981 * with "512 kBytes of Prestoserve battery backed RAM."
1982 */
1983 if (machine->emulated_hz == 0)
1984 machine->emulated_hz = 30000000;
1985
1986 /*
1987 * See KN220 docs for more info.
1988 *
1989 * something at 0x10000000
1990 * something at 0x10001000
1991 * something at 0x10040000
1992 * scc at 0x10140000
1993 * qbus at (or around) 0x10080000
1994 * dssi (disk controller) buffers at 0x10100000, registers at 0x10160000.
1995 * sgec (ethernet) registers at 0x10008000, station addresss at 0x10120000.
1996 * asc (scsi) at 0x17100000.
1997 */
1998
1999 dev_ssc_init(machine, mem, 0x10140000, 0, machine->use_x11, NULL); /* TODO: not irq 0 */
2000
2001 /* something at 0x17000000, ultrix says "cpu 0 panic: DS5500 I/O Board is missing" if this is not here */
2002 dev_dec5500_ioboard_init(cpu, mem, 0x17000000);
2003
2004 dev_sgec_init(mem, 0x10008000, 0); /* irq? */
2005
2006 /* The asc controller might be TURBOchannel-ish? */
2007 #if 0
2008 dev_turbochannel_init(machine, mem, 0, 0x17100000, 0x171fffff, "PMAZ-AA", 0); /* irq? */
2009 #else
2010 dev_asc_init(machine, mem, 0x17100000, 0, NULL, DEV_ASC_DEC, NULL, NULL); /* irq? */
2011 #endif
2012
2013 framebuffer_console_name = "osconsole=0,0"; /* TODO (?) */
2014 serial_console_name = "osconsole=0";
2015 break;
2016
2017 case MACHINE_DEC_MIPSMATE_5100: /* type 12 */
2018 machine->machine_name = "DEC MIPSMATE 5100 (KN230)";
2019 if (machine->emulated_hz == 0)
2020 machine->emulated_hz = 20000000;
2021 if (machine->physical_ram_in_mb > 128)
2022 fprintf(stderr, "WARNING! Real MIPSMATE 5100 machines cannot have more than 128MB RAM. Continuing anyway.\n");
2023
2024 if (machine->use_x11)
2025 fprintf(stderr, "WARNING! Real MIPSMATE 5100 machines cannot have a graphical framebuffer. Continuing anyway.\n");
2026
2027 /* KN230 interrupts: */
2028 machine->md_interrupt = kn230_interrupt;
2029
2030 /*
2031 * According to NetBSD/pmax:
2032 * dc0 at ibus0 addr 0x1c000000
2033 * le0 at ibus0 addr 0x18000000: address 00:00:00:00:00:00
2034 * sii0 at ibus0 addr 0x1a000000
2035 */
2036 dev_mc146818_init(machine, mem, KN230_SYS_CLOCK, 4, MC146818_DEC, 1);
2037 dev_dc7085_init(machine, mem, KN230_SYS_DZ0, KN230_CSR_INTR_DZ0, machine->use_x11); /* NOTE: CSR_INTR */
2038 /* dev_dc7085_init(machine, mem, KN230_SYS_DZ1, KN230_CSR_INTR_OPT0, machine->use_x11); */ /* NOTE: CSR_INTR */
2039 /* dev_dc7085_init(machine, mem, KN230_SYS_DZ2, KN230_CSR_INTR_OPT1, machine->use_x11); */ /* NOTE: CSR_INTR */
2040 dev_le_init(machine, mem, KN230_SYS_LANCE, KN230_SYS_LANCE_B_START, KN230_SYS_LANCE_B_END, KN230_CSR_INTR_LANCE, 4*1048576);
2041 dev_sii_init(machine, mem, KN230_SYS_SII, KN230_SYS_SII_B_START, KN230_SYS_SII_B_END, KN230_CSR_INTR_SII);
2042
2043 snprintf(tmpstr, sizeof(tmpstr),
2044 "kn230 addr=0x%llx", (long long)KN230_SYS_ICSR);
2045 machine->md_int.kn230_csr = device_add(machine, tmpstr);
2046
2047 serial_console_name = "osconsole=0";
2048 break;
2049
2050 default:
2051 ;
2052 }
2053
2054 /*
2055 * Most OSes on DECstation use physical addresses below
2056 * 0x20000000, but OSF/1 seems to use 0xbe...... as if it was
2057 * 0x1e......, so we need this hack:
2058 */
2059 dev_ram_init(mem, 0xa0000000, 0x20000000, DEV_RAM_MIRROR, 0x0);
2060
2061 /* DECstation PROM stuff: (TODO: endianness) */
2062 for (i=0; i<100; i++)
2063 store_32bit_word(cpu, DEC_PROM_CALLBACK_STRUCT + i*4,
2064 DEC_PROM_EMULATION + i*8);
2065
2066 /* Fill PROM with dummy return instructions: (TODO: make this nicer) */
2067 for (i=0; i<100; i++) {
2068 store_32bit_word(cpu, DEC_PROM_EMULATION + i*8,
2069 0x03e00008); /* return */
2070 store_32bit_word(cpu, DEC_PROM_EMULATION + i*8 + 4,
2071 0x00000000); /* nop */
2072 }
2073
2074 /*
2075 * According to dec_prom.h from NetBSD:
2076 *
2077 * "Programs loaded by the new PROMs pass the following arguments:
2078 * a0 argc
2079 * a1 argv
2080 * a2 DEC_PROM_MAGIC
2081 * a3 The callback vector defined below"
2082 *
2083 * So we try to emulate a PROM, even though no such thing has been
2084 * loaded.
2085 */
2086
2087 cpu->cd.mips.gpr[MIPS_GPR_A0] = 3;
2088 cpu->cd.mips.gpr[MIPS_GPR_A1] = DEC_PROM_INITIAL_ARGV;
2089 cpu->cd.mips.gpr[MIPS_GPR_A2] = DEC_PROM_MAGIC;
2090 cpu->cd.mips.gpr[MIPS_GPR_A3] = DEC_PROM_CALLBACK_STRUCT;
2091
2092 store_32bit_word(cpu, INITIAL_STACK_POINTER + 0x10,
2093 BOOTINFO_MAGIC);
2094 store_32bit_word(cpu, INITIAL_STACK_POINTER + 0x14,
2095 BOOTINFO_ADDR);
2096
2097 store_32bit_word(cpu, DEC_PROM_INITIAL_ARGV,
2098 (DEC_PROM_INITIAL_ARGV + 0x10));
2099 store_32bit_word(cpu, DEC_PROM_INITIAL_ARGV+4,
2100 (DEC_PROM_INITIAL_ARGV + 0x70));
2101 store_32bit_word(cpu, DEC_PROM_INITIAL_ARGV+8,
2102 (DEC_PROM_INITIAL_ARGV + 0xe0));
2103 store_32bit_word(cpu, DEC_PROM_INITIAL_ARGV+12, 0);
2104
2105 /*
2106 * NetBSD and Ultrix expect the boot args to be like this:
2107 *
2108 * "boot" "bootdev" [args?]
2109 *
2110 * where bootdev is supposed to be "rz(0,0,0)netbsd" for
2111 * 3100/2100 (although that crashes Ultrix :-/), and
2112 * "5/rz0a/netbsd" for all others. The number '5' is the
2113 * slot number of the boot device.
2114 *
2115 * 'rz' for disks, 'tz' for tapes.
2116 *
2117 * TODO: Make this nicer.
2118 */
2119 {
2120 char bootpath[200];
2121
2122 #if 0
2123 if (machine->machine_subtype == MACHINE_DEC_PMAX_3100)
2124 strlcpy(bootpath, "rz(0,0,0)", sizeof(bootpath));
2125 else
2126 #endif
2127 strlcpy(bootpath, "5/rz1/", sizeof(bootpath));
2128
2129 if (bootdev_id < 0 || machine->force_netboot) {
2130 /* tftp boot: */
2131 strlcpy(bootpath, "5/tftp/", sizeof(bootpath));
2132 bootpath[0] = '0' + boot_net_boardnumber;
2133 } else {
2134 /* disk boot: */
2135 bootpath[0] = '0' + boot_scsi_boardnumber;
2136 if (diskimage_is_a_tape(machine, bootdev_id,
2137 bootdev_type))
2138 bootpath[2] = 't';
2139 bootpath[4] = '0' + bootdev_id;
2140 }
2141
2142 init_bootpath = bootpath;
2143 }
2144
2145 bootarg = malloc(BOOTARG_BUFLEN);
2146 if (bootarg == NULL) {
2147 fprintf(stderr, "out of memory\n");
2148 exit(1);
2149 }
2150 strlcpy(bootarg, init_bootpath, BOOTARG_BUFLEN);
2151 if (strlcat(bootarg, machine->boot_kernel_filename,
2152 BOOTARG_BUFLEN) > BOOTARG_BUFLEN) {
2153 fprintf(stderr, "bootarg truncated?\n");
2154 exit(1);
2155 }
2156
2157 bootstr = "boot";
2158
2159 store_string(cpu, DEC_PROM_INITIAL_ARGV+0x10, bootstr);
2160 store_string(cpu, DEC_PROM_INITIAL_ARGV+0x70, bootarg);
2161 store_string(cpu, DEC_PROM_INITIAL_ARGV+0xe0,
2162 machine->boot_string_argument);
2163
2164 /* Decrease the nr of args, if there are no args :-) */
2165 if (machine->boot_string_argument == NULL ||
2166 machine->boot_string_argument[0] == '\0')
2167 cpu->cd.mips.gpr[MIPS_GPR_A0] --;
2168
2169 if (machine->boot_string_argument[0] != '\0') {
2170 strlcat(bootarg, " ", BOOTARG_BUFLEN);
2171 if (strlcat(bootarg, machine->boot_string_argument,
2172 BOOTARG_BUFLEN) >= BOOTARG_BUFLEN) {
2173 fprintf(stderr, "bootstr truncated?\n");
2174 exit(1);
2175 }
2176 }
2177
2178 xx.a.common.next = (char *)&xx.b - (char *)&xx;
2179 xx.a.common.type = BTINFO_MAGIC;
2180 xx.a.magic = BOOTINFO_MAGIC;
2181
2182 xx.b.common.next = (char *)&xx.c - (char *)&xx.b;
2183 xx.b.common.type = BTINFO_BOOTPATH;
2184 strlcpy(xx.b.bootpath, bootstr, sizeof(xx.b.bootpath));
2185
2186 xx.c.common.next = 0;
2187 xx.c.common.type = BTINFO_SYMTAB;
2188 xx.c.nsym = 0;
2189 xx.c.ssym = 0;
2190 xx.c.esym = machine->file_loaded_end_addr;
2191
2192 store_buf(cpu, BOOTINFO_ADDR, (char *)&xx, sizeof(xx));
2193
2194 /*
2195 * The system's memmap: (memmap is a global variable, in
2196 * dec_prom.h)
2197 */
2198 store_32bit_word_in_host(cpu,
2199 (unsigned char *)&memmap.pagesize, 4096);
2200 {
2201 unsigned int i;
2202 for (i=0; i<sizeof(memmap.bitmap); i++)
2203 memmap.bitmap[i] = ((int)i * 4096*8 <
2204 1048576*machine->physical_ram_in_mb)?
2205 0xff : 0x00;
2206 }
2207 store_buf(cpu, DEC_MEMMAP_ADDR, (char *)&memmap, sizeof(memmap));
2208
2209 /* Environment variables: */
2210 addr = DEC_PROM_STRINGS;
2211
2212 if (machine->use_x11 && machine->n_gfx_cards > 0)
2213 /* (0,3) Keyboard and Framebuffer */
2214 add_environment_string(cpu, framebuffer_console_name, &addr);
2215 else
2216 /* Serial console */
2217 add_environment_string(cpu, serial_console_name, &addr);
2218
2219 /*
2220 * The KN5800 (SMP system) uses a CCA (console communications
2221 * area): (See VAX 6000 documentation for details.)
2222 */
2223 {
2224 char tmps[300];
2225 snprintf(tmps, sizeof(tmps), "cca=%x",
2226 (int)(DEC_DECCCA_BASEADDR + 0xa0000000ULL));
2227 add_environment_string(cpu, tmps, &addr);
2228 }
2229
2230 /* These are needed for Sprite to boot: */
2231 {
2232 char tmps[500];
2233
2234 snprintf(tmps, sizeof(tmps), "boot=%s", bootarg);
2235 tmps[sizeof(tmps)-1] = '\0';
2236 add_environment_string(cpu, tmps, &addr);
2237
2238 snprintf(tmps, sizeof(tmps), "bitmap=0x%x", (uint32_t)((
2239 DEC_MEMMAP_ADDR + sizeof(memmap.pagesize))
2240 & 0xffffffffULL));
2241 tmps[sizeof(tmps)-1] = '\0';
2242 add_environment_string(cpu, tmps, &addr);
2243
2244 snprintf(tmps, sizeof(tmps), "bitmaplen=0x%x",
2245 machine->physical_ram_in_mb * 1048576 / 4096 / 8);
2246 tmps[sizeof(tmps)-1] = '\0';
2247 add_environment_string(cpu, tmps, &addr);
2248 }
2249
2250 add_environment_string(cpu, "scsiid0=7", &addr);
2251 add_environment_string(cpu, "bootmode=a", &addr);
2252 add_environment_string(cpu, "testaction=q", &addr);
2253 add_environment_string(cpu, "haltaction=h", &addr);
2254 add_environment_string(cpu, "more=24", &addr);
2255
2256 /* Used in at least Ultrix on the 5100: */
2257 add_environment_string(cpu, "scsiid=7", &addr);
2258 add_environment_string(cpu, "baud0=9600", &addr);
2259 add_environment_string(cpu, "baud1=9600", &addr);
2260 add_environment_string(cpu, "baud2=9600", &addr);
2261 add_environment_string(cpu, "baud3=9600", &addr);
2262 add_environment_string(cpu, "iooption=0x1", &addr);
2263
2264 /* The end: */
2265 add_environment_string(cpu, "", &addr);
2266
2267 break;
2268
2269 case MACHINE_COBALT:
2270 cpu->byte_order = EMUL_LITTLE_ENDIAN;
2271 machine->machine_name = "Cobalt";
2272
2273 /*
2274 * Interrupts seem to be the following:
2275 * (according to http://www.funet.fi/pub/Linux/PEOPLE/Linus/v2.4/patch-html/patch-2.4.19/linux-2.4.19_arch_mips_cobalt_irq.c.html)
2276 *
2277 * 2 Galileo chip (timer)
2278 * 3 Tulip 0 + NCR SCSI
2279 * 4 Tulip 1
2280 * 5 16550 UART (serial console)
2281 * 6 VIA southbridge PIC
2282 * 7 PCI (Note: Not used. The PCI controller
2283 * interrupts at ISA interrupt 9.)
2284 */
2285
2286 /* ISA interrupt controllers: */
2287 snprintf(tmpstr, sizeof(tmpstr), "8259 irq=24 addr=0x10000020");
2288 machine->md_int.isa_pic_data.pic1 = device_add(machine, tmpstr);
2289 snprintf(tmpstr, sizeof(tmpstr), "8259 irq=24 addr=0x100000a0");
2290 machine->md_int.isa_pic_data.pic2 = device_add(machine, tmpstr);
2291 machine->md_interrupt = cobalt_interrupt;
2292
2293 dev_mc146818_init(machine, mem, 0x10000070, 0, MC146818_PC_CMOS, 4);
2294
2295 machine->main_console_handle = (size_t)
2296 device_add(machine, "ns16550 irq=5 addr=0x1c800000 name2=tty0 in_use=1");
2297
2298 #if 0
2299 device_add(machine, "ns16550 irq=0 addr=0x1f000010 name2=tty1 in_use=0");
2300 #endif
2301
2302 /*
2303 * According to NetBSD/cobalt:
2304 *
2305 * pchb0 at pci0 dev 0 function 0: Galileo GT-64111 System Controller, rev 1 (NOTE: added by dev_gt_init())
2306 * tlp0 at pci0 dev 7 function 0: DECchip 21143 Ethernet, pass 4.1
2307 * Symbios Logic 53c860 (SCSI mass storage, revision 0x02) at pci0 dev 8
2308 * pcib0 at pci0 dev 9 function 0, VIA Technologies VT82C586 (Apollo VP) PCI-ISA Bridge, rev 37
2309 * pciide0 at pci0 dev 9 function 1: VIA Technologies VT82C586 (Apollo VP) ATA33 cr
2310 * tlp1 at pci0 dev 12 function 0: DECchip 21143 Ethernet, pass 4.1
2311 *
2312 * The PCI controller interrupts at ISA interrupt 9.
2313 */
2314 pci_data = dev_gt_init(machine, mem, 0x14000000, 2, 8 + 9, 11);
2315 /* bus_pci_add(machine, pci_data, mem, 0, 7, 0, pci_dec21143_init, pci_dec21143_rr); */
2316 bus_pci_add(machine, pci_data, mem, 0, 8, 0, NULL, NULL); /* PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_860 */
2317 bus_pci_add(machine, pci_data, mem, 0, 9, 0, pci_vt82c586_isa_init, pci_vt82c586_isa_rr);
2318 bus_pci_add(machine, pci_data, mem, 0, 9, 1, pci_vt82c586_ide_init, pci_vt82c586_ide_rr);
2319 /* bus_pci_add(machine, pci_data, mem, 0, 12, 0, pci_dec21143_init, pci_dec21143_rr); */
2320
2321 /*
2322 * NetBSD/cobalt expects memsize in a0, but it seems that what
2323 * it really wants is the end of memory + 0x80000000.
2324 *
2325 * The bootstring is stored 512 bytes before the end of
2326 * physical ram.
2327 */
2328 cpu->cd.mips.gpr[MIPS_GPR_A0] =
2329 machine->physical_ram_in_mb * 1048576 + 0xffffffff80000000ULL;
2330 bootstr = "root=/dev/hda1 ro";
2331 /* bootstr = "nfsroot=/usr/cobalt/"; */
2332 /* TODO: bootarg, and/or automagic boot device detection */
2333 store_string(cpu, cpu->cd.mips.gpr[MIPS_GPR_A0] - 512, bootstr);
2334 break;
2335
2336 case MACHINE_HPCMIPS:
2337 cpu->byte_order = EMUL_LITTLE_ENDIAN;
2338 memset(&hpc_bootinfo, 0, sizeof(hpc_bootinfo));
2339 /* TODO: set platid from netbsd/usr/src/sys/arch/hpc/include/platid* */
2340 /*
2341 #define PLATID_FLAGS_SHIFT 0
2342 #define PLATID_CPU_SUBMODEL_SHIFT 8
2343 #define PLATID_CPU_MODEL_SHIFT 14
2344 #define PLATID_CPU_SERIES_SHIFT 20
2345 #define PLATID_CPU_ARCH_SHIFT 26
2346
2347 #define PLATID_SUBMODEL_SHIFT 0
2348 #define PLATID_MODEL_SHIFT 8
2349 #define PLATID_SERIES_SHIFT 16
2350 #define PLATID_VENDOR_SHIFT 22
2351 */
2352
2353 /*
2354 NOTE: See http://forums.projectmayo.com/viewtopic.php?topic=2743&forum=23
2355 for info on framebuffer addresses.
2356 */
2357
2358 switch (machine->machine_subtype) {
2359 case MACHINE_HPCMIPS_CASIO_BE300:
2360 /* 166MHz VR4131 */
2361 machine->machine_name = "Casio Cassiopeia BE-300";
2362 hpcmips_fb_addr = 0x0a200000;
2363 hpcmips_fb_xsize = 240;
2364 hpcmips_fb_ysize = 320;
2365 hpcmips_fb_xsize_mem = 256;
2366 hpcmips_fb_ysize_mem = 320;
2367 hpcmips_fb_bits = 15;
2368 hpcmips_fb_encoding = BIFB_D16_0000;
2369
2370 /* TODO: irq? */
2371 snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=0 addr=0x0a008680 addr_mult=4 in_use=%i", machine->use_x11? 0 : 1);
2372 machine->main_console_handle = (size_t)device_add(machine, tmpstr);
2373
2374 machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4131);
2375 machine->md_interrupt = vr41xx_interrupt;
2376
2377 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_cpu,
2378 (1 << 26) /* 1 = MIPS */
2379 + (1 << 20) /* 1 = VR */
2380 + (1 << 14) /* 1 = VR41XX */
2381 + (6 << 8) /* 6 = VR4131 */
2382 );
2383 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_machine,
2384 (3 << 22) /* 22: vendor 3=casio */
2385 + (1 << 16) /* 16: series 1=CASSIOPEIAE*/
2386 + (2 << 8) /* 8: model 2=EXXX*/
2387 + (3) /* 0: submodel 3=E500 */
2388 );
2389 /* TODO: Don't use model number for E500, it's a BE300! */
2390 break;
2391 case MACHINE_HPCMIPS_CASIO_E105:
2392 /* 131MHz VR4121 */
2393 machine->machine_name = "Casio Cassiopeia E-105";
2394 hpcmips_fb_addr = 0x0a200000; /* TODO? */
2395 hpcmips_fb_xsize = 240;
2396 hpcmips_fb_ysize = 320;
2397 hpcmips_fb_xsize_mem = 256;
2398 hpcmips_fb_ysize_mem = 320;
2399 hpcmips_fb_bits = 16;
2400 hpcmips_fb_encoding = BIFB_D16_0000;
2401
2402 /* TODO: irq? */
2403 snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=0 addr=0x0a008680 addr_mult=4 in_use=%i", machine->use_x11? 0 : 1);
2404 machine->main_console_handle = (size_t)device_add(machine, tmpstr);
2405
2406 machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4121);
2407 machine->md_interrupt = vr41xx_interrupt;
2408
2409 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_cpu,
2410 (1 << 26) /* 1 = MIPS */
2411 + (1 << 20) /* 1 = VR */
2412 + (1 << 14) /* 1 = VR41XX */
2413 + (3 << 8) /* 3 = VR4121 */
2414 );
2415 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_machine,
2416 (3 << 22) /* 22: vendor 3=casio */
2417 + (1 << 16) /* 16: series 1=CASSIOPEIAE*/
2418 + (2 << 8) /* 8: model 2=EXXX*/
2419 + (2) /* 0: submodel 2=E105 */
2420 );
2421 break;
2422 case MACHINE_HPCMIPS_NEC_MOBILEPRO_770:
2423 /* 131 MHz VR4121 */
2424 machine->machine_name = "NEC MobilePro 770";
2425 /* TODO: */
2426 hpcmips_fb_addr = 0xa000000;
2427 hpcmips_fb_xsize = 640;
2428 hpcmips_fb_ysize = 240;
2429 hpcmips_fb_xsize_mem = 800;
2430 hpcmips_fb_ysize_mem = 240;
2431 hpcmips_fb_bits = 16;
2432 hpcmips_fb_encoding = BIFB_D16_0000;
2433
2434 machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4121);
2435 machine->md_interrupt = vr41xx_interrupt;
2436
2437 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_cpu,
2438 (1 << 26) /* 1 = MIPS */
2439 + (1 << 20) /* 1 = VR */
2440 + (1 << 14) /* 1 = VR41XX */
2441 + (3 << 8) /* 3 = VR4121 */
2442 );
2443 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_machine,
2444 (1 << 22) /* 22: vendor 1=NEC */
2445 + (2 << 16) /* 16: series 2="NEC MCR" */
2446 + (2 << 8) /* 8: model 2="MCR 5XX" */
2447 + (4) /* 0: submodel 4="MCR 520A" */
2448 );
2449 break;
2450 case MACHINE_HPCMIPS_NEC_MOBILEPRO_780:
2451 /* 166 (or 168) MHz VR4121 */
2452 machine->machine_name = "NEC MobilePro 780";
2453 /* TODO: */
2454 hpcmips_fb_addr = 0xa180100;
2455 hpcmips_fb_xsize = 640;
2456 hpcmips_fb_ysize = 240;
2457 hpcmips_fb_xsize_mem = 640;
2458 hpcmips_fb_ysize_mem = 240;
2459 hpcmips_fb_bits = 16;
2460 hpcmips_fb_encoding = BIFB_D16_0000;
2461
2462 machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4121);
2463 machine->md_interrupt = vr41xx_interrupt;
2464
2465 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_cpu,
2466 (1 << 26) /* 1 = MIPS */
2467 + (1 << 20) /* 1 = VR */
2468 + (1 << 14) /* 1 = VR41XX */
2469 + (3 << 8) /* 3 = VR4121 */
2470 );
2471 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_machine,
2472 (1 << 22) /* 22: vendor 1=NEC */
2473 + (2 << 16) /* 16: series 2="NEC MCR" */
2474 + (2 << 8) /* 8: model 2="MCR 5XX" */
2475 + (8) /* 0: submodel 8="MCR 530A" */
2476 );
2477 break;
2478 case MACHINE_HPCMIPS_NEC_MOBILEPRO_800:
2479 /* 131 MHz VR4121 */
2480 machine->machine_name = "NEC MobilePro 800";
2481 /* TODO: */
2482 hpcmips_fb_addr = 0xa000000;
2483 hpcmips_fb_xsize = 800;
2484 hpcmips_fb_ysize = 600;
2485 hpcmips_fb_xsize_mem = 800;
2486 hpcmips_fb_ysize_mem = 600;
2487 hpcmips_fb_bits = 16;
2488 hpcmips_fb_encoding = BIFB_D16_0000;
2489
2490 machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4121);
2491 machine->md_interrupt = vr41xx_interrupt;
2492
2493 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_cpu,
2494 (1 << 26) /* 1 = MIPS */
2495 + (1 << 20) /* 1 = VR */
2496 + (1 << 14) /* 1 = VR41XX */
2497 + (3 << 8) /* 3 = VR4121 */
2498 );
2499 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_machine,
2500 (1 << 22) /* 22: vendor 1=NEC */
2501 + (2 << 16) /* 16: series 2="NEC MCR" */
2502 + (3 << 8) /* 8: model 3="MCR 7XX" */
2503 + (2) /* 0: submodel 2="MCR 700A" */
2504 );
2505 break;
2506 case MACHINE_HPCMIPS_NEC_MOBILEPRO_880:
2507 /* 168 MHz VR4121 */
2508 machine->machine_name = "NEC MobilePro 880";
2509 /* TODO: */
2510 hpcmips_fb_addr = 0xa0ea600;
2511 hpcmips_fb_xsize = 800;
2512 hpcmips_fb_ysize = 600;
2513 hpcmips_fb_xsize_mem = 800;
2514 hpcmips_fb_ysize_mem = 600;
2515 hpcmips_fb_bits = 16;
2516 hpcmips_fb_encoding = BIFB_D16_0000;
2517
2518 machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4121);
2519 machine->md_interrupt = vr41xx_interrupt;
2520
2521 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_cpu,
2522 (1 << 26) /* 1 = MIPS */
2523 + (1 << 20) /* 1 = VR */
2524 + (1 << 14) /* 1 = VR41XX */
2525 + (3 << 8) /* 3 = VR4121 */
2526 );
2527 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_machine,
2528 (1 << 22) /* 22: vendor 1=NEC */
2529 + (2 << 16) /* 16: series 2="NEC MCR" */
2530 + (3 << 8) /* 8: model 3="MCR 7XX" */
2531 + (4) /* 0: submodel 4="MCR 730A" */
2532 );
2533 break;
2534 case MACHINE_HPCMIPS_AGENDA_VR3:
2535 /* 66 MHz VR4181 */
2536 machine->machine_name = "Agenda VR3";
2537 /* TODO: */
2538 hpcmips_fb_addr = 0x1000;
2539 hpcmips_fb_xsize = 160;
2540 hpcmips_fb_ysize = 240;
2541 hpcmips_fb_xsize_mem = 160;
2542 hpcmips_fb_ysize_mem = 240;
2543 hpcmips_fb_bits = 4;
2544 hpcmips_fb_encoding = BIFB_D4_M2L_F;
2545
2546 machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4181);
2547 machine->md_interrupt = vr41xx_interrupt;
2548
2549 /* TODO: Hm... irq 17 according to linux, but
2550 VRIP_INTR_SIU (=9) here? */
2551 {
2552 int x;
2553 snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=%i addr=0x0c000010", 8 + VRIP_INTR_SIU);
2554 x = (size_t)device_add(machine, tmpstr);
2555
2556 if (!machine->use_x11)
2557 machine->main_console_handle = x;
2558 }
2559
2560 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_cpu,
2561 (1 << 26) /* 1 = MIPS */
2562 + (1 << 20) /* 1 = VR */
2563 + (1 << 14) /* 1 = VR41XX */
2564 + (4 << 8) /* 4 = VR4181 */
2565 );
2566 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_machine,
2567 (15 << 22) /* 22: vendor 15=Agenda */
2568 + (1 << 16) /* 16: series 2=VR */
2569 + (1 << 8) /* 8: model 1=VR3 */
2570 + (0) /* 0: submodel 0="VR3" */
2571 );
2572
2573 dev_ram_init(mem, 0x0f000000, 0x01000000, DEV_RAM_MIRROR, 0x0);
2574 break;
2575 case MACHINE_HPCMIPS_IBM_WORKPAD_Z50:
2576 /* 131 MHz VR4121 */
2577 machine->machine_name = "IBM Workpad Z50";
2578 /* TODO: */
2579 hpcmips_fb_addr = 0xa000000;
2580 hpcmips_fb_xsize = 640;
2581 hpcmips_fb_ysize = 480;
2582 hpcmips_fb_xsize_mem = 640;
2583 hpcmips_fb_ysize_mem = 480;
2584 hpcmips_fb_bits = 16;
2585 hpcmips_fb_encoding = BIFB_D16_0000;
2586
2587 machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4121);
2588 machine->md_interrupt = vr41xx_interrupt;
2589
2590 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_cpu,
2591 (1 << 26) /* 1 = MIPS */
2592 + (1 << 20) /* 1 = VR */
2593 + (1 << 14) /* 1 = VR41XX */
2594 + (3 << 8) /* 3 = VR4121 */
2595 );
2596 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.platid_machine,
2597 (9 << 22) /* 22: vendor 9=IBM */
2598 + (1 << 16) /* 16: series 1=WorkPad */
2599 + (1 << 8) /* 8: model 1=Z50 */
2600 + (0) /* 0: submodel 0 */
2601 );
2602 break;
2603 default:
2604 printf("Unimplemented hpcmips machine number.\n");
2605 exit(1);
2606 }
2607
2608 if (machine->use_x11)
2609 machine->main_console_handle =
2610 machine->md_int.vr41xx_data->kiu_console_handle;
2611
2612 /* NetBSD/hpcmips and possibly others expects the following: */
2613
2614 cpu->cd.mips.gpr[MIPS_GPR_A0] = 1; /* argc */
2615 cpu->cd.mips.gpr[MIPS_GPR_A1] = machine->physical_ram_in_mb * 1048576
2616 + 0xffffffff80000000ULL - 512; /* argv */
2617 cpu->cd.mips.gpr[MIPS_GPR_A2] = machine->physical_ram_in_mb * 1048576
2618 + 0xffffffff80000000ULL - 256; /* ptr to hpc_bootinfo */
2619
2620 bootstr = machine->boot_kernel_filename;
2621 store_32bit_word(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 16);
2622 store_32bit_word(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 4, 0);
2623 store_string(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 16, bootstr);
2624
2625 /* Special case for the Agenda VR3: */
2626 if (machine->machine_subtype == MACHINE_HPCMIPS_AGENDA_VR3) {
2627 const int tmplen = 1000;
2628 char *tmp = malloc(tmplen);
2629
2630 cpu->cd.mips.gpr[MIPS_GPR_A0] = 2; /* argc */
2631
2632 store_32bit_word(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 4, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 64);
2633 store_32bit_word(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 8, 0);
2634
2635 snprintf(tmp, tmplen, "root=/dev/rom video=vr4181fb:xres:160,yres:240,bpp:4,"
2636 "gray,hpck:3084,inv ether=0,0x03fe0300,eth0");
2637 tmp[tmplen-1] = '\0';
2638
2639 if (!machine->use_x11)
2640 snprintf(tmp+strlen(tmp), tmplen-strlen(tmp), " console=ttyS0,115200");
2641 tmp[tmplen-1] = '\0';
2642
2643 if (machine->boot_string_argument[0])
2644 snprintf(tmp+strlen(tmp), tmplen-strlen(tmp), " %s", machine->boot_string_argument);
2645 tmp[tmplen-1] = '\0';
2646
2647 store_string(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 64, tmp);
2648
2649 bootarg = tmp;
2650 } else if (machine->boot_string_argument[0]) {
2651 cpu->cd.mips.gpr[MIPS_GPR_A0] ++; /* argc */
2652
2653 store_32bit_word(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 4, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 64);
2654 store_32bit_word(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 8, 0);
2655
2656 store_string(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 512 + 64,
2657 machine->boot_string_argument);
2658
2659 bootarg = machine->boot_string_argument;
2660 }
2661
2662 store_16bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.length, sizeof(hpc_bootinfo));
2663 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.magic, HPC_BOOTINFO_MAGIC);
2664 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.fb_addr, 0x80000000 + hpcmips_fb_addr);
2665 store_16bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.fb_line_bytes, hpcmips_fb_xsize_mem * (((hpcmips_fb_bits-1)|7)+1) / 8);
2666 store_16bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.fb_width, hpcmips_fb_xsize);
2667 store_16bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.fb_height, hpcmips_fb_ysize);
2668 store_16bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.fb_type, hpcmips_fb_encoding);
2669 store_16bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.bi_cnuse, BI_CNUSE_BUILTIN); /* _BUILTIN or _SERIAL */
2670
2671 /* printf("hpc_bootinfo.platid_cpu = 0x%08x\n", hpc_bootinfo.platid_cpu);
2672 printf("hpc_bootinfo.platid_machine = 0x%08x\n", hpc_bootinfo.platid_machine); */
2673 store_32bit_word_in_host(cpu, (unsigned char *)&hpc_bootinfo.timezone, 0);
2674 store_buf(cpu, 0x80000000 + machine->physical_ram_in_mb * 1048576 - 256, (char *)&hpc_bootinfo, sizeof(hpc_bootinfo));
2675
2676 if (hpcmips_fb_addr != 0) {
2677 dev_fb_init(machine, mem, hpcmips_fb_addr, VFB_HPCMIPS,
2678 hpcmips_fb_xsize, hpcmips_fb_ysize,
2679 hpcmips_fb_xsize_mem, hpcmips_fb_ysize_mem,
2680 hpcmips_fb_bits, "HPCmips");
2681
2682 /* NetBSD/hpcmips uses framebuffer at physical
2683 address 0x8.......: */
2684 dev_ram_init(mem, 0x80000000, 0x20000000,
2685 DEV_RAM_MIRROR, 0x0);
2686 }
2687
2688 break;
2689
2690 case MACHINE_PS2:
2691 cpu->byte_order = EMUL_LITTLE_ENDIAN;
2692 machine->machine_name = "Playstation 2";
2693
2694 if (machine->physical_ram_in_mb != 32)
2695 fprintf(stderr, "WARNING! Playstation 2 machines are supposed to have exactly 32 MB RAM. Continuing anyway.\n");
2696 if (!machine->use_x11)
2697 fprintf(stderr, "WARNING! Playstation 2 without -X is pretty meaningless. Continuing anyway.\n");
2698
2699 /*
2700 * According to NetBSD:
2701 * Hardware irq 0 is timer/interrupt controller
2702 * Hardware irq 1 is dma controller
2703 *
2704 * Some things are not yet emulated (at all), and hence are detected incorrectly:
2705 * sbus0 at mainbus0: controller type 2
2706 * ohci0 at sbus0 (at 0x1f801600, according to linux)
2707 * ohci0: OHCI version 1.0
2708 */
2709
2710 machine->md_int.ps2_data = dev_ps2_stuff_init(machine, mem, 0x10000000);
2711 device_add(machine, "ps2_gs addr=0x12000000");
2712 device_add(machine, "ps2_ether addr=0x14001000");
2713 dev_ram_init(mem, 0x1c000000, 4 * 1048576, DEV_RAM_RAM, 0); /* TODO: how much? */
2714 /* irq = 8 + 32 + 1 (SBUS/USB) */
2715 device_add(machine, "ohci addr=0x1f801600 irq=41");
2716
2717 machine->md_interrupt = ps2_interrupt;
2718
2719 add_symbol_name(&machine->symbol_context,
2720 PLAYSTATION2_SIFBIOS, 0x10000, "[SIFBIOS entry]", 0, 0);
2721 store_32bit_word(cpu, PLAYSTATION2_BDA + 0, PLAYSTATION2_SIFBIOS);
2722 store_buf(cpu, PLAYSTATION2_BDA + 4, "PS2b", 4);
2723
2724 /* Set the Harddisk controller present flag, if either
2725 disk 0 or 1 is present: */
2726 if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
2727 diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
2728 store_32bit_word(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x0, 0x100);
2729 dev_ps2_spd_init(machine, mem, 0x14000000);
2730 }
2731
2732 store_32bit_word(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x4, PLAYSTATION2_OPTARGS);
2733 {
2734 int tmplen = 1000;
2735 char *tmp = malloc(tmplen);
2736 if (tmp == NULL) {
2737 fprintf(stderr, "out of memory\n");
2738 exit(1);
2739 }
2740
2741 strlcpy(tmp, "root=/dev/hda1 crtmode=vesa0,60", tmplen);
2742
2743 if (machine->boot_string_argument[0])
2744 snprintf(tmp+strlen(tmp), tmplen-strlen(tmp),
2745 " %s", machine->boot_string_argument);
2746 tmp[tmplen-1] = '\0';
2747
2748 bootstr = tmp;
2749 store_string(cpu, PLAYSTATION2_OPTARGS, bootstr);
2750 }
2751
2752 /* TODO: netbsd's bootinfo.h, for symbolic names */
2753 {
2754 time_t timet;
2755 struct tm *tmp;
2756
2757 /* RTC data given by the BIOS: */
2758 timet = time(NULL) + 9*3600; /* PS2 uses Japanese time */
2759 tmp = gmtime(&timet);
2760 /* TODO: are these 0- or 1-based? */
2761 store_byte(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x10 + 1, int_to_bcd(tmp->tm_sec));
2762 store_byte(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x10 + 2, int_to_bcd(tmp->tm_min));
2763 store_byte(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x10 + 3, int_to_bcd(tmp->tm_hour));
2764 store_byte(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x10 + 5, int_to_bcd(tmp->tm_mday));
2765 store_byte(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x10 + 6, int_to_bcd(tmp->tm_mon + 1));
2766 store_byte(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x10 + 7, int_to_bcd(tmp->tm_year - 100));
2767 }
2768
2769 /* "BOOTINFO_PCMCIA_TYPE" in NetBSD's bootinfo.h. This contains the sbus controller type. */
2770 store_32bit_word(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x1c, 2);
2771
2772 break;
2773
2774 case MACHINE_SGI:
2775 case MACHINE_ARC:
2776 /*
2777 * SGI and ARC emulation share a lot of code. (SGI is a special case of
2778 * "almost ARC".)
2779 *
2780 * http://obsolete.majix.org/computers/sgi/iptable.shtml contains a pretty
2781 * detailed list of IP ("Inhouse Processor") model numbers.
2782 * (Or http://hardware.majix.org/computers/sgi/iptable.shtml)
2783 */
2784 machine->machine_name = malloc(MACHINE_NAME_MAXBUF);
2785 if (machine->machine_name == NULL) {
2786 fprintf(stderr, "out of memory\n");
2787 exit(1);
2788 }
2789
2790 if (machine->machine_type == MACHINE_SGI) {
2791 cpu->byte_order = EMUL_BIG_ENDIAN;
2792 snprintf(machine->machine_name, MACHINE_NAME_MAXBUF,
2793 "SGI-IP%i", machine->machine_subtype);
2794
2795 sgi_ram_offset = 1048576 * machine->memory_offset_in_mb;
2796
2797 /* Special cases for IP20,22,24,26 memory offset: */
2798 if (machine->machine_subtype == 20 || machine->machine_subtype == 22 ||
2799 machine->machine_subtype == 24 || machine->machine_subtype == 26) {
2800 dev_ram_init(mem, 0x00000000, 0x10000, DEV_RAM_MIRROR, sgi_ram_offset);
2801 dev_ram_init(mem, 0x00050000, sgi_ram_offset-0x50000, DEV_RAM_MIRROR, sgi_ram_offset + 0x50000);
2802 }
2803
2804 /* Special cases for IP28,30 memory offset: */
2805 if (machine->machine_subtype == 28 || machine->machine_subtype == 30) {
2806 /* TODO: length below should maybe not be 128MB? */
2807 dev_ram_init(mem, 0x00000000, 128*1048576, DEV_RAM_MIRROR, sgi_ram_offset);
2808 }
2809 } else {
2810 cpu->byte_order = EMUL_LITTLE_ENDIAN;
2811 snprintf(machine->machine_name,
2812 MACHINE_NAME_MAXBUF, "ARC");
2813 }
2814
2815 if (machine->machine_type == MACHINE_SGI) {
2816 /* TODO: Other SGI machine types? */
2817 switch (machine->machine_subtype) {
2818 case 12:
2819 strlcat(machine->machine_name,
2820 " (Iris Indigo IP12)", MACHINE_NAME_MAXBUF);
2821
2822 /* TODO */
2823 /* 33 MHz R3000, according to http://www.irisindigo.com/ */
2824 /* "capable of addressing up to 96MB of memory." */
2825
2826 break;
2827 case 19:
2828 strlcat(machine->machine_name,
2829 " (Everest IP19)", MACHINE_NAME_MAXBUF);
2830 machine->main_console_handle =
2831 dev_zs_init(machine, mem, 0x1fbd9830, 0, 1, "serial zs"); /* serial? netbsd? */
2832 dev_scc_init(machine, mem, 0x10086000, 0, machine->use_x11, 0, 8); /* serial? irix? */
2833
2834 device_add(machine, "sgi_ip19 addr=0x18000000");
2835
2836 /* Irix' <everest_du_init+0x130> reads this device: */
2837 device_add(machine, "random addr=0x10006000 len=16");
2838
2839 /* Irix' get_mpconf() looks for this: (TODO) */
2840 store_32bit_word(cpu, 0xa0000000 + 0x3000,
2841 0xbaddeed2);
2842
2843 /* Memory size, not 4096 byte pages, but 256 bytes? (16 is size of kernel... approx) */
2844 store_32bit_word(cpu, 0xa0000000 + 0x26d0,
2845 30000); /* (machine->physical_ram_in_mb - 16) * (1048576 / 256)); */
2846
2847 break;
2848 case 20:
2849 strlcat(machine->machine_name,
2850 " (Indigo)", MACHINE_NAME_MAXBUF);
2851
2852 /*
2853 * Guesses based on NetBSD 2.0 beta, 20040606.
2854 *
2855 * int0 at mainbus0 addr 0x1fb801c0: bus 1MHz, CPU 2MHz
2856 * imc0 at mainbus0 addr 0x1fa00000: revision 0
2857 * gio0 at imc0
2858 * unknown GIO card (product 0x00 revision 0x00) at gio0 slot 0 addr 0x1f400000 not configured
2859 * unknown GIO card (product 0x00 revision 0x00) at gio0 slot 1 addr 0x1f600000 not configured
2860 * unknown GIO card (product 0x00 revision 0x00) at gio0 slot 2 addr 0x1f000000 not configured
2861 * hpc0 at gio0 addr 0x1fb80000: SGI HPC1
2862 * zsc0 at hpc0 offset 0xd10 (channels 0 and 1, channel 1 for console)
2863 * zsc1 at hpc0 offset 0xd00 (2 channels)
2864 * sq0 at hpc0 offset 0x100: SGI Seeq 80c03
2865 * wdsc0 at hpc0 offset 0x11f
2866 * dpclock0 at hpc0 offset 0xe00
2867 */
2868
2869 /* int0 at mainbus0 addr 0x1fb801c0 */
2870 machine->md_int.sgi_ip20_data = dev_sgi_ip20_init(cpu, mem, DEV_SGI_IP20_BASE);
2871
2872 /* imc0 at mainbus0 addr 0x1fa00000: revision 0: TODO (or in dev_sgi_ip20?) */
2873
2874 dev_zs_init(machine, mem, 0x1fbd9830, 0, 1, "zs console");
2875
2876 /* This is the zsc0 reported by NetBSD: TODO: irqs */
2877 machine->main_console_handle = dev_zs_init(machine, mem, 0x1fb80d10, 0, 1, "zsc0"); /* zsc0 */
2878 dev_zs_init(machine, mem, 0x1fb80d00, 0, 1, "zsc1"); /* zsc1 */
2879
2880 /* WDSC SCSI controller: */
2881 dev_wdsc_init(machine, mem, 0x1fb8011f, 0, 0);
2882
2883 /* Return memory read errors so that hpc1
2884 and hpc2 are not detected: */
2885 device_add(machine, "unreadable addr=0x1fb00000 len=0x10000");
2886 device_add(machine, "unreadable addr=0x1f980000 len=0x10000");
2887
2888 /* Return nothing for gio slots 0, 1, and 2: */
2889 device_add(machine, "unreadable addr=0x1f400000 len=0x1000"); /* gio0 slot 0 */
2890 device_add(machine, "unreadable addr=0x1f600000 len=0x1000"); /* gio0 slot 1 */
2891 device_add(machine, "unreadable addr=0x1f000000 len=0x1000"); /* gio0 slot 2 */
2892
2893 break;
2894 case 21:
2895 strlcat(machine->machine_name, /* TODO */
2896 " (uknown SGI-IP21 ?)", MACHINE_NAME_MAXBUF);
2897 /* NOTE: Special case for arc_wordlen: */
2898 arc_wordlen = sizeof(uint64_t);
2899
2900 device_add(machine, "random addr=0x418000200, len=0x20000");
2901
2902 break;
2903 case 22:
2904 case 24:
2905 if (machine->machine_subtype == 22) {
2906 strlcat(machine->machine_name,
2907 " (Indy, Indigo2, Challenge S; Full-house)",
2908 MACHINE_NAME_MAXBUF);
2909 machine->md_int.sgi_ip22_data = dev_sgi_ip22_init(machine, mem, 0x1fbd9000, 0);
2910 } else {
2911 strlcat(machine->machine_name,
2912 " (Indy, Indigo2, Challenge S; Guiness)",
2913 MACHINE_NAME_MAXBUF);
2914 machine->md_int.sgi_ip22_data = dev_sgi_ip22_init(machine, mem, 0x1fbd9880, 1);
2915 }
2916
2917 /*
2918 Why is this here? TODO
2919 dev_ram_init(mem, 0x88000000ULL,
2920 128 * 1048576, DEV_RAM_MIRROR, 0x08000000);
2921 */
2922 machine->md_interrupt = sgi_ip22_interrupt;
2923
2924 /*
2925 * According to NetBSD 1.6.2:
2926 *
2927 * imc0 at mainbus0 addr 0x1fa00000, Revision 0
2928 * gio0 at imc0
2929 * hpc0 at gio0 addr 0x1fb80000: SGI HPC3
2930 * zsc0 at hpc0 offset 0x59830
2931 * zstty0 at zsc0 channel 1 (console i/o)
2932 * zstty1 at zsc0 channel 0
2933 * sq0 at hpc0 offset 0x54000: SGI Seeq 80c03 (Ethernet)
2934 * wdsc0 at hpc0 offset 0x44000: WD33C93 SCSI, rev=0, target 7
2935 * scsibus2 at wdsc0: 8 targets, 8 luns per target
2936 * dsclock0 at hpc0 offset 0x60000
2937 *
2938 * According to Linux/IP22:
2939 * tty00 at 0xbfbd9830 (irq = 45) is a Zilog8530
2940 * tty01 at 0xbfbd9838 (irq = 45) is a Zilog8530
2941 *
2942 * and according to NetBSD 2.0_BETA (20040606):
2943 *
2944 * haltwo0 at hpc0 offset 0x58000: HAL2 revision 0.0.0
2945 * audio0 at haltwo0: half duplex
2946 *
2947 * IRQ numbers are of the form 8 + x, where x = 0..31 for local0
2948 * interrupts, and 32..63 for local1. + y*65 for "mappable".
2949 */
2950
2951 /* zsc0 serial console. */
2952 i = dev_zs_init(machine, mem, 0x1fbd9830,
2953 8 + 32 + 3 + 64*5, 1, "zsc0");
2954
2955 /* Not supported by NetBSD 1.6.2, but by 2.0_BETA: */
2956 j = dev_pckbc_init(machine, mem, 0x1fbd9840, PCKBC_8242,
2957 0, 0, machine->use_x11, 0); /* TODO: irq numbers */
2958
2959 if (machine->use_x11)
2960 machine->main_console_handle = j;
2961
2962 /* sq0: Ethernet. TODO: This should have irq_nr = 8 + 3 */
2963 /* dev_sq_init... */
2964
2965 /* wdsc0: SCSI */
2966 dev_wdsc_init(machine, mem, 0x1fbc4000, 0, 8 + 1);
2967
2968 /* wdsc1: SCSI TODO: irq nr */
2969 dev_wdsc_init(machine, mem, 0x1fbcc000, 1, 8 + 1);
2970
2971 /* dsclock0: TODO: possibly irq 8 + 33 */
2972
2973 /* Return memory read errors so that hpc1 and hpc2 are not detected: */
2974 device_add(machine, "unreadable addr=0x1fb00000, len=0x10000");
2975 device_add(machine, "unreadable addr=0x1f980000, len=0x10000");
2976
2977 /* Similarly for gio slots 0, 1, and 2: */
2978 device_add(machine, "unreadable addr=0x1f400000, len=0x1000"); /* gio0 slot 0 */
2979 device_add(machine, "unreadable addr=0x1f600000, len=0x1000"); /* gio0 slot 1 */
2980 device_add(machine, "unreadable addr=0x1f000000, len=0x1000"); /* gio0 slot 2 */
2981
2982 break;
2983 case 25:
2984 /* NOTE: Special case for arc_wordlen: */
2985 arc_wordlen = sizeof(uint64_t);
2986 strlcat(machine->machine_name,
2987 " (Everest IP25)", MACHINE_NAME_MAXBUF);
2988
2989 /* serial? irix? */
2990 dev_scc_init(machine, mem,
2991 0x400086000ULL, 0, machine->use_x11, 0, 8);
2992
2993 /* NOTE: ip19! (perhaps not really the same */
2994 device_add(machine, "sgi_ip19 addr=0x18000000");
2995
2996 /*
2997 * Memory size, not 4096 byte pages, but 256
2998 * bytes? (16 is size of kernel... approx)
2999 */
3000 store_32bit_word(cpu, 0xa0000000ULL + 0x26d0,
3001 30000); /* (machine->physical_ram_in_mb - 16)
3002 * (1048576 / 256)); */
3003
3004 break;
3005 case 26:
3006 /* NOTE: Special case for arc_wordlen: */
3007 arc_wordlen = sizeof(uint64_t);
3008 strlcat(machine->machine_name,
3009 " (uknown SGI-IP26 ?)",
3010 MACHINE_NAME_MAXBUF); /* TODO */
3011 machine->main_console_handle =
3012 dev_zs_init(machine, mem, 0x1fbd9830,
3013 0, 1, "zs console");
3014 break;
3015 case 27:
3016 strlcat(machine->machine_name,
3017 " (Origin 200/2000, Onyx2)",
3018 MACHINE_NAME_MAXBUF);
3019 arc_wordlen = sizeof(uint64_t);
3020 /* 2 cpus per node */
3021
3022 machine->main_console_handle =
3023 dev_zs_init(machine, mem, 0x1fbd9830,
3024 0, 1, "zs console");
3025 break;
3026 case 28:
3027 /* NOTE: Special case for arc_wordlen: */
3028 arc_wordlen = sizeof(uint64_t);
3029 strlcat(machine->machine_name,
3030 " (Impact Indigo2 ?)", MACHINE_NAME_MAXBUF);
3031
3032 device_add(machine, "random addr=0x1fbe0000, len=1");
3033
3034 /* Something at paddr 0x1880fb0000. */
3035
3036 break;
3037 case 30:
3038 /* NOTE: Special case for arc_wordlen: */
3039 arc_wordlen = sizeof(uint64_t);
3040 strlcat(machine->machine_name,
3041 " (Octane)", MACHINE_NAME_MAXBUF);
3042
3043 machine->md_int.sgi_ip30_data = dev_sgi_ip30_init(machine, mem, 0x0ff00000);
3044 machine->md_interrupt = sgi_ip30_interrupt;
3045
3046 dev_ram_init(mem, 0xa0000000ULL,
3047 128 * 1048576, DEV_RAM_MIRROR, 0x00000000);
3048
3049 dev_ram_init(mem, 0x80000000ULL,
3050 32 * 1048576, DEV_RAM_RAM, 0x00000000);
3051
3052 /*
3053 * Something at paddr=1f022004: TODO
3054 * Something at paddr=813f0510 - paddr=813f0570 ?
3055 * Something at paddr=813f04b8
3056 * Something at paddr=f8000003c used by Linux/Octane
3057 *
3058 * 16550 serial port at paddr=1f620178, addr mul 1
3059 * (Error messages are printed to this serial port by the PROM.)
3060 *
3061 * There seems to also be a serial port at 1f620170. The "symmon"
3062 * program dumps something there, but it doesn't look like
3063 * readable text. (TODO)
3064 */
3065
3066 /* TODO: irq! */
3067 snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=0 addr=0x1f620170 name2=tty0 in_use=%i", machine->use_x11? 0 : 1);
3068 machine->main_console_handle = (size_t)device_add(machine, tmpstr);
3069 snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=0 addr=0x1f620178 name2=tty1 in_use=0");
3070 device_add(machine, tmpstr);
3071
3072 /* MardiGras graphics: */
3073 device_add(machine, "sgi_mardigras addr=0x1c000000");
3074
3075 break;
3076 case 32:
3077 strlcat(machine->machine_name,
3078 " (O2)", MACHINE_NAME_MAXBUF);
3079
3080 /* TODO: Find out where the physical ram is actually located. */
3081 dev_ram_init(mem, 0x07ffff00ULL, 256, DEV_RAM_MIRROR, 0x03ffff00);
3082 dev_ram_init(mem, 0x10000000ULL, 256, DEV_RAM_MIRROR, 0x00000000);
3083 dev_ram_init(mem, 0x11ffff00ULL, 256, DEV_RAM_MIRROR, 0x01ffff00);
3084 dev_ram_init(mem, 0x12000000ULL, 256, DEV_RAM_MIRROR, 0x02000000);
3085 dev_ram_init(mem, 0x17ffff00ULL, 256, DEV_RAM_MIRROR, 0x03ffff00);
3086 dev_ram_init(mem, 0x20000000ULL, 128 * 1048576, DEV_RAM_MIRROR, 0x00000000);
3087 dev_ram_init(mem, 0x40000000ULL, 128 * 1048576, DEV_RAM_MIRROR, 0x10000000);
3088
3089 machine->md_int.ip32.crime_data = dev_crime_init(machine, mem, 0x14000000, 2, machine->use_x11); /* crime0 */
3090 dev_sgi_mte_init(mem, 0x15000000); /* mte ??? memory thing */
3091 dev_sgi_gbe_init(machine, mem, 0x16000000); /* gbe? framebuffer? */
3092
3093 /*
3094 * A combination of NetBSD and Linux info:
3095 *
3096 * 17000000 vice (Video Image Compression Engine)
3097 * 1f000000 mace
3098 * 1f080000 macepci
3099 * 1f100000 vin1
3100 * 1f180000 vin2
3101 * 1f200000 vout
3102 * 1f280000 enet (mec0, MAC-110 Ethernet)
3103 * 1f300000 perif:
3104 * 1f300000 audio
3105 * 1f310000 isa
3106 * 1f318000 (accessed by Irix' pciio_pio_write64)
3107 * 1f320000 kbdms
3108 * 1f330000 i2c
3109 * 1f340000 ust
3110 * 1f380000 isa ext
3111 * 1f390000 com0 (serial)
3112 * 1f398000 com1 (serial)
3113 * 1f3a0000 mcclock0
3114 */
3115
3116 machine->md_int.ip32.mace_data = dev_mace_init(mem, 0x1f310000, 2);
3117 machine->md_interrupt = sgi_ip32_interrupt;
3118
3119 /*
3120 * IRQ mapping is really ugly. TODO: fix
3121 *
3122 * com0 at mace0 offset 0x390000 intr 4 intrmask 0x3f00000: ns16550a, working fifo
3123 * com1 at mace0 offset 0x398000 intr 4 intrmask 0xfc000000: ns16550a, working fifo
3124 * pckbc0 at mace0 offset 0x320000 intr 5 intrmask 0x0
3125 * mcclock0 at mace0 offset 0x3a0000 intrmask 0x0
3126 * macepci0 at mace0 offset 0x80000 intr 7 intrmask 0x0: rev 1
3127 *
3128 * intr 4 = MACE_PERIPH_SERIAL
3129 * intr 5 = MACE_PERIPH_MISC
3130 * intr 7 = MACE_PCI_BRIDGE
3131 */
3132
3133 #if 0
3134 i = dev_pckbc_init(machine, mem, 0x1f320000,
3135 PCKBC_8242, 0x200 + MACE_PERIPH_MISC,
3136 0x800 + MACE_PERIPH_MISC, machine->use_x11, 0);
3137 /* keyb+mouse (mace irq numbers) */
3138 #endif
3139
3140 net_generate_unique_mac(machine, macaddr);
3141 eaddr_string = malloc(ETHERNET_STRING_MAXLEN);
3142 if (eaddr_string == NULL) {
3143 fprintf(stderr, "out of memory\n");
3144 exit(1);
3145 }
3146 snprintf(eaddr_string, ETHERNET_STRING_MAXLEN,
3147 "eaddr=%02x:%02x:%02x:%02x:%02x:%02x",
3148 macaddr[0], macaddr[1], macaddr[2],
3149 macaddr[3], macaddr[4], macaddr[5]);
3150 dev_sgi_mec_init(machine, mem, 0x1f280000,
3151 MACE_ETHERNET, macaddr);
3152
3153 dev_sgi_ust_init(mem, 0x1f340000); /* ust? */
3154
3155 snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=%i addr=0x1f390000 addr_mult=0x100 in_use=%i name2=tty0",
3156 (1<<20) + MACE_PERIPH_SERIAL, machine->use_x11? 0 : 1);
3157 j = (size_t)device_add(machine, tmpstr);
3158 snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=%i addr=0x1f398000 addr_mult=0x100 in_use=%i name2=tty1",
3159 (1<<26) + MACE_PERIPH_SERIAL, 0);
3160 device_add(machine, tmpstr);
3161 #if 0
3162 if (machine->use_x11)
3163 machine->main_console_handle = i;
3164 else
3165 #endif
3166 machine->main_console_handle = j;
3167
3168 dev_mc146818_init(machine, mem, 0x1f3a0000, (1<<8) + MACE_PERIPH_MISC, MC146818_SGI, 0x40); /* mcclock0 */
3169 dev_zs_init(machine, mem, 0x1fbd9830, 0, 1, "zs console");
3170
3171 /*
3172 * PCI devices: (according to NetBSD's GENERIC config file for sgimips)
3173 *
3174 * ne* at pci? dev ? function ?
3175 * ahc0 at pci0 dev 1 function ?
3176 * ahc1 at pci0 dev 2 function ?
3177 */
3178
3179 pci_data = dev_macepci_init(mem, 0x1f080000, MACE_PCI_BRIDGE); /* macepci0 */
3180 /* bus_pci_add(machine, pci_data, mem, 0, 0, 0, pci_ne2000_init, pci_ne2000_rr); TODO */
3181
3182 /* TODO: make this nicer */
3183 if (diskimage_exist(machine, 0, DISKIMAGE_SCSI) ||
3184 diskimage_exist(machine, 1, DISKIMAGE_SCSI) ||
3185 diskimage_exist(machine, 2, DISKIMAGE_SCSI) ||
3186 diskimage_exist(machine, 3, DISKIMAGE_SCSI) ||
3187 diskimage_exist(machine, 4, DISKIMAGE_SCSI) ||
3188 diskimage_exist(machine, 5, DISKIMAGE_SCSI) ||
3189 diskimage_exist(machine, 6, DISKIMAGE_SCSI) ||
3190 diskimage_exist(machine, 7, DISKIMAGE_SCSI))
3191 bus_pci_add(machine, pci_data, mem, 0, 1, 0, pci_ahc_init, pci_ahc_rr);
3192
3193 /* TODO: second ahc */
3194 /* bus_pci_add(machine, pci_data, mem, 0, 2, 0, pci_ahc_init, pci_ahc_rr); */
3195
3196 break;
3197 case 35:
3198 strlcat(machine->machine_name,
3199 " (Origin 3000)", MACHINE_NAME_MAXBUF);
3200 /* 4 cpus per node */
3201
3202 machine->main_console_handle =
3203 dev_zs_init(machine, mem, 0x1fbd9830,
3204 0, 1, "zs console");
3205 break;
3206 case 53:
3207 strlcat(machine->machine_name,
3208 " (Origin 350)", MACHINE_NAME_MAXBUF);
3209 /*
3210 * According to http://kumba.drachentekh.net/xml/myguide.html
3211 * Origin 350, Tezro IP53 R16000
3212 */
3213 break;
3214 default:
3215 fatal("unimplemented SGI machine type IP%i\n",
3216 machine->machine_subtype);
3217 exit(1);
3218 }
3219 } else {
3220 switch (machine->machine_subtype) {
3221
3222 case MACHINE_ARC_NEC_RD94:
3223 case MACHINE_ARC_NEC_R94:
3224 case MACHINE_ARC_NEC_R96:
3225 /*
3226 * "NEC-RD94" (NEC RISCstation 2250)
3227 * "NEC-R94" (NEC RISCstation 2200)
3228 * "NEC-R96" (NEC Express RISCserver)
3229 *
3230 * http://mirror.aarnet.edu.au/pub/NetBSD/misc/chs/arcdiag.out (NEC-R96)
3231 */
3232
3233 switch (machine->machine_subtype) {
3234 case MACHINE_ARC_NEC_RD94:
3235 strlcat(machine->machine_name,
3236 " (NEC-RD94, NEC RISCstation 2250)",
3237 MACHINE_NAME_MAXBUF);
3238 break;
3239 case MACHINE_ARC_NEC_R94:
3240 strlcat(machine->machine_name, " (NEC-R94; NEC RISCstation 2200)",
3241 MACHINE_NAME_MAXBUF);
3242 break;
3243 case MACHINE_ARC_NEC_R96:
3244 strlcat(machine->machine_name, " (NEC-R96; NEC Express RISCserver)",
3245 MACHINE_NAME_MAXBUF);
3246 break;
3247 }
3248
3249 /* TODO: interrupt controller! */
3250
3251 pci_data = device_add(machine,
3252 "rd94 addr=0x80000000, irq=0");
3253
3254 device_add(machine, "sn addr=0x80001000 irq=0");
3255 dev_mc146818_init(machine, mem, 0x80004000ULL, 0, MC146818_ARC_NEC, 1);
3256 i = dev_pckbc_init(machine, mem, 0x80005000ULL, PCKBC_8042, 0, 0, machine->use_x11, 0);
3257
3258 snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=3 addr=0x80006000 in_use=%i name2=tty0", machine->use_x11? 0 : 1);
3259 j = (size_t)device_add(machine, tmpstr);
3260 snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=0 addr=0x80007000 in_use=%i name2=tty1", 0);
3261 device_add(machine, tmpstr);
3262
3263 if (machine->use_x11)
3264 machine->main_console_handle = i;
3265 else
3266 machine->main_console_handle = j;
3267
3268 /* lpt at 0x80008000 */
3269
3270 device_add(machine, "fdc addr=0x8000c000, irq=0");
3271
3272 switch (machine->machine_subtype) {
3273 case MACHINE_ARC_NEC_RD94:
3274 case MACHINE_ARC_NEC_R94:
3275 /* PCI devices: (NOTE: bus must be 0, device must be 3, 4, or 5, for NetBSD to accept interrupts) */
3276 bus_pci_add(machine, pci_data, mem, 0, 3, 0, pci_dec21030_init, pci_dec21030_rr); /* tga graphics */
3277 break;
3278 case MACHINE_ARC_NEC_R96:
3279 dev_fb_init(machine, mem, 0x100e00000ULL,
3280 VFB_GENERIC, 640,480, 1024,480,
3281 8, "necvdfrb");
3282 break;
3283 }
3284 break;
3285
3286 case MACHINE_ARC_NEC_R98:
3287 /*
3288 * "NEC-R98" (NEC RISCserver 4200)
3289 *
3290 * According to http://mail-index.netbsd.org/port-arc/2004/02/01/0001.html:
3291 *
3292 * Network adapter at "start: 0x 0 18600000, length: 0x1000, level: 4, vector: 9"
3293 * Disk at "start: 0x 0 18c103f0, length: 0x1000, level: 5, vector: 6"
3294 * Keyboard at "start: 0x 0 18c20060, length: 0x1000, level: 5, vector: 3"
3295 * Serial at "start: 0x 0 18c103f8, length: 0x1000, level: 5, vector: 4"
3296 * Serial at "start: 0x 0 18c102f8, length: 0x1000, level: 5, vector: 4"
3297 * Parallel at "start: 0x 0 18c10278, length: 0x1000, level: 5, vector: 5"
3298 */
3299
3300 strlcat(machine->machine_name,
3301 " (NEC-R98; NEC RISCserver 4200)",
3302 MACHINE_NAME_MAXBUF);
3303
3304 /*
3305 * Windows NT access stuff at these addresses:
3306 *
3307 * 19980308, 18000210, 18c0a008,
3308 * 19022018, 19026010, andso on.
3309 */
3310 break;
3311
3312 case MACHINE_ARC_JAZZ_PICA:
3313 case MACHINE_ARC_JAZZ_MAGNUM:
3314 /*
3315 * "PICA-61"
3316 *
3317 * According to NetBSD 1.6.2:
3318 *
3319 * jazzio0 at mainbus0
3320 * timer0 at jazzio0 addr 0xe0000228
3321 * mcclock0 at jazzio0 addr 0xe0004000: mc146818 or compatible
3322 * lpt at jazzio0 addr 0xe0008000 intr 0 not configured
3323 * fdc at jazzio0 addr 0xe0003000 intr 1 not configured
3324 * MAGNUM at jazzio0 addr 0xe000c000 intr 2 not configured
3325 * ALI_S3 at jazzio0 addr 0xe0800000 intr 3 not configured
3326 * sn0 at jazzio0 addr 0xe0001000 intr 4: SONIC Ethernet
3327 * sn0: Ethernet address 69:6a:6b:6c:00:00
3328 * asc0 at jazzio0 addr 0xe0002000 intr 5: NCR53C94, target 0
3329 * pckbd at jazzio0 addr 0xe0005000 intr 6 not configured
3330 * pms at jazzio0 addr 0xe0005000 intr 7 not configured
3331 * com0 at jazzio0 addr 0xe0006000 intr 8: ns16550a, working fifo
3332 * com at jazzio0 addr 0xe0007000 intr 9 not configured
3333 * jazzisabr0 at mainbus0
3334 * isa0 at jazzisabr0 isa_io_base 0xe2000000 isa_mem_base 0xe3000000
3335 *
3336 * "Microsoft-Jazz", "MIPS Magnum"
3337 *
3338 * timer0 at jazzio0 addr 0xe0000228
3339 * mcclock0 at jazzio0 addr 0xe0004000: mc146818 or compatible
3340 * lpt at jazzio0 addr 0xe0008000 intr 0 not configured
3341 * fdc at jazzio0 addr 0xe0003000 intr 1 not configured
3342 * MAGNUM at jazzio0 addr 0xe000c000 intr 2 not configured
3343 * VXL at jazzio0 addr 0xe0800000 intr 3 not configured
3344 * sn0 at jazzio0 addr 0xe0001000 intr 4: SONIC Ethernet
3345 * sn0: Ethernet address 69:6a:6b:6c:00:00
3346 * asc0 at jazzio0 addr 0xe0002000 intr 5: NCR53C94, target 0
3347 * scsibus0 at asc0: 8 targets, 8 luns per target
3348 * pckbd at jazzio0 addr 0xe0005000 intr 6 not configured
3349 * pms at jazzio0 addr 0xe0005000 intr 7 not configured
3350 * com0 at jazzio0 addr 0xe0006000 intr 8: ns16550a, working fifo
3351 * com at jazzio0 addr 0xe0007000 intr 9 not configured
3352 * jazzisabr0 at mainbus0
3353 * isa0 at jazzisabr0 isa_io_base 0xe2000000 isa_mem_base 0xe3000000
3354 */
3355
3356 switch (machine->machine_subtype) {
3357 case MACHINE_ARC_JAZZ_PICA:
3358 strlcat(machine->machine_name, " (Microsoft Jazz, Acer PICA-61)",
3359 MACHINE_NAME_MAXBUF);
3360 break;
3361 case MACHINE_ARC_JAZZ_MAGNUM:
3362 strlcat(machine->machine_name, " (Microsoft Jazz, MIPS Magnum)",
3363 MACHINE_NAME_MAXBUF);
3364 break;
3365 default:
3366 fatal("error in machine.c. jazz\n");
3367 exit(1);
3368 }
3369
3370 machine->md_int.jazz_data = device_add(machine,
3371 "jazz addr=0x80000000");
3372 machine->md_interrupt = jazz_interrupt;
3373
3374 i = dev_pckbc_init(machine, mem, 0x80005000ULL,
3375 PCKBC_JAZZ, 8 + 6, 8 + 7, machine->use_x11, 0);
3376
3377 snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=16 addr=0x80006000 in_use=%i name2=tty0", machine->use_x11? 0 : 1);
3378 j = (size_t)device_add(machine, tmpstr);
3379 snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=17 addr=0x80007000 in_use=%i name2=tty1", 0);
3380 device_add(machine, tmpstr);
3381
3382 if (machine->use_x11)
3383 machine->main_console_handle = i;
3384 else
3385 machine->main_console_handle = j;
3386
3387 switch (machine->machine_subtype) {
3388 case MACHINE_ARC_JAZZ_PICA:
3389 if (machine->use_x11) {
3390 dev_vga_init(machine, mem,
3391 0x400a0000ULL, 0x600003c0ULL,
3392 machine->machine_name);
3393 arcbios_console_init(machine,
3394 0x400b8000ULL, 0x600003c0ULL);
3395 }
3396 break;
3397 case MACHINE_ARC_JAZZ_MAGNUM:
3398 /* PROM mirror? */
3399 dev_ram_init(mem, 0xfff00000, 0x100000,
3400 DEV_RAM_MIRROR, 0x1fc00000);
3401
3402 /* VXL. TODO */
3403 /* control at 0x60100000? */
3404 dev_fb_init(machine, mem, 0x60200000ULL,
3405 VFB_GENERIC, 1024,768, 1024,768,
3406 8, "VXL");
3407 break;
3408 }
3409
3410 /* irq 8 + 4 */
3411 device_add(machine, "sn addr=0x80001000 irq=12");
3412
3413 dev_asc_init(machine, mem,
3414 0x80002000ULL, 8 + 5, NULL, DEV_ASC_PICA,
3415 dev_jazz_dma_controller,
3416 machine->md_int.jazz_data);
3417
3418 device_add(machine, "fdc addr=0x80003000, irq=0");
3419
3420 dev_mc146818_init(machine, mem,
3421 0x80004000ULL, 2, MC146818_ARC_JAZZ, 1);
3422
3423 #if 0
3424 Not yet.
3425 dev_wdc_init(machine, mem, 0x900001f0ULL, 8+16 + 14, 0);
3426 #endif
3427
3428 break;
3429
3430 case MACHINE_ARC_JAZZ_M700:
3431 /*
3432 * "Microsoft-Jazz", "Olivetti M700"
3433 *
3434 * Different enough from Pica and Magnum to be
3435 * separate here.
3436 *
3437 * See http://mail-index.netbsd.org/port-arc/2000/10/18/0001.html.
3438 */
3439
3440 strlcat(machine->machine_name, " (Microsoft Jazz, Olivetti M700)",
3441 MACHINE_NAME_MAXBUF);
3442
3443 machine->md_int.jazz_data = device_add(machine,
3444 "jazz addr=0x80000000");
3445 machine->md_interrupt = jazz_interrupt;
3446
3447 dev_mc146818_init(machine, mem,
3448 0x80004000ULL, 2, MC146818_ARC_JAZZ, 1);
3449
3450 i = 0; /* TODO: Yuck! */
3451 #if 0
3452 i = dev_pckbc_init(machine, mem, 0x80005000ULL,
3453 PCKBC_JAZZ, 8 + 6, 8 + 7, machine->use_x11, 0);
3454 #endif
3455
3456 snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=16 addr=0x80006000 in_use=%i name2=tty0", machine->use_x11? 0 : 1);
3457 j = (size_t)device_add(machine, tmpstr);
3458 snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=17 addr=0x80007000 in_use=%i name2=tty1", 0);
3459 device_add(machine, tmpstr);
3460
3461 if (machine->use_x11)
3462 machine->main_console_handle = i;
3463 else
3464 machine->main_console_handle = j;
3465
3466 dev_m700_fb_init(machine, mem,
3467 0x180080000ULL, 0x100000000ULL);
3468
3469 break;
3470
3471 case MACHINE_ARC_DESKTECH_TYNE:
3472 /*
3473 * "Deskstation Tyne" (?)
3474 *
3475 * TODO
3476 * http://mail-index.netbsd.org/port-arc/2000/10/14/0000.html
3477 */
3478
3479 strlcat(machine->machine_name, " (Deskstation Tyne)",
3480 MACHINE_NAME_MAXBUF);
3481
3482 snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=0 addr=0x9000003f8 in_use=%i name2=tty0", machine->use_x11? 0 : 1);
3483 i = (size_t)device_add(machine, tmpstr);
3484 device_add(machine, "ns16550 irq=0 addr=0x9000002f8 in_use=0 name2=tty1");
3485 device_add(machine, "ns16550 irq=0 addr=0x9000003e8 in_use=0 name2=tty2");
3486 device_add(machine, "ns16550 irq=0 addr=0x9000002e8 in_use=0 name2=tty3");
3487
3488 dev_mc146818_init(machine, mem,
3489 0x900000070ULL, 2, MC146818_PC_CMOS, 1);
3490
3491 #if 0
3492 dev_wdc_init(machine, mem, 0x9000001f0ULL, 0, 0);
3493 dev_wdc_init(machine, mem, 0x900000170ULL, 0, 2);
3494 #endif
3495 /* PC kbd */
3496 j = dev_pckbc_init(machine, mem, 0x900000060ULL,
3497 PCKBC_8042, 0, 0, machine->use_x11, 0);
3498
3499 if (machine->use_x11)
3500 machine->main_console_handle = j;
3501 else
3502 machine->main_console_handle = i;
3503
3504 if (machine->use_x11) {
3505 dev_vga_init(machine, mem, 0x1000a0000ULL,
3506 0x9000003c0ULL, machine->machine_name);
3507
3508 arcbios_console_init(machine,
3509 0x1000b8000ULL, 0x9000003c0ULL);
3510 }
3511 break;
3512
3513 default:
3514 fatal("Unimplemented ARC machine type %i\n",
3515 machine->machine_subtype);
3516 exit(1);
3517 }
3518 }
3519
3520 /*
3521 * This is important: :-)
3522 *
3523 * TODO: There should not be any use of ARCBIOS before this
3524 * point.
3525 */
3526
3527 if (machine->prom_emulation)
3528 arcbios_init(machine, arc_wordlen == sizeof(uint64_t),
3529 sgi_ram_offset);
3530 else
3531 goto no_arc_prom_emulation; /* TODO: ugly */
3532
3533 /*
3534 * TODO: How to build the component tree intermixed with
3535 * the rest of device initialization?
3536 */
3537
3538 /*
3539 * Boot string in ARC format:
3540 *
3541 * TODO: How about floppies? multi()disk()fdisk()
3542 * Is tftp() good for netbooting?
3543 */
3544 init_bootpath = malloc(500);
3545 if (init_bootpath == NULL) {
3546 fprintf(stderr, "out of mem, bootpath\n");
3547 exit(1);
3548 }
3549 init_bootpath[0] = '\0';
3550
3551 if (bootdev_id < 0 || machine->force_netboot) {
3552 snprintf(init_bootpath, 400, "tftp()");
3553 } else {
3554 /* TODO: Make this nicer. */
3555 if (machine->machine_type == MACHINE_SGI) {
3556 if (machine->machine_subtype == 30)
3557 strlcat(init_bootpath, "xio(0)pci(15)",
3558 MACHINE_NAME_MAXBUF);
3559 if (machine->machine_subtype == 32)
3560 strlcat(init_bootpath, "pci(0)",
3561 MACHINE_NAME_MAXBUF);
3562 }
3563
3564 if (diskimage_is_a_cdrom(machine, bootdev_id,
3565 bootdev_type))
3566 snprintf(init_bootpath + strlen(init_bootpath),
3567 400,"scsi(0)cdrom(%i)fdisk(0)", bootdev_id);
3568 else
3569 snprintf(init_bootpath + strlen(init_bootpath),
3570 400,"scsi(0)disk(%i)rdisk(0)partition(1)",
3571 bootdev_id);
3572 }
3573
3574 if (machine->machine_type == MACHINE_ARC)
3575 strlcat(init_bootpath, "\\", MACHINE_NAME_MAXBUF);
3576
3577 bootstr = malloc(BOOTSTR_BUFLEN);
3578 if (bootstr == NULL) {
3579 fprintf(stderr, "out of memory\n");
3580 exit(1);
3581 }
3582 strlcpy(bootstr, init_bootpath, BOOTSTR_BUFLEN);
3583 if (strlcat(bootstr, machine->boot_kernel_filename,
3584 BOOTSTR_BUFLEN) >= BOOTSTR_BUFLEN) {
3585 fprintf(stderr, "boot string too long?\n");
3586 exit(1);
3587 }
3588
3589 /* Boot args., eg "-a" */
3590 bootarg = machine->boot_string_argument;
3591
3592 /* argc, argv, envp in a0, a1, a2: */
3593 cpu->cd.mips.gpr[MIPS_GPR_A0] = 0; /* note: argc is increased later */
3594
3595 /* TODO: not needed? */
3596 cpu->cd.mips.gpr[MIPS_GPR_SP] = (int64_t)(int32_t)
3597 (machine->physical_ram_in_mb * 1048576 + 0x80000000 - 0x2080);
3598
3599 /* Set up argc/argv: */
3600 addr = ARC_ENV_STRINGS;
3601 addr2 = ARC_ARGV_START;
3602 cpu->cd.mips.gpr[MIPS_GPR_A1] = addr2;
3603
3604 /* bootstr: */
3605 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3606 add_environment_string(cpu, bootstr, &addr);
3607 cpu->cd.mips.gpr[MIPS_GPR_A0] ++;
3608
3609 /* bootarg: */
3610 if (bootarg[0] != '\0') {
3611 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3612 add_environment_string(cpu, bootarg, &addr);
3613 cpu->cd.mips.gpr[MIPS_GPR_A0] ++;
3614 }
3615
3616 cpu->cd.mips.gpr[MIPS_GPR_A2] = addr2;
3617
3618 /*
3619 * Add environment variables. For each variable, add it
3620 * as a string using add_environment_string(), and add a
3621 * pointer to it to the ARC_ENV_POINTERS array.
3622 */
3623 if (machine->use_x11) {
3624 if (machine->machine_type == MACHINE_ARC) {
3625 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3626 add_environment_string(cpu, "CONSOLEIN=multi()key()keyboard()console()", &addr);
3627 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3628 add_environment_string(cpu, "CONSOLEOUT=multi()video()monitor()console()", &addr);
3629 } else {
3630 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3631 add_environment_string(cpu, "ConsoleIn=keyboard()", &addr);
3632 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3633 add_environment_string(cpu, "ConsoleOut=video()", &addr);
3634
3635 /* g for graphical mode. G for graphical mode
3636 with SGI logo visible on Irix? */
3637 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3638 add_environment_string(cpu, "console=g", &addr);
3639 }
3640 } else {
3641 if (machine->machine_type == MACHINE_ARC) {
3642 /* TODO: serial console for ARC? */
3643 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3644 add_environment_string(cpu, "CONSOLEIN=multi()serial(0)", &addr);
3645 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3646 add_environment_string(cpu, "CONSOLEOUT=multi()serial(0)", &addr);
3647 } else {
3648 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3649 add_environment_string(cpu, "ConsoleIn=serial(0)", &addr);
3650 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3651 add_environment_string(cpu, "ConsoleOut=serial(0)", &addr);
3652
3653 /* 'd' or 'd2' in Irix, 'ttyS0' in Linux? */
3654 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3655 add_environment_string(cpu, "console=d", &addr); /* d2 = serial? */
3656 }
3657 }
3658
3659 if (machine->machine_type == MACHINE_SGI) {
3660 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3661 add_environment_string(cpu, "AutoLoad=No", &addr);
3662 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3663 add_environment_string(cpu, "diskless=0", &addr);
3664 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3665 add_environment_string(cpu, "volume=80", &addr);
3666 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3667 add_environment_string(cpu, "sgilogo=y", &addr);
3668
3669 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3670 add_environment_string(cpu, "monitor=h", &addr);
3671 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3672 add_environment_string(cpu, "TimeZone=GMT", &addr);
3673 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3674 add_environment_string(cpu, "nogfxkbd=1", &addr);
3675
3676 /* TODO: 'xio(0)pci(15)scsi(0)disk(1)rdisk(0)partition(0)' on IP30 at least */
3677
3678 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3679 add_environment_string(cpu, "SystemPartition=pci(0)scsi(0)disk(2)rdisk(0)partition(8)", &addr);
3680 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3681 add_environment_string(cpu, "OSLoadPartition=pci(0)scsi(0)disk(2)rdisk(0)partition(0)", &addr);
3682 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3683 add_environment_string(cpu, "OSLoadFilename=/unix", &addr);
3684 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3685 add_environment_string(cpu, "OSLoader=sash", &addr);
3686
3687 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3688 add_environment_string(cpu, "rbaud=9600", &addr);
3689 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3690 add_environment_string(cpu, "rebound=y", &addr);
3691 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3692 add_environment_string(cpu, "crt_option=1", &addr);
3693 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3694 add_environment_string(cpu, "netaddr=10.0.0.1", &addr);
3695
3696 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3697 add_environment_string(cpu, "keybd=US", &addr);
3698
3699 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3700 add_environment_string(cpu, "cpufreq=3", &addr);
3701 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3702 add_environment_string(cpu, "dbaud=9600", &addr);
3703 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3704 add_environment_string(cpu, eaddr_string, &addr);
3705 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3706 add_environment_string(cpu, "verbose=istrue", &addr);
3707 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3708 add_environment_string(cpu, "showconfig=istrue", &addr);
3709 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3710 add_environment_string(cpu, "diagmode=v", &addr);
3711 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3712 add_environment_string(cpu, "kernname=unix", &addr);
3713 } else {
3714 char *tmp;
3715 size_t mlen = strlen(bootarg) + strlen("OSLOADOPTIONS=") + 2;
3716 tmp = malloc(mlen);
3717 snprintf(tmp, mlen, "OSLOADOPTIONS=%s", bootarg);
3718 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3719 add_environment_string(cpu, tmp, &addr);
3720
3721 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3722 add_environment_string(cpu, "OSLOADPARTITION=scsi(0)cdrom(6)fdisk(0);scsi(0)disk(0)rdisk(0)partition(1)", &addr);
3723
3724 store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t));
3725 add_environment_string(cpu, "SYSTEMPARTITION=scsi(0)cdrom(6)fdisk(0);scsi(0)disk(0)rdisk(0)partition(1)", &addr);
3726 }
3727
3728 /* End the environment strings with an empty zero-terminated
3729 string, and the envp array with a NULL pointer. */
3730 add_environment_string(cpu, "", &addr); /* the end */
3731 store_pointer_and_advance(cpu, &addr2,
3732 0, arc_wordlen==sizeof(uint64_t));
3733
3734 no_arc_prom_emulation: /* TODO: ugly, get rid of the goto */
3735
3736 /* Return address: (0x20 = ReturnFromMain()) */
3737 cpu->cd.mips.gpr[MIPS_GPR_RA] = ARC_FIRMWARE_ENTRIES + 0x20;
3738
3739 break;
3740
3741 case MACHINE_MESHCUBE:
3742 machine->machine_name = "MeshCube";
3743
3744 if (machine->physical_ram_in_mb != 64)
3745 fprintf(stderr, "WARNING! MeshCubes are supposed to have exactly 64 MB RAM. Continuing anyway.\n");
3746 if (machine->use_x11)
3747 fprintf(stderr, "WARNING! MeshCube with -X is meaningless. Continuing anyway.\n");
3748
3749 /* First of all, the MeshCube has an Au1500 in it: */
3750 machine->md_interrupt = au1x00_interrupt;
3751 machine->md_int.au1x00_ic_data = dev_au1x00_init(machine, mem);
3752
3753 /*
3754 * TODO: Which non-Au1500 devices, and at what addresses?
3755 *
3756 * "4G Systems MTX-1 Board" at ?
3757 * 1017fffc, 14005004, 11700000, 11700008, 11900014,
3758 * 1190002c, 11900100, 11900108, 1190010c,
3759 * 10400040 - 10400074,
3760 * 14001000 (possibly LCD?)
3761 * 11100028 (possibly ttySx?)
3762 *
3763 * "usb_ohci=base:0x10100000,len:0x100000,irq:26"
3764 */
3765
3766 device_add(machine, "random addr=0x1017fffc len=4");
3767
3768 /*
3769 * TODO: A Linux kernel wants "memsize" from somewhere... I
3770 * haven't found any docs on how it is used though.
3771 */
3772
3773 cpu->cd.mips.gpr[MIPS_GPR_A0] = 1;
3774 cpu->cd.mips.gpr[MIPS_GPR_A1] = 0xa0001000ULL;
3775 store_32bit_word(cpu, cpu->cd.mips.gpr[MIPS_GPR_A1],
3776 0xa0002000ULL);
3777 store_string(cpu, 0xa0002000ULL, "something=somethingelse");
3778
3779 cpu->cd.mips.gpr[MIPS_GPR_A2] = 0xa0003000ULL;
3780 store_string(cpu, 0xa0002000ULL, "hello=world\n");
3781
3782 break;
3783
3784 case MACHINE_NETGEAR:
3785 machine->machine_name = "NetGear WG602";
3786
3787 if (machine->use_x11)
3788 fprintf(stderr, "WARNING! NetGear with -X is meaningless. Continuing anyway.\n");
3789 if (machine->physical_ram_in_mb != 16)
3790 fprintf(stderr, "WARNING! Real NetGear WG602 boxes have exactly 16 MB RAM. Continuing anyway.\n");
3791
3792 /*
3793 * Lots of info about the IDT 79RC 32334
3794 * http://www.idt.com/products/pages/Integrated_Processors-79RC32334.html
3795 */
3796 device_add(machine, "8250 addr=0x18000800 addr_mult=4 irq=0");
3797 break;
3798
3799 case MACHINE_SONYNEWS:
3800 /*
3801 * There are several models, according to
3802 * http://www.netbsd.org/Ports/newsmips/:
3803 *
3804 * "R3000 and hyper-bus based models"
3805 * NWS-3470D, -3410, -3460, -3710, -3720
3806 *
3807 * "R4000/4400 and apbus based models"
3808 * NWS-5000
3809 *
3810 * For example: (found using google)
3811 *
3812 * cpu_model = news3700
3813 * SONY NET WORK STATION, Model NWS-3710, Machine ID #30145
3814 * cpu0: MIPS R3000 (0x220) Rev. 2.0 with MIPS R3010 Rev.2.0
3815 * 64KB/4B direct-mapped I, 64KB/4B direct-mapped w-thr. D
3816 *
3817 * See http://katsu.watanabe.name/doc/sonynews/model.html
3818 * for more details.
3819 */
3820 cpu->byte_order = EMUL_BIG_ENDIAN;
3821 machine->machine_name = "Sony NeWS (NET WORK STATION)";
3822
3823 /* This is just a test. TODO */
3824 {
3825 int i;
3826 for (i=0; i<32; i++)
3827 cpu->cd.mips.gpr[i] =
3828 0x01230000 + (i << 8) + 0x55;
3829 }
3830
3831 machine->main_console_handle =
3832 dev_zs_init(machine, mem, 0x1e950000, 0, 1, "zs console");
3833
3834 break;
3835
3836 case MACHINE_EVBMIPS:
3837 /* http://www.netbsd.org/Ports/evbmips/ */
3838 cpu->byte_order = EMUL_LITTLE_ENDIAN;
3839
3840 switch (machine->machine_subtype) {
3841 case MACHINE_EVBMIPS_MALTA:
3842 case MACHINE_EVBMIPS_MALTA_BE:
3843 machine->machine_name = "MALTA (evbmips, little endian)";
3844 cpu->byte_order = EMUL_LITTLE_ENDIAN;
3845
3846 if (machine->machine_subtype == MACHINE_EVBMIPS_MALTA_BE) {
3847 machine->machine_name = "MALTA (evbmips, big endian)";
3848 cpu->byte_order = EMUL_BIG_ENDIAN;
3849 }
3850
3851 /* ISA interrupt controllers: */
3852 snprintf(tmpstr, sizeof(tmpstr), "8259 irq=24 addr=0x18000020");
3853 machine->md_int.isa_pic_data.pic1 = device_add(machine, tmpstr);
3854 snprintf(tmpstr, sizeof(tmpstr), "8259 irq=24 addr=0x180000a0");
3855 machine->md_int.isa_pic_data.pic2 = device_add(machine, tmpstr);
3856 machine->md_interrupt = malta_interrupt;
3857
3858 dev_mc146818_init(machine, mem, 0x18000070, 8 + 8, MC146818_PC_CMOS, 1);
3859
3860 machine->main_console_handle = (size_t)
3861 device_add(machine, "ns16550 irq=12 addr=0x180003f8 name2=tty0");
3862 device_add(machine, "ns16550 irq=11 addr=0x180002f8 name2=tty1");
3863
3864 snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=4 addr=0x%x name2=tty2", MALTA_CBUSUART);
3865 device_add(machine, tmpstr);
3866 /* TODO: Irqs */
3867 pci_data = dev_gt_init(machine, mem, 0x1be00000, 8+9, 8+9, 120);
3868
3869 /* TODO: Haha, this is bogus. Just a cut&paste
3870 from the Cobalt emulation above. */
3871 bus_pci_add(machine, pci_data, mem, 0, 9, 0, pci_vt82c586_isa_init, pci_vt82c586_isa_rr);
3872 bus_pci_add(machine, pci_data, mem, 0, 9, 1, pci_vt82c586_ide_init, pci_vt82c586_ide_rr);
3873
3874 device_add(machine, "malta_lcd addr=0x1f000400");
3875 break;
3876 case MACHINE_EVBMIPS_PB1000:
3877 machine->machine_name = "PB1000 (evbmips)";
3878 cpu->byte_order = EMUL_BIG_ENDIAN;
3879
3880 machine->md_interrupt = au1x00_interrupt;
3881 machine->md_int.au1x00_ic_data = dev_au1x00_init(machine, mem);
3882 /* TODO */
3883 break;
3884 default:
3885 fatal("Unimplemented EVBMIPS model.\n");
3886 exit(1);
3887 }
3888
3889 if (machine->prom_emulation) {
3890 /* This is just a test. TODO */
3891 for (i=0; i<32; i++)
3892 cpu->cd.mips.gpr[i] =
3893 0x01230000 + (i << 8) + 0x55;
3894
3895 /* NetBSD/evbmips wants these: (at least for Malta) */
3896
3897 /* a0 = argc */
3898 cpu->cd.mips.gpr[MIPS_GPR_A0] = 2;
3899
3900 /* a1 = argv */
3901 cpu->cd.mips.gpr[MIPS_GPR_A1] = (int32_t)0x9fc01000;
3902 store_32bit_word(cpu, (int32_t)0x9fc01000, 0x9fc01040);
3903 store_32bit_word(cpu, (int32_t)0x9fc01004, 0x9fc01200);
3904 store_32bit_word(cpu, (int32_t)0x9fc01008, 0);
3905
3906 bootstr = strdup(machine->boot_kernel_filename);
3907 bootarg = strdup(machine->boot_string_argument);
3908 store_string(cpu, (int32_t)0x9fc01040, bootstr);
3909 store_string(cpu, (int32_t)0x9fc01200, bootarg);
3910
3911 /* a2 = (yamon_env_var *)envp */
3912 cpu->cd.mips.gpr[MIPS_GPR_A2] = (int32_t)0x9fc01800;
3913 {
3914 uint64_t env = cpu->cd.mips.gpr[MIPS_GPR_A2];
3915 uint64_t tmpptr = 0xffffffff9fc01c00ULL;
3916 char tmps[50];
3917
3918 snprintf(tmps, sizeof(tmps), "0x%08x",
3919 machine->physical_ram_in_mb * 1048576);
3920 add_environment_string_dual(cpu,
3921 &env, &tmpptr, "memsize", tmps);
3922
3923 add_environment_string_dual(cpu,
3924 &env, &tmpptr, "yamonrev", "02.06");
3925
3926 /* End of env: */
3927 tmpptr = 0;
3928 add_environment_string_dual(cpu,
3929 &env, &tmpptr, NULL, NULL);
3930 }
3931
3932 /* a3 = memsize */
3933 cpu->cd.mips.gpr[MIPS_GPR_A3] =
3934 machine->physical_ram_in_mb * 1048576;
3935 /* Hm. Linux ignores a3. */
3936
3937 /*
3938 * TODO:
3939 * Core ID numbers.
3940 * How much of this is not valid for PBxxxx?
3941 *
3942 * See maltareg.h for more info.
3943 */
3944 store_32bit_word(cpu, (int32_t)(0x80000000 + MALTA_REVISION), (1 << 10) + 0x26);
3945
3946 /* Call vectors at 0x9fc005xx: */
3947 for (i=0; i<0x100; i+=4)
3948 store_32bit_word(cpu, (int64_t)(int32_t)0x9fc00500 + i,
3949 (int64_t)(int32_t)0x9fc00800 + i);
3950 }
3951 break;
3952
3953 case MACHINE_PSP:
3954 /*
3955 * The Playstation Portable seems to be a strange beast.
3956 *
3957 * http://yun.cup.com/psppg004.html (in Japanese) seems to
3958 * suggest that virtual addresses are not displaced by
3959 * 0x80000000 as on normal CPUs, but by 0x40000000?
3960 */
3961 machine->machine_name = "Playstation Portable";
3962 cpu->byte_order = EMUL_LITTLE_ENDIAN;
3963
3964 if (!machine->use_x11 && !quiet_mode)
3965 fprintf(stderr, "-------------------------------------"
3966 "------------------------------------------\n"
3967 "\n WARNING! You are emulating a PSP without -X. "
3968 "You will miss graphical output!\n\n"
3969 "-------------------------------------"
3970 "------------------------------------------\n");
3971
3972 /* 480 x 272 pixels framebuffer (512 bytes per line) */
3973 fb = dev_fb_init(machine, mem, 0x04000000, VFB_HPCMIPS,
3974 480,272, 512,1088, -15, "Playstation Portable");
3975
3976 /*
3977 * TODO/NOTE: This is ugly, but necessary since GXemul doesn't
3978 * emulate any MIPS CPU without MMU right now.
3979 */
3980 mips_coproc_tlb_set_entry(cpu, 0, 1048576*16,
3981 0x44000000 /*vaddr*/, 0x4000000, 0x4000000 + 1048576*16,
3982 1,1,1,1,1, 0, 2, 2);
3983 mips_coproc_tlb_set_entry(cpu, 1, 1048576*16,
3984 0x8000000 /*vaddr*/, 0x0, 0x0 + 1048576*16,
3985 1,1,1,1,1, 0, 2, 2);
3986 mips_coproc_tlb_set_entry(cpu, 2, 1048576*16,
3987 0x9000000 /*vaddr*/, 0x01000000, 0x01000000 + 1048576*16,
3988 1,1,1,1,1, 0, 2, 2);
3989 mips_coproc_tlb_set_entry(cpu, 3, 1048576*16,
3990 0x0 /*vaddr*/, 0, 0 + 1048576*16, 1,1,1,1,1, 0, 2, 2);
3991
3992 cpu->cd.mips.gpr[MIPS_GPR_SP] = 0xfff0;
3993
3994 break;
3995 #endif /* ENABLE_MIPS */
3996
3997 #ifdef ENABLE_PPC
3998 case MACHINE_BAREPPC:
3999 /*
4000 * A "bare" PPC machine.
4001 *
4002 * NOTE: NO devices at all.
4003 */
4004 machine->machine_name = "\"Bare\" PPC machine";
4005 break;
4006
4007 case MACHINE_TESTPPC:
4008 /*
4009 * A PPC test machine, similar to the test machine for MIPS.
4010 */
4011 machine->machine_name = "PPC test machine";
4012
4013 /* TODO: interrupt for PPC? */
4014 snprintf(tmpstr, sizeof(tmpstr), "cons addr=0x%llx irq=0",
4015 (long long)DEV_CONS_ADDRESS);
4016 cons_data = device_add(machine, tmpstr);
4017 machine->main_console_handle = cons_data->console_handle;
4018
4019 snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%llx",
4020 (long long)DEV_MP_ADDRESS);
4021 device_add(machine, tmpstr);
4022
4023 fb = dev_fb_init(machine, mem, DEV_FB_ADDRESS, VFB_GENERIC,
4024 640,480, 640,480, 24, "testppc generic");
4025
4026 snprintf(tmpstr, sizeof(tmpstr), "disk addr=0x%llx",
4027 (long long)DEV_DISK_ADDRESS);
4028 device_add(machine, tmpstr);
4029
4030 snprintf(tmpstr, sizeof(tmpstr), "ether addr=0x%llx irq=0",
4031 (long long)DEV_ETHER_ADDRESS);
4032 device_add(machine, tmpstr);
4033
4034 break;
4035
4036 case MACHINE_WALNUT:
4037 /*
4038 * NetBSD/evbppc (http://www.netbsd.org/Ports/evbppc/)
4039 */
4040 machine->machine_name = "Walnut evaluation board";
4041
4042 break;
4043
4044 case MACHINE_PMPPC:
4045 /*
4046 * NetBSD/pmppc (http://www.netbsd.org/Ports/pmppc/)
4047 */
4048 machine->machine_name = "Artesyn's PM/PPC board";
4049
4050 dev_pmppc_init(mem);
4051
4052 /* com0 = 0xff600300, com1 = 0xff600400 */
4053
4054 machine->main_console_handle = (size_t)device_add(machine, "ns16550 irq=0 addr=0xff600300 name2=tty0");
4055 device_add(machine, "ns16550 irq=0 addr=0xff600400 in_use=0 name2=tty1");
4056
4057 break;
4058
4059 case MACHINE_SANDPOINT:
4060 /*
4061 * NetBSD/sandpoint (http://www.netbsd.org/Ports/sandpoint/)
4062 */
4063 machine->machine_name = "Motorola Sandpoint";
4064
4065 {
4066 int i;
4067 for (i=0; i<32; i++)
4068 cpu->cd.ppc.gpr[i] =
4069 0x12340000 + (i << 8) + 0x55;
4070 }
4071
4072 break;
4073
4074 case MACHINE_BEBOX:
4075 /*
4076 * NetBSD/bebox (http://www.netbsd.org/Ports/bebox/)
4077 */
4078 machine->machine_name = "BeBox";
4079
4080 device_add(machine, "bebox");
4081
4082 machine->main_console_handle = (size_t)
4083 device_add(machine, "ns16550 irq=0 addr=0x800003f8 name2=tty0");
4084 device_add(machine, "ns16550 irq=0 addr=0x800002f8 name2=tty1 in_use=0");
4085
4086 if (machine->use_x11)
4087 dev_vga_init(machine, mem, 0xc00a0000ULL, 0x800003c0ULL,
4088 machine->machine_name);
4089
4090 store_32bit_word(cpu, 0x3010,
4091 machine->physical_ram_in_mb * 1048576);
4092
4093 /* TODO: List of stuff, see http://www.beatjapan.org/
4094 mirror/www.be.com/aboutbe/benewsletter/
4095 Issue27.html#Cookbook for the details. */
4096 store_32bit_word(cpu, 0x301c, 0);
4097
4098 /* NetBSD/bebox: r3 = startkernel, r4 = endkernel,
4099 r5 = args, r6 = ptr to bootinfo? */
4100 cpu->cd.ppc.gpr[3] = 0x3100;
4101 cpu->cd.ppc.gpr[4] = 0x200000;
4102 cpu->cd.ppc.gpr[5] = 0x2000;
4103 store_string(cpu, cpu->cd.ppc.gpr[5], "-a");
4104 cpu->cd.ppc.gpr[6] = machine->physical_ram_in_mb * 1048576
4105 - 0x100;
4106
4107 /* See NetBSD's bebox/include/bootinfo.h for details */
4108 store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 0, 12); /* next */
4109 store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 4, 0); /* mem */
4110 store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 8,
4111 machine->physical_ram_in_mb * 1048576);
4112
4113 store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 12, 20); /* next */
4114 store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 16, 1); /* console */
4115 store_buf(cpu, cpu->cd.ppc.gpr[6] + 20,
4116 machine->use_x11? "vga" : "com", 4);
4117 store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 24, 0x3f8);/* addr */
4118 store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 28, 9600);/* speed */
4119
4120 store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 32, 0); /* next */
4121 store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 36, 2); /* clock */
4122 store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 40, 100);
4123
4124 break;
4125
4126 case MACHINE_PREP:
4127 /*
4128 * NetBSD/prep (http://www.netbsd.org/Ports/prep/)
4129 */
4130 machine->machine_name = "PowerPC Reference Platform";
4131
4132 {
4133 int i;
4134 for (i=0; i<32; i++)
4135 cpu->cd.ppc.gpr[i] =
4136 0x12340000 + (i << 8) + 0x55;
4137 }
4138
4139 /* Linux on PReP has 0xdeadc0de at address 0? (See
4140 http://joshua.raleigh.nc.us/docs/linux-2.4.10_html/113568.html) */
4141 store_32bit_word(cpu, 0, 0xdeadc0de);
4142
4143 /* r6 should point to "residual data"? */
4144 cpu->cd.ppc.gpr[6] = machine->physical_ram_in_mb * 1048576
4145 - 0x1000;
4146
4147 break;
4148
4149 case MACHINE_MACPPC:
4150 /*
4151 * NetBSD/macppc (http://www.netbsd.org/Ports/macppc/)
4152 * OpenBSD/macppc (http://www.openbsd.org/macppc.html)
4153 */
4154 machine->machine_name = "Macintosh (PPC)";
4155
4156 /* r5 = OpenFirmware entry point */
4157 cpu->cd.ppc.gpr[5] = cpu->cd.ppc.of_emul_addr;
4158
4159 break;
4160
4161 case MACHINE_DB64360:
4162 /* For playing with PMON2000 for PPC: */
4163 machine->machine_name = "DB64360";
4164
4165 machine->main_console_handle = (size_t)device_add(machine, "ns16550 irq=0 addr=0x1d000020");
4166
4167 {
4168 int i;
4169 for (i=0; i<32; i++)
4170 cpu->cd.ppc.gpr[i] =
4171 0x12340000 + (i << 8) + 0x55;
4172 }
4173
4174 break;
4175 #endif /* ENABLE_PPC */
4176
4177 #ifdef ENABLE_SPARC
4178 case MACHINE_BARESPARC:
4179 /* A bare SPARC machine, with no devices. */
4180 machine->machine_name = "\"Bare\" SPARC machine";
4181 break;
4182
4183 case MACHINE_TESTSPARC:
4184 machine->machine_name = "SPARC test machine";
4185
4186 snprintf(tmpstr, sizeof(tmpstr), "cons addr=0x%llx irq=0",
4187 (long long)DEV_CONS_ADDRESS);
4188 cons_data = device_add(machine, tmpstr);
4189 machine->main_console_handle = cons_data->console_handle;
4190
4191 snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%llx",
4192 (long long)DEV_MP_ADDRESS);
4193 device_add(machine, tmpstr);
4194
4195 fb = dev_fb_init(machine, mem, DEV_FB_ADDRESS, VFB_GENERIC,
4196 640,480, 640,480, 24, "testsparc generic");
4197
4198 snprintf(tmpstr, sizeof(tmpstr), "disk addr=0x%llx",
4199 (long long)DEV_DISK_ADDRESS);
4200 device_add(machine, tmpstr);
4201
4202 snprintf(tmpstr, sizeof(tmpstr), "ether addr=0x%llx irq=0",
4203 (long long)DEV_ETHER_ADDRESS);
4204 device_add(machine, tmpstr);
4205
4206 break;
4207
4208 case MACHINE_ULTRA1:
4209 /*
4210 * NetBSD/sparc64 (http://www.netbsd.org/Ports/sparc64/)
4211 * OpenBSD/sparc64 (http://www.openbsd.org/sparc64.html)
4212 */
4213 machine->machine_name = "Sun Ultra1";
4214 break;
4215 #endif /* ENABLE_SPARC */
4216
4217 #ifdef ENABLE_ALPHA
4218 case MACHINE_BAREALPHA:
4219 machine->machine_name = "\"Bare\" Alpha machine";
4220 break;
4221
4222 case MACHINE_TESTALPHA:
4223 machine->machine_name = "Alpha test machine";
4224
4225 snprintf(tmpstr, sizeof(tmpstr), "cons addr=0x%llx irq=0",
4226 (long long)DEV_CONS_ADDRESS);
4227 cons_data = device_add(machine, tmpstr);
4228 machine->main_console_handle = cons_data->console_handle;
4229
4230 snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%llx",
4231 (long long)DEV_MP_ADDRESS);
4232 device_add(machine, tmpstr);
4233
4234 fb = dev_fb_init(machine, mem, DEV_FB_ADDRESS, VFB_GENERIC,
4235 640,480, 640,480, 24, "testalpha generic");
4236
4237 snprintf(tmpstr, sizeof(tmpstr), "disk addr=0x%llx",
4238 (long long)DEV_DISK_ADDRESS);
4239 device_add(machine, tmpstr);
4240
4241 snprintf(tmpstr, sizeof(tmpstr), "ether addr=0x%llx irq=0",
4242 (long long)DEV_ETHER_ADDRESS);
4243 device_add(machine, tmpstr);
4244
4245 break;
4246
4247 case MACHINE_ALPHA:
4248 /* TODO: Most of these... They are used by NetBSD/alpha: */
4249 /* a0 = First free Page Frame Number */
4250 /* a1 = PFN of current Level 1 page table */
4251 /* a2 = Bootinfo magic */
4252 /* a3 = Bootinfo pointer */
4253 /* a4 = Bootinfo version */
4254 cpu->cd.alpha.r[ALPHA_A0] = 16*1024*1024 / 8192;
4255 cpu->cd.alpha.r[ALPHA_A1] = 0;
4256 cpu->cd.alpha.r[ALPHA_A2] = 0;
4257 cpu->cd.alpha.r[ALPHA_A3] = 0;
4258 cpu->cd.alpha.r[ALPHA_A4] = 0;
4259
4260 if (machine->prom_emulation) {
4261 struct rpb rpb;
4262 struct crb crb;
4263 struct ctb ctb;
4264
4265 /* HWRPB: Hardware Restart Parameter Block */
4266 memset(&rpb, 0, sizeof(struct rpb));
4267 store_64bit_word_in_host(cpu, (unsigned char *)
4268 &(rpb.rpb_phys), HWRPB_ADDR);
4269 strlcpy((char *)&(rpb.rpb_magic), "HWRPB", 8);
4270 store_64bit_word_in_host(cpu, (unsigned char *)
4271 &(rpb.rpb_size), sizeof(struct rpb));
4272 store_64bit_word_in_host(cpu, (unsigned char *)
4273 &(rpb.rpb_page_size), 8192);
4274 store_64bit_word_in_host(cpu, (unsigned char *)
4275 &(rpb.rpb_type), machine->machine_subtype);
4276 store_64bit_word_in_host(cpu, (unsigned char *)
4277 &(rpb.rpb_cc_freq), 100000000);
4278 store_64bit_word_in_host(cpu, (unsigned char *)
4279 &(rpb.rpb_ctb_off), CTB_ADDR - HWRPB_ADDR);
4280 store_64bit_word_in_host(cpu, (unsigned char *)
4281 &(rpb.rpb_crb_off), CRB_ADDR - HWRPB_ADDR);
4282
4283 /* CTB: Console Terminal Block */
4284 memset(&ctb, 0, sizeof(struct ctb));
4285 store_64bit_word_in_host(cpu, (unsigned char *)
4286 &(ctb.ctb_term_type), machine->use_x11?
4287 CTB_GRAPHICS : CTB_PRINTERPORT);
4288
4289 /* CRB: Console Routine Block */
4290 memset(&crb, 0, sizeof(struct crb));
4291 store_64bit_word_in_host(cpu, (unsigned char *)
4292 &(crb.crb_v_dispatch), CRB_ADDR - 0x100);
4293 store_64bit_word(cpu, CRB_ADDR - 0x100 + 8, 0x10000);
4294
4295 /*
4296 * Place a special "hack" palcode call at 0x10000:
4297 * (Hopefully nothing else will be there.)
4298 */
4299 store_32bit_word(cpu, 0x10000, 0x3fffffe);
4300
4301 store_buf(cpu, HWRPB_ADDR, (char *)&rpb, sizeof(struct rpb));
4302 store_buf(cpu, CTB_ADDR, (char *)&ctb, sizeof(struct ctb));
4303 store_buf(cpu, CRB_ADDR, (char *)&crb, sizeof(struct crb));
4304 }
4305
4306 switch (machine->machine_subtype) {
4307 case ST_DEC_3000_300:
4308 machine->machine_name = "DEC 3000/300";
4309 break;
4310 default:fatal("Unimplemented Alpha machine type %i\n",
4311 machine->machine_subtype);
4312 exit(1);
4313 }
4314
4315 break;
4316 #endif /* ENABLE_ALPHA */
4317
4318 #ifdef ENABLE_ARM
4319 case MACHINE_BAREARM:
4320 machine->machine_name = "\"Bare\" ARM machine";
4321 break;
4322
4323 case MACHINE_TESTARM:
4324 machine->machine_name = "ARM test machine";
4325
4326 snprintf(tmpstr, sizeof(tmpstr), "cons addr=0x%llx irq=0",
4327 (long long)DEV_CONS_ADDRESS);
4328 cons_data = device_add(machine, tmpstr);
4329 machine->main_console_handle = cons_data->console_handle;
4330
4331 snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%llx",
4332 (long long)DEV_MP_ADDRESS);
4333 device_add(machine, tmpstr);
4334
4335 fb = dev_fb_init(machine, mem, DEV_FB_ADDRESS, VFB_GENERIC,
4336 640,480, 640,480, 24, "testarm generic");
4337
4338 snprintf(tmpstr, sizeof(tmpstr), "disk addr=0x%llx",
4339 (long long)DEV_DISK_ADDRESS);
4340 device_add(machine, tmpstr);
4341
4342 snprintf(tmpstr, sizeof(tmpstr), "ether addr=0x%llx irq=0",
4343 (long long)DEV_ETHER_ADDRESS);
4344 device_add(machine, tmpstr);
4345
4346 /* Place a tiny stub at end of memory, and set the link
4347 register to point to it. This stub halts the machine. */
4348 cpu->cd.arm.r[ARM_SP] =
4349 machine->physical_ram_in_mb * 1048576 - 4096;
4350 cpu->cd.arm.r[ARM_LR] = cpu->cd.arm.r[ARM_SP] + 32;
4351 store_32bit_word(cpu, cpu->cd.arm.r[ARM_LR] + 0, 0xe3a00201);
4352 store_32bit_word(cpu, cpu->cd.arm.r[ARM_LR] + 4, 0xe5c00010);
4353 store_32bit_word(cpu, cpu->cd.arm.r[ARM_LR] + 8,
4354 0xeafffffe);
4355 break;
4356 #endif /* ENABLE_ARM */
4357
4358 #ifdef ENABLE_IA64
4359 case MACHINE_BAREIA64:
4360 machine->machine_name = "\"Bare\" IA64 machine";
4361 break;
4362
4363 case MACHINE_TESTIA64:
4364 machine->machine_name = "IA64 test machine";
4365
4366 snprintf(tmpstr, sizeof(tmpstr), "cons addr=0x%llx irq=0",
4367 (long long)DEV_CONS_ADDRESS);
4368 cons_data = device_add(machine, tmpstr);
4369 machine->main_console_handle = cons_data->console_handle;
4370
4371 snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%llx",
4372 (long long)DEV_MP_ADDRESS);
4373 device_add(machine, tmpstr);
4374
4375 fb = dev_fb_init(machine, mem, DEV_FB_ADDRESS, VFB_GENERIC,
4376 640,480, 640,480, 24, "testia64 generic");
4377
4378 snprintf(tmpstr, sizeof(tmpstr), "disk addr=0x%llx",
4379 (long long)DEV_DISK_ADDRESS);
4380 device_add(machine, tmpstr);
4381
4382 snprintf(tmpstr, sizeof(tmpstr), "ether addr=0x%llx irq=0",
4383 (long long)DEV_ETHER_ADDRESS);
4384 device_add(machine, tmpstr);
4385
4386 break;
4387 #endif /* ENABLE_IA64 */
4388
4389 #ifdef ENABLE_M68K
4390 case MACHINE_BAREM68K:
4391 machine->machine_name = "\"Bare\" M68K machine";
4392 break;
4393
4394 case MACHINE_TESTM68K:
4395 machine->machine_name = "M68K test machine";
4396
4397 snprintf(tmpstr, sizeof(tmpstr), "cons addr=0x%llx irq=0",
4398 (long long)DEV_CONS_ADDRESS);
4399 cons_data = device_add(machine, tmpstr);
4400 machine->main_console_handle = cons_data->console_handle;
4401
4402 snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%llx",
4403 (long long)DEV_MP_ADDRESS);
4404 device_add(machine, tmpstr);
4405
4406 fb = dev_fb_init(machine, mem, DEV_FB_ADDRESS, VFB_GENERIC,
4407 640,480, 640,480, 24, "testm68k generic");
4408
4409 snprintf(tmpstr, sizeof(tmpstr), "disk addr=0x%llx",
4410 (long long)DEV_DISK_ADDRESS);
4411 device_add(machine, tmpstr);
4412
4413 snprintf(tmpstr, sizeof(tmpstr), "ether addr=0x%llx irq=0",
4414 (long long)DEV_ETHER_ADDRESS);
4415 device_add(machine, tmpstr);
4416
4417 break;
4418 #endif /* ENABLE_M68K */
4419
4420 #ifdef ENABLE_X86
4421 case MACHINE_BAREX86:
4422 machine->machine_name = "\"Bare\" x86 machine";
4423 break;
4424
4425 case MACHINE_X86:
4426 if (machine->machine_subtype == MACHINE_X86_XT)
4427 machine->machine_name = "PC XT";
4428 else
4429 machine->machine_name = "Generic x86 PC";
4430
4431 /* Interrupt controllers: */
4432 snprintf(tmpstr, sizeof(tmpstr), "8259 irq=16 addr=0x%llx",
4433 (long long)(X86_IO_BASE + 0x20));
4434 machine->md.pc.pic1 = device_add(machine, tmpstr);
4435 if (machine->machine_subtype != MACHINE_X86_XT) {
4436 snprintf(tmpstr, sizeof(tmpstr), "8259 irq=16 addr=0x%llx irq=2",
4437 (long long)(X86_IO_BASE + 0xa0));
4438 machine->md.pc.pic2 = device_add(machine, tmpstr);
4439 }
4440
4441 machine->md_interrupt = x86_pc_interrupt;
4442
4443 /* Timer: */
4444 snprintf(tmpstr, sizeof(tmpstr), "8253 addr=0x%llx irq=0",
4445 (long long)(X86_IO_BASE + 0x40));
4446 device_add(machine, tmpstr);
4447
4448 snprintf(tmpstr, sizeof(tmpstr), "pccmos addr=0x%llx",
4449 (long long)(X86_IO_BASE + 0x70));
4450 device_add(machine, tmpstr);
4451
4452 /* TODO: IRQ when emulating a PC XT? */
4453
4454 /* IDE controllers: */
4455 if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
4456 diskimage_exist(machine, 1, DISKIMAGE_IDE))
4457 dev_wdc_init(machine, mem, X86_IO_BASE + 0x1f0, 14, 0);
4458 if (diskimage_exist(machine, 2, DISKIMAGE_IDE) ||
4459 diskimage_exist(machine, 3, DISKIMAGE_IDE))
4460 dev_wdc_init(machine, mem, X86_IO_BASE + 0x170, 15, 2);
4461
4462 /* Floppy controller at irq 6 */
4463 snprintf(tmpstr, sizeof(tmpstr), "fdc addr=0x%llx irq=6",
4464 (long long)(X86_IO_BASE + 0x3f0));
4465 device_add(machine, tmpstr);
4466
4467 /* TODO: sound blaster (eventually) at irq 7? */
4468
4469 /* TODO: parallel port */
4470
4471 /* Serial ports: (TODO: 8250 for PC XT?) */
4472
4473 snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=4 addr=0x%llx name2=com1 in_use=0",
4474 (long long)X86_IO_BASE + 0x3f8);
4475 device_add(machine, tmpstr);
4476 snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=3 addr=0x%llx name2=com2 in_use=0",
4477 (long long)X86_IO_BASE + 0x2f8);
4478 device_add(machine, tmpstr);
4479
4480 /* VGA + keyboard: */
4481 dev_vga_init(machine, mem, 0xa0000ULL, X86_IO_BASE + 0x3c0,
4482 "Generic x86 PC");
4483 machine->main_console_handle = dev_pckbc_init(machine,
4484 mem, X86_IO_BASE + 0x60, PCKBC_8042, 1, 12, 1, 1);
4485
4486 if (machine->prom_emulation)
4487 pc_bios_init(cpu);
4488
4489 if (!machine->use_x11 && !quiet_mode)
4490 fprintf(stderr, "-------------------------------------"
4491 "------------------------------------------\n"
4492 "\n WARNING! You are emulating a PC without -X. "
4493 "You will miss graphical output!\n\n"
4494 "-------------------------------------"
4495 "------------------------------------------\n");
4496 break;
4497 #endif /* ENABLE_X86 */
4498
4499 default:
4500 fatal("Unknown emulation type %i\n", machine->machine_type);
4501 exit(1);
4502 }
4503
4504 if (machine->machine_name != NULL)
4505 debug("machine: %s", machine->machine_name);
4506
4507 if (machine->emulated_hz > 0)
4508 debug(" (%.2f MHz)", (float)machine->emulated_hz / 1000000);
4509 debug("\n");
4510
4511 if (machine->emulated_hz < 1)
4512 machine->emulated_hz = 1000000;
4513
4514 if (bootstr != NULL) {
4515 debug("bootstring%s: %s", (bootarg!=NULL &&
4516 strlen(bootarg) >= 1)? "(+bootarg)" : "", bootstr);
4517 if (bootarg != NULL && strlen(bootarg) >= 1)
4518 debug(" %s", bootarg);
4519 debug("\n");
4520 }
4521 }
4522
4523
4524 /*
4525 * machine_memsize_fix():
4526 *
4527 * Sets physical_ram_in_mb (if not already set), and memory_offset_in_mb,
4528 * depending on machine type.
4529 */
4530 void machine_memsize_fix(struct machine *m)
4531 {
4532 if (m == NULL) {
4533 fatal("machine_defaultmemsize(): m == NULL?\n");
4534 exit(1);
4535 }
4536
4537 if (m->physical_ram_in_mb == 0) {
4538 switch (m->machine_type) {
4539 case MACHINE_PS2:
4540 m->physical_ram_in_mb = 32;
4541 break;
4542 case MACHINE_SGI:
4543 m->physical_ram_in_mb = 64;
4544 break;
4545 case MACHINE_HPCMIPS:
4546 /* Most have 32 MB by default. */
4547 m->physical_ram_in_mb = 32;
4548 switch (m->machine_subtype) {
4549 case MACHINE_HPCMIPS_CASIO_BE300:
4550 m->physical_ram_in_mb = 16;
4551 break;
4552 case MACHINE_HPCMIPS_CASIO_E105:
4553 m->physical_ram_in_mb = 32;
4554 break;
4555 case MACHINE_HPCMIPS_AGENDA_VR3:
4556 m->physical_ram_in_mb = 16;
4557 break;
4558 }
4559 break;
4560 case MACHINE_MESHCUBE:
4561 m->physical_ram_in_mb = 64;
4562 break;
4563 case MACHINE_NETGEAR:
4564 m->physical_ram_in_mb = 16;
4565 break;
4566 case MACHINE_EVBMIPS:
4567 m->physical_ram_in_mb = 64;
4568 break;
4569 case MACHINE_PSP:
4570 /*
4571 * According to
4572 * http://wiki.ps2dev.org/psp:memory_map:
4573 * 0×08000000 = 8 MB kernel memory
4574 * 0×08800000 = 24 MB user memory
4575 */
4576 m->physical_ram_in_mb = 8 + 24;
4577 break;
4578 case MACHINE_ARC:
4579 switch (m->machine_subtype) {
4580 case MACHINE_ARC_JAZZ_PICA:
4581 m->physical_ram_in_mb = 64;
4582 break;
4583 case MACHINE_ARC_JAZZ_M700:
4584 m->physical_ram_in_mb = 64;
4585 break;
4586 default:
4587 m->physical_ram_in_mb = 32;
4588 }
4589 break;
4590 case MACHINE_DEC:
4591 switch (m->machine_subtype) {
4592 case MACHINE_DEC_PMAX_3100:
4593 m->physical_ram_in_mb = 24;
4594 break;
4595 default:
4596 m->physical_ram_in_mb = 32;
4597 }
4598 break;
4599 case MACHINE_ALPHA:
4600 m->physical_ram_in_mb = 64;
4601 break;
4602 case MACHINE_BEBOX:
4603 m->physical_ram_in_mb = 64;
4604 break;
4605 case MACHINE_X86:
4606 if (m->machine_subtype == MACHINE_X86_XT)
4607 m->physical_ram_in_mb = 1;
4608 break;
4609 }
4610 }
4611
4612 /* Special hack for hpcmips machines: */
4613 if (m->machine_type == MACHINE_HPCMIPS) {
4614 m->dbe_on_nonexistant_memaccess = 0;
4615 }
4616
4617 /* Special SGI memory offsets: */
4618 if (m->machine_type == MACHINE_SGI) {
4619 switch (m->machine_subtype) {
4620 case 20:
4621 case 22:
4622 case 24:
4623 case 26:
4624 m->memory_offset_in_mb = 128;
4625 break;
4626 case 28:
4627 case 30:
4628 m->memory_offset_in_mb = 512;
4629 break;
4630 }
4631 }
4632
4633 if (m->physical_ram_in_mb == 0)
4634 m->physical_ram_in_mb = DEFAULT_RAM_IN_MB;
4635 }
4636
4637
4638 /*
4639 * machine_default_cputype():
4640 *
4641 * Sets m->cpu_name, if it isn't already set, depending on the machine
4642 * type.
4643 */
4644 void machine_default_cputype(struct machine *m)
4645 {
4646 if (m == NULL) {
4647 fatal("machine_default_cputype(): m == NULL?\n");
4648 exit(1);
4649 }
4650
4651 if (m->cpu_name != NULL)
4652 return;
4653
4654 switch (m->machine_type) {
4655 case MACHINE_BAREMIPS:
4656 case MACHINE_TESTMIPS:
4657 m->cpu_name = strdup("R4000");
4658 break;
4659 case MACHINE_PS2:
4660 m->cpu_name = strdup("R5900");
4661 break;
4662 case MACHINE_DEC:
4663 if (m->machine_subtype > 2)
4664 m->cpu_name = strdup("R3000A");
4665 if (m->machine_subtype > 1 && m->cpu_name == NULL)
4666 m->cpu_name = strdup("R3000");
4667 if (m->cpu_name == NULL)
4668 m->cpu_name = strdup("R2000");
4669 break;
4670 case MACHINE_SONYNEWS:
4671 m->cpu_name = strdup("R3000");
4672 break;
4673 case MACHINE_HPCMIPS:
4674 switch (m->machine_subtype) {
4675 case MACHINE_HPCMIPS_CASIO_BE300:
4676 m->cpu_name = strdup("VR4131");
4677 break;
4678 case MACHINE_HPCMIPS_CASIO_E105:
4679 m->cpu_name = strdup("VR4121");
4680 break;
4681 case MACHINE_HPCMIPS_NEC_MOBILEPRO_770:
4682 case MACHINE_HPCMIPS_NEC_MOBILEPRO_780:
4683 case MACHINE_HPCMIPS_NEC_MOBILEPRO_800:
4684 case MACHINE_HPCMIPS_NEC_MOBILEPRO_880:
4685 m->cpu_name = strdup("VR4121");
4686 break;
4687 case MACHINE_HPCMIPS_AGENDA_VR3:
4688 m->cpu_name = strdup("VR4181");
4689 break;
4690 case MACHINE_HPCMIPS_IBM_WORKPAD_Z50:
4691 m->cpu_name = strdup("VR4121");
4692 break;
4693 default:
4694 printf("Unimplemented HPCMIPS model?\n");
4695 exit(1);
4696 }
4697 break;
4698 case MACHINE_COBALT:
4699 m->cpu_name = strdup("RM5200");
4700 break;
4701 case MACHINE_MESHCUBE:
4702 m->cpu_name = strdup("R4400");
4703 /* TODO: Should be AU1500, but Linux doesn't like
4704 the absence of caches in the emulator */
4705 break;
4706 case MACHINE_NETGEAR:
4707 m->cpu_name = strdup("RC32334");
4708 break;
4709 case MACHINE_ARC:
4710 switch (m->machine_subtype) {
4711 case MACHINE_ARC_JAZZ_PICA:
4712 m->cpu_name = strdup("R4000");
4713 break;
4714 default:
4715 m->cpu_name = strdup("R4400");
4716 }
4717 break;
4718 case MACHINE_SGI:
4719 if (m->machine_subtype <= 12)
4720 m->cpu_name = strdup("R3000");
4721 if (m->cpu_name == NULL && m->machine_subtype == 35)
4722 m->cpu_name = strdup("R12000");
4723 if (m->cpu_name == NULL && (m->machine_subtype == 25 ||
4724 m->machine_subtype == 27 ||
4725 m->machine_subtype == 28 ||
4726 m->machine_subtype == 30 ||
4727 m->machine_subtype == 32))
4728 m->cpu_name = strdup("R10000");
4729 if (m->cpu_name == NULL && (m->machine_subtype == 21 ||
4730 m->machine_subtype == 26))
4731 m->cpu_name = strdup("R8000");
4732 if (m->cpu_name == NULL && m->machine_subtype == 24)
4733 m->cpu_name = strdup("R5000");
4734
4735 /* Other SGIs should probably work with
4736 R4000, R4400 or R5000 or similar: */
4737 if (m->cpu_name == NULL)
4738 m->cpu_name = strdup("R4400");
4739 break;
4740 case MACHINE_EVBMIPS:
4741 switch (m->machine_subtype) {
4742 case MACHINE_EVBMIPS_MALTA:
4743 case MACHINE_EVBMIPS_MALTA_BE:
4744 m->cpu_name = strdup("5Kc");
4745 break;
4746 case MACHINE_EVBMIPS_PB1000:
4747 m->cpu_name = strdup("AU1000");
4748 break;
4749 default:fatal("Unimpl. evbmips.\n");
4750 exit(1);
4751 }
4752 break;
4753 case MACHINE_PSP:
4754 m->cpu_name = strdup("Allegrex");
4755 break;
4756
4757 /* PowerPC: */
4758 case MACHINE_BAREPPC:
4759 case MACHINE_TESTPPC:
4760 m->cpu_name = strdup("PPC970");
4761 break;
4762 case MACHINE_WALNUT:
4763 /* For NetBSD/evbppc. */
4764 m->cpu_name = strdup("PPC405GP");
4765 break;
4766 case MACHINE_PMPPC:
4767 /* For NetBSD/pmppc. */
4768 m->cpu_name = strdup("PPC750");
4769 break;
4770 case MACHINE_SANDPOINT:
4771 /*
4772 * For NetBSD/sandpoint. According to NetBSD's page:
4773 *
4774 * "Unity" module has an MPC8240.
4775 * "Altimus" module has an MPC7400 (G4) or an MPC107.
4776 */
4777 m->cpu_name = strdup("MPC7400");
4778 break;
4779 case MACHINE_BEBOX:
4780 /* For NetBSD/bebox. Dual 133 MHz 603e CPUs, for example. */
4781 m->cpu_name = strdup("PPC603e");
4782 break;
4783 case MACHINE_PREP:
4784 /* For NetBSD/prep. TODO */
4785 m->cpu_name = strdup("PPC603e");
4786 break;
4787 case MACHINE_MACPPC:
4788 switch (m->machine_subtype) {
4789 case MACHINE_MACPPC_G4:
4790 m->cpu_name = strdup("G4e");
4791 break;
4792 case MACHINE_MACPPC_G5:
4793 m->cpu_name = strdup("PPC970");
4794 break;
4795 }
4796 break;
4797 case MACHINE_DB64360:
4798 m->cpu_name = strdup("PPC750");
4799 break;
4800
4801 /* SPARC: */
4802 case MACHINE_BARESPARC:
4803 case MACHINE_TESTSPARC:
4804 case MACHINE_ULTRA1:
4805 m->cpu_name = strdup("SPARCv9");
4806 break;
4807
4808 /* Alpha: */
4809 case MACHINE_BAREALPHA:
4810 case MACHINE_TESTALPHA:
4811 case MACHINE_ALPHA:
4812 m->cpu_name = strdup("Alpha");
4813 break;
4814
4815 /* ARM: */
4816 case MACHINE_BAREARM:
4817 case MACHINE_TESTARM:
4818 m->cpu_name = strdup("ARM");
4819 break;
4820
4821 /* IA64: */
4822 case MACHINE_BAREIA64:
4823 case MACHINE_TESTIA64:
4824 m->cpu_name = strdup("IA64");
4825 break;
4826
4827 /* M68K: */
4828 case MACHINE_BAREM68K:
4829 case MACHINE_TESTM68K:
4830 m->cpu_name = strdup("68020");
4831 break;
4832
4833 /* x86: */
4834 case MACHINE_BAREX86:
4835 case MACHINE_X86:
4836 if (m->machine_subtype == MACHINE_X86_XT)
4837 m->cpu_name = strdup("8086");
4838 else
4839 m->cpu_name = strdup("AMD64");
4840 break;
4841 }
4842
4843 if (m->cpu_name == NULL) {
4844 fprintf(stderr, "machine_default_cputype(): no default"
4845 " cpu for machine type %i subtype %i\n",
4846 m->machine_type, m->machine_subtype);
4847 exit(1);
4848 }
4849 }
4850
4851
4852 /*
4853 * machine_dumpinfo():
4854 *
4855 * Dumps info about a machine in some kind of readable format. (Used by
4856 * the 'machine' debugger command.)
4857 */
4858 void machine_dumpinfo(struct machine *m)
4859 {
4860 int i;
4861
4862 debug("serial nr: %i", m->serial_nr);
4863 if (m->nr_of_nics > 0)
4864 debug(" (nr of nics: %i)", m->nr_of_nics);
4865 debug("\n");
4866
4867 debug("memory: %i MB", m->physical_ram_in_mb);
4868 if (m->memory_offset_in_mb != 0)
4869 debug(" (offset by %i MB)", m->memory_offset_in_mb);
4870 if (m->random_mem_contents)
4871 debug(", randomized contents");
4872 if (m->dbe_on_nonexistant_memaccess)
4873 debug(", dbe_on_nonexistant_memaccess");
4874 debug("\n");
4875
4876 if (m->single_step_on_bad_addr)
4877 debug("single-step on bad addresses\n");
4878
4879 if (m->arch == ARCH_MIPS) {
4880 if (m->bintrans_enable)
4881 debug("bintrans enabled (%i MB cache)\n",
4882 (int) (m->bintrans_size / 1048576));
4883 else
4884 debug("bintrans disabled, other speedtricks %s\n",
4885 m->speed_tricks? "enabled" : "disabled");
4886 }
4887
4888 debug("clock: ");
4889 if (m->automatic_clock_adjustment)
4890 debug("adjusted automatically");
4891 else
4892 debug("fixed at %i Hz", m->emulated_hz);
4893 debug("\n");
4894
4895 if (!m->prom_emulation)
4896 debug("PROM emulation disabled\n");
4897
4898 for (i=0; i<m->ncpus; i++)
4899 cpu_dumpinfo(m, m->cpus[i]);
4900
4901 if (m->ncpus > 1)
4902 debug("Bootstrap cpu is nr %i\n", m->bootstrap_cpu);
4903
4904 if (m->slow_serial_interrupts_hack_for_linux)
4905 debug("Using slow_serial_interrupts_hack_for_linux\n");
4906
4907 if (m->use_x11) {
4908 debug("Using X11");
4909 if (m->x11_scaledown > 1)
4910 debug(", scaledown %i", m->x11_scaledown);
4911 if (m->x11_n_display_names > 0) {
4912 for (i=0; i<m->x11_n_display_names; i++) {
4913 debug(i? ", " : " (");
4914 debug("\"%s\"", m->x11_display_names[i]);
4915 }
4916 debug(")");
4917 }
4918 debug("\n");
4919 }
4920
4921 diskimage_dump_info(m);
4922
4923 if (m->force_netboot)
4924 debug("Forced netboot\n");
4925 }
4926
4927
4928 /*
4929 * machine_entry_new():
4930 *
4931 * This function creates a new machine_entry struct, and fills it with some
4932 * valid data; it is up to the caller to add additional data that weren't
4933 * passed as arguments to this function.
4934 *
4935 * For internal use.
4936 */
4937 static struct machine_entry *machine_entry_new(const char *name,
4938 int arch, int oldstyle_type, int n_aliases, int n_subtypes)
4939 {
4940 struct machine_entry *me;
4941
4942 me = malloc(sizeof(struct machine_entry));
4943 if (me == NULL) {
4944 fprintf(stderr, "machine_entry_new(): out of memory (1)\n");
4945 exit(1);
4946 }
4947
4948 memset(me, 0, sizeof(struct machine_entry));
4949
4950 me->name = name;
4951 me->arch = arch;
4952 me->machine_type = oldstyle_type;
4953 me->n_aliases = n_aliases;
4954 me->aliases = malloc(sizeof(char *) * n_aliases);
4955 if (me->aliases == NULL) {
4956 fprintf(stderr, "machine_entry_new(): out of memory (2)\n");
4957 exit(1);
4958 }
4959 me->n_subtypes = n_subtypes;
4960
4961 if (n_subtypes > 0) {
4962 me->subtype = malloc(sizeof(struct machine_entry_subtype *) *
4963 n_subtypes);
4964 if (me->subtype == NULL) {
4965 fprintf(stderr, "machine_entry_new(): out of "
4966 "memory (3)\n");
4967 exit(1);
4968 }
4969 }
4970
4971 return me;
4972 }
4973
4974
4975 /*
4976 * machine_entry_subtype_new():
4977 *
4978 * This function creates a new machine_entry_subtype struct, and fills it with
4979 * some valid data; it is up to the caller to add additional data that weren't
4980 * passed as arguments to this function.
4981 *
4982 * For internal use.
4983 */
4984 static struct machine_entry_subtype *machine_entry_subtype_new(
4985 const char *name, int oldstyle_type, int n_aliases)
4986 {
4987 struct machine_entry_subtype *mes;
4988
4989 mes = malloc(sizeof(struct machine_entry_subtype));
4990 if (mes == NULL) {
4991 fprintf(stderr, "machine_entry_subtype_new(): out "
4992 "of memory (1)\n");
4993 exit(1);
4994 }
4995
4996 memset(mes, 0, sizeof(struct machine_entry_subtype));
4997 mes->name = name;
4998 mes->machine_subtype = oldstyle_type;
4999 mes->n_aliases = n_aliases;
5000 mes->aliases = malloc(sizeof(char *) * n_aliases);
5001 if (mes->aliases == NULL) {
5002 fprintf(stderr, "machine_entry_subtype_new(): "
5003 "out of memory (2)\n");
5004 exit(1);
5005 }
5006
5007 return mes;
5008 }
5009
5010
5011 /*
5012 * machine_list_available_types_and_cpus():
5013 *
5014 * List all available machine types (for example when running the emulator
5015 * with just -H as command line argument).
5016 */
5017 void machine_list_available_types_and_cpus(void)
5018 {
5019 struct machine_entry *me;
5020 int iadd = 8;
5021
5022 debug("Available CPU types:\n\n");
5023
5024 debug_indentation(iadd);
5025 cpu_list_available_types();
5026 debug_indentation(-iadd);
5027
5028 debug("\nMost of the CPU types are bogus, and not really implemented."
5029 " The main effect of\nselecting a specific CPU type is to choose "
5030 "what kind of 'id' it will have.\n\nAvailable machine types (with "
5031 "aliases) and their subtypes:\n\n");
5032
5033 debug_indentation(iadd);
5034 me = first_machine_entry;
5035
5036 if (me == NULL)
5037 fatal("No machines defined!\n");
5038
5039 while (me != NULL) {
5040 int i, j, iadd = 4;
5041
5042 debug("%s", me->name);
5043 debug(" (");
5044 for (i=0; i<me->n_aliases; i++)
5045 debug("%s\"%s\"", i? ", " : "", me->aliases[i]);
5046 debug(")\n");
5047
5048 debug_indentation(iadd);
5049 for (i=0; i<me->n_subtypes; i++) {
5050 struct machine_entry_subtype *mes;
5051 mes = me->subtype[i];
5052 debug("- %s", mes->name);
5053 debug(" (");
5054 for (j=0; j<mes->n_aliases; j++)
5055 debug("%s\"%s\"", j? ", " : "",
5056 mes->aliases[j]);
5057 debug(")\n");
5058 }
5059 debug_indentation(-iadd);
5060
5061 me = me->next;
5062 }
5063 debug_indentation(-iadd);
5064
5065 debug("\nMost of the machine types are bogus too. Please read the "
5066 "GXemul\ndocumentation for information about which machine"
5067 " types that actually\nwork. Use the alias when selecting a "
5068 "machine type or subtype, not the\nreal name.\n");
5069
5070 debug("\n");
5071
5072 useremul_list_emuls();
5073 debug("Userland emulation works for programs with the complexity"
5074 " of Hello World,\nbut not much more.\n");
5075 }
5076
5077
5078 /*
5079 * machine_init():
5080 *
5081 * This function should be called before any other machine_*() function
5082 * is used.
5083 */
5084 void machine_init(void)
5085 {
5086 struct machine_entry *me;
5087
5088 /*
5089 * NOTE: This list is in reverse order, so that the
5090 * entries will appear in normal order when listed. :-)
5091 */
5092
5093 /* X86 machine: */
5094 me = machine_entry_new("x86-based PC", ARCH_X86,
5095 MACHINE_X86, 2, 2);
5096 me->aliases[0] = "pc";
5097 me->aliases[1] = "x86";
5098 me->subtype[0] = machine_entry_subtype_new("Generic PC",
5099 MACHINE_X86_GENERIC, 1);
5100 me->subtype[0]->aliases[0] = "generic";
5101 me->subtype[1] = machine_entry_subtype_new("PC XT", MACHINE_X86_XT, 1);
5102 me->subtype[1]->aliases[0] = "xt";
5103 if (cpu_family_ptr_by_number(ARCH_X86) != NULL) {
5104 me->next = first_machine_entry; first_machine_entry = me;
5105 }
5106
5107 /* Walnut: (NetBSD/evbppc) */
5108 me = machine_entry_new("Walnut evaluation board", ARCH_PPC,
5109 MACHINE_WALNUT, 2, 0);
5110 me->aliases[0] = "walnut";
5111 me->aliases[1] = "evbppc";
5112 if (cpu_family_ptr_by_number(ARCH_PPC) != NULL) {
5113 me->next = first_machine_entry; first_machine_entry = me;
5114 }
5115
5116 /* Test-machine for SPARC: */
5117 me = machine_entry_new("Test-machine for SPARC", ARCH_SPARC,
5118 MACHINE_TESTSPARC, 1, 0);
5119 me->aliases[0] = "testsparc";
5120 if (cpu_family_ptr_by_number(ARCH_SPARC) != NULL) {
5121 me->next = first_machine_entry; first_machine_entry = me;
5122 }
5123
5124 /* Test-machine for PPC: */
5125 me = machine_entry_new("Test-machine for PPC", ARCH_PPC,
5126 MACHINE_TESTPPC, 1, 0);
5127 me->aliases[0] = "testppc";
5128 if (cpu_family_ptr_by_number(ARCH_PPC) != NULL) {
5129 me->next = first_machine_entry; first_machine_entry = me;
5130 }
5131
5132 /* Test-machine for MIPS: */
5133 me = machine_entry_new("Test-machine for MIPS", ARCH_MIPS,
5134 MACHINE_TESTMIPS, 1, 0);
5135 me->aliases[0] = "testmips";
5136 if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5137 me->next = first_machine_entry; first_machine_entry = me;
5138 }
5139
5140 /* Test-machine for M68K: */
5141 me = machine_entry_new("Test-machine for M68K", ARCH_M68K,
5142 MACHINE_TESTM68K, 1, 0);
5143 me->aliases[0] = "testm68k";
5144 if (cpu_family_ptr_by_number(ARCH_M68K) != NULL) {
5145 me->next = first_machine_entry; first_machine_entry = me;
5146 }
5147
5148 /* Test-machine for IA64: */
5149 me = machine_entry_new("Test-machine for IA64", ARCH_IA64,
5150 MACHINE_TESTIA64, 1, 0);
5151 me->aliases[0] = "testia64";
5152 if (cpu_family_ptr_by_number(ARCH_IA64) != NULL) {
5153 me->next = first_machine_entry; first_machine_entry = me;
5154 }
5155
5156 /* Test-machine for ARM: */
5157 me = machine_entry_new("Test-machine for ARM", ARCH_ARM,
5158 MACHINE_TESTARM, 1, 0);
5159 me->aliases[0] = "testarm";
5160 if (cpu_family_ptr_by_number(ARCH_ARM) != NULL) {
5161 me->next = first_machine_entry; first_machine_entry = me;
5162 }
5163
5164 /* Test-machine for Alpha: */
5165 me = machine_entry_new("Test-machine for Alpha", ARCH_ALPHA,
5166 MACHINE_TESTALPHA, 1, 0);
5167 me->aliases[0] = "testalpha";
5168 if (cpu_family_ptr_by_number(ARCH_ALPHA) != NULL) {
5169 me->next = first_machine_entry; first_machine_entry = me;
5170 }
5171
5172 /* Sun Ultra1: */
5173 me = machine_entry_new("Sun Ultra1", ARCH_SPARC, MACHINE_ULTRA1, 1, 0);
5174 me->aliases[0] = "ultra1";
5175 if (cpu_family_ptr_by_number(ARCH_SPARC) != NULL) {
5176 me->next = first_machine_entry; first_machine_entry = me;
5177 }
5178
5179 /* Sony Playstation 2: */
5180 me = machine_entry_new("Sony Playstation 2", ARCH_MIPS,
5181 MACHINE_PS2, 2, 0);
5182 me->aliases[0] = "playstation2";
5183 me->aliases[1] = "ps2";
5184 if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5185 me->next = first_machine_entry; first_machine_entry = me;
5186 }
5187
5188 /* Sony NeWS: */
5189 me = machine_entry_new("Sony NeWS", ARCH_MIPS,
5190 MACHINE_SONYNEWS, 2, 0);
5191 me->aliases[0] = "sonynews";
5192 me->aliases[1] = "news";
5193 if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5194 me->next = first_machine_entry; first_machine_entry = me;
5195 }
5196
5197 /* SGI: */
5198 me = machine_entry_new("SGI", ARCH_MIPS, MACHINE_SGI, 2, 10);
5199 me->aliases[0] = "silicon graphics";
5200 me->aliases[1] = "sgi";
5201 me->subtype[0] = machine_entry_subtype_new("IP12", 12, 1);
5202 me->subtype[0]->aliases[0] = "ip12";
5203 me->subtype[1] = machine_entry_subtype_new("IP19", 19, 1);
5204 me->subtype[1]->aliases[0] = "ip19";
5205 me->subtype[2] = machine_entry_subtype_new("IP20", 20, 1);
5206 me->subtype[2]->aliases[0] = "ip20";
5207 me->subtype[3] = machine_entry_subtype_new("IP22", 22, 2);
5208 me->subtype[3]->aliases[0] = "ip22";
5209 me->subtype[3]->aliases[1] = "indy";
5210 me->subtype[4] = machine_entry_subtype_new("IP24", 24, 1);
5211 me->subtype[4]->aliases[0] = "ip24";
5212 me->subtype[5] = machine_entry_subtype_new("IP27", 27, 3);
5213 me->subtype[5]->aliases[0] = "ip27";
5214 me->subtype[5]->aliases[1] = "origin 200";
5215 me->subtype[5]->aliases[2] = "origin 2000";
5216 me->subtype[6] = machine_entry_subtype_new("IP28", 28, 1);
5217 me->subtype[6]->aliases[0] = "ip28";
5218 me->subtype[7] = machine_entry_subtype_new("IP30", 30, 2);
5219 me->subtype[7]->aliases[0] = "ip30";
5220 me->subtype[7]->aliases[1] = "octane";
5221 me->subtype[8] = machine_entry_subtype_new("IP32", 32, 2);
5222 me->subtype[8]->aliases[0] = "ip32";
5223 me->subtype[8]->aliases[1] = "o2";
5224 me->subtype[9] = machine_entry_subtype_new("IP35", 35, 1);
5225 me->subtype[9]->aliases[0] = "ip35";
5226 if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5227 me->next = first_machine_entry; first_machine_entry = me;
5228 }
5229
5230 /* PReP: (NetBSD/prep etc.) */
5231 me = machine_entry_new("PowerPC Reference Platform", ARCH_PPC,
5232 MACHINE_PREP, 1, 0);
5233 me->aliases[0] = "prep";
5234 if (cpu_family_ptr_by_number(ARCH_PPC) != NULL) {
5235 me->next = first_machine_entry; first_machine_entry = me;
5236 }
5237
5238 /* Playstation Portable: */
5239 me = machine_entry_new("Playstation Portable", ARCH_MIPS,
5240 MACHINE_PSP, 1, 0);
5241 me->aliases[0] = "psp";
5242 if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5243 me->next = first_machine_entry; first_machine_entry = me;
5244 }
5245
5246 /* NetGear: */
5247 me = machine_entry_new("NetGear WG602", ARCH_MIPS,
5248 MACHINE_NETGEAR, 2, 0);
5249 me->aliases[0] = "netgear";
5250 me->aliases[1] = "wg602";
5251 if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5252 me->next = first_machine_entry; first_machine_entry = me;
5253 }
5254
5255 /* Motorola Sandpoint: (NetBSD/sandpoint) */
5256 me = machine_entry_new("Motorola Sandpoint",
5257 ARCH_PPC, MACHINE_SANDPOINT, 1, 0);
5258 me->aliases[0] = "sandpoint";
5259 if (cpu_family_ptr_by_number(ARCH_PPC) != NULL) {
5260 me->next = first_machine_entry; first_machine_entry = me;
5261 }
5262
5263 /* Meshcube: */
5264 me = machine_entry_new("Meshcube", ARCH_MIPS, MACHINE_MESHCUBE, 1, 0);
5265 me->aliases[0] = "meshcube";
5266 if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5267 me->next = first_machine_entry; first_machine_entry = me;
5268 }
5269
5270 /* Macintosh (PPC): */
5271 me = machine_entry_new("Macintosh (PPC)", ARCH_PPC,
5272 MACHINE_MACPPC, 1, 2);
5273 me->aliases[0] = "macppc";
5274 me->subtype[0] = machine_entry_subtype_new("MacPPC G4",
5275 MACHINE_MACPPC_G4, 1);
5276 me->subtype[0]->aliases[0] = "g4";
5277 me->subtype[1] = machine_entry_subtype_new("MacPPC G5",
5278 MACHINE_MACPPC_G5, 1);
5279 me->subtype[1]->aliases[0] = "g5";
5280 if (cpu_family_ptr_by_number(ARCH_PPC) != NULL) {
5281 me->next = first_machine_entry; first_machine_entry = me;
5282 }
5283
5284 /* HPCmips: */
5285 me = machine_entry_new("Handheld MIPS (HPCmips)",
5286 ARCH_MIPS, MACHINE_HPCMIPS, 1, 8);
5287 me->aliases[0] = "hpcmips";
5288 me->subtype[0] = machine_entry_subtype_new(
5289 "Casio Cassiopeia BE-300", MACHINE_HPCMIPS_CASIO_BE300, 2);
5290 me->subtype[0]->aliases[0] = "be-300";
5291 me->subtype[0]->aliases[1] = "be300";
5292 me->subtype[1] = machine_entry_subtype_new(
5293 "Casio Cassiopeia E-105", MACHINE_HPCMIPS_CASIO_E105, 2);
5294 me->subtype[1]->aliases[0] = "e-105";
5295 me->subtype[1]->aliases[1] = "e105";
5296 me->subtype[2] = machine_entry_subtype_new(
5297 "Agenda VR3", MACHINE_HPCMIPS_AGENDA_VR3, 2);
5298 me->subtype[2]->aliases[0] = "agenda";
5299 me->subtype[2]->aliases[1] = "vr3";
5300 me->subtype[3] = machine_entry_subtype_new(
5301 "IBM WorkPad Z50", MACHINE_HPCMIPS_IBM_WORKPAD_Z50, 2);
5302 me->subtype[3]->aliases[0] = "workpad";
5303 me->subtype[3]->aliases[1] = "z50";
5304 me->subtype[4] = machine_entry_subtype_new(
5305 "NEC MobilePro 770", MACHINE_HPCMIPS_NEC_MOBILEPRO_770, 1);
5306 me->subtype[4]->aliases[0] = "mobilepro770";
5307 me->subtype[5] = machine_entry_subtype_new(
5308 "NEC MobilePro 780", MACHINE_HPCMIPS_NEC_MOBILEPRO_780, 1);
5309 me->subtype[5]->aliases[0] = "mobilepro780";
5310 me->subtype[6] = machine_entry_subtype_new(
5311 "NEC MobilePro 800", MACHINE_HPCMIPS_NEC_MOBILEPRO_800, 1);
5312 me->subtype[6]->aliases[0] = "mobilepro800";
5313 me->subtype[7] = machine_entry_subtype_new(
5314 "NEC MobilePro 880", MACHINE_HPCMIPS_NEC_MOBILEPRO_880, 1);
5315 me->subtype[7]->aliases[0] = "mobilepro880";
5316 if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5317 me->next = first_machine_entry; first_machine_entry = me;
5318 }
5319
5320 /* Generic "bare" X86 machine: */
5321 me = machine_entry_new("Generic \"bare\" X86 machine", ARCH_X86,
5322 MACHINE_BAREX86, 1, 0);
5323 me->aliases[0] = "barex86";
5324 if (cpu_family_ptr_by_number(ARCH_X86) != NULL) {
5325 me->next = first_machine_entry; first_machine_entry = me;
5326 }
5327
5328 /* Generic "bare" SPARC machine: */
5329 me = machine_entry_new("Generic \"bare\" SPARC machine", ARCH_SPARC,
5330 MACHINE_BARESPARC, 1, 0);
5331 me->aliases[0] = "baresparc";
5332 if (cpu_family_ptr_by_number(ARCH_SPARC) != NULL) {
5333 me->next = first_machine_entry; first_machine_entry = me;
5334 }
5335
5336 /* Generic "bare" PPC machine: */
5337 me = machine_entry_new("Generic \"bare\" PPC machine", ARCH_PPC,
5338 MACHINE_BAREPPC, 1, 0);
5339 me->aliases[0] = "bareppc";
5340 if (cpu_family_ptr_by_number(ARCH_PPC) != NULL) {
5341 me->next = first_machine_entry; first_machine_entry = me;
5342 }
5343
5344 /* Generic "bare" MIPS machine: */
5345 me = machine_entry_new("Generic \"bare\" MIPS machine", ARCH_MIPS,
5346 MACHINE_BAREMIPS, 1, 0);
5347 me->aliases[0] = "baremips";
5348 if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5349 me->next = first_machine_entry; first_machine_entry = me;
5350 }
5351
5352 /* Generic "bare" M68K machine: */
5353 me = machine_entry_new("Generic \"bare\" M68K machine", ARCH_M68K,
5354 MACHINE_BAREM68K, 1, 0);
5355 me->aliases[0] = "barem68k";
5356 if (cpu_family_ptr_by_number(ARCH_M68K) != NULL) {
5357 me->next = first_machine_entry; first_machine_entry = me;
5358 }
5359
5360 /* Generic "bare" IA64 machine: */
5361 me = machine_entry_new("Generic \"bare\" IA64 machine", ARCH_IA64,
5362 MACHINE_BAREIA64, 1, 0);
5363 me->aliases[0] = "bareia64";
5364 if (cpu_family_ptr_by_number(ARCH_IA64) != NULL) {
5365 me->next = first_machine_entry; first_machine_entry = me;
5366 }
5367
5368 /* Generic "bare" ARM machine: */
5369 me = machine_entry_new("Generic \"bare\" ARM machine", ARCH_ARM,
5370 MACHINE_BAREARM, 1, 0);
5371 me->aliases[0] = "barearm";
5372 if (cpu_family_ptr_by_number(ARCH_ARM) != NULL) {
5373 me->next = first_machine_entry; first_machine_entry = me;
5374 }
5375
5376 /* Generic "bare" Alpha machine: */
5377 me = machine_entry_new("Generic \"bare\" Alpha machine", ARCH_ALPHA,
5378 MACHINE_BAREALPHA, 1, 0);
5379 me->aliases[0] = "barealpha";
5380 if (cpu_family_ptr_by_number(ARCH_ALPHA) != NULL) {
5381 me->next = first_machine_entry; first_machine_entry = me;
5382 }
5383
5384 /* Evaluation Boards (MALTA etc): */
5385 me = machine_entry_new("Evaluation boards (evbmips)", ARCH_MIPS,
5386 MACHINE_EVBMIPS, 1, 3);
5387 me->aliases[0] = "evbmips";
5388 me->subtype[0] = machine_entry_subtype_new("Malta",
5389 MACHINE_EVBMIPS_MALTA, 1);
5390 me->subtype[0]->aliases[0] = "malta";
5391 me->subtype[1] = machine_entry_subtype_new("Malta (Big-Endian)",
5392 MACHINE_EVBMIPS_MALTA_BE, 1);
5393 me->subtype[1]->aliases[0] = "maltabe";
5394 me->subtype[2] = machine_entry_subtype_new("PB1000",
5395 MACHINE_EVBMIPS_PB1000, 1);
5396 me->subtype[2]->aliases[0] = "pb1000";
5397 if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5398 me->next = first_machine_entry; first_machine_entry = me;
5399 }
5400
5401 /* DECstation: */
5402 me = machine_entry_new("DECstation/DECsystem",
5403 ARCH_MIPS, MACHINE_DEC, 3, 9);
5404 me->aliases[0] = "decstation";
5405 me->aliases[1] = "decsystem";
5406 me->aliases[2] = "dec";
5407 me->subtype[0] = machine_entry_subtype_new(
5408 "DECstation 3100 (PMAX)", MACHINE_DEC_PMAX_3100, 3);
5409 me->subtype[0]->aliases[0] = "pmax";
5410 me->subtype[0]->aliases[1] = "3100";
5411 me->subtype[0]->aliases[2] = "2100";
5412
5413 me->subtype[1] = machine_entry_subtype_new(
5414 "DECstation 5000/200 (3MAX)", MACHINE_DEC_3MAX_5000, 2);
5415 me->subtype[1]->aliases[0] = "3max";
5416 me->subtype[1]->aliases[1] = "5000/200";
5417
5418 me->subtype[2] = machine_entry_subtype_new(
5419 "DECstation 5000/1xx (3MIN)", MACHINE_DEC_3MIN_5000, 2);
5420 me->subtype[2]->aliases[0] = "3min";
5421 me->subtype[2]->aliases[1] = "5000/1xx";
5422
5423 me->subtype[3] = machine_entry_subtype_new(
5424 "DECstation 5000 (3MAXPLUS)", MACHINE_DEC_3MAXPLUS_5000, 2);
5425 me->subtype[3]->aliases[0] = "3maxplus";
5426 me->subtype[3]->aliases[1] = "3max+";
5427
5428 me->subtype[4] = machine_entry_subtype_new(
5429 "DECsystem 58x0", MACHINE_DEC_5800, 2);
5430 me->subtype[4]->aliases[0] = "5800";
5431 me->subtype[4]->aliases[1] = "58x0";
5432
5433 me->subtype[5] = machine_entry_subtype_new(
5434 "DECsystem 5400", MACHINE_DEC_5400, 1);
5435 me->subtype[5]->aliases[0] = "5400";
5436
5437 me->subtype[6] = machine_entry_subtype_new(
5438 "DECstation Maxine (5000)", MACHINE_DEC_MAXINE_5000, 1);
5439 me->subtype[6]->aliases[0] = "maxine";
5440
5441 me->subtype[7] = machine_entry_subtype_new(
5442 "DECsystem 5500", MACHINE_DEC_5500, 1);
5443 me->subtype[7]->aliases[0] = "5500";
5444
5445 me->subtype[8] = machine_entry_subtype_new(
5446 "DECstation MipsMate (5100)", MACHINE_DEC_MIPSMATE_5100, 2);
5447 me->subtype[8]->aliases[0] = "5100";
5448 me->subtype[8]->aliases[1] = "mipsmate";
5449
5450 if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5451 me->next = first_machine_entry; first_machine_entry = me;
5452 }
5453
5454 /* DB64360: (for playing with PMON for PPC) */
5455 me = machine_entry_new("DB64360", ARCH_PPC, MACHINE_DB64360, 1, 0);
5456 me->aliases[0] = "db64360";
5457 if (cpu_family_ptr_by_number(ARCH_PPC) != NULL) {
5458 me->next = first_machine_entry; first_machine_entry = me;
5459 }
5460
5461 /* Cobalt: */
5462 me = machine_entry_new("Cobalt", ARCH_MIPS, MACHINE_COBALT, 1, 0);
5463 me->aliases[0] = "cobalt";
5464 if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5465 me->next = first_machine_entry; first_machine_entry = me;
5466 }
5467
5468 /* BeBox: (NetBSD/bebox) */
5469 me = machine_entry_new("BeBox", ARCH_PPC, MACHINE_BEBOX, 1, 0);
5470 me->aliases[0] = "bebox";
5471 if (cpu_family_ptr_by_number(ARCH_PPC) != NULL) {
5472 me->next = first_machine_entry; first_machine_entry = me;
5473 }
5474
5475 /* Artesyn's PM/PPC board: (NetBSD/pmppc) */
5476 me = machine_entry_new("Artesyn's PM/PPC board", ARCH_PPC,
5477 MACHINE_PMPPC, 1, 0);
5478 me->aliases[0] = "pmppc";
5479 if (cpu_family_ptr_by_number(ARCH_PPC) != NULL) {
5480 me->next = first_machine_entry; first_machine_entry = me;
5481 }
5482
5483 /* ARC: */
5484 me = machine_entry_new("ARC", ARCH_MIPS, MACHINE_ARC, 1, 8);
5485 me->aliases[0] = "arc";
5486
5487 me->subtype[0] = machine_entry_subtype_new(
5488 "Acer PICA-61", MACHINE_ARC_JAZZ_PICA, 3);
5489 me->subtype[0]->aliases[0] = "pica-61";
5490 me->subtype[0]->aliases[1] = "acer pica";
5491 me->subtype[0]->aliases[2] = "pica";
5492
5493 me->subtype[1] = machine_entry_subtype_new(
5494 "Deskstation Tyne", MACHINE_ARC_DESKTECH_TYNE, 3);
5495 me->subtype[1]->aliases[0] = "deskstation tyne";
5496 me->subtype[1]->aliases[1] = "desktech";
5497 me->subtype[1]->aliases[2] = "tyne";
5498
5499 me->subtype[2] = machine_entry_subtype_new(
5500 "Jazz Magnum", MACHINE_ARC_JAZZ_MAGNUM, 2);
5501 me->subtype[2]->aliases[0] = "magnum";
5502 me->subtype[2]->aliases[1] = "jazz magnum";
5503
5504 me->subtype[3] = machine_entry_subtype_new(
5505 "NEC-R94", MACHINE_ARC_NEC_R94, 2);
5506 me->subtype[3]->aliases[0] = "nec-r94";
5507 me->subtype[3]->aliases[1] = "r94";
5508
5509 me->subtype[4] = machine_entry_subtype_new(
5510 "NEC-RD94", MACHINE_ARC_NEC_RD94, 2);
5511 me->subtype[4]->aliases[0] = "nec-rd94";
5512 me->subtype[4]->aliases[1] = "rd94";
5513
5514 me->subtype[5] = machine_entry_subtype_new(
5515 "NEC-R96", MACHINE_ARC_NEC_R96, 2);
5516 me->subtype[5]->aliases[0] = "nec-r96";
5517 me->subtype[5]->aliases[1] = "r96";
5518
5519 me->subtype[6] = machine_entry_subtype_new(
5520 "NEC-R98", MACHINE_ARC_NEC_R98, 2);
5521 me->subtype[6]->aliases[0] = "nec-r98";
5522 me->subtype[6]->aliases[1] = "r98";
5523
5524 me->subtype[7] = machine_entry_subtype_new(
5525 "Olivetti M700", MACHINE_ARC_JAZZ_M700, 2);
5526 me->subtype[7]->aliases[0] = "olivetti";
5527 me->subtype[7]->aliases[1] = "m700";
5528
5529 if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) {
5530 me->next = first_machine_entry; first_machine_entry = me;
5531 }
5532
5533 /* Alpha: */
5534 me = machine_entry_new("Alpha", ARCH_ALPHA, MACHINE_ALPHA, 1, 1);
5535 me->aliases[0] = "alpha";
5536 me->subtype[0] = machine_entry_subtype_new(
5537 "DEC 3000/300", ST_DEC_3000_300, 1);
5538 me->subtype[0]->aliases[0] = "3000/300";
5539 if (cpu_family_ptr_by_number(ARCH_ALPHA) != NULL) {
5540 me->next = first_machine_entry; first_machine_entry = me;
5541 }
5542 }
5543

  ViewVC Help
Powered by ViewVC 1.1.26