hos/vmm.c

139 lines
2.8 KiB
C

// vmm.c
// Author: Josh Holtrop
// Date: 09/30/03
PageDirectory *vmm_PDBR = 0;
dword vmm_first_virtual_address = 0;
void vmm_init()
{
if (!(vmm_PDBR = mm_palloc(1, PID_KERNEL)))
{
printf("ERROR! COULD NOT ALLOCATE PAGE FOR INITIAL PAGE DIRECTORY!!\n");
halt();
}
vmm_init_pagetable((dword)vmm_PDBR);
if (mm_totalmem % 4096)
vmm_first_virtual_address = mm_totalmem + (4096 - (mm_totalmem % 4096));
else
vmm_first_virtual_address = mm_totalmem;
if (vmm_mapn(0, 0, 0x03, mm_totalmem/4096+1))
{
printf("Could not page in all physical RAM!\n");
halt();
}
//we also need to map in the video framebuffer memory:
if (video_mode.PhysBasePtr > 0 && video_mode.BitsPerPixel > 0)
{
if (vmm_mapn(video_mode.PhysBasePtr, video_mode.PhysBasePtr, 0x03, (video_mode.BitsPerPixel/8 * video_mode.XResolution * video_mode.YResolution)/4096+1))
{
printf("Could not page in video memory at 0x%x!\n", video_mode.PhysBasePtr);
halt();
}
}
}
void vmm_enable_paging()
{
write_cr3((dword)vmm_PDBR);
write_cr0(0x80000000|read_cr0());
}
int vmm_map1(dword virtual, dword physical, dword flags)
{
if (virtual & 0x00000FFF)
return 1; // ERROR 1: address not page-aligned
if (physical & 0x00000FFF)
return 1; // ERROR 1: address not page-aligned
int pde = (virtual & 0xFFC00000) >> 22;
int pte = (virtual & 0x003FF000) >> 12;
if (!(vmm_PDBR->pageTables[pde] & 0x01))
{
vmm_PDBR->pageTables[pde] = (dword)mm_palloc(1, PID_KERNEL) | 0x7; //user, r/w, present
vmm_init_pagetable(vmm_PDBR->pageTables[pde] & 0xFFFFF000);
if (vmm_PDBR->pageTables[pde] == 0x07)
return 2; // ERROR 2: page table could not be created
}
PageTable *ptp = (PageTable *)(vmm_PDBR->pageTables[pde] & 0xFFFFF000);
if (ptp->page[pte] & 0x01)
return 3; // ERROR 3: page table entry already exists
ptp->page[pte] = physical | flags;
return 0;
}
int vmm_mapn(dword virtual, dword physical, dword flags, dword n)
{
int mapped;
int result = 0;
dword va = virtual;
dword pa = physical;
for (mapped = 0; mapped < n; mapped++)
{
result = vmm_map1(va, pa, flags);
if (result != 0)
{
if (mapped > 0)
vmm_unmapn(virtual, mapped);
return result;
}
va += 4096;
pa += 4096;
}
}
int vmm_unmap1(dword virtual)
{
int pde = (virtual & 0xFFC00000) >> 22;
int pte = (virtual & 0x003FF000) >> 12;
if (virtual & 0x00000FFF)
return 1; // ERROR 1: address not page-aligned
PageTable *ptp = (PageTable *)(vmm_PDBR->pageTables[pde] & 0xFFFFF000);
}
int vmm_unmapn(dword virtual, dword n)
{
}
void vmm_init_pagetable(dword address)
{
PageTable *ptp = (PageTable *)address;
int n;
for (n = 0; n < 1024; n++)
ptp->page[n] = 0;
}
void *malloc(dword bytes)
{
}
int free(void *ptr)
{
}