@declare_func("__kgetcs", "int", "()")@
@declare_func("__kgetds", "int", "()")@
@declare_func("__kgetss", "int", "()")@
@declare_func("__kreloadselectors", "int", "()")@
@declare_func("__klgdt", "void", "(i32)")@
ptr mm_head
ptr mm_pos
ptr last_alloc
function(int start) KMM::init -> void does
mm_head=start|ptr
mm_pos=mm_head
last_alloc=0xDEADBEEF|ptr
return
function(int amt) malloc -> ptr does
ptr ret=mm_pos
mm_pos=mm_pos:offset(amt)
last_alloc=ret
return ret
function(int to) malign -> void does
mm_pos=mm_pos:offset(to-((mm_pos|int)%to))
return
function(ptr idx) free -> void does
if last_alloc|int==idx|int do
mm_pos=last_alloc
last_alloc=0xDEADBEEF|ptr
done
return
function(ptr addr, int len, byte value) memset -> void does
int idx=0
while idx<len do
addr[idx]=value
idx+=1
done
return
function(ptr source, ptr dest, int len) memcpy -> void does
int idx=0
while idx<len do
dest[idx]=source[idx]
idx+=1
done
return
type __i32Box is packed
int i
endtype
function(ptr source, ptr dest, int len) memcpy32 -> void does
while len>=4 do
(dest:offset(len)|__i32Box).i=(source:offset(len)|__i32Box).i
len-=4
done
return
function(ptr p, int amt) ptr:offset -> ptr does
return ((p|int)+amt)|ptr
type GDTEntry is packed
short limit_low
short base_low
byte base_mid
byte access_flags
byte monstrosity
byte base_high
function(int base, int to, bool exec, bool user) GDTEntry::new -> GDTEntry does
GDTEntry new = malloc(@sizeof(GDTEntry)@)|GDTEntry
uint limit = (to|uint)-(base|uint)
bool page_granularity = 0|bool
if limit > 0xFFFFF|uint do
limit = limit >> 12
page_granularity = 1|bool
done
new.limit_low = (limit & 0xFFFF)|short
new.monstrosity = ((limit >> 16) & 0xF)|byte
new.base_low = (base & 0xFFFF)|short
new.base_mid = ((base >> 16) & 0xFF)|byte
new.base_high = ((base >> 24) & 0xFF)|byte
new.monstrosity += 0b01000000 |byte
new.access_flags = 0b10010010 |byte
if user do
new.access_flags += 0b01100000 |byte
done
if exec do
new.access_flags += 0b00001000 |byte
done
if page_granularity do
new.monstrosity += 0b10000000 |byte
done
return new
function(GDTEntry e) GDTEntry:print -> void does
kterm:print("GDTEntry<")
kterm:printi(e.limit_low|int)
kterm:print(",")
kterm:printi(e.base_low|int)
kterm:print(",")
kterm:printi(e.base_mid|int)
kterm:print(",")
kterm:printi(e.access_flags|int)
kterm:print(",")
kterm:printi(e.monstrosity|int)
kterm:print(",")
kterm:printi(e.base_high|int)
kterm:printl(">")
return
endtype
type GDT is packed
short size
int pointer
int current_idx
function(int entries) GDT::new -> GDT does
malign(256)
GDT new=malloc(@sizeof(GDT)@)|GDT
new.size=((entries+1)*@sizeof(GDTEntry)@)|short
malign(256)
new.pointer=malloc(new.size|int)|int
new.current_idx=1
memset(new.pointer|ptr, new.size|int, 0|byte)
new.size-=1|short
return new
function(GDT table, int idx, GDTEntry entry) GDT:insert -> void does
int entry_sz=@sizeof(GDTEntry)@
ptr target=(table.pointer|ptr):offset(entry_sz*idx)
memcpy(entry|ptr, target, entry_sz)
return
function(GDT table, GDTEntry entry) GDT:add -> void does
table:insert(table.current_idx, entry)
table.current_idx+=1
return
endtype
function() install_gdt -> void does
GDT gdt = GDT::new(2)
GDTEntry kernel_code = GDTEntry::new(0x0, 0xFFFFFFFF, 1|bool, 0|bool)
gdt:add(kernel_code)
GDTEntry kernel_data = GDTEntry::new(0x0, 0xFFFFFFFF, 0|bool, 0|bool)
gdt:add(kernel_data)
kterm:print("GDT@")
kterm:dumphexi((gdt|ptr)|int)
__klgdt((gdt|ptr)|int)
return