/
trap_handler.c
193 lines (166 loc) · 6.57 KB
/
trap_handler.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#include <comp421/yalnix.h>
#include <comp421/hardware.h>
#include "global.h"
#include "util.h"
#include "kernel_call.h"
#include "trap_handler.h"
#include <stdlib.h>
#include <stdio.h>
static int clockCount = 0;
struct PCBNode* init;
struct PCBNode* idle;
struct PCBNode* active_process;
struct PCBNode *current;
struct PCBNode *readyQuqueHead;
struct PCBNode *readyQueueTail;
struct PCBNode *delayBlockingQueueHead;
struct PCBNode *delayBlockingQueueTail;
extern void trapKernel(ExceptionStackFrame *exceptionStackFrame)
{
TracePrintf(512, "trapKernel: vector(%d), code(%d), addr(%d), psr(%d), pc(%d), sp(%d), regs(%s)\n",
exceptionStackFrame->vector, exceptionStackFrame->code, exceptionStackFrame->addr,
exceptionStackFrame->psr, exceptionStackFrame->pc, exceptionStackFrame->sp,
exceptionStackFrame->regs);
int temp = 0;
switch(exceptionStackFrame->code){
case YALNIX_FORK:
TracePrintf(0, "calling kernel Fork()");
break;
case YALNIX_EXEC:
KernelExec((char *)exceptionStackFrame->regs[1], (char **)exceptionStackFrame->regs[2], exceptionStackFrame);
break;
default:
break;
}
}
extern void trapClock(ExceptionStackFrame *exceptionStackFrame)
{
TracePrintf(512, "trapClock: vector(%d), code(%d), addr(%d), psr(%d), pc(%d), sp(%d), regs(%s)\n",
exceptionStackFrame->vector, exceptionStackFrame->code, exceptionStackFrame->addr,
exceptionStackFrame->psr, exceptionStackFrame->pc, exceptionStackFrame->sp,
exceptionStackFrame->regs);
if(active_process->PID == 0)
{
clockCount = 1;
// //TracePrintf(510, "Waiting for the next trap clock to do context switch\n");
ContextSwitch(generalSwitchFunc, &(active_process->ctxp), active_process,init);
TracePrintf(510, "Trap_clock: switch from idle to init\n");
}
else
{
clockCount = 0;
ContextSwitch(generalSwitchFunc, &(active_process->ctxp), active_process, idle);
TracePrintf(510, "Trap_clock: switch from init to idle\n");
}
}
extern void trapIllegal(ExceptionStackFrame *exceptionStackFrame)
{
TracePrintf(512, "trapIllegal: vector(%d), code(%d), addr(%d), psr(%d), pc(%d), sp(%d), regs(%s)\n",
exceptionStackFrame->vector, exceptionStackFrame->code, exceptionStackFrame->addr,
exceptionStackFrame->psr, exceptionStackFrame->pc, exceptionStackFrame->sp,
exceptionStackFrame->regs);
int code = exceptionStackFrame->code;
char string[128];
char* msg = string;
if (code == ILL_BADSTK)
msg = "Bad stack\n";
else if (code == ILL_ILLOPC || code == ILL_ILLOPN || code == ILL_ILLADR)
msg = "Illegal instruction\n";
else if (code == ILL_PRVOPC || code == ILL_PRVREG)
msg = "Privileged instruction\n";
else if (code == ILL_COPROC)
msg = "Coprocessor error\n";
else if (code == ILL_ILLTRP)
msg = "Illegal software trap\n";
else if (code == BUS_ADRALN + 20)
printf(msg, "Invalid address alignment %p", exceptionStackFrame->addr);
else if (code == SI_KERNEL)
msg = "Linux kernel SIGILL\n";
else if (code == SI_USER)
msg = "Received SIGILL from user\n";
else
printf(msg, "Unknown code 0x%x", code);
//KernelExit(ERROR);
printf(msg);
}
extern void trapMemory(ExceptionStackFrame *exceptionStackFrame)
{
TracePrintf(512, "trapMemory: vector(%d), code(%d), addr(%d), psr(%d), pc(%d), sp(%d), regs(%s)\n",
exceptionStackFrame->vector, exceptionStackFrame->code, exceptionStackFrame->addr,
exceptionStackFrame->psr, exceptionStackFrame->pc, exceptionStackFrame->sp,
exceptionStackFrame->regs);
if( exceptionStackFrame -> addr > current -> stack_brk )
{
TracePrintf(0, "Trap Memory Error: addr: %d is large than stack_brk: %d\n", exceptionStackFrame -> addr, current -> stack_brk);
//Exit;
}
if( exceptionStackFrame -> addr < UP_TO_PAGE(current -> heap_brk) + PAGESIZE )
{
TracePrintf(0, "Trap Memory Error: addr: %d is smaller than heap_brk: %d\n", exceptionStackFrame -> addr, current -> heap_brk);
//Exit;
}
long userTablePTE;
TracePrintf(510, "Moving user stack down to address: %d (%d)\n", exceptionStackFrame -> addr, (long)exceptionStackFrame -> addr >> PAGESHIFT);
for (userTablePTE = (DOWN_TO_PAGE(exceptionStackFrame -> addr)); userTablePTE < (DOWN_TO_PAGE(current -> stack_brk)); userTablePTE += PAGESIZE)
{
unsigned int i = ((userTablePTE) >> PAGESHIFT) % PAGE_TABLE_LEN;
UserPageTable[i].valid = 1;
UserPageTable[i].uprot = PROT_NONE;
UserPageTable[i].kprot = PROT_READ | PROT_WRITE;
/* Need to change the pfn here */
UserPageTable[i].pfn = allocatePhysicalPage();
TracePrintf(250, "Allocate physical pages for user process: PID(%d), VPN(%d), PFN(%d).\n", current -> PID, i, UserPageTable[i].pfn);
}
}
extern void trapMath(ExceptionStackFrame *exceptionStackFrame)
{
TracePrintf(512, "trapMath: vector(%d), code(%d), addr(%d), psr(%d), pc(%d), sp(%d), regs(%s)\n",
exceptionStackFrame->vector, exceptionStackFrame->code, exceptionStackFrame->addr,
exceptionStackFrame->psr, exceptionStackFrame->pc, exceptionStackFrame->sp,
exceptionStackFrame->regs);
char string[128];
char *msg = string;
switch (exceptionStackFrame->code) {
case FPE_INTOVF:
msg = "Integer overflow";
break;
case FPE_INTDIV:
msg = "Integer divide by zero";
break;
case FPE_FLTRES:
msg = "Floating inexact result";
break;
case FPE_FLTDIV:
msg = "Floating divide by zero";
break;
case FPE_FLTUND:
msg = "Floating underflow";
break;
case FPE_FLTINV:
msg = "Invalid floating operation";
break;
case FPE_FLTSUB:
msg = "FP subscript out of range";
break;
case FPE_FLTOVF:
msg = "Floating overflow";
break;
case SI_KERNEL:
msg = "Linux kernel SIGFPE";
break;
case SI_USER:
msg = "Received SIGFPE from user";
break;
default:
printf(msg, "Unknown code %d", exceptionStackFrame->code);
}
//Kernel_Exit(ERROR);
}
extern void trapTTYReceive(ExceptionStackFrame *exceptionStackFrame)
{
TracePrintf(512, "trapTTYReceive: vector(%d), code(%d), addr(%d), psr(%d), pc(%d), sp(%d), regs(%s)\n", exceptionStackFrame->vector, exceptionStackFrame->code, exceptionStackFrame->addr, exceptionStackFrame->psr, exceptionStackFrame->pc, exceptionStackFrame->sp,exceptionStackFrame->regs);
}
extern void trapTTYTransmit(ExceptionStackFrame *exceptionStackFrame)
{
TracePrintf(512, "trapTTYTransmit: vector(%d), code(%d), addr(%d), psr(%d), pc(%d), sp(%d), regs(%s)\n", exceptionStackFrame->vector, exceptionStackFrame->code, exceptionStackFrame->addr, exceptionStackFrame->psr, exceptionStackFrame->pc, exceptionStackFrame->sp,exceptionStackFrame->regs);
}