| 1 | /* @title: GDT */ |
| 2 | #include <compiler.h> |
| 3 | #include <stdalign.h> |
| 4 | #include <stdint.h> |
| 5 | |
| 6 | struct gdt_entry { |
| 7 | uint16_t limit_low; |
| 8 | uint16_t base_low; |
| 9 | uint8_t base_middle; |
| 10 | uint8_t access; |
| 11 | uint8_t granularity; |
| 12 | uint8_t base_high; |
| 13 | } __packed; |
| 14 | |
| 15 | struct gdt_ptr { |
| 16 | uint16_t limit; |
| 17 | uint64_t base; |
| 18 | } __packed; |
| 19 | |
| 20 | struct gdt_entry_tss { |
| 21 | uint16_t limit_low; |
| 22 | uint16_t base_low; |
| 23 | uint8_t base_middle; |
| 24 | uint8_t access; |
| 25 | uint8_t granularity; |
| 26 | uint8_t base_high; |
| 27 | uint32_t base_upper; |
| 28 | uint32_t reserved; |
| 29 | } __packed; |
| 30 | |
| 31 | #define ACCESS_CODE_RING0 0x9A // exec/read, ring 0 |
| 32 | #define ACCESS_DATA_RING0 0x92 // read/write, ring 0 |
| 33 | #define ACCESS_CODE_RING3 0xFA // exec/read, ring 3 |
| 34 | #define ACCESS_DATA_RING3 0xF2 // read/write, ring 3 |
| 35 | |
| 36 | #define GRAN_CODE 0xAF // G=1, D/B=0, L=1, AVL=0 |
| 37 | #define GRAN_DATA 0xAF // G=1, D/B=0, L=0, AVL=0 |
| 38 | |
| 39 | void gdt_install(); |
| 40 | // Kernel selectors (RPL = 0) |
| 41 | #define GDT_KERNEL_CODE 0x08 // index 1 |
| 42 | #define GDT_KERNEL_DATA 0x10 // index 2 |
| 43 | |
| 44 | #define KERNEL_CS GDT_KERNEL_CODE |
| 45 | #define KERNEL_DS GDT_KERNEL_DATA |
| 46 | |
| 47 | // User selectors (RPL = 3) |
| 48 | #define GDT_USER_CODE 0x28 // index 5 << 3 |
| 49 | #define GDT_USER_DATA 0x30 // index 6 << 3 |
| 50 | |
| 51 | #define USER_CS (GDT_USER_CODE | 0x3) // == 0x2B |
| 52 | #define USER_DS (GDT_USER_DATA | 0x3) // == 0x33 |
| 53 | #define USER_SS USER_DS |
| 54 | |
| 55 | #pragma once |
| 56 | |