#include "clib.h" #include "i386.h" #include "phmem.h" #include "systab.h" #define IS_NULL_DESCRIPTOR(d) ((d).access.system.type == 0) #define MARK_USED_DESCRIPTOR(d) ((d).access.system.type = 1) #define MARK_FREE_DESCRIPTOR(d) ((d).access.system.type = 0) static inline void lidt (lidt_t *p) { asm volatile ("lidt %0" : : "m" (*p)); } /* static inline void sidt (lidt_t *p) { asm volatile ("sidt %0" : "=m" (*p) : : "memory"); } */ static inline void lgdt (lgdt_t *p) { asm volatile ("lgdt %0" : : "m" (*p)); } static inline void sgdt (lgdt_t *p) { asm volatile ("sgdt %0" : "=m"(*p) : : "memory"); } /* * gdt : * *1 000: NULL *2 008: VCPI reserved *3 010: VCPI reserved *4 018: VCPI reserved *5 020: 16 bit code (L64K, R+, C-) *6 028: 16 bit data (64K, W+) *7 030: 16 bit stub (255, W+) *8 038: 32 bit kernel data (4G, W+, B+) *9 040: 32 bit kernel code (4G, R+, C-) *A 048: temp TSS *B 050: *C 058: *D 060: *E 068: *F 070: */ descriptor_t *_gdt; gate_t *_idt; systable_t gdt_table; systable_t idt_table; static descriptor_t gdt[MAX_GDT_DESC]; static gate_t idt[MAX_GDT_DESC]; /* * [23/09/97] la gdt e la idt vengono ora allocate in modo statico */ void systab_setup() { lgdt_t gdti; lidt_t idti; DEBUG_TRACE; _gdt = &gdt[0]; memset(_gdt, 0, MAX_GDT_DESC*sizeof(descriptor_t)); // imposta la nuova gdt sgdt(&gdti); memcpy(_gdt, (void*) gdti.address, gdti.limit + 1); gdti.limit = (sizeof(*_gdt) * MAX_GDT_DESC) - 1; gdti.address = _gdt; lgdt(&gdti); // imposta nuova idt _idt = &idt[0]; idti.limit = (sizeof(*_idt) * MAX_IDT_DESC) - 1; idti.address = _idt; lidt(&idti); gdt_table.table = _gdt; gdt_table.alloc_start = GDT_ALLOC_START; gdt_table.alloc_end = MAX_GDT_DESC - 1; idt_table.table = (descriptor_t*)_idt; idt_table.alloc_start = 0; idt_table.alloc_end = MAX_IDT_DESC - 1; DEBUG_VERBOSE("gdt %xh idt %xh\n", gdti.address, idti.address); } int alloc_descriptors(systable_t *t, int num) { int nn = num; int i; for (i = t->alloc_start; i <= t->alloc_end; i++) { if (IS_NULL_DESCRIPTOR(t->table[i])) { if (--nn == 0) { int j; for (j = 0; j < num; j++) { MARK_USED_DESCRIPTOR(t->table[i-j]); } return i - j; } } else nn = num; } return ENOMEM; } int alloc_descriptor(systable_t *t) { int i; for (i = t->alloc_start; i <= t->alloc_end; i++) { if (IS_NULL_DESCRIPTOR(t->table[i])) { MARK_USED_DESCRIPTOR(t->table[i]); return i; }; } return ENOMEM; } int free_descriptors(systable_t *t, int num, int count) { int i; if (num+count > t->alloc_end) return EINVAL; for (i = 0; i < count; i++) { MARK_FREE_DESCRIPTOR(t->table[num+i]); } return 0; } int set_descriptor(systable_t *t, int numd, descriptor_t* d) { if (numd < t->alloc_end && d) t->table[numd] = *d; else return EINVAL; return 0; } int get_descriptor(systable_t *t, int numd, descriptor_t* d) { if (numd < t->alloc_end && d) *d = t->table[numd]; else return EINVAL; return 0; }