/[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

Annotation of /trunk/src/machine.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (hide 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 dpavlin 2 /*
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 dpavlin 12 * $Id: machine.c,v 1.515 2005/08/16 09:16:26 debug Exp $
29 dpavlin 2 *
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 dpavlin 12 /* For Alpha emulation: */
68     #include "alpha_rpb.h"
69    
70 dpavlin 2 /* For SGI and ARC emulation: */
71     #include "sgi_arcbios.h"
72     #include "crimereg.h"
73    
74 dpavlin 12 /* For evbmips emulation: */
75     #include "maltareg.h"
76    
77 dpavlin 2 /* 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 dpavlin 10 #define BOOTSTR_BUFLEN 1000
92     #define BOOTARG_BUFLEN 2000
93     #define ETHERNET_STRING_MAXLEN 40
94 dpavlin 2
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 dpavlin 6
118     /* See main.c: */
119     extern int quiet_mode;
120    
121    
122 dpavlin 2 /* 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 dpavlin 10 m->serial_nr = 1;
149 dpavlin 2 m->machine_type = MACHINE_NONE;
150     m->machine_subtype = MACHINE_NONE;
151 dpavlin 10 #ifdef BINTRANS
152 dpavlin 2 m->bintrans_enable = 1;
153 dpavlin 10 m->old_bintrans_enable = 1;
154     #endif
155 dpavlin 12 m->arch_pagesize = 4096; /* Should be overriden in
156     emul.c for other pagesizes. */
157     m->dyntrans_alignment_check = 1;
158 dpavlin 2 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 dpavlin 12 int i, j, k, nmatches = 0;
189 dpavlin 2
190     *type = MACHINE_NONE;
191     *subtype = 0;
192    
193 dpavlin 12 /* Check stype, and optionally ssubtype: */
194 dpavlin 2 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 dpavlin 6 fatal("Unknown subtype '%s' for emulation"
218 dpavlin 2 " '%s'\n", ssubtype, stype);
219 dpavlin 6 if (!ssubtype[0])
220     fatal("(Maybe you forgot the -e"
221     " command line option?)\n");
222 dpavlin 2 exit(1);
223     }
224    
225     me = me->next;
226     }
227    
228 dpavlin 12 /* 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 dpavlin 2 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 dpavlin 12 * 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 dpavlin 2 * 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 dpavlin 6 int psize = 1024; /* 1024 256 64 16 4 1 */
504    
505 dpavlin 2 if ((addr >> 32) == 0)
506     addr = (int64_t)(int32_t)addr;
507    
508 dpavlin 6 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 dpavlin 2 }
519 dpavlin 6 psize >>= 2;
520 dpavlin 2 }
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 dpavlin 4 * 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 dpavlin 2 * 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 dpavlin 6 m->md_int.kn02_csr->csr[0] |= irq_nr;
680 dpavlin 2 } else {
681     /* AND out the irq_nr from the CSR: */
682 dpavlin 6 m->md_int.kn02_csr->csr[0] &= ~irq_nr;
683 dpavlin 2 }
684    
685 dpavlin 6 current = m->md_int.kn02_csr->csr[0] & m->md_int.kn02_csr->csr[2];
686 dpavlin 2 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 dpavlin 6 m->md_int.dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START) / 0x10] |= irq_nr;
705 dpavlin 2 else
706 dpavlin 6 m->md_int.dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START) / 0x10] &= ~irq_nr;
707 dpavlin 2
708 dpavlin 6 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 dpavlin 2 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 dpavlin 6 m->md_int.dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START) / 0x10] |= irq_nr;
726 dpavlin 2 else
727 dpavlin 6 m->md_int.dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START) / 0x10] &= ~irq_nr;
728 dpavlin 2
729 dpavlin 6 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 dpavlin 2 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 dpavlin 6 m->md_int.dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START)
748 dpavlin 2 / 0x10] |= irq_nr;
749     else
750 dpavlin 6 m->md_int.dec_ioasic_data->reg[(IOASIC_INTR - IOASIC_SLOT_1_START)
751 dpavlin 2 / 0x10] &= ~irq_nr;
752    
753 dpavlin 6 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 dpavlin 2 / 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 dpavlin 6 m->md_int.kn230_csr->csr |= irq_nr;
770 dpavlin 2
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 dpavlin 6 m->md_int.kn230_csr->csr |= irq_nr;
788 dpavlin 2
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 dpavlin 6 m->md_int.kn230_csr->csr &= ~irq_nr;
794 dpavlin 2
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 dpavlin 6 if ((m->md_int.kn230_csr->csr & (KN230_CSR_INTR_DZ0
800 dpavlin 2 | KN230_CSR_INTR_OPT0 | KN230_CSR_INTR_OPT1)) == 0)
801     cpu_interrupt_ack(cpu, r2);
802     } else {
803     /* irq 3: */
804 dpavlin 6 if ((m->md_int.kn230_csr->csr & (KN230_CSR_INTR_SII |
805 dpavlin 2 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 dpavlin 6 m->md_int.jazz_data->isa_int_asserted |= irq;
839 dpavlin 2 else
840 dpavlin 6 m->md_int.jazz_data->isa_int_asserted &= ~irq;
841 dpavlin 2 } else {
842     if (assrt)
843 dpavlin 6 m->md_int.jazz_data->int_asserted |= irq;
844 dpavlin 2 else
845 dpavlin 6 m->md_int.jazz_data->int_asserted &= ~irq;
846 dpavlin 2 }
847    
848 dpavlin 6 /* 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 dpavlin 2
853 dpavlin 6 if (m->md_int.jazz_data->int_asserted
854     /* & m->md_int.jazz_data->int_enable_mask */ & ~0x8000 )
855 dpavlin 2 cpu_interrupt(cpu, 3);
856     else
857     cpu_interrupt_ack(cpu, 3);
858    
859 dpavlin 6 if (m->md_int.jazz_data->isa_int_asserted &
860     m->md_int.jazz_data->isa_int_enable_mask)
861 dpavlin 2 cpu_interrupt(cpu, 4);
862     else
863     cpu_interrupt_ack(cpu, 4);
864    
865     /* TODO: this "15" (0x8000) is the timer... fix this? */
866 dpavlin 6 if (m->md_int.jazz_data->int_asserted & 0x8000)
867 dpavlin 2 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 dpavlin 6 m->md_int.vr41xx_data->giuint |= (1 << giu_irq);
892 dpavlin 2 else
893 dpavlin 6 m->md_int.vr41xx_data->giuint &= ~(1 << giu_irq);
894 dpavlin 2 }
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 dpavlin 6 if (m->md_int.vr41xx_data->giuint &
902     m->md_int.vr41xx_data->giumask)
903 dpavlin 2 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 dpavlin 6 m->md_int.vr41xx_data->sysint1 |= (1 << irq_nr);
914 dpavlin 2 else
915 dpavlin 6 m->md_int.vr41xx_data->sysint1 &= ~(1 << irq_nr);
916 dpavlin 2 } else if (irq_nr < 32) {
917     irq_nr -= 16;
918     if (assrt)
919 dpavlin 6 m->md_int.vr41xx_data->sysint2 |= (1 << irq_nr);
920 dpavlin 2 else
921 dpavlin 6 m->md_int.vr41xx_data->sysint2 &= ~(1 << irq_nr);
922 dpavlin 2 }
923    
924     /* TODO: Which hardware interrupt pin? */
925    
926     /* debug(" sysint1=%04x mask=%04x, sysint2=%04x mask=%04x\n",
927 dpavlin 6 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 dpavlin 2
930 dpavlin 6 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 dpavlin 2 cpu_interrupt(cpu, 2);
933     else
934     cpu_interrupt_ack(cpu, 2);
935     }
936    
937    
938     /*
939     * Playstation 2 interrupt routine:
940 dpavlin 4 *
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 dpavlin 2 */
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 dpavlin 4 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 dpavlin 6 m->md_int.ps2_data->sbus_smflg |= msk;
966 dpavlin 4 else
967 dpavlin 6 m->md_int.ps2_data->sbus_smflg &= ~msk;
968 dpavlin 4
969 dpavlin 6 if (m->md_int.ps2_data->sbus_smflg != 0)
970 dpavlin 4 cpu_interrupt(cpu, 8 + 1);
971     else
972     cpu_interrupt_ack(cpu, 8 + 1);
973     return;
974     }
975    
976 dpavlin 2 if (assrt) {
977     /* OR into the INTR: */
978 dpavlin 4 if (irq_nr < 16)
979 dpavlin 6 m->md_int.ps2_data->intr |= (1 << irq_nr);
980 dpavlin 2 else
981 dpavlin 6 m->md_int.ps2_data->dmac_reg[0x601] |=
982     (1 << (irq_nr-16));
983 dpavlin 2 } else {
984     /* AND out of the INTR: */
985 dpavlin 4 if (irq_nr < 16)
986 dpavlin 6 m->md_int.ps2_data->intr &= ~(1 << irq_nr);
987 dpavlin 2 else
988 dpavlin 6 m->md_int.ps2_data->dmac_reg[0x601] &=
989     ~(1 << (irq_nr-16));
990 dpavlin 4 }
991 dpavlin 2
992 dpavlin 4 /* TODO: Hm? How about the mask? */
993 dpavlin 6 if (m->md_int.ps2_data->intr /* & m->md_int.ps2_data->imask */ )
994 dpavlin 4 cpu_interrupt(cpu, 2);
995     else
996     cpu_interrupt_ack(cpu, 2);
997    
998     /* TODO: mask? */
999 dpavlin 6 if (m->md_int.ps2_data->dmac_reg[0x601] & 0xffff)
1000 dpavlin 4 cpu_interrupt(cpu, 3);
1001     else
1002     cpu_interrupt_ack(cpu, 3);
1003 dpavlin 2 }
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 dpavlin 6 m->md_int.sgi_ip22_data->reg[4] |= new;
1032 dpavlin 2 else
1033 dpavlin 6 m->md_int.sgi_ip22_data->reg[4] &= ~new;
1034 dpavlin 2 /* TODO: is this enough? */
1035     irq_nr &= 63;
1036     }
1037    
1038     if (irq_nr < 32) {
1039     if (assrt)
1040 dpavlin 6 m->md_int.sgi_ip22_data->reg[0] |= newmask;
1041 dpavlin 2 else
1042 dpavlin 6 m->md_int.sgi_ip22_data->reg[0] &= ~newmask;
1043 dpavlin 2 } else {
1044     if (assrt)
1045 dpavlin 6 m->md_int.sgi_ip22_data->reg[2] |= newmask;
1046 dpavlin 2 else
1047 dpavlin 6 m->md_int.sgi_ip22_data->reg[2] &= ~newmask;
1048 dpavlin 2 }
1049    
1050     /* Read stat and mask for local0: */
1051 dpavlin 6 stat = m->md_int.sgi_ip22_data->reg[0];
1052     mask = m->md_int.sgi_ip22_data->reg[1];
1053 dpavlin 2 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 dpavlin 6 stat = m->md_int.sgi_ip22_data->reg[2];
1060     mask = m->md_int.sgi_ip22_data->reg[3];
1061 dpavlin 2 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 dpavlin 6 m->md_int.sgi_ip30_data->isr |= newmask;
1093 dpavlin 2 else
1094 dpavlin 6 m->md_int.sgi_ip30_data->isr &= ~newmask;
1095 dpavlin 2
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 dpavlin 6 stat = m->md_int.sgi_ip30_data->isr;
1105     mask = m->md_int.sgi_ip30_data->imask0;
1106 dpavlin 2
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 dpavlin 10 uint64_t mace_addr = 0x10;
1140     uint64_t crime_interrupts, crime_interrupts_mask;
1141     uint64_t mace_interrupts, mace_interrupt_mask;
1142 dpavlin 2 unsigned int i;
1143     unsigned char x[8];
1144    
1145 dpavlin 10 /* 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 dpavlin 2 /*
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 dpavlin 10 if ((mace_interrupts & mace_interrupt_mask) == 0)
1181 dpavlin 2 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 dpavlin 10 if ((mace_interrupts & mace_interrupt_mask) == 0)
1195 dpavlin 2 assrt = 0;
1196     else
1197     assrt = 1;
1198     }
1199    
1200 dpavlin 10 /* 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 dpavlin 2 /* Read CRIME_INTSTAT: */
1206 dpavlin 10 memcpy(x, m->md_int.ip32.crime_data->reg + crime_addr,
1207     sizeof(uint64_t));
1208 dpavlin 2 crime_interrupts = 0;
1209 dpavlin 10 for (i=0; i<sizeof(uint64_t); i++) {
1210 dpavlin 2 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 dpavlin 10 for (i=0; i<sizeof(uint64_t); i++)
1221 dpavlin 2 x[7-i] = crime_interrupts >> (i*8);
1222 dpavlin 10 memcpy(m->md_int.ip32.crime_data->reg + crime_addr, x,
1223     sizeof(uint64_t));
1224 dpavlin 2
1225     /* Read CRIME_INTMASK: */
1226 dpavlin 10 memcpy(x, m->md_int.ip32.crime_data->reg + CRIME_INTMASK,
1227     sizeof(uint64_t));
1228 dpavlin 2 crime_interrupts_mask = 0;
1229 dpavlin 10 for (i=0; i<sizeof(uint64_t); i++) {
1230 dpavlin 2 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 dpavlin 10 /* printf("sgi_crime_machine_irq(%i,%i): new interrupts = 0x%08x\n",
1240     assrt, irq_nr, crime_interrupts); */
1241 dpavlin 2 }
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 dpavlin 6 m->md_int.au1x00_ic_data->request0_int |= ms;
1274 dpavlin 2 else
1275 dpavlin 6 m->md_int.au1x00_ic_data->request0_int &= ~ms;
1276 dpavlin 2
1277     /* TODO: Controller 1 */
1278     }
1279    
1280 dpavlin 6 if ((m->md_int.au1x00_ic_data->request0_int &
1281     m->md_int.au1x00_ic_data->mask) != 0)
1282 dpavlin 2 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 dpavlin 6 /*
1293 dpavlin 10 * 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 dpavlin 12 m->md_int.isa_pic_data.pic1->irr |= mask;
1309 dpavlin 10 else
1310 dpavlin 12 m->md_int.isa_pic_data.pic1->irr &= ~mask;
1311 dpavlin 10 } else if (irq_nr < 16) {
1312     if (assrt)
1313 dpavlin 12 m->md_int.isa_pic_data.pic2->irr |= mask;
1314 dpavlin 10 else
1315 dpavlin 12 m->md_int.isa_pic_data.pic2->irr &= ~mask;
1316 dpavlin 10 }
1317    
1318     /* Any interrupt assertions on PIC2 go to irq 2 on PIC1 */
1319 dpavlin 12 /* (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 dpavlin 10 else
1324 dpavlin 12 m->md_int.isa_pic_data.pic1->irr &= ~0x04;
1325 dpavlin 10
1326     /* Now, PIC1: */
1327 dpavlin 12 if (m->md_int.isa_pic_data.pic1->irr &
1328     ~m->md_int.isa_pic_data.pic1->ier)
1329 dpavlin 10 cpu_interrupt(cpu, 2);
1330     else
1331     cpu_interrupt_ack(cpu, 2);
1332 dpavlin 12
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 dpavlin 10 }
1339    
1340    
1341     /*
1342 dpavlin 12 * 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 dpavlin 6 * 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 dpavlin 2 /****************************************************************************
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 dpavlin 12 struct cons_data *cons_data;
1451 dpavlin 2
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 dpavlin 6 int bootdev_type = 0;
1481     int bootdev_id;
1482 dpavlin 2 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 dpavlin 6 bootdev_id = diskimage_bootdev(machine, &bootdev_type);
1497    
1498 dpavlin 2 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 dpavlin 12 #ifdef ENABLE_MIPS
1524 dpavlin 2 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 dpavlin 10 * A MIPS test machine (which happens to work with the
1537     * code in my master's thesis). :-)
1538 dpavlin 12 *
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 dpavlin 2 */
1547     cpu->byte_order = EMUL_BIG_ENDIAN;
1548     machine->machine_name = "MIPS test machine";
1549    
1550 dpavlin 12 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 dpavlin 2
1555 dpavlin 12 snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%llx",
1556 dpavlin 2 (long long)DEV_MP_ADDRESS);
1557     device_add(machine, tmpstr);
1558    
1559 dpavlin 12 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 dpavlin 2 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 dpavlin 12 0,0,0,0,0, color_fb_flag? "VFB02":"VFB01");
1612 dpavlin 2 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 dpavlin 6 machine->md_int.kn02_csr =
1702 dpavlin 2 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 dpavlin 6 machine->md_int.dec_ioasic_data = dev_dec_ioasic_init(cpu, mem, 0x1c000000, 0);
1736 dpavlin 2 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 dpavlin 6 machine->md_int.dec_ioasic_data = dev_dec_ioasic_init(cpu, mem, 0x1f800000, 0);
1802 dpavlin 2
1803     dev_le_init(machine, mem, KN03_SYS_LANCE, 0, 0, KN03_INTR_LANCE +8, 4*65536);
1804    
1805 dpavlin 6 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 dpavlin 2
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 dpavlin 6 machine->md_int.dec5800_csr = dev_dec5800_init(machine, mem, 0x10000000);
1868 dpavlin 2 dev_decbi_init(mem, 0x10000000);
1869 dpavlin 6 dev_ssc_init(machine, mem, 0x10140000, 2, machine->use_x11, &machine->md_int.dec5800_csr->csr);
1870 dpavlin 2 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 dpavlin 6 machine->md_int.dec_ioasic_data = dev_dec_ioasic_init(cpu, mem, 0x1c000000, 0);
1939 dpavlin 2
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 dpavlin 12 snprintf(tmpstr, sizeof(tmpstr),
2044 dpavlin 2 "kn230 addr=0x%llx", (long long)KN230_SYS_ICSR);
2045 dpavlin 6 machine->md_int.kn230_csr = device_add(machine, tmpstr);
2046 dpavlin 2
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 dpavlin 10 strlcpy(bootpath, "rz(0,0,0)", sizeof(bootpath));
2125 dpavlin 2 else
2126     #endif
2127 dpavlin 10 strlcpy(bootpath, "5/rz1/", sizeof(bootpath));
2128 dpavlin 2
2129     if (bootdev_id < 0 || machine->force_netboot) {
2130     /* tftp boot: */
2131 dpavlin 10 strlcpy(bootpath, "5/tftp/", sizeof(bootpath));
2132 dpavlin 2 bootpath[0] = '0' + boot_net_boardnumber;
2133     } else {
2134     /* disk boot: */
2135     bootpath[0] = '0' + boot_scsi_boardnumber;
2136 dpavlin 6 if (diskimage_is_a_tape(machine, bootdev_id,
2137     bootdev_type))
2138 dpavlin 2 bootpath[2] = 't';
2139     bootpath[4] = '0' + bootdev_id;
2140     }
2141    
2142     init_bootpath = bootpath;
2143     }
2144    
2145 dpavlin 10 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 dpavlin 2
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 dpavlin 10 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 dpavlin 2 }
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 dpavlin 10 strlcpy(xx.b.bootpath, bootstr, sizeof(xx.b.bootpath));
2185 dpavlin 2
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 dpavlin 10 snprintf(tmps, sizeof(tmps), "cca=%x",
2226 dpavlin 2 (int)(DEC_DECCCA_BASEADDR + 0xa0000000ULL));
2227     add_environment_string(cpu, tmps, &addr);
2228     }
2229    
2230     /* These are needed for Sprite to boot: */
2231     {
2232 dpavlin 10 char tmps[500];
2233 dpavlin 2
2234 dpavlin 10 snprintf(tmps, sizeof(tmps), "boot=%s", bootarg);
2235     tmps[sizeof(tmps)-1] = '\0';
2236 dpavlin 2 add_environment_string(cpu, tmps, &addr);
2237    
2238 dpavlin 10 snprintf(tmps, sizeof(tmps), "bitmap=0x%x", (uint32_t)((
2239 dpavlin 2 DEC_MEMMAP_ADDR + sizeof(memmap.pagesize))
2240     & 0xffffffffULL));
2241 dpavlin 10 tmps[sizeof(tmps)-1] = '\0';
2242 dpavlin 2 add_environment_string(cpu, tmps, &addr);
2243    
2244 dpavlin 10 snprintf(tmps, sizeof(tmps), "bitmaplen=0x%x",
2245 dpavlin 2 machine->physical_ram_in_mb * 1048576 / 4096 / 8);
2246 dpavlin 10 tmps[sizeof(tmps)-1] = '\0';
2247 dpavlin 2 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 dpavlin 12 * 7 PCI (Note: Not used. The PCI controller
2283     * interrupts at ISA interrupt 9.)
2284 dpavlin 2 */
2285 dpavlin 12
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 dpavlin 2 dev_mc146818_init(machine, mem, 0x10000070, 0, MC146818_PC_CMOS, 4);
2294 dpavlin 6
2295 dpavlin 12 machine->main_console_handle = (size_t)
2296     device_add(machine, "ns16550 irq=5 addr=0x1c800000 name2=tty0 in_use=1");
2297 dpavlin 2
2298 dpavlin 6 #if 0
2299 dpavlin 12 device_add(machine, "ns16550 irq=0 addr=0x1f000010 name2=tty1 in_use=0");
2300 dpavlin 6 #endif
2301    
2302 dpavlin 2 /*
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 dpavlin 12 *
2312     * The PCI controller interrupts at ISA interrupt 9.
2313 dpavlin 2 */
2314 dpavlin 12 pci_data = dev_gt_init(machine, mem, 0x14000000, 2, 8 + 9, 11);
2315 dpavlin 2 /* 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 dpavlin 12 * The bootstring is stored 512 bytes before the end of
2326     * physical ram.
2327 dpavlin 2 */
2328 dpavlin 12 cpu->cd.mips.gpr[MIPS_GPR_A0] =
2329     machine->physical_ram_in_mb * 1048576 + 0xffffffff80000000ULL;
2330 dpavlin 2 bootstr = "root=/dev/hda1 ro";
2331     /* bootstr = "nfsroot=/usr/cobalt/"; */
2332 dpavlin 12 /* TODO: bootarg, and/or automagic boot device detection */
2333     store_string(cpu, cpu->cd.mips.gpr[MIPS_GPR_A0] - 512, bootstr);
2334 dpavlin 2 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 dpavlin 12 /* 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 dpavlin 6 machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4131);
2375 dpavlin 2 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 dpavlin 12 /* 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 dpavlin 6 machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4121);
2407 dpavlin 2 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 dpavlin 6 machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4121);
2435 dpavlin 2 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 dpavlin 6 machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4121);
2463 dpavlin 2 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 dpavlin 6 machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4121);
2491 dpavlin 2 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 dpavlin 6 machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4121);
2519 dpavlin 2 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 dpavlin 6 machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4181);
2547 dpavlin 2 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 dpavlin 12 snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=%i addr=0x0c000010", 8 + VRIP_INTR_SIU);
2554     x = (size_t)device_add(machine, tmpstr);
2555 dpavlin 2
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 dpavlin 12 machine->machine_name = "IBM Workpad Z50";
2578 dpavlin 2 /* 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 dpavlin 6 machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4121);
2588 dpavlin 2 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 dpavlin 6 machine->md_int.vr41xx_data->kiu_console_handle;
2611 dpavlin 2
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 dpavlin 12 hpcmips_fb_bits, "HPCmips");
2681 dpavlin 2
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 dpavlin 6 machine->md_int.ps2_data = dev_ps2_stuff_init(machine, mem, 0x10000000);
2711 dpavlin 2 device_add(machine, "ps2_gs addr=0x12000000");
2712 dpavlin 4 device_add(machine, "ps2_ether addr=0x14001000");
2713 dpavlin 2 dev_ram_init(mem, 0x1c000000, 4 * 1048576, DEV_RAM_RAM, 0); /* TODO: how much? */
2714 dpavlin 4 /* irq = 8 + 32 + 1 (SBUS/USB) */
2715     device_add(machine, "ohci addr=0x1f801600 irq=41");
2716 dpavlin 2
2717     machine->md_interrupt = ps2_interrupt;
2718    
2719     add_symbol_name(&machine->symbol_context,
2720 dpavlin 12 PLAYSTATION2_SIFBIOS, 0x10000, "[SIFBIOS entry]", 0, 0);
2721 dpavlin 2 store_32bit_word(cpu, PLAYSTATION2_BDA + 0, PLAYSTATION2_SIFBIOS);
2722     store_buf(cpu, PLAYSTATION2_BDA + 4, "PS2b", 4);
2723    
2724 dpavlin 4 /* Set the Harddisk controller present flag, if either
2725     disk 0 or 1 is present: */
2726 dpavlin 6 if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
2727     diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
2728 dpavlin 4 store_32bit_word(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x0, 0x100);
2729     dev_ps2_spd_init(machine, mem, 0x14000000);
2730     }
2731 dpavlin 2
2732     store_32bit_word(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x4, PLAYSTATION2_OPTARGS);
2733 dpavlin 4 {
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 dpavlin 2
2741 dpavlin 10 strlcpy(tmp, "root=/dev/hda1 crtmode=vesa0,60", tmplen);
2742 dpavlin 4
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 dpavlin 2 /* 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 dpavlin 4 store_32bit_word(cpu, 0xa0000000 + machine->physical_ram_in_mb*1048576 - 0x1000 + 0x1c, 2);
2771 dpavlin 2
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 dpavlin 10 machine->machine_name = malloc(MACHINE_NAME_MAXBUF);
2785 dpavlin 2 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 dpavlin 10 snprintf(machine->machine_name, MACHINE_NAME_MAXBUF,
2793     "SGI-IP%i", machine->machine_subtype);
2794 dpavlin 2
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 dpavlin 10 snprintf(machine->machine_name,
2812     MACHINE_NAME_MAXBUF, "ARC");
2813 dpavlin 2 }
2814    
2815     if (machine->machine_type == MACHINE_SGI) {
2816     /* TODO: Other SGI machine types? */
2817     switch (machine->machine_subtype) {
2818     case 12:
2819 dpavlin 10 strlcat(machine->machine_name,
2820     " (Iris Indigo IP12)", MACHINE_NAME_MAXBUF);
2821 dpavlin 2
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 dpavlin 10 strlcat(machine->machine_name,
2829     " (Everest IP19)", MACHINE_NAME_MAXBUF);
2830 dpavlin 2 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 dpavlin 10 strlcat(machine->machine_name,
2850     " (Indigo)", MACHINE_NAME_MAXBUF);
2851 dpavlin 2
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 dpavlin 6 machine->md_int.sgi_ip20_data = dev_sgi_ip20_init(cpu, mem, DEV_SGI_IP20_BASE);
2871 dpavlin 2
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 dpavlin 10 strlcat(machine->machine_name, /* TODO */
2896     " (uknown SGI-IP21 ?)", MACHINE_NAME_MAXBUF);
2897 dpavlin 2 /* 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 dpavlin 10 strlcat(machine->machine_name,
2907     " (Indy, Indigo2, Challenge S; Full-house)",
2908     MACHINE_NAME_MAXBUF);
2909 dpavlin 6 machine->md_int.sgi_ip22_data = dev_sgi_ip22_init(machine, mem, 0x1fbd9000, 0);
2910 dpavlin 2 } else {
2911 dpavlin 10 strlcat(machine->machine_name,
2912     " (Indy, Indigo2, Challenge S; Guiness)",
2913     MACHINE_NAME_MAXBUF);
2914 dpavlin 6 machine->md_int.sgi_ip22_data = dev_sgi_ip22_init(machine, mem, 0x1fbd9880, 1);
2915 dpavlin 2 }
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 dpavlin 6 0, 0, machine->use_x11, 0); /* TODO: irq numbers */
2958 dpavlin 2
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 dpavlin 10 strlcat(machine->machine_name,
2987     " (Everest IP25)", MACHINE_NAME_MAXBUF);
2988 dpavlin 2
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 dpavlin 10 strlcat(machine->machine_name,
3009     " (uknown SGI-IP26 ?)",
3010     MACHINE_NAME_MAXBUF); /* TODO */
3011 dpavlin 2 machine->main_console_handle =
3012     dev_zs_init(machine, mem, 0x1fbd9830,
3013     0, 1, "zs console");
3014     break;
3015     case 27:
3016 dpavlin 10 strlcat(machine->machine_name,
3017     " (Origin 200/2000, Onyx2)",
3018     MACHINE_NAME_MAXBUF);
3019 dpavlin 2 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 dpavlin 10 strlcat(machine->machine_name,
3030     " (Impact Indigo2 ?)", MACHINE_NAME_MAXBUF);
3031 dpavlin 2
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 dpavlin 10 strlcat(machine->machine_name,
3041     " (Octane)", MACHINE_NAME_MAXBUF);
3042 dpavlin 2
3043 dpavlin 6 machine->md_int.sgi_ip30_data = dev_sgi_ip30_init(machine, mem, 0x0ff00000);
3044 dpavlin 2 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 dpavlin 12 /* 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 dpavlin 2 /* MardiGras graphics: */
3073     device_add(machine, "sgi_mardigras addr=0x1c000000");
3074    
3075     break;
3076     case 32:
3077 dpavlin 10 strlcat(machine->machine_name,
3078     " (O2)", MACHINE_NAME_MAXBUF);
3079 dpavlin 2
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 dpavlin 6 machine->md_int.ip32.crime_data = dev_crime_init(machine, mem, 0x14000000, 2, machine->use_x11); /* crime0 */
3090 dpavlin 2 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 dpavlin 6 machine->md_int.ip32.mace_data = dev_mace_init(mem, 0x1f310000, 2);
3117 dpavlin 2 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 dpavlin 10 #if 0
3134 dpavlin 2 i = dev_pckbc_init(machine, mem, 0x1f320000,
3135     PCKBC_8242, 0x200 + MACE_PERIPH_MISC,
3136 dpavlin 6 0x800 + MACE_PERIPH_MISC, machine->use_x11, 0);
3137 dpavlin 2 /* keyb+mouse (mace irq numbers) */
3138 dpavlin 10 #endif
3139 dpavlin 2
3140     net_generate_unique_mac(machine, macaddr);
3141 dpavlin 10 eaddr_string = malloc(ETHERNET_STRING_MAXLEN);
3142 dpavlin 2 if (eaddr_string == NULL) {
3143     fprintf(stderr, "out of memory\n");
3144     exit(1);
3145     }
3146 dpavlin 10 snprintf(eaddr_string, ETHERNET_STRING_MAXLEN,
3147     "eaddr=%02x:%02x:%02x:%02x:%02x:%02x",
3148 dpavlin 2 macaddr[0], macaddr[1], macaddr[2],
3149     macaddr[3], macaddr[4], macaddr[5]);
3150 dpavlin 10 dev_sgi_mec_init(machine, mem, 0x1f280000,
3151     MACE_ETHERNET, macaddr);
3152 dpavlin 2
3153     dev_sgi_ust_init(mem, 0x1f340000); /* ust? */
3154    
3155 dpavlin 12 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 dpavlin 10 #if 0
3162 dpavlin 2 if (machine->use_x11)
3163     machine->main_console_handle = i;
3164     else
3165 dpavlin 10 #endif
3166 dpavlin 2 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 dpavlin 6
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 dpavlin 2 /* bus_pci_add(machine, pci_data, mem, 0, 2, 0, pci_ahc_init, pci_ahc_rr); */
3195    
3196     break;
3197     case 35:
3198 dpavlin 10 strlcat(machine->machine_name,
3199     " (Origin 3000)", MACHINE_NAME_MAXBUF);
3200 dpavlin 2 /* 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 dpavlin 10 strlcat(machine->machine_name,
3208     " (Origin 350)", MACHINE_NAME_MAXBUF);
3209 dpavlin 2 /*
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 dpavlin 10 strlcat(machine->machine_name,
3236     " (NEC-RD94, NEC RISCstation 2250)",
3237     MACHINE_NAME_MAXBUF);
3238 dpavlin 2 break;
3239     case MACHINE_ARC_NEC_R94:
3240 dpavlin 10 strlcat(machine->machine_name, " (NEC-R94; NEC RISCstation 2200)",
3241     MACHINE_NAME_MAXBUF);
3242 dpavlin 2 break;
3243     case MACHINE_ARC_NEC_R96:
3244 dpavlin 10 strlcat(machine->machine_name, " (NEC-R96; NEC Express RISCserver)",
3245     MACHINE_NAME_MAXBUF);
3246 dpavlin 2 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 dpavlin 6 i = dev_pckbc_init(machine, mem, 0x80005000ULL, PCKBC_8042, 0, 0, machine->use_x11, 0);
3257 dpavlin 2
3258 dpavlin 12 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 dpavlin 2 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 dpavlin 12 8, "necvdfrb");
3282 dpavlin 2 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 dpavlin 10 strlcat(machine->machine_name,
3301     " (NEC-R98; NEC RISCserver 4200)",
3302     MACHINE_NAME_MAXBUF);
3303 dpavlin 2
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 dpavlin 10 strlcat(machine->machine_name, " (Microsoft Jazz, Acer PICA-61)",
3359     MACHINE_NAME_MAXBUF);
3360 dpavlin 2 break;
3361     case MACHINE_ARC_JAZZ_MAGNUM:
3362 dpavlin 10 strlcat(machine->machine_name, " (Microsoft Jazz, MIPS Magnum)",
3363     MACHINE_NAME_MAXBUF);
3364 dpavlin 2 break;
3365     default:
3366     fatal("error in machine.c. jazz\n");
3367     exit(1);
3368     }
3369    
3370 dpavlin 6 machine->md_int.jazz_data = device_add(machine,
3371 dpavlin 2 "jazz addr=0x80000000");
3372     machine->md_interrupt = jazz_interrupt;
3373    
3374 dpavlin 6 i = dev_pckbc_init(machine, mem, 0x80005000ULL,
3375     PCKBC_JAZZ, 8 + 6, 8 + 7, machine->use_x11, 0);
3376    
3377 dpavlin 12 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 dpavlin 6
3382     if (machine->use_x11)
3383     machine->main_console_handle = i;
3384     else
3385     machine->main_console_handle = j;
3386    
3387 dpavlin 2 switch (machine->machine_subtype) {
3388     case MACHINE_ARC_JAZZ_PICA:
3389 dpavlin 6 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 dpavlin 2 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 dpavlin 12 8, "VXL");
3407 dpavlin 2 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 dpavlin 6 dev_jazz_dma_controller,
3416     machine->md_int.jazz_data);
3417 dpavlin 2
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 dpavlin 10 strlcat(machine->machine_name, " (Microsoft Jazz, Olivetti M700)",
3441     MACHINE_NAME_MAXBUF);
3442 dpavlin 2
3443 dpavlin 6 machine->md_int.jazz_data = device_add(machine,
3444 dpavlin 2 "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 dpavlin 6 PCKBC_JAZZ, 8 + 6, 8 + 7, machine->use_x11, 0);
3454 dpavlin 2 #endif
3455    
3456 dpavlin 12 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 dpavlin 2 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 dpavlin 10 strlcat(machine->machine_name, " (Deskstation Tyne)",
3480     MACHINE_NAME_MAXBUF);
3481 dpavlin 2
3482 dpavlin 12 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 dpavlin 2
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 dpavlin 6 PCKBC_8042, 0, 0, machine->use_x11, 0);
3498 dpavlin 2
3499     if (machine->use_x11)
3500     machine->main_console_handle = j;
3501     else
3502     machine->main_console_handle = i;
3503    
3504 dpavlin 6 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 dpavlin 2 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 dpavlin 6 * TODO: There should not be any use of ARCBIOS before this
3524     * point.
3525 dpavlin 2 */
3526    
3527 dpavlin 6 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 dpavlin 2
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 dpavlin 10 strlcat(init_bootpath, "xio(0)pci(15)",
3558     MACHINE_NAME_MAXBUF);
3559 dpavlin 2 if (machine->machine_subtype == 32)
3560 dpavlin 10 strlcat(init_bootpath, "pci(0)",
3561     MACHINE_NAME_MAXBUF);
3562 dpavlin 2 }
3563    
3564 dpavlin 6 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 dpavlin 2 else
3569 dpavlin 6 snprintf(init_bootpath + strlen(init_bootpath),
3570     400,"scsi(0)disk(%i)rdisk(0)partition(1)",
3571     bootdev_id);
3572 dpavlin 2 }
3573    
3574     if (machine->machine_type == MACHINE_ARC)
3575 dpavlin 10 strlcat(init_bootpath, "\\", MACHINE_NAME_MAXBUF);
3576 dpavlin 2
3577 dpavlin 10 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 dpavlin 2
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 dpavlin 6 cpu->cd.mips.gpr[MIPS_GPR_SP] = (int64_t)(int32_t)
3597     (machine->physical_ram_in_mb * 1048576 + 0x80000000 - 0x2080);
3598 dpavlin 2
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 dpavlin 10 size_t mlen = strlen(bootarg) + strlen("OSLOADOPTIONS=") + 2;
3716     tmp = malloc(mlen);
3717     snprintf(tmp, mlen, "OSLOADOPTIONS=%s", bootarg);
3718 dpavlin 2 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 dpavlin 6 machine->md_int.au1x00_ic_data = dev_au1x00_init(machine, mem);
3752 dpavlin 2
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 dpavlin 8 case MACHINE_EVBMIPS:
3837 dpavlin 10 /* http://www.netbsd.org/Ports/evbmips/ */
3838     cpu->byte_order = EMUL_LITTLE_ENDIAN;
3839    
3840 dpavlin 8 switch (machine->machine_subtype) {
3841     case MACHINE_EVBMIPS_MALTA:
3842 dpavlin 12 case MACHINE_EVBMIPS_MALTA_BE:
3843     machine->machine_name = "MALTA (evbmips, little endian)";
3844     cpu->byte_order = EMUL_LITTLE_ENDIAN;
3845 dpavlin 10
3846 dpavlin 12 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 dpavlin 10 machine->md_interrupt = malta_interrupt;
3857    
3858 dpavlin 12 dev_mc146818_init(machine, mem, 0x18000070, 8 + 8, MC146818_PC_CMOS, 1);
3859 dpavlin 10
3860 dpavlin 12 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 dpavlin 10 /* TODO: Irqs */
3867 dpavlin 12 pci_data = dev_gt_init(machine, mem, 0x1be00000, 8+9, 8+9, 120);
3868 dpavlin 10
3869     /* TODO: Haha, this is bogus. Just a cut&paste
3870     from the Cobalt emulation above. */
3871 dpavlin 12 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 dpavlin 10
3874     device_add(machine, "malta_lcd addr=0x1f000400");
3875 dpavlin 8 break;
3876     case MACHINE_EVBMIPS_PB1000:
3877     machine->machine_name = "PB1000 (evbmips)";
3878 dpavlin 12 cpu->byte_order = EMUL_BIG_ENDIAN;
3879    
3880 dpavlin 10 machine->md_interrupt = au1x00_interrupt;
3881 dpavlin 12 machine->md_int.au1x00_ic_data = dev_au1x00_init(machine, mem);
3882     /* TODO */
3883 dpavlin 8 break;
3884     default:
3885     fatal("Unimplemented EVBMIPS model.\n");
3886     exit(1);
3887     }
3888    
3889 dpavlin 12 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 dpavlin 8
3895 dpavlin 12 /* NetBSD/evbmips wants these: (at least for Malta) */
3896 dpavlin 8
3897 dpavlin 12 /* a0 = argc */
3898     cpu->cd.mips.gpr[MIPS_GPR_A0] = 2;
3899 dpavlin 10
3900 dpavlin 12 /* 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 dpavlin 10
3906 dpavlin 12 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 dpavlin 10
3911 dpavlin 12 /* 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 dpavlin 10
3918 dpavlin 12 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 dpavlin 10
3923 dpavlin 12 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 dpavlin 8 break;
3952    
3953 dpavlin 10 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 dpavlin 12 480,272, 512,1088, -15, "Playstation Portable");
3975 dpavlin 10
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 dpavlin 12 #endif /* ENABLE_MIPS */
3996 dpavlin 10
3997 dpavlin 12 #ifdef ENABLE_PPC
3998 dpavlin 2 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 dpavlin 12 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 dpavlin 2
4019 dpavlin 12 snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%llx",
4020 dpavlin 2 (long long)DEV_MP_ADDRESS);
4021     device_add(machine, tmpstr);
4022    
4023 dpavlin 12 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 dpavlin 2 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 dpavlin 12 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 dpavlin 2 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 dpavlin 12 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 dpavlin 2
4086 dpavlin 12 if (machine->use_x11)
4087     dev_vga_init(machine, mem, 0xc00a0000ULL, 0x800003c0ULL,
4088     machine->machine_name);
4089 dpavlin 2
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 dpavlin 12 store_buf(cpu, cpu->cd.ppc.gpr[6] + 20,
4116     machine->use_x11? "vga" : "com", 4);
4117 dpavlin 2 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 dpavlin 12 machine->main_console_handle = (size_t)device_add(machine, "ns16550 irq=0 addr=0x1d000020");
4166 dpavlin 2
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 dpavlin 12 #endif /* ENABLE_PPC */
4176 dpavlin 2
4177 dpavlin 12 #ifdef ENABLE_SPARC
4178 dpavlin 2 case MACHINE_BARESPARC:
4179     /* A bare SPARC machine, with no devices. */
4180     machine->machine_name = "\"Bare\" SPARC machine";
4181     break;
4182    
4183 dpavlin 12 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 dpavlin 2 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 dpavlin 12 #endif /* ENABLE_SPARC */
4216 dpavlin 2
4217 dpavlin 12 #ifdef ENABLE_ALPHA
4218     case MACHINE_BAREALPHA:
4219     machine->machine_name = "\"Bare\" Alpha machine";
4220 dpavlin 2 break;
4221    
4222 dpavlin 12 case MACHINE_TESTALPHA:
4223     machine->machine_name = "Alpha test machine";
4224 dpavlin 2
4225 dpavlin 12 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 dpavlin 2
4230 dpavlin 12 snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%llx",
4231     (long long)DEV_MP_ADDRESS);
4232     device_add(machine, tmpstr);
4233 dpavlin 2
4234 dpavlin 12 fb = dev_fb_init(machine, mem, DEV_FB_ADDRESS, VFB_GENERIC,
4235     640,480, 640,480, 24, "testalpha generic");
4236 dpavlin 2
4237 dpavlin 12 snprintf(tmpstr, sizeof(tmpstr), "disk addr=0x%llx",
4238     (long long)DEV_DISK_ADDRESS);
4239     device_add(machine, tmpstr);
4240 dpavlin 2
4241 dpavlin 12 snprintf(tmpstr, sizeof(tmpstr), "ether addr=0x%llx irq=0",
4242     (long long)DEV_ETHER_ADDRESS);
4243     device_add(machine, tmpstr);
4244 dpavlin 2
4245     break;
4246    
4247 dpavlin 12 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 dpavlin 2
4260 dpavlin 12 if (machine->prom_emulation) {
4261     struct rpb rpb;
4262     struct crb crb;
4263     struct ctb ctb;
4264 dpavlin 2
4265 dpavlin 12 /* 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 dpavlin 2 break;
4316 dpavlin 12 #endif /* ENABLE_ALPHA */
4317 dpavlin 2
4318 dpavlin 12 #ifdef ENABLE_ARM
4319 dpavlin 6 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 dpavlin 12 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 dpavlin 10
4331 dpavlin 12 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 dpavlin 6 break;
4356 dpavlin 12 #endif /* ENABLE_ARM */
4357 dpavlin 6
4358 dpavlin 12 #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 dpavlin 4 case MACHINE_BAREX86:
4422     machine->machine_name = "\"Bare\" x86 machine";
4423     break;
4424    
4425     case MACHINE_X86:
4426 dpavlin 6 if (machine->machine_subtype == MACHINE_X86_XT)
4427     machine->machine_name = "PC XT";
4428     else
4429     machine->machine_name = "Generic x86 PC";
4430 dpavlin 4
4431 dpavlin 6 /* Interrupt controllers: */
4432 dpavlin 12 snprintf(tmpstr, sizeof(tmpstr), "8259 irq=16 addr=0x%llx",
4433 dpavlin 6 (long long)(X86_IO_BASE + 0x20));
4434     machine->md.pc.pic1 = device_add(machine, tmpstr);
4435     if (machine->machine_subtype != MACHINE_X86_XT) {
4436 dpavlin 12 snprintf(tmpstr, sizeof(tmpstr), "8259 irq=16 addr=0x%llx irq=2",
4437 dpavlin 6 (long long)(X86_IO_BASE + 0xa0));
4438     machine->md.pc.pic2 = device_add(machine, tmpstr);
4439 dpavlin 4 }
4440    
4441 dpavlin 6 machine->md_interrupt = x86_pc_interrupt;
4442    
4443     /* Timer: */
4444 dpavlin 12 snprintf(tmpstr, sizeof(tmpstr), "8253 addr=0x%llx irq=0",
4445 dpavlin 6 (long long)(X86_IO_BASE + 0x40));
4446     device_add(machine, tmpstr);
4447    
4448 dpavlin 12 snprintf(tmpstr, sizeof(tmpstr), "pccmos addr=0x%llx",
4449 dpavlin 6 (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 dpavlin 12 snprintf(tmpstr, sizeof(tmpstr), "fdc addr=0x%llx irq=6",
4464 dpavlin 6 (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 dpavlin 12 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 dpavlin 6 /* VGA + keyboard: */
4481     dev_vga_init(machine, mem, 0xa0000ULL, X86_IO_BASE + 0x3c0,
4482 dpavlin 4 "Generic x86 PC");
4483 dpavlin 6 machine->main_console_handle = dev_pckbc_init(machine,
4484     mem, X86_IO_BASE + 0x60, PCKBC_8042, 1, 12, 1, 1);
4485 dpavlin 4
4486 dpavlin 6 if (machine->prom_emulation)
4487     pc_bios_init(cpu);
4488 dpavlin 4
4489 dpavlin 6 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 dpavlin 4 break;
4497 dpavlin 12 #endif /* ENABLE_X86 */
4498 dpavlin 4
4499 dpavlin 2 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 dpavlin 10 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 dpavlin 2 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 dpavlin 12 case MACHINE_ALPHA:
4600     m->physical_ram_in_mb = 64;
4601     break;
4602 dpavlin 2 case MACHINE_BEBOX:
4603     m->physical_ram_in_mb = 64;
4604     break;
4605 dpavlin 6 case MACHINE_X86:
4606     if (m->machine_subtype == MACHINE_X86_XT)
4607     m->physical_ram_in_mb = 1;
4608     break;
4609 dpavlin 2 }
4610     }
4611    
4612 dpavlin 6 /* Special hack for hpcmips machines: */
4613     if (m->machine_type == MACHINE_HPCMIPS) {
4614 dpavlin 2 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 dpavlin 10 case MACHINE_EVBMIPS:
4741     switch (m->machine_subtype) {
4742     case MACHINE_EVBMIPS_MALTA:
4743 dpavlin 12 case MACHINE_EVBMIPS_MALTA_BE:
4744 dpavlin 10 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 dpavlin 2
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 dpavlin 12 case MACHINE_TESTSPARC:
4804 dpavlin 2 case MACHINE_ULTRA1:
4805 dpavlin 12 m->cpu_name = strdup("SPARCv9");
4806 dpavlin 2 break;
4807    
4808     /* Alpha: */
4809     case MACHINE_BAREALPHA:
4810     case MACHINE_TESTALPHA:
4811 dpavlin 12 case MACHINE_ALPHA:
4812     m->cpu_name = strdup("Alpha");
4813 dpavlin 2 break;
4814 dpavlin 4
4815 dpavlin 6 /* ARM: */
4816     case MACHINE_BAREARM:
4817     case MACHINE_TESTARM:
4818     m->cpu_name = strdup("ARM");
4819     break;
4820    
4821 dpavlin 12 /* 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 dpavlin 4 /* x86: */
4834     case MACHINE_BAREX86:
4835     case MACHINE_X86:
4836 dpavlin 6 if (m->machine_subtype == MACHINE_X86_XT)
4837     m->cpu_name = strdup("8086");
4838     else
4839     m->cpu_name = strdup("AMD64");
4840 dpavlin 4 break;
4841 dpavlin 2 }
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 dpavlin 12 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 dpavlin 2
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 dpavlin 12 debug("Userland emulation works for programs with the complexity"
5074     " of Hello World,\nbut not much more.\n");
5075 dpavlin 2 }
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 dpavlin 4 /* X86 machine: */
5094 dpavlin 6 me = machine_entry_new("x86-based PC", ARCH_X86,
5095     MACHINE_X86, 2, 2);
5096 dpavlin 4 me->aliases[0] = "pc";
5097     me->aliases[1] = "x86";
5098 dpavlin 6 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 dpavlin 4 if (cpu_family_ptr_by_number(ARCH_X86) != NULL) {
5104     me->next = first_machine_entry; first_machine_entry = me;
5105     }
5106    
5107 dpavlin 2 /* 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 dpavlin 12 /* 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 dpavlin 2 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 dpavlin 12 /* 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 dpavlin 2 me->next = first_machine_entry; first_machine_entry = me;
5146     }
5147    
5148 dpavlin 12 /* 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 dpavlin 6 /* 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 dpavlin 2 /* 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 dpavlin 12 me = machine_entry_new("SGI", ARCH_MIPS, MACHINE_SGI, 2, 10);
5199 dpavlin 2 me->aliases[0] = "silicon graphics";
5200     me->aliases[1] = "sgi";
5201 dpavlin 12 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 dpavlin 2 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 dpavlin 10 /* 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 dpavlin 2 /* 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 dpavlin 12 me = machine_entry_new("Handheld MIPS (HPCmips)",
5286     ARCH_MIPS, MACHINE_HPCMIPS, 1, 8);
5287 dpavlin 2 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 dpavlin 4 /* 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 dpavlin 2 /* 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 dpavlin 12 /* 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 dpavlin 2 me->next = first_machine_entry; first_machine_entry = me;
5358     }
5359    
5360 dpavlin 12 /* 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 dpavlin 6 /* 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 dpavlin 2 /* 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 dpavlin 12 /* 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 dpavlin 2 /* 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 dpavlin 12
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 dpavlin 2 }
5543    

  ViewVC Help
Powered by ViewVC 1.1.26