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

Contents of /upstream/0.4.3/src/promemul/dec_prom.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 33 - (show annotations)
Mon Oct 8 16:21:06 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 19677 byte(s)
0.4.3
1 /*
2 * Copyright (C) 2003-2006 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 * $Id: dec_prom.c,v 1.10 2006/07/26 23:21:48 debug Exp $
29 *
30 * DECstation PROM emulation.
31 *
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 */
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 {
69 unsigned char ch;
70 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 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 (int32_t)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 }
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 cpu->memory_rw(cpu, cpu->mem, (int32_t)
316 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 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
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 size_t x;
352
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 for (i=0; i<(int)sizeof(buf); i++)
511 cpu->memory_rw(cpu, cpu->mem, (int32_t)
512 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 for (j=0; j<(int32_t)strlen((char *)buf); j++) {
520 cpu->memory_rw(cpu, cpu->mem, (int32_t)
521 (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 cpu->memory_rw(cpu, cpu->mem, (int32_t)(DEC_PROM_STRINGS
528 + i + strlen((char *)buf)), &ch2, sizeof(char),
529 MEM_READ, CACHE_DATA | NO_EXCEPTIONS);
530 if (nmatches == (int)strlen((char *)buf) && ch2=='=') {
531 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 (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 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 switch ((int32_t)cpu->cd.mips.gpr[MIPS_GPR_A0]) {
647 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 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 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 cpu->memory_rw(cpu, cpu->mem, (int32_t)
672 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