/[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 10 - (hide annotations)
Mon Oct 8 16:18:27 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 160095 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.815 2005/06/27 23:04:35 debug Exp $
20050617	Experimenting some more with netbooting OpenBSD/sgi. Adding
		a hack which allows emulated ethernet networks to be
		distributed across multiple emulator processes.
20050618	Minor updates (documentation, dummy YAMON emulation, etc).
20050620	strcpy/strcat -> strlcpy/strlcat updates.
		Some more progress on evbmips (Malta).
20050621	Adding a section to doc/configfiles.html about ethernet
		emulation across multiple hosts.
		Beginning the work on the ARM translation engine (using the
		dynamic-but-not-binary translation method).
		Fixing a bintrans bug: 0x9fc00000 should always be treated as
		PROM area, just as 0xbfc00000 is.
		Minor progress on Malta emulation (the PCI-ISA bus).
20050622	NetBSD/evbmips can now be installed (using another emulated
		machine) and run (including userland and so on). :-)
		Spliting up the bintrans haddr_entry field into two (one for
		read, one for write). Probably not much of a speed increase,
		though.
		Updating some NetBSD 2.0 -> 2.0.2 in the documentation.
20050623	Minor updates (documentation, the TODO file, etc).
		gzipped kernels are now always automagically gunzipped when
		loaded.
20050624	Adding a dummy Playstation Portable (PSP) mode, just barely
		enough to run Hello World (in weird colors :-).
		Removing the -b command line option; old bintrans is enabled
		by default instead. It makes more sense.
		Trying to finally fix the non-working performance measurement
		thing (instr/second etc).
20050625	Continuing on the essential basics for ARM emulation. Two
		instructions seem to work, a branch and a simple "mov". (The
		mov arguments are not correct yet.) Performance is definitely
		reasonable.
		Various other minor updates.
		Adding the ARM "bl" instruction.
		Adding support for combining multiple ARM instructions into one
		function call. ("mov" + "mov" is the only one implemented so
		far, but it seems to work.)
		Cleaning up some IP32 interrupt things (crime/mace); disabling
		the PS/2 keyboard controller on IP32, so that NetBSD/sgimips
		boots into userland again.
20050626	Finally! NetBSD/sgimips netboots. Adding instructions to
		doc/guestoses.html on how to set up an nfs server etc.
		Various other minor fixes.
		Playstation Portable ".pbp" files can now be used directly.
		(The ELF part of the .pbp is extracted transparently.)
		Converting some sprintf -> snprintf.
		Adding some more instructions to the ARM disassembler.
20050627	More ARM updates. Adding some simple ldr(b), str(b),
		cmps, and conditional branch instructions, enough to run
		a simple Hello World program.
		All ARM instructions are now inlined/generated for all possible
		condition codes.
		Adding add and sub, and more load/store instructions.
		Removing dummy files: cpu_alpha.c, cpu_hppa.c, and cpu_sparc.c.
		Some minor documentation updates; preparing for a 0.3.4
		release. Updating some URLs.

==============  RELEASE 0.3.4  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26