/[gxemul]/upstream/0.3.3.2/src/dec_prom.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 /upstream/0.3.3.2/src/dec_prom.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9 - (hide annotations)
Mon Oct 8 16:18:22 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 19383 byte(s)
0.3.3.2
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 6 * $Id: dec_prom.c,v 1.58 2005/05/15 01:55:49 debug Exp $
29 dpavlin 2 *
30     * DECstation PROM emulation.
31     */
32    
33     #include <stdio.h>
34     #include <stdlib.h>
35     #include <string.h>
36     #include <sys/types.h>
37     #include <sys/time.h>
38     #include <sys/resource.h>
39    
40     #include "console.h"
41     #include "cpu.h"
42     #include "cpu_mips.h"
43     #include "diskimage.h"
44     #include "machine.h"
45     #include "memory.h"
46     #include "misc.h"
47    
48     #include "dec_prom.h"
49     #include "dec_5100.h"
50     #include "dec_kn01.h"
51     #include "dec_kn02.h"
52     #include "dec_kn03.h"
53    
54    
55     extern int quiet_mode;
56    
57    
58     /*
59     * mem_readchar():
60     *
61     * Reads a byte from emulated RAM, using a MIPS register as a base address.
62     * (Helper function.)
63     */
64     static unsigned char mem_readchar(struct cpu *cpu, int regbase, int offset)
65     {
66     unsigned char ch;
67     cpu->memory_rw(cpu, cpu->mem, cpu->cd.mips.gpr[regbase] + offset,
68     &ch, sizeof(ch), MEM_READ, CACHE_DATA | NO_EXCEPTIONS);
69     return ch;
70     }
71    
72    
73     /*
74     * dec_jumptable_func():
75     *
76     * The jumptable is located at the beginning of the PROM, at 0xbfc00000 + i*8,
77     * where i is the decimal function number. Many of these can be converted to
78     * an identical callback function.
79     *
80     * Return value is non-zero if the vector number was converted into a callback
81     * function number, otherwise 0.
82     *
83     * Vector (dec) Function
84     * 0x0 0 reset()
85     * 0x10 2 restart()
86     * 0x18 3 reinit()
87     * 0x30 6 open()
88     * 0x38 7 read()
89     * 0x58 11 lseek()
90     * 0x68 13 putchar()
91     * 0x88 17 printf()
92     * 0x108 33 getenv2()
93     */
94     int dec_jumptable_func(struct cpu *cpu, int vector)
95     {
96     int i;
97     static int file_opened = 0;
98     static int current_file_offset = 0;
99    
100     switch (vector) {
101     case 0x0: /* reset() */
102     /* TODO */
103     cpu->machine->exit_without_entering_debugger = 1;
104     cpu->running = 0;
105     cpu->dead = 1;
106     break;
107     case 0x10: /* restart() */
108     /* TODO */
109     cpu->machine->exit_without_entering_debugger = 1;
110     cpu->running = 0;
111     cpu->dead = 1;
112     break;
113     case 0x18: /* reinit() */
114     /* TODO */
115     cpu->machine->exit_without_entering_debugger = 1;
116     cpu->cd.mips.gpr[MIPS_GPR_V0] = 0;
117     break;
118     case 0x30: /* open() */
119     /*
120     * TODO: This is just a hack to allow Sprite/pmax' bootblock
121     * code to load /vmsprite. The filename argument (in A0)
122     * is ignored, and a file handle value of 1 is returned.
123     */
124     if (file_opened) {
125     fatal("\ndec_jumptable_func(): opening more than one "
126     "file isn't supported yet.\n");
127     cpu->running = 0;
128     cpu->dead = 1;
129     }
130     file_opened = 1;
131     cpu->cd.mips.gpr[MIPS_GPR_V0] = 1;
132     break;
133     case 0x38: /* read(handle, ptr, length) */
134     cpu->cd.mips.gpr[MIPS_GPR_V0] = -1;
135     if ((int32_t)cpu->cd.mips.gpr[MIPS_GPR_A2] > 0) {
136 dpavlin 6 int disk_id = diskimage_bootdev(cpu->machine, NULL);
137 dpavlin 2 int res;
138     unsigned char *tmp_buf;
139    
140     tmp_buf = malloc(cpu->cd.mips.gpr[MIPS_GPR_A2]);
141     if (tmp_buf == NULL) {
142     fprintf(stderr, "[ *** Out of memory in "
143     "dec_prom.c, allocating %i bytes ]\n",
144     (int)cpu->cd.mips.gpr[MIPS_GPR_A2]);
145     break;
146     }
147    
148 dpavlin 6 res = diskimage_access(cpu->machine, disk_id,
149     DISKIMAGE_SCSI, 0, current_file_offset, tmp_buf,
150 dpavlin 2 cpu->cd.mips.gpr[MIPS_GPR_A2]);
151    
152     /* If the transfer was successful, transfer the data
153     to emulated memory: */
154     if (res) {
155     uint64_t dst = cpu->cd.mips.gpr[MIPS_GPR_A1];
156     store_buf(cpu, dst, (char *)tmp_buf,
157     cpu->cd.mips.gpr[MIPS_GPR_A2]);
158     cpu->cd.mips.gpr[MIPS_GPR_V0] =
159     cpu->cd.mips.gpr[MIPS_GPR_A2];
160     current_file_offset +=
161     cpu->cd.mips.gpr[MIPS_GPR_A2];
162     }
163    
164     free(tmp_buf);
165     }
166     break;
167     case 0x58: /* lseek(handle, offset[, whence]) */
168     /* TODO */
169     if (cpu->cd.mips.gpr[MIPS_GPR_A2] == 0)
170     current_file_offset = cpu->cd.mips.gpr[MIPS_GPR_A1];
171     else
172     fatal("WARNING! Unimplemented whence in "
173     "dec_jumptable_func()\n");
174     cpu->cd.mips.gpr[MIPS_GPR_V0] = 0;
175     break;
176     case 0x68: /* putchar() */
177     console_putchar(cpu->machine->main_console_handle,
178     cpu->cd.mips.gpr[MIPS_GPR_A0]);
179     break;
180     case 0x88: /* printf() */
181     return 0x30;
182     case 0x108: /* getenv2() */
183     return 0x64;
184     default:
185     cpu_register_dump(cpu->machine, cpu, 1, 0x1);
186     printf("a0 points to: ");
187     for (i=0; i<40; i++) {
188     unsigned char ch = '\0';
189     cpu->memory_rw(cpu, cpu->mem,
190     cpu->cd.mips.gpr[MIPS_GPR_A0] + i, &ch,
191     sizeof(ch), MEM_READ, CACHE_DATA | NO_EXCEPTIONS);
192     if (ch >= ' ' && ch < 126)
193     printf("%c", ch);
194     else
195     printf("[%02x]", ch);
196     }
197     printf("\n");
198     fatal("PROM emulation: unimplemented JUMP TABLE vector "
199     "0x%x (decimal function %i)\n", vector, vector/8);
200     cpu->running = 0;
201     cpu->dead = 1;
202     }
203    
204     return 0;
205     }
206    
207    
208     /*
209     * decstation_prom_emul():
210     *
211     * DECstation PROM emulation.
212     *
213     * Callback functions:
214     * 0x0c strcmp()
215     * 0x14 strlen()
216     * 0x24 getchar()
217     * 0x28 gets()
218     * 0x2c puts()
219     * 0x30 printf()
220     * 0x38 iopoll()
221     * 0x54 bootinit()
222     * 0x58 bootread()
223     * 0x64 getenv()
224     * 0x6c slot_address()
225     * 0x70 wbflush()
226     * 0x7c clear_cache()
227     * 0x80 getsysid()
228     * 0x84 getbitmap()
229     * 0x88 disableintr()
230     * 0x8c enableintr()
231     * 0x9c halt()
232     * 0xa4 gettcinfo()
233     * 0xa8 execute_cmd()
234     * 0xac rex()
235     */
236     int decstation_prom_emul(struct cpu *cpu)
237     {
238     int i, j, ch, argreg, argdata;
239     int vector = cpu->pc & 0xfff;
240     int callback = (cpu->pc & 0xf000)? 1 : 0;
241     unsigned char buf[100];
242     unsigned char ch1, ch2, ch3;
243     uint64_t tmpaddr, slot_base = 0x10000000, slot_size = 0;
244    
245     if (!callback) {
246     vector = dec_jumptable_func(cpu, vector);
247     if (vector == 0)
248     return 1;
249     } else {
250     /* Vector number is n*4, PC points to n*8. */
251     vector /= 2;
252     }
253    
254     switch (vector) {
255     case 0x0c: /* strcmp(): */
256     i = j = 0;
257     do {
258     ch1 = mem_readchar(cpu, MIPS_GPR_A0, i++);
259     ch2 = mem_readchar(cpu, MIPS_GPR_A1, j++);
260     } while (ch1 == ch2 && ch1 != '\0');
261    
262     /* If ch1=='\0', then strings are equal. */
263     if (ch1 == '\0')
264     cpu->cd.mips.gpr[MIPS_GPR_V0] = 0;
265     if ((signed char)ch1 > (signed char)ch2)
266     cpu->cd.mips.gpr[MIPS_GPR_V0] = 1;
267     if ((signed char)ch1 < (signed char)ch2)
268     cpu->cd.mips.gpr[MIPS_GPR_V0] = -1;
269     break;
270     case 0x14: /* strlen(): */
271     i = 0;
272     do {
273     ch2 = mem_readchar(cpu, MIPS_GPR_A0, i++);
274     } while (ch2 != 0);
275     cpu->cd.mips.gpr[MIPS_GPR_V0] = i - 1;
276     break;
277     case 0x24: /* getchar() */
278     /* debug("[ DEC PROM getchar() ]\n"); */
279     cpu->cd.mips.gpr[MIPS_GPR_V0] = console_readchar(
280     cpu->machine->main_console_handle);
281     break;
282     case 0x28: /* gets() */
283     /* debug("[ DEC PROM gets() ]\n"); */
284     tmpaddr = cpu->cd.mips.gpr[MIPS_GPR_A0];
285     i = 0;
286    
287     /* TODO: Make this not hang (block) the entire emulator */
288    
289     do {
290     while ((ch = console_readchar(
291     cpu->machine->main_console_handle)) < 1)
292     ;
293     if (ch == '\r')
294     ch = '\n';
295     ch2 = ch;
296    
297     if (ch == '\b') {
298     if (i > 0) {
299     console_putchar(cpu->machine->
300     main_console_handle, ch2);
301     console_putchar(cpu->machine->
302     main_console_handle, ' ');
303     console_putchar(cpu->machine->
304     main_console_handle, ch2);
305     }
306     } else
307     console_putchar(cpu->machine->
308     main_console_handle, ch2);
309    
310     fflush(stdout);
311    
312     if (ch == '\n') {
313     /* It seems that trailing newlines
314     are not included in the buffer. */
315     } else if (ch != '\b') {
316     cpu->memory_rw(cpu, cpu->mem,
317     cpu->cd.mips.gpr[MIPS_GPR_A0] + i,
318     &ch2, sizeof(ch2), MEM_WRITE,
319     CACHE_DATA | NO_EXCEPTIONS);
320     i++;
321     } else {
322     if (i > 0)
323     i--;
324     }
325     } while (ch2 != '\n');
326    
327     /* Trailing nul-byte: */
328     ch2 = '\0';
329     cpu->memory_rw(cpu, cpu->mem, cpu->cd.mips.gpr[MIPS_GPR_A0] +
330     i, &ch2, sizeof(ch2), MEM_WRITE,
331     CACHE_DATA | NO_EXCEPTIONS);
332    
333     /* Return the input argument: */
334     cpu->cd.mips.gpr[MIPS_GPR_V0] = cpu->cd.mips.gpr[MIPS_GPR_A0];
335     break;
336     case 0x2c: /* puts() */
337     i = 0;
338     while ((ch = mem_readchar(cpu, MIPS_GPR_A0, i++)) != '\0')
339     console_putchar(cpu->machine->main_console_handle, ch);
340     console_putchar(cpu->machine->main_console_handle, '\n');
341     cpu->cd.mips.gpr[MIPS_GPR_V0] = 0;
342     break;
343     case 0x30: /* printf() */
344     if (cpu->machine->register_dump ||
345     cpu->machine->instruction_trace)
346     debug("PROM printf(0x%08lx): \n",
347     (long)cpu->cd.mips.gpr[MIPS_GPR_A0]);
348    
349     i = 0; ch = -1; argreg = MIPS_GPR_A1;
350     while (ch != '\0') {
351     char printfbuf[8000];
352     int x;
353    
354     printfbuf[0] = printfbuf[sizeof(printfbuf)-1] = '\0';
355    
356     ch = mem_readchar(cpu, MIPS_GPR_A0, i++);
357     switch (ch) {
358     case '%':
359     ch = '0';
360     while (ch >= '0' && ch <= '9')
361     ch = mem_readchar(cpu,
362     MIPS_GPR_A0, i++);
363    
364     switch (ch) {
365     case '%':
366     strcpy(printfbuf, "%%");
367     break;
368     case 'c':
369     case 'd':
370     case 's':
371     case 'x':
372     /* Get argument: */
373     if (argreg > MIPS_GPR_A3) {
374     #if 1
375     /* Linux booters seem to go
376     over the edge sometimes: */
377     ch = '\0';
378     strcpy(printfbuf, "[...]\n");
379     #else
380     printf("[ decstation_prom_emul"
381     "(): too many arguments ]");
382     /* This reuses the last arg,
383     which is utterly incorrect.
384     (TODO) */
385     argreg = MIPS_GPR_A3;
386     #endif
387     }
388    
389     ch2 = argdata =
390     cpu->cd.mips.gpr[argreg];
391    
392     switch (ch) {
393     case 'c':
394     sprintf(printfbuf, "%c", ch2);
395     break;
396     case 'd':
397     sprintf(printfbuf, "%d",
398     argdata);
399     break;
400     case 'x':
401     sprintf(printfbuf, "%x",
402     argdata);
403     break;
404     case 's':
405     /* Print a "%s" string. */
406     j = 0; ch3 = '\n';
407     while (ch2) {
408     ch2 = mem_readchar(cpu,
409     argreg, j++);
410     if (ch2) {
411     snprintf(
412     printfbuf +
413     strlen(
414     printfbuf),
415     sizeof(
416     printfbuf)-
417     1-strlen(
418     printfbuf),
419     "%c", ch2);
420     ch3 = ch2;
421     }
422     }
423     break;
424     }
425     argreg ++;
426     break;
427     default:
428     printf("[ unknown printf format char"
429     " '%c' ]", ch);
430     }
431     break;
432     case '\0':
433     break;
434     default:
435     sprintf(printfbuf, "%c", ch);
436     }
437    
438     printfbuf[sizeof(printfbuf)-1] = '\0';
439    
440     for (x=0; x<strlen(printfbuf); x++)
441     console_putchar(cpu->machine->
442     main_console_handle, printfbuf[x]);
443     }
444     if (cpu->machine->register_dump ||
445     cpu->machine->instruction_trace)
446     debug("\n");
447     fflush(stdout);
448     cpu->cd.mips.gpr[MIPS_GPR_V0] = 0;
449     break;
450     case 0x54: /* bootinit() */
451     /* debug("[ DEC PROM bootinit(0x%08x): TODO ]\n",
452     (int)cpu->cd.mips.gpr[MIPS_GPR_A0]); */
453     cpu->cd.mips.gpr[MIPS_GPR_V0] = 0;
454     break;
455     case 0x58: /* bootread(int b, void *buffer, int n) */
456     /*
457     * Read data from the boot device.
458     * b is a sector number (512 bytes per sector),
459     * buffer is the destination address, and n
460     * is the number of _bytes_ to read.
461     *
462     * TODO: Return value? NetBSD thinks that 0 is ok.
463     */
464     debug("[ DEC PROM bootread(0x%x, 0x%08x, 0x%x) ]\n",
465     (int)cpu->cd.mips.gpr[MIPS_GPR_A0],
466     (int)cpu->cd.mips.gpr[MIPS_GPR_A1],
467     (int)cpu->cd.mips.gpr[MIPS_GPR_A2]);
468    
469     cpu->cd.mips.gpr[MIPS_GPR_V0] = 0;
470    
471     if ((int32_t)cpu->cd.mips.gpr[MIPS_GPR_A2] > 0) {
472 dpavlin 6 int disk_id = diskimage_bootdev(cpu->machine, NULL);
473 dpavlin 2 int res;
474     unsigned char *tmp_buf;
475    
476     tmp_buf = malloc(cpu->cd.mips.gpr[MIPS_GPR_A2]);
477     if (tmp_buf == NULL) {
478     fprintf(stderr, "[ *** Out of memory in "
479     "dec_prom.c, allocating %i bytes ]\n",
480     (int)cpu->cd.mips.gpr[MIPS_GPR_A2]);
481     break;
482     }
483    
484 dpavlin 6 res = diskimage_access(cpu->machine, disk_id,
485     DISKIMAGE_SCSI, 0,
486 dpavlin 2 cpu->cd.mips.gpr[MIPS_GPR_A0] * 512, tmp_buf,
487     cpu->cd.mips.gpr[MIPS_GPR_A2]);
488    
489     /* If the transfer was successful, transfer the data
490     to emulated memory: */
491     if (res) {
492     uint64_t dst = cpu->cd.mips.gpr[MIPS_GPR_A1];
493     if (dst < 0x80000000ULL)
494     dst |= 0x80000000;
495    
496     store_buf(cpu, dst, (char *)tmp_buf,
497     cpu->cd.mips.gpr[MIPS_GPR_A2]);
498     cpu->cd.mips.gpr[MIPS_GPR_V0] =
499     cpu->cd.mips.gpr[MIPS_GPR_A2];
500     }
501    
502     free(tmp_buf);
503     }
504     break;
505     case 0x64: /* getenv() */
506     /* Find the environment variable given by a0: */
507     for (i=0; i<sizeof(buf); i++)
508     cpu->memory_rw(cpu, cpu->mem,
509     cpu->cd.mips.gpr[MIPS_GPR_A0] + i, &buf[i],
510     sizeof(char), MEM_READ, CACHE_DATA | NO_EXCEPTIONS);
511     buf[sizeof(buf)-1] = '\0';
512     debug("[ DEC PROM getenv(\"%s\") ]\n", buf);
513     for (i=0; i<0x1000; i++) {
514     /* Matching string at offset i? */
515     int nmatches = 0;
516     for (j=0; j<strlen((char *)buf); j++) {
517     cpu->memory_rw(cpu, cpu->mem, (uint64_t)
518     (DEC_PROM_STRINGS + i + j), &ch2,
519     sizeof(char), MEM_READ, CACHE_DATA |
520     NO_EXCEPTIONS);
521     if (ch2 == buf[j])
522     nmatches++;
523     }
524     cpu->memory_rw(cpu, cpu->mem,
525     (uint64_t)(DEC_PROM_STRINGS
526     + i + strlen((char *)buf)), &ch2, sizeof(char),
527     MEM_READ, CACHE_DATA | NO_EXCEPTIONS);
528     if (nmatches == strlen((char *)buf) && ch2 == '=') {
529     cpu->cd.mips.gpr[MIPS_GPR_V0] =
530     DEC_PROM_STRINGS + i +
531     strlen((char *)buf) + 1;
532     return 1;
533     }
534     }
535     /* Return NULL if string wasn't found. */
536     fatal("[ DEC PROM getenv(\"%s\"): WARNING: Not in "
537     "environment! ]\n", buf);
538     cpu->cd.mips.gpr[MIPS_GPR_V0] = 0;
539     break;
540     case 0x6c: /* ulong slot_address(int sn) */
541     debug("[ DEC PROM slot_address(%i) ]\n",
542     (int)cpu->cd.mips.gpr[MIPS_GPR_A0]);
543     /* TODO: This is too hardcoded. */
544     /* TODO 2: Should these be physical or virtual addresses? */
545     switch (cpu->machine->machine_subtype) {
546     case MACHINE_DEC_3MAX_5000:
547     slot_base = KN02_PHYS_TC_0_START;/* 0x1e000000 */
548     slot_size = 4*1048576; /* 4 MB */
549     break;
550     case MACHINE_DEC_3MIN_5000:
551     slot_base = 0x10000000;
552     slot_size = 0x4000000; /* 64 MB */
553     break;
554     case MACHINE_DEC_3MAXPLUS_5000:
555     slot_base = 0x1e000000;
556     slot_size = 0x800000; /* 8 MB */
557     break;
558     case MACHINE_DEC_MAXINE_5000:
559     slot_base = 0x10000000;
560     slot_size = 0x4000000; /* 64 MB */
561     break;
562     default:
563     fatal("warning: DEC PROM slot_address() "
564     "unimplemented for this machine type\n");
565     }
566     cpu->cd.mips.gpr[MIPS_GPR_V0] = (int64_t)(int32_t)
567     (0x80000000 + slot_base + slot_size *
568     cpu->cd.mips.gpr[MIPS_GPR_A0]);
569     break;
570     case 0x70: /* wbflush() */
571     debug("[ DEC PROM wbflush(): TODO ]\n");
572     cpu->cd.mips.gpr[MIPS_GPR_V0] = 0;
573     break;
574     case 0x7c: /* clear_cache(addr, len) */
575     debug("[ DEC PROM clear_cache(0x%x,%i) ]\n",
576     (uint32_t)cpu->cd.mips.gpr[MIPS_GPR_A0],
577     (int)cpu->cd.mips.gpr[MIPS_GPR_A1]);
578     /* TODO */
579     cpu->cd.mips.gpr[MIPS_GPR_V0] = 0; /* ? */
580     break;
581     case 0x80: /* getsysid() */
582     /* debug("[ DEC PROM getsysid() ]\n"); */
583     /* TODO: why did I add the 0x82 stuff??? */
584     cpu->cd.mips.gpr[MIPS_GPR_V0] = ((uint32_t)0x82 << 24)
585     + (cpu->machine->machine_subtype << 16) + (0x3 << 8);
586     cpu->cd.mips.gpr[MIPS_GPR_V0] =
587     (int64_t)(int32_t)cpu->cd.mips.gpr[MIPS_GPR_V0];
588     break;
589     case 0x84: /* getbitmap() */
590     debug("[ DEC PROM getbitmap(0x%08x) ]\n",
591     (int)cpu->cd.mips.gpr[MIPS_GPR_A0]);
592     store_buf(cpu, cpu->cd.mips.gpr[MIPS_GPR_A0],
593     (char *)&memmap, sizeof(memmap));
594     cpu->cd.mips.gpr[MIPS_GPR_V0] = sizeof((memmap.bitmap));
595     break;
596     case 0x88: /* disableintr() */
597     debug("[ DEC PROM disableintr(): TODO ]\n");
598     cpu->cd.mips.gpr[MIPS_GPR_V0] = 0;
599     break;
600     case 0x8c: /* enableintr() */
601     debug("[ DEC PROM enableintr(): TODO ]\n");
602     cpu->cd.mips.gpr[MIPS_GPR_V0] = 0;
603     break;
604     case 0x9c: /* halt() */
605     debug("[ DEC PROM halt() ]\n");
606     cpu->machine->exit_without_entering_debugger = 1;
607     cpu->running = 0;
608     cpu->dead = 1;
609     break;
610     case 0xa4: /* gettcinfo() */
611     /*
612     * These are just bogus values... TODO
613     *
614     * 0: revision
615     * 4: clock period in nano seconds
616     * 8: slot size in megabytes TODO: not same for all models!
617     * 12: I/O timeout in cycles
618     * 16: DMA address range in megabytes
619     * 20: maximum DMA burst length
620     * 24: turbochannel parity (yes = 1)
621     * 28: reserved
622     */
623     store_32bit_word(cpu, DEC_PROM_TCINFO + 0, 0);
624     store_32bit_word(cpu, DEC_PROM_TCINFO + 4, 50);
625     store_32bit_word(cpu, DEC_PROM_TCINFO + 8, 4);
626     store_32bit_word(cpu, DEC_PROM_TCINFO + 12, 10);
627     store_32bit_word(cpu, DEC_PROM_TCINFO + 16, 1);
628     store_32bit_word(cpu, DEC_PROM_TCINFO + 20, 100);
629     store_32bit_word(cpu, DEC_PROM_TCINFO + 24, 0);
630     store_32bit_word(cpu, DEC_PROM_TCINFO + 28, 0);
631     cpu->cd.mips.gpr[MIPS_GPR_V0] = DEC_PROM_TCINFO;
632     break;
633     case 0xa8: /* int execute_cmd(char *) */
634     i = 0;
635     while ((ch = mem_readchar(cpu, MIPS_GPR_A0, i++)) != '\0')
636     console_putchar(cpu->machine->main_console_handle, ch);
637     console_putchar(cpu->machine->main_console_handle, '\n');
638     cpu->cd.mips.gpr[MIPS_GPR_V0] = 0;
639     break;
640     case 0xac: /* rex() */
641     debug("[ DEC PROM rex('%c') ]\n",
642     (int)cpu->cd.mips.gpr[MIPS_GPR_A0]);
643     switch (cpu->cd.mips.gpr[MIPS_GPR_A0]) {
644     case 'h':
645     debug("DEC PROM: rex('h') ==> halt\n");
646     cpu->machine->exit_without_entering_debugger = 1;
647     cpu->running = 0;
648     cpu->dead = 1;
649     break;
650     case 'b':
651     debug("DEC PROM: rex('b') ==> reboot: TODO "
652     "(halting CPU instead)\n");
653     cpu->machine->exit_without_entering_debugger = 1;
654     cpu->running = 0;
655     cpu->dead = 1;
656     break;
657     default:
658     fatal("DEC prom emulation: unknown rex() a0=0x%llx ("
659     "'%c')\n", (long long)cpu->cd.mips.gpr[MIPS_GPR_A0],
660     (char)cpu->cd.mips.gpr[MIPS_GPR_A0]);
661     cpu->running = 0;
662     cpu->dead = 1;
663     }
664     break;
665     default:
666     cpu_register_dump(cpu->machine, cpu, 1, 0x1);
667     printf("a0 points to: ");
668     for (i=0; i<40; i++) {
669     unsigned char ch = '\0';
670     cpu->memory_rw(cpu, cpu->mem,
671     cpu->cd.mips.gpr[MIPS_GPR_A0] + i, &ch,
672     sizeof(ch), MEM_READ, CACHE_DATA | NO_EXCEPTIONS);
673     if (ch >= ' ' && ch < 126)
674     printf("%c", ch);
675     else
676     printf("[%02x]", ch);
677     }
678     printf("\n");
679     fatal("PROM emulation: unimplemented callback vector 0x%x\n",
680     vector);
681     cpu->running = 0;
682     cpu->dead = 1;
683     }
684    
685     return 1;
686     }
687    

  ViewVC Help
Powered by ViewVC 1.1.26