Vystem 0.2
This commit is contained in:
126
shelter/lib/include/irq/gdt.h
Normal file
126
shelter/lib/include/irq/gdt.h
Normal file
@@ -0,0 +1,126 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
#ifndef SH_LIB_GDT_H
|
||||
#define SH_LIB_GDT_H
|
||||
#include "std/status.h"
|
||||
#include "std/type.h"
|
||||
#include "irq/tss.h"
|
||||
// Long mode GDT part
|
||||
// GDT entry 64 bits structure
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
sh_uint16 limit_low;
|
||||
sh_uint16 base_low;
|
||||
sh_uint8 base_mid;
|
||||
sh_uint8 access;
|
||||
sh_uint8 flags_limit_high;
|
||||
sh_uint8 base_high;
|
||||
} sh_gdt_GDT_ENTRY_64;
|
||||
#pragma pack()
|
||||
// GDT entry 128 bits (special TSS) structure
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
sh_uint16 limit_low;
|
||||
sh_uint16 base_low;
|
||||
sh_uint8 base_mid;
|
||||
sh_uint8 access;
|
||||
sh_uint8 flags_limit_high;
|
||||
sh_uint8 base_high;
|
||||
sh_uint32 base_upper;
|
||||
sh_uint32 reserved;
|
||||
} sh_gdt_GDT_ENTRY_128;
|
||||
#pragma pack()
|
||||
// GDTR structure
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
sh_uint16 limit;
|
||||
sh_uint64 base;
|
||||
} sh_gdt_GDTR;
|
||||
#pragma pack()
|
||||
// GDT structure for bootstrap core
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
sh_gdt_GDT_ENTRY_64 null;
|
||||
sh_gdt_GDT_ENTRY_64 kernel_code;
|
||||
sh_gdt_GDT_ENTRY_64 kernel_data;
|
||||
sh_gdt_GDT_ENTRY_64 user_code;
|
||||
sh_gdt_GDT_ENTRY_64 user_data;
|
||||
sh_gdt_GDT_ENTRY_128 tss;
|
||||
} sh_gdt_GDT;
|
||||
#pragma pack()
|
||||
// GDT structure for all APs
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
sh_gdt_GDT_ENTRY_64 null;
|
||||
sh_gdt_GDT_ENTRY_64 kernel_code;
|
||||
sh_gdt_GDT_ENTRY_64 kernel_data;
|
||||
sh_gdt_GDT_ENTRY_64 user_code;
|
||||
sh_gdt_GDT_ENTRY_64 user_data;
|
||||
sh_gdt_GDT_ENTRY_128 tss[256];
|
||||
} sh_gdt_GDT_AP;
|
||||
#pragma pack()
|
||||
// Generate access byte
|
||||
inline sh_uint8 sh_gdt_fill_access_byte(sh_bool present,sh_uint8 dpl,sh_bool descriptor_type,sh_uint8 segment_type) {
|
||||
return ((present?1:0)<<7)|((dpl&0x3)<<5)|((descriptor_type?1:0)<<4)|(segment_type&0xF);
|
||||
}
|
||||
// Generate flags byte (put all 4 bits in bit 0-3 of the returned byte)
|
||||
inline sh_uint8 sh_gdt_fill_flags_byte(sh_bool g,sh_bool db,sh_bool l,sh_bool avl) {
|
||||
return ((g?1:0)<<3)|((db?1:0)<<2)|((l?1:0)<<1)|((avl?1:0)<<0);
|
||||
}
|
||||
// Fill GDT entry 64 bits, expect flags as sh_gdt_fill_flags_byte would return it
|
||||
sh_gdt_GDT_ENTRY_64 sh_gdt_fill_gdt_entry_64(sh_uint32 limit,sh_uint32 base,sh_uint8 access,sh_uint8 flags);
|
||||
// Fill GDT entry 128 bits, expect flags as sh_gdt_fill_flags_byte would return it
|
||||
sh_gdt_GDT_ENTRY_128 sh_gdt_fill_gdt_entry_128(sh_uint32 limit,sh_uint64 base,sh_uint8 access,sh_uint8 flags);
|
||||
// Fill GDT with provided TSS
|
||||
SH_STATUS sh_gdt_fill_gdt(sh_tss_TSS *tss,sh_gdt_GDT *gdt);
|
||||
// Fill APs common GDT with provided TSS array
|
||||
SH_STATUS sh_gdt_fill_gdt_ap(sh_tss_TSS *tss,sh_uint64 tss_count,sh_gdt_GDT_AP *gdt);
|
||||
// Generate GDTR for AP GDT
|
||||
sh_gdt_GDTR sh_gdt_make_gdtr_ap(sh_gdt_GDT_AP *gdt);
|
||||
// Fill and load GDTR
|
||||
SH_STATUS sh_gdt_load_gdtr(sh_gdt_GDT *gdt);
|
||||
// Reload registers
|
||||
SH_STATUS sh_gdt_reload_registers();
|
||||
// 16/32 bits mode GDT part
|
||||
// GDT entry 32 bits structure
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
sh_uint16 limit_low;
|
||||
sh_uint16 base_low;
|
||||
sh_uint8 base_middle;
|
||||
sh_uint8 access;
|
||||
sh_uint8 granularity;
|
||||
sh_uint8 base_high;
|
||||
} sh_gdt_GDT_ENTRY_32;
|
||||
#pragma pack()
|
||||
// GDT 32 bits structure
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
sh_gdt_GDT_ENTRY_32 null;
|
||||
sh_gdt_GDT_ENTRY_32 code_64;
|
||||
sh_gdt_GDT_ENTRY_32 code;
|
||||
sh_gdt_GDT_ENTRY_32 data;
|
||||
} sh_gdt_GDT_32;
|
||||
#pragma pack()
|
||||
// Generate access byte
|
||||
inline sh_uint8 sh_gdt_fill_access_byte_32(sh_bool present,sh_uint8 dpl,sh_bool descriptor_type,sh_uint8 segment_type) {
|
||||
sh_uint8 access=0;
|
||||
access|=(present?1:0)<<7;
|
||||
access|=(dpl&0x3)<<5;
|
||||
access|=(descriptor_type?1:0)<<4;
|
||||
access|=(segment_type&0xF);
|
||||
return access;
|
||||
}
|
||||
// Generate granularity byte
|
||||
inline sh_uint8 sh_gdt_fill_granularity_byte_32(sh_bool granularity,sh_bool db,sh_bool l,sh_bool avl) {
|
||||
sh_uint8 g=0;
|
||||
g|=(granularity?1:0)<<7;
|
||||
g|=(db?1:0)<<6;
|
||||
g|=(l?1:0)<<5;
|
||||
g|=(avl?1:0)<<4;
|
||||
return g;
|
||||
}
|
||||
// Fill GDT entry 32 bits, expect granularity as sh_gdt_fill_granularity_byte_32 would return it
|
||||
sh_gdt_GDT_ENTRY_32 sh_gdt_fill_gdt_entry_32(sh_uint32 limit,sh_uint32 base,sh_uint8 access,sh_uint8 granularity);
|
||||
// Fill GDT 32 bits
|
||||
SH_STATUS sh_gdt_fill_gdt_32(sh_gdt_GDT_32 *gdt_32);
|
||||
#endif
|
||||
Reference in New Issue
Block a user