kern
diff src/segm.c @ 55:88a6c4e192f9
Fixed most important task switching bugs.
Now it seems that I can switch in and out of user space reliably.
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 15 Aug 2011 04:03:39 +0300 |
parents | 4eaecb14fe31 |
children |
line diff
1.1 --- a/src/segm.c Sun Aug 14 16:57:23 2011 +0300 1.2 +++ b/src/segm.c Mon Aug 15 04:03:39 2011 +0300 1.3 @@ -1,6 +1,7 @@ 1.4 #include <string.h> 1.5 #include "segm.h" 1.6 #include "desc.h" 1.7 +#include "tss.h" 1.8 1.9 /* bits for the 3rd 16bt part of the descriptor */ 1.10 #define BIT_ACCESSED (1 << 8) 1.11 @@ -21,10 +22,11 @@ 1.12 1.13 enum {TYPE_DATA, TYPE_CODE}; 1.14 1.15 -#define TSS_TYPE_BITS (BIT_ACCESSED | BIT_CODE) 1.16 +/* we need the following bit pattern at the 8th bit excluding the busy bit: 1001 */ 1.17 +#define TSS_TYPE_BITS (9 << 8) 1.18 1.19 static void segm_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl, int type); 1.20 -static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl, unsigned int busy); 1.21 +static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl); 1.22 1.23 /* these functions are implemented in segm-asm.S */ 1.24 void setup_selectors(uint16_t code, uint16_t data); 1.25 @@ -57,7 +59,7 @@ 1.26 1.27 void set_tss(uint32_t addr) 1.28 { 1.29 - task_desc(gdt + SEGM_TASK, 0, sizeof(struct tss) - 1, 3, TSS_BUSY); 1.30 + task_desc(gdt + SEGM_TASK, addr, sizeof(struct task_state) - 1, 3); 1.31 set_task_reg(selector(SEGM_TASK, 0)); 1.32 } 1.33 1.34 @@ -79,12 +81,44 @@ 1.35 desc->d[3] = ((limit >> 16) & 0xf) | ((base >> 16) & 0xff00) | BIT_GRAN | BIT_BIG; 1.36 } 1.37 1.38 -static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl, unsigned int busy) 1.39 +static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl) 1.40 { 1.41 desc->d[0] = limit & 0xffff; 1.42 desc->d[1] = base & 0xffff; 1.43 1.44 desc->d[2] = ((base >> 16) & 0xff) | ((dpl & 3) << 13) | BIT_PRESENT | 1.45 - TSS_TYPE_BITS | busy; 1.46 + TSS_TYPE_BITS; /* XXX busy ? */ 1.47 desc->d[3] = ((limit >> 16) & 0xf) | ((base >> 16) & 0xff00) | BIT_GRAN; 1.48 } 1.49 +/* 1.50 +static void dbg_print_gdt(void) 1.51 +{ 1.52 + int i; 1.53 + 1.54 + printf("Global Descriptor Table\n"); 1.55 + printf("-----------------------\n"); 1.56 + 1.57 + for(i=0; i<6; i++) { 1.58 + print_desc(gdt + i); 1.59 + } 1.60 +} 1.61 + 1.62 +static void print_desc(desc_t *desc) 1.63 +{ 1.64 + uint32_t base, limit; 1.65 + int dpl, g, db, l, avl, p, s, type; 1.66 + char *type_str; 1.67 + 1.68 + base = (uint32_t)desc->d[1] | ((uint32_t)(desc->d[2] & 0xff) << 16) | ((uint32_t)(desc->d[3] >> 8) << 24); 1.69 + limit = (uint32_t)desc->d[0] | ((uint32_t)(desc->d[3] & 0xf) << 16); 1.70 + dpl = (desc->d[2] >> 13) & 3; 1.71 + type = (desc->d[2] >> 8) & 0xf; 1.72 + g = (desc->d[3] >> 23) & 1; 1.73 + db = (desc->d[3] >> 22) & 1; 1.74 + l = (desc->d[3] >> 21) & 1; 1.75 + avl = (desc->d[3] >> 20) & 1; 1.76 + 1.77 + p = (desc->d[2] >> 15) & 1; 1.78 + s = (desc->d[2] >> 12) & 1; 1.79 +} 1.80 +*/