|
|
1.1 root 1:
2: #include "../machine/alignment.h"
3: exception(infop, type, param1, param2)
4: process_info *infop;
5: int type, param1, param2;
6: {
7: /*
8: * Signal an exception. It will be handled by 'locore.s'. Here, I:
9: * 1) Put the exception code where it belongs on the stack.
10: * 2) Restore pc and sp to show that the current opcode
11: * 'was not executed'.
12: * 3) Execute one big non-local-goto. In the process we take care
13: * to reset the current HW fp such that 'alignment' will
14: * indeed return to 'locore.s'.
15: * IMPORTANT NOTE : the process I use will NOT restore
16: * all registers (like normal returns) so the call to the
17: * handling routine HAS TO BE the last thing in 'alignment'.
18: * Otherwise, all its own register variables will be a mess !!
19: * I also know that 'alignment' itself WILL restore all
20: * registers for 'locore.s' since its entry mask is all-1.
21: */
22: register long *my_fp;
23: register long *current_fp, *prev_fp;
24:
25: my_fp = (long *)&infop-1 ;
26: infop->ret_exception = type;
27: switch (type) {
28: case ARITHMETIC:
29: infop->ret_code = param1;
30: break;
31: case ILL_ACCESS:
32: infop->ret_addr = param1;
33: infop->ret_code = param2;
34: break;
35: case ALIGNMENT:
36: case ILL_ADDRMOD:
37: case ILL_OPRND:
38: break;
39: default :
40: printf ("Bad exception type %d (alignment code)\n", type);
41: break;
42: }
43: /*
44: * Now the big trick. Look up the stack until the frame of
45: * 'alignment' is found. prev_fp will point to it and current_fp
46: * will then point to the frame of whoever 'alignment' called.
47: * This should better work ...
48: */
49: prev_fp = my_fp;
50: while (prev_fp != &fp) {
51: current_fp = prev_fp;
52: prev_fp = (long *) *prev_fp;
53: }
54: /*
55: * Found it. Now fool the HW into thinking that 'alignment' called
56: * us directly here, so this routine's 'return' will go back
57: * all the way to 'alignment', stopping any further emulation
58: * for the current offending opcode.
59: * "fool the HW..." ha ha, am I realy fooling myself ?
60: */
61: *my_fp = *current_fp;
62: *(my_fp - 2) = *(current_fp -2); /* Alter program counter */
63: /*
64: * Without further ado, just go back now !!!!
65: */
66: }
67:
68: not_needed (infop)
69: process_info *infop;
70: {
71: /*
72: * Shouldn't ever come to this routine.
73: */
74:
75: printf ("Opcode 0x%x should not trap to alignment code.",
76: opCODE);
77: printf (" OS or machine problem!! \n");
78: }
79:
80:
81: cannot_do (infop)
82: process_info *infop;
83: {
84: /*
85: * Some opcode-caused alignments cannot be emulated. See table.c for
86: * specific reasons. Reflect this back to the process as alignment
87: * exception.
88: */
89: exception (infop, ALIGNMENT);
90: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.