]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/ia32/32/trap_state.cpp
Update
[l4.git] / kernel / fiasco / src / kern / ia32 / 32 / trap_state.cpp
1
2 INTERFACE:
3
4 #include "l4_types.h"
5
6 class Trap_state
7 {
8   friend class Jdb_tcb;
9   friend class Jdb_stack_view;
10
11 public:
12   typedef FIASCO_FASTCALL int (*Handler)(Trap_state*, unsigned cpu);
13   static Handler base_handler asm ("BASE_TRAP_HANDLER");
14
15   // Saved segment registers
16   Mword  _es;
17   Mword  _ds;
18   Mword  _gs;                                     // => utcb->values[ 0]
19   Mword  _fs;                                     // => utcb->values[ 1]
20
21   // PUSHA register state frame
22   Mword  _di;                                     // => utcb->values[ 2]
23   Mword  _si;                                     // => utcb->values[ 3]
24   Mword  _bp;                                     // => utcb->values[ 4]
25   Mword  _cr2; // we save cr2 over esp for PFs    // => utcb->values[ 5]
26   Mword  _bx;                                     // => utcb->values[ 6]
27   Mword  _dx;                                     // => utcb->values[ 7]
28   Mword  _cx;                                     // => utcb->values[ 8]
29   Mword  _ax;                                     // => utcb->values[ 9]
30
31   // Processor trap number, 0-31
32   Mword  _trapno;                                 // => utcb->values[10]
33
34   // Error code pushed by the processor, 0 if none
35   Mword  _err;                                    // => utcb->values[11]
36
37   // Processor state frame
38   Mword  _ip;                                     // => utcb->values[12]
39   Mword  _cs;                                     // => utcb->values[13]
40   Mword  _flags;                                  // => utcb->values[14]
41   Mword  _sp;                                     // => utcb->values[15]
42   Mword  _ss;
43 };
44
45 struct Trex
46 {
47   Trap_state s;
48
49   void set_ipc_upcall()
50   {
51     s._err = 0;
52     s._trapno = 0xfe;
53   }
54
55   void dump() { s.dump(); }
56 };
57
58 //---------------------------------------------------------------------------
59 IMPLEMENTATION [ia32]:
60
61 #include "regdefs.h"
62 #include "gdt.h"
63
64 PUBLIC inline NEEDS["regdefs.h", "gdt.h"]
65 void
66 Trap_state::sanitize_user_state()
67 {
68   _cs = Gdt::gdt_code_user | Gdt::Selector_user;
69   _ss = Gdt::gdt_data_user | Gdt::Selector_user;
70   _flags = (_flags & ~(EFLAGS_IOPL | EFLAGS_NT)) | EFLAGS_IF;
71 }
72
73 //---------------------------------------------------------------------------
74 IMPLEMENTATION [ux]:
75
76 #include "emulation.h"
77 #include "regdefs.h"
78
79 PUBLIC inline NEEDS["emulation.h", "regdefs.h"]
80 void
81 Trap_state::sanitize_user_state()
82 {
83   _cs = Emulation::kernel_cs() & ~1;
84   _ss = Emulation::kernel_ss();
85   _flags = (_flags & ~(EFLAGS_IOPL | EFLAGS_NT)) | EFLAGS_IF;
86 }
87
88 //---------------------------------------------------------------------------
89 IMPLEMENTATION [ia32 || ux]:
90
91 #include <cstdio>
92 #include <panic.h>
93 #include "cpu.h"
94 #include "atomic.h"
95 #include "mem.h"
96
97 Trap_state::Handler Trap_state::base_handler FIASCO_FASTCALL;
98
99 PUBLIC inline NEEDS[Trap_state::sanitize_user_state, "mem.h"]
100 void
101 Trap_state::copy_and_sanitize(Trap_state const *src)
102 {
103   Mem::memcpy_mwords(this, src, sizeof(*this) / sizeof(Mword));
104   sanitize_user_state();
105 }
106
107 PUBLIC inline
108 void
109 Trap_state::set_pagefault(Mword pfa, Mword error)
110 {
111   _cr2 = pfa;
112   _trapno = 0xe;
113   _err = error;
114 }
115
116 PUBLIC inline
117 Mword
118 Trap_state::trapno() const
119 { return _trapno; }
120
121 PUBLIC inline
122 Mword
123 Trap_state::error() const
124 { return _err; }
125
126 PUBLIC inline
127 Mword
128 Trap_state::ip() const
129 { return _ip; }
130
131 PUBLIC inline
132 Mword
133 Trap_state::cs() const
134 { return _cs; }
135
136 PUBLIC inline
137 Mword
138 Trap_state::flags() const
139 { return _flags; }
140
141 PUBLIC inline
142 Mword
143 Trap_state::sp() const
144 { return _sp; }
145
146 PUBLIC inline
147 Mword
148 Trap_state::ss() const
149 { return _ss; }
150
151 PUBLIC inline
152 Mword
153 Trap_state::value() const
154 { return _ax; }
155
156 PUBLIC inline
157 Mword
158 Trap_state::value2() const
159 { return _cx; }
160
161 PUBLIC inline
162 Mword
163 Trap_state::dx() const
164 { return _dx; }
165
166 PUBLIC inline
167 Mword
168 Trap_state::value3() const
169 { return _dx; }
170
171 PUBLIC inline
172 Mword
173 Trap_state::value4() const
174 { return _bx; }
175
176 PUBLIC inline
177 void
178 Trap_state::ip(Mword ip)
179 { _ip = ip; }
180
181 PUBLIC inline
182 void
183 Trap_state::cs(Mword cs)
184 { _cs = cs; }
185
186 PUBLIC inline
187 void
188 Trap_state::flags(Mword flags)
189 { _flags = flags; }
190
191 PUBLIC inline
192 void
193 Trap_state::sp(Mword sp)
194 { _sp = sp; }
195
196 PUBLIC inline
197 void
198 Trap_state::ss(Mword ss)
199 { _ss = ss; }
200
201 PUBLIC inline
202 void
203 Trap_state::value(Mword value)
204 { _ax = value; }
205
206 PUBLIC inline
207 void
208 Trap_state::value3(Mword value)
209 { _dx = value; }
210
211 PUBLIC inline NEEDS["atomic.h"] 
212 void
213 Trap_state::consume_instruction(unsigned count)
214 { cas ((Address*)(&_ip), _ip, _ip + count); }
215
216 PUBLIC inline
217 bool
218 Trap_state::is_debug_exception() const
219 { return _trapno == 1 || _trapno == 3; }
220
221 PUBLIC
222 void
223 Trap_state::dump()
224 {
225   int from_user = _cs & 3;
226
227   printf("EAX %08lx EBX %08lx ECX %08lx EDX %08lx\n"
228          "ESI %08lx EDI %08lx EBP %08lx ESP %08lx\n"
229          "EIP %08lx EFLAGS %08lx\n"
230          "CS %04lx SS %04lx DS %04lx ES %04lx FS %04lx GS %04lx\n"
231          "trap %lu (%s), error %08lx, from %s mode\n",
232          _ax, _bx, _cx, _dx,
233          _si, _di, _bp, from_user ? _sp : (Unsigned32)&_sp,
234          _ip, _flags,
235          _cs & 0xffff, from_user ? _ss & 0xffff : Cpu::get_ss() & 0xffff,
236          _ds & 0xffff, _es & 0xffff, _fs & 0xffff, _gs & 0xffff,
237          _trapno, Cpu::exception_string(_trapno), _err, from_user ? "user" : "kernel");
238
239   if (_trapno == 13)
240     {
241       if (_err & 1)
242         printf("(external event");
243       else
244         printf("(internal event");
245       if (_err & 2)
246         printf(" regarding IDT gate descriptor no. 0x%02lx)\n", _err >> 3);
247       else
248         printf(" regarding %s entry no. 0x%02lx)\n",
249               _err & 4 ? "LDT" : "GDT", _err >> 3);
250     }
251   else if (_trapno == 14)
252     printf("page fault linear address %08lx\n", _cr2);
253 }
254
255 extern "C" FIASCO_FASTCALL
256 void
257 trap_dump_panic(Trap_state *ts)
258 {
259   ts->dump();
260   panic("terminated due to trap");
261 }
262
263 PUBLIC inline
264 bool
265 Trap_state::exclude_logging()
266 { return _trapno == 1 || _trapno == 3; }