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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26