#include "kernel.h" #include "log.h" #include "gdt.h" #include "asm_gdt.h" #include "kmalloc.h" #include #define GDT_SIZE 6 static uint8_t gdt_structs[GDT_SIZE*8*SMP_MAX_PROC]; // GLOBAL DESCRIPTOR TABLES typedef volatile struct strtss{ unsigned short link; unsigned short link_h; unsigned long esp0; unsigned short ss0; unsigned short ss0_h; unsigned long esp1; unsigned short ss1; unsigned short ss1_h; unsigned long esp2; unsigned short ss2; unsigned short ss2_h; unsigned long cr3; unsigned long eip; unsigned long eflags; unsigned long eax; unsigned long ecx; unsigned long edx; unsigned long ebx; unsigned long esp; unsigned long ebp; unsigned long esi; unsigned long edi; unsigned short es; unsigned short es_h; unsigned short cs; unsigned short cs_h; unsigned short ss; unsigned short ss_h; unsigned short ds; unsigned short ds_h; unsigned short fs; unsigned short fs_h; unsigned short gs; unsigned short gs_h; unsigned short ldt; unsigned short ldt_h; unsigned short trap; unsigned short iomap; }__attribute__((packed)) tss_struct; tss_struct sys_tss[SMP_MAX_PROC]; typedef struct GDT_struct { uint32_t base; uint32_t limit; uint32_t type; }GDT; void install_tss(uint32_t cpu,uint32_t esp0){ // now fill each value // set values necessary sys_tss[cpu].ss0 = 0x10; //kernel data sys_tss[cpu].esp0 = esp0; // now set the IO bitmap (not necessary, so set above limit) // sys_tss.iomap = ( unsigned short ) sizeof( tss_struct ); } /* //alternative struct gdt_entry_bits { unsigned int limit_low:16; unsigned int base_low : 24; //attribute byte split into bitfields unsigned int accessed :1; unsigned int read_write :1; //readable for code, writable for data unsigned int conforming_expand_down :1; //conforming for code, expand down for data unsigned int code :1; //1 for code, 0 for data unsigned int always_1 :1; //should be 1 for everything but TSS and LDT unsigned int DPL :2; //priveledge level unsigned int present :1; //and now into granularity unsigned int limit_high :4; unsigned int available :1; unsigned int always_0 :1; //should always be 0 unsigned int big :1; //32bit opcodes for code, uint32_t stack for data unsigned int gran :1; //1 to use 4k page addressing, 0 for byte addressing unsigned int base_high :8; } __packed; //or __attribute__((packed)) */ void setup_gdt(uint8_t *gdt_struct) { asm_setup_gdt(&gdt_struct[0],8*GDT_SIZE); } /** * \param target A pointer to the 8-byte GDT entry * \param source An arbitrary structure describing the GDT entry */ void encodeGdtEntry(uint8_t *target, GDT source) { // Check the limit to make sure that it can be encoded if ((source.limit > 65536) && (source.limit & 0xFFF) != 0xFFF) { kpanic("trying to set an invalid GDT source.limit!"); } if (source.limit > 65536) { // Adjust granularity if required source.limit = source.limit >> 12; target[6] = 0xC0; } else { target[6] = 0x40; } // Encode the limit target[0] = source.limit & 0xFF; target[1] = (source.limit >> 8) & 0xFF; // Encode the base target[2] = source.base & 0xFF; target[3] = (source.base >> 8) & 0xFF; target[4] = (source.base >> 16) & 0xFF; target[7] = (source.base >> 24) & 0xFF; target[5] = source.type; target[6] |= (source.limit >> 16) & 0xF; // And... Type /* 0 1 dw 0xffff ;limit 2 3 dw 0x0 ;base 4 db 0x0 ;base 5 db 10011010b ;flags 6 db 11001111b ;flags & seg.limit 7 db 0x0 ;base */ } void gdt_init() { static int last_cpu=0; if(last_cpu>=SMP_MAX_PROC)kpanic("not enough SMP_MAX_PROC"); /* Pr=1 Privl 1 Exec DC RW Ac 0x9A == 1001 1010 == 1 00 1 1 0 1 0 0x92 == 1001 0010 == 1 00 1 0 0 1 0 0xFA == 1111 1010 == 1 11 1 1 0 1 0 0xF2 == 1111 0010 == 1 11 1 0 0 1 0 */ //static uint8_t gdt_struct[GDT_SIZE*8]; // GLOBAL DESCRIPTOR TABLE //uint8_t *gdt_struct=kballoc(1); //[GDT_SIZE*8]; // GLOBAL DESCRIPTOR TABLE uint8_t *gdt_struct=&gdt_structs[GDT_SIZE*8*last_cpu]; GDT myGDT[GDT_SIZE]; //selector 0x0 myGDT[0].base=0; myGDT[0].limit=0; myGDT[0].type=0; //selector 0x8 code myGDT[1].base=0; myGDT[1].limit=0xffffffff; myGDT[1].type=0x9a; //selector 0x10 data myGDT[2].base=0; myGDT[2].limit=0xffffffff; myGDT[2].type=0x92; //selector 0x18 code user myGDT[3].base=0; myGDT[3].limit=0xffffffff; myGDT[3].type=0xFa; //selector 0x20 data user myGDT[4].base=0; myGDT[4].limit=0xffffffff; myGDT[4].type=0xF2; //TSS 0x28 myGDT[5].base=&sys_tss[last_cpu]; //tss start myGDT[5].limit=sizeof(tss_struct); //tss end myGDT[5].type=0x89; // transcript to format the processor wants for(int i=0;i