Asuro/src/vmemorymanager.pas
kieron 48461c2ae3 vfdl
git-svn-id: https://spexeah.com:8443/svn/Asuro@152 6dbc8c32-bb84-406f-8558-d1cf31a0ab0c
2017-05-20 19:45:01 +00:00

155 lines
3.5 KiB
ObjectPascal

unit vmemorymanager;
interface
uses
util,
pmemorymanager,
console;
type
PPageDirEntry = ^TPageDirEntry;
TPageDirEntry = bitpacked record
Present,
Writable,
UserMode,
WriteThrough,
NotCacheable,
Accessed,
Reserved,
PageSize,
GlobalPage: Boolean;
Available: UBit3;
Address: UBit20;
end;
TPageDirectory = Array[0..1023] of TPageDirEntry;
PPageDirectory = ^TPageDirectory;
var
PageDirectory : PPageDirectory;
procedure init;
function new_page(page_number : uint16) : boolean;
function map_page(page_number : uint16; block : uint16) : boolean;
function new_page_at_address(address : uint32) : boolean;
procedure free_page(page_number : uint16);
procedure free_page_at_address(address : uint32);
implementation
function load_current_page_directory : PPageDirectory;
var
Directory : uint32;
begin
asm
MOV EAX, CR3
MOV Directory, EAX
end;
Directory:= Directory + KERNEL_VIRTUAL_BASE;
load_current_page_directory:= PPageDirectory(Directory);
end;
procedure init;
var
i : uint32;
begin
console.writestringln('VMM: INIT BEGIN.');
PageDirectory:= load_current_page_directory;
map_page(KERNEL_PAGE_NUMBER + 1, 1);
map_page(KERNEL_PAGE_NUMBER + 2, 2);
console.writestringln('VMM: INIT END.');
end;
function map_page(page_number : uint16; block : uint16) : boolean;
var
addr : ubit20;
page : uint16;
rldpd : uint32;
begin
map_page:= false;
PageDirectory^[page_number].Present:= true;
addr:= block;
writehexln(block);
PageDirectory^[page_number].Address:= addr SHL 9;
PageDirectory^[page_number].PageSize:= true;
PageDirectory^[page_number].Writable:= true;
rldpd:= uint32(PageDirectory) - KERNEL_VIRTUAL_BASE;
asm
mov eax, rldpd
mov CR3, eax
end;
console.writestringln('VMM: New Page Added:');
console.writestring('VMM: - P:');
console.writehex(page_number);
console.writestring('-->B:');
console.writehexln(block);
console.writestring('VMM: - P:[');
console.writehex(page_number SHL 22);
console.writestring(' - ');
console.writehex(((page_number+1) SHL 22));
console.writestring(']-->B:[');
console.writehex(block SHL 22);
console.writestring(' - ');
console.writehex(((block+1) SHL 22));
console.writestringln(']');
map_page:= true;
end;
function new_page(page_number : uint16) : boolean;
var
block : uint16;
begin
new_page:= false;
if PageDirectory^[page_number].Present then exit;
if PageDirectory^[page_number].Reserved then exit;
block:= pmemorymanager.new_block(uint32(PageDirectory));
if block < 2 then begin
GPF;
exit;
end else begin
new_page:= map_page(page_number, block);
end;
end;
function new_page_at_address(address : uint32) : boolean;
var
page_number : uint16;
begin
page_number:= address SHR 22;
new_page_at_address:= new_page(page_number);
end;
procedure free_page(page_number : uint16);
var
block : uint16;
begin
if PageDirectory^[page_number].Present then begin
block:= PageDirectory^[page_number].Address;
asm
invlpg [page_number]
end;
pmemorymanager.free_block(block, uint32(PageDirectory));
end else begin
GPF;
end;
end;
procedure free_page_at_address(address : uint32);
var
page_number : uint16;
begin
page_number:= address SHR 22;
free_page(page_number);
end;
end.