Diff markup
001 !! 001
002 !! 002
003 003
004 004
005 005
006 006
007 007
008 008
009 009
010 010
011 011
012 012
013 013
014 014
015 015
016 016
017 017
018 018
019 019
020 020
021 #include <sos/assert.h> 021 #include <sos/assert.h>
022 #include <sos/klibc.h> 022 #include <sos/klibc.h>
023 #include <drivers/bochs.h> 023 #include <drivers/bochs.h>
024 #include <drivers/x86_videomem.h> 024 #include <drivers/x86_videomem.h>
025 #include <hwcore/segment.h> 025 #include <hwcore/segment.h>
026 026
027 #include "cpu_context.h" 027 #include "cpu_context.h"
028 028
029 029
030 030
031 031
032 032
033 033
034 034
035 035
036 036
037 037
038 038
039 039
040 040
041 041
042 042
043 struct sos_cpu_kstate { !! 043 struct sos_cpu_state {
044 044
045 045
046 046
047 sos_ui16_t gs; 047 sos_ui16_t gs;
048 sos_ui16_t fs; 048 sos_ui16_t fs;
049 sos_ui16_t es; 049 sos_ui16_t es;
050 sos_ui16_t ds; 050 sos_ui16_t ds;
051 sos_ui16_t ss; !! 051 sos_ui16_t cpl0_ss;
>> 052
>> 053
052 sos_ui16_t alignment_padding; 054 sos_ui16_t alignment_padding;
053 sos_ui32_t eax; 055 sos_ui32_t eax;
054 sos_ui32_t ebx; 056 sos_ui32_t ebx;
055 sos_ui32_t ecx; 057 sos_ui32_t ecx;
056 sos_ui32_t edx; 058 sos_ui32_t edx;
057 sos_ui32_t esi; 059 sos_ui32_t esi;
058 sos_ui32_t edi; 060 sos_ui32_t edi;
059 sos_ui32_t ebp; 061 sos_ui32_t ebp;
060 062
061 063
062 sos_ui32_t error_code; 064 sos_ui32_t error_code;
063 sos_vaddr_t eip; 065 sos_vaddr_t eip;
064 sos_ui32_t cs; !! 066 sos_ui32_t cs;
>> 067
065 sos_ui32_t eflags; 068 sos_ui32_t eflags;
066 069
067 070
068 } __attribute__((packed)); 071 } __attribute__((packed));
069 072
070 073
>> 074
>> 075
>> 076
>> 077
>> 078
>> 079
>> 080
>> 081
>> 082
>> 083
>> 084
>> 085
>> 086
>> 087 #define GET_CPU_CS_REGISTER_VALUE(pushed_ui32_cs_value) \
>> 088 ( (pushed_ui32_cs_value) & 0xffff )
>> 089
>> 090
>> 091
>> 092
>> 093
>> 094 struct sos_cpu_kstate
>> 095 {
>> 096 struct sos_cpu_state regs;
>> 097 } __attribute__((packed));
>> 098
>> 099
>> 100
>> 101
>> 102
>> 103
>> 104
071 static void core_routine (sos_cpu_kstate_funct 105 static void core_routine (sos_cpu_kstate_function_arg1_t *start_func,
072 sos_ui32_t start_arg 106 sos_ui32_t start_arg,
073 sos_cpu_kstate_funct 107 sos_cpu_kstate_function_arg1_t *exit_func,
074 sos_ui32_t exit_arg) 108 sos_ui32_t exit_arg)
075 __attribute__((noreturn)); 109 __attribute__((noreturn));
076 110
077 static void core_routine (sos_cpu_kstate_funct 111 static void core_routine (sos_cpu_kstate_function_arg1_t *start_func,
078 sos_ui32_t start_arg 112 sos_ui32_t start_arg,
079 sos_cpu_kstate_funct 113 sos_cpu_kstate_function_arg1_t *exit_func,
080 sos_ui32_t exit_arg) 114 sos_ui32_t exit_arg)
081 { 115 {
082 start_func(start_arg); 116 start_func(start_arg);
083 exit_func(exit_arg); 117 exit_func(exit_arg);
084 118
085 SOS_ASSERT_FATAL(! "The exit function of the 119 SOS_ASSERT_FATAL(! "The exit function of the thread should NOT return !");
086 for(;;); 120 for(;;);
087 } 121 }
088 122
089 123
090 sos_ret_t sos_cpu_kstate_init(struct sos_cpu_k !! 124 sos_ret_t sos_cpu_kstate_init(struct sos_cpu_state **ctxt,
091 sos_cpu_kstate_f 125 sos_cpu_kstate_function_arg1_t *start_func,
092 sos_ui32_t star 126 sos_ui32_t start_arg,
093 sos_vaddr_t stac 127 sos_vaddr_t stack_bottom,
094 sos_size_t stac 128 sos_size_t stack_size,
095 sos_cpu_kstate_f 129 sos_cpu_kstate_function_arg1_t *exit_func,
096 sos_ui32_t exit 130 sos_ui32_t exit_arg)
097 { 131 {
>> 132
>> 133 struct sos_cpu_kstate *kctxt;
>> 134
098 135
099 136
100 137
101 138
102 139
103 140
104 141
105 142
106 143
107 144
108 145
109 146
110 147
111 148
112 149
113 150
114 151
115 152
116 153
117 154
118 155
119 156
120 sos_vaddr_t tmp_vaddr = stack_bottom + stack 157 sos_vaddr_t tmp_vaddr = stack_bottom + stack_size;
121 sos_ui32_t *stack = (sos_ui32_t*)tmp_vaddr; 158 sos_ui32_t *stack = (sos_ui32_t*)tmp_vaddr;
122 159
123 160
124 #ifdef SOS_CPU_KSTATE_DETECT_UNINIT_VARS !! 161 #ifdef SOS_CPU_STATE_DETECT_UNINIT_KERNEL_VARS
125 memset((void*)stack_bottom, SOS_CPU_KSTATE_S !! 162 memset((void*)stack_bottom, SOS_CPU_STATE_STACK_POISON, stack_size);
126 #elif defined(SOS_CPU_KSTATE_DETECT_STACK_OVER !! 163 #elif defined(SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW)
127 sos_cpu_kstate_prepare_detect_stack_overflow !! 164 sos_cpu_state_prepare_detect_kernel_stack_overflow(stack_bottom, stack_size);
128 #endif 165 #endif
129 166
130 167
131 168
132 *(--stack) = exit_arg; 169 *(--stack) = exit_arg;
133 *(--stack) = (sos_ui32_t)exit_func; 170 *(--stack) = (sos_ui32_t)exit_func;
134 *(--stack) = start_arg; 171 *(--stack) = start_arg;
135 *(--stack) = (sos_ui32_t)start_func; 172 *(--stack) = (sos_ui32_t)start_func;
136 *(--stack) = 0; 173 *(--stack) = 0;
137 174
138 175
139 176
140 177
141 178
142 179
143 180
144 181
145 182
146 tmp_vaddr = ((sos_vaddr_t)stack) - sizeof(s 183 tmp_vaddr = ((sos_vaddr_t)stack) - sizeof(struct sos_cpu_kstate);
147 *ctxt = (struct sos_cpu_kstate*)tmp_vaddr; !! 184 kctxt = (struct sos_cpu_kstate*)tmp_vaddr;
148 185
149 186
150 memset(*ctxt, 0x0, sizeof(struct sos_cpu_kst !! 187 memset(kctxt, 0x0, sizeof(struct sos_cpu_kstate));
151 188
152 189
153 190
154 (*ctxt)->eip = (sos_ui32_t)core_routine; !! 191 kctxt->regs.eip = (sos_ui32_t)core_routine;
155 192
156 193
157 (*ctxt)->cs = SOS_BUILD_SEGMENT_REG_VALUE(0 !! 194 kctxt->regs.cs
158 (*ctxt)->ds = SOS_BUILD_SEGMENT_REG_VALUE(0 !! 195 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KCODE);
159 (*ctxt)->es = SOS_BUILD_SEGMENT_REG_VALUE(0 !! 196 kctxt->regs.ds
160 (*ctxt)->ss = SOS_BUILD_SEGMENT_REG_VALUE(0 !! 197 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KDATA);
>> 198 kctxt->regs.es
>> 199 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KDATA);
>> 200 kctxt->regs.cpl0_ss
>> 201 = SOS_BUILD_SEGMENT_REG_VALUE(0, FALSE, SOS_SEG_KDATA);
161 202
162 203
163 204
164 (*ctxt)->eflags = (1 << 9); !! 205 kctxt->regs.eflags = (1 << 9);
>> 206
>> 207
>> 208 *ctxt = (struct sos_cpu_state*) kctxt;
165 209
166 return SOS_OK; 210 return SOS_OK;
167 } 211 }
168 212
169 213
170 #if defined(SOS_CPU_KSTATE_DETECT_STACK_OVERFL !! 214 #if defined(SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW)
171 void 215 void
172 sos_cpu_kstate_prepare_detect_stack_overflow(c !! 216 sos_cpu_state_prepare_detect_kernel_stack_overflow(const struct sos_cpu_state *ctxt,
173 s !! 217 sos_vaddr_t stack_bottom,
174 s !! 218 sos_size_t stack_size)
175 { 219 {
176 sos_size_t poison_size = SOS_CPU_KSTATE_DETE !! 220 sos_size_t poison_size = SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW;
177 if (poison_size > stack_size) 221 if (poison_size > stack_size)
178 poison_size = stack_size; 222 poison_size = stack_size;
179 223
180 memset((void*)stack_bottom, SOS_CPU_KSTATE_S !! 224 memset((void*)stack_bottom, SOS_CPU_STATE_STACK_POISON, poison_size);
181 } 225 }
182 226
183 227
184 void 228 void
185 sos_cpu_kstate_detect_stack_overflow(const str !! 229 sos_cpu_state_detect_kernel_stack_overflow(const struct sos_cpu_state *ctxt,
186 sos_vaddr !! 230 sos_vaddr_t stack_bottom,
187 sos_size_ !! 231 sos_size_t stack_size)
188 { 232 {
189 unsigned char *c; 233 unsigned char *c;
190 int i; 234 int i;
191 235
>> 236
>> 237
>> 238
>> 239
192 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) >= stac 240 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) >= stack_bottom);
193 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) + sizeo 241 SOS_ASSERT_FATAL(((sos_vaddr_t)ctxt) + sizeof(struct sos_cpu_kstate)
194 <= stack_bottom + stack_siz 242 <= stack_bottom + stack_size);
>> 243
>> 244
195 for (c = (unsigned char*) stack_bottom, i = 245 for (c = (unsigned char*) stack_bottom, i = 0 ;
196 (i < SOS_CPU_KSTATE_DETECT_STACK_OVERFL !! 246 (i < SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW) && (i < stack_size) ;
197 c++, i++) 247 c++, i++)
198 { 248 {
199 SOS_ASSERT_FATAL(SOS_CPU_KSTATE_STACK_PO !! 249 SOS_ASSERT_FATAL(SOS_CPU_STATE_STACK_POISON == *c);
200 } 250 }
201 } 251 }
202 #endif 252 #endif
203 253
204 254
205 sos_vaddr_t sos_cpu_kstate_get_PC(const struct !! 255
>> 256
>> 257
>> 258
>> 259
>> 260 sos_vaddr_t sos_cpu_context_get_PC(const struct sos_cpu_state *ctxt)
206 { 261 {
207 SOS_ASSERT_FATAL(NULL != ctxt); 262 SOS_ASSERT_FATAL(NULL != ctxt);
>> 263
>> 264
>> 265
208 return ctxt->eip; 266 return ctxt->eip;
209 } 267 }
210 268
211 269
212 sos_vaddr_t sos_cpu_kstate_get_SP(const struct !! 270 sos_vaddr_t sos_cpu_context_get_SP(const struct sos_cpu_state *ctxt)
213 { 271 {
214 SOS_ASSERT_FATAL(NULL != ctxt); 272 SOS_ASSERT_FATAL(NULL != ctxt);
>> 273
>> 274
>> 275
>> 276
215 return (sos_vaddr_t)ctxt; 277 return (sos_vaddr_t)ctxt;
216 } 278 }
217 279
218 280
219 void sos_cpu_kstate_dump(const struct sos_cpu_ !! 281 void sos_cpu_context_dump(const struct sos_cpu_state *ctxt)
220 { 282 {
221 char buf[128]; 283 char buf[128];
222 snprintf(buf, sizeof(buf), 284 snprintf(buf, sizeof(buf),
223 "CPU: eip=%x esp=%x eflags=%x cs=%x 285 "CPU: eip=%x esp=%x eflags=%x cs=%x ds=%x ss=%x err=%x",
224 (unsigned)ctxt->eip, (unsigned)ctxt 286 (unsigned)ctxt->eip, (unsigned)ctxt, (unsigned)ctxt->eflags,
225 (unsigned)ctxt->cs, (unsigned)ctxt- !! 287 (unsigned)GET_CPU_CS_REGISTER_VALUE(ctxt->cs), (unsigned)ctxt->ds,
>> 288 (unsigned)ctxt->cpl0_ss,
226 (unsigned)ctxt->error_code); 289 (unsigned)ctxt->error_code);
227 sos_bochs_putstring(buf); sos_bochs_putstrin 290 sos_bochs_putstring(buf); sos_bochs_putstring("\n");
228 sos_x86_videomem_putstring(23, 0, 291 sos_x86_videomem_putstring(23, 0,
229 SOS_X86_VIDEO_FG_BLA 292 SOS_X86_VIDEO_FG_BLACK | SOS_X86_VIDEO_BG_LTGRAY,
230 buf); 293 buf);
231 } 294 }
232 295
233 296
234 sos_ui32_t sos_cpu_kstate_get_EX_info(const st !! 297
>> 298
>> 299
>> 300
>> 301
>> 302 sos_ui32_t sos_cpu_context_get_EX_info(const struct sos_cpu_state *ctxt)
235 { 303 {
236 SOS_ASSERT_FATAL(NULL != ctxt); 304 SOS_ASSERT_FATAL(NULL != ctxt);
237 return ctxt->error_code; 305 return ctxt->error_code;
238 } 306 }
239 307
240 308
241 sos_vaddr_t 309 sos_vaddr_t
242 sos_cpu_kstate_get_EX_faulting_vaddr(const str !! 310 sos_cpu_context_get_EX_faulting_vaddr(const struct sos_cpu_state *ctxt)
243 { 311 {
244 sos_ui32_t cr2; 312 sos_ui32_t cr2;
245 313
246 !! 314
247 !! 315
>> 316
>> 317
>> 318
>> 319
>> 320
>> 321
>> 322
>> 323
>> 324
>> 325
>> 326
248 asm volatile ("movl %%cr2, %0" 327 asm volatile ("movl %%cr2, %0"
249 :"=r"(cr2) 328 :"=r"(cr2)
250 : ); 329 : );
251 330
252 return cr2; 331 return cr2;
253 } 332 }
254 333
255 334
256 sos_ui32_t sos_backtrace(const struct sos_cpu_ !! 335
>> 336
>> 337
>> 338
>> 339
>> 340 sos_ui32_t sos_backtrace(const struct sos_cpu_state *cpu_state,
257 sos_ui32_t max_depth, 341 sos_ui32_t max_depth,
258 sos_vaddr_t stack_bot 342 sos_vaddr_t stack_bottom,
259 sos_size_t stack_size 343 sos_size_t stack_size,
260 sos_backtrace_callbac 344 sos_backtrace_callback_t * backtracer,
261 void *custom_arg) 345 void *custom_arg)
262 { 346 {
263 int depth; 347 int depth;
264 sos_vaddr_t callee_PC, caller_frame; 348 sos_vaddr_t callee_PC, caller_frame;
265 349
266 350
267 351
268 352
269 353
270 354
271 355
272 356
273 357
274 358
275 359
276 360
277 361
278 362
279 363
280 364
281 365
282 366
283 367
284 368
285 369
286 370
287 371
288 372
289 373
290 374
291 375
292 376
293 377
294 378
295 if (cpu_kstate) !! 379 if (cpu_state)
296 { 380 {
297 callee_PC = cpu_kstate->eip; !! 381 callee_PC = cpu_state->eip;
298 caller_frame = cpu_kstate->ebp; !! 382 caller_frame = cpu_state->ebp;
299 } 383 }
300 else 384 else
301 { 385 {
302 386
303 callee_PC = (sos_vaddr_t)__builtin_re 387 callee_PC = (sos_vaddr_t)__builtin_return_address(0);
304 caller_frame = (sos_vaddr_t)__builtin_fr 388 caller_frame = (sos_vaddr_t)__builtin_frame_address(1);
305 } 389 }
306 390
307 for(depth=0 ; depth < max_depth ; depth ++) 391 for(depth=0 ; depth < max_depth ; depth ++)
308 { 392 {
309 393
310 backtracer(callee_PC, caller_frame + 8, 394 backtracer(callee_PC, caller_frame + 8, depth, custom_arg);
311 395
312 396
313 if ( (caller_frame < stack_bottom) 397 if ( (caller_frame < stack_bottom)
314 || (caller_frame + 4 >= stack_botto 398 || (caller_frame + 4 >= stack_bottom + stack_size) )
315 return depth; 399 return depth;
316 400
317 401
318 callee_PC = *((sos_vaddr_t*) (caller_ 402 callee_PC = *((sos_vaddr_t*) (caller_frame + 4));
319 caller_frame = *((sos_vaddr_t*) caller_f 403 caller_frame = *((sos_vaddr_t*) caller_frame);
320 } 404 }
321 405
322 return depth; 406 return depth;
323 } 407 }