Files
2018-12-09 21:08:06 -06:00

152 lines
6.6 KiB
C

/*
* Source file used to initialize paging
*/
#include "paging.h"
#include "devices/acpi.h"
#include "devices/qemu_vga.h"
/* void init_paging()
* @output: page table and page directory initialized.
* @description: initialize page table and page directory table to utilize
* virtual memory.
*/
void init_paging()
{
// loop variable
uint32_t index;
// initialize Page Table
for (index = 0; index < NUM_PTE; index++)
{
// initially, clear all flags
page_table[index].present
= ((index == VIDEO_MEM_INDEX)
|| (index == VIDEO_MEM_DIRECT_INDEX)
|| (index >= VIDEO_MEM_ALT_START && index < VIDEO_MEM_ALT_END)
|| (index >= SB16_MEM_BEGIN && index < SB16_MEM_END)
|| (index >= ACPI_MEM_BEGIN && index < ACPI_MEM_END)
) ? 1 : 0;
page_table[index].read_write = 0;
page_table[index].user_supervisor = 0;
page_table[index].write_through = 0;
page_table[index].cache_disabled = 0;
page_table[index].accessed = 0;
page_table[index].dirty = 0;
page_table[index].pat = 0;
page_table[index].global = 0;
page_table[index].avail = 0;
// Redirect VIDEO_MEM_DIRECT_INDEX to VIDEO_MEM_INDEX,
// to ensure there is always way to directly access video mem without handling multi terminal
page_table[index].PB_addr = (index == VIDEO_MEM_DIRECT_INDEX) ? VIDEO_MEM_INDEX : index;
// // If QEMU VGA is enabled, redirect VGA text mode mem to another place,
// // or QEMU VGA will destroy the contents in it
// if(qemu_vga_enabled && ((index == VIDEO_MEM_INDEX)
// || (index == VIDEO_MEM_DIRECT_INDEX)
// || (index >= VIDEO_MEM_ALT_START && index < VIDEO_MEM_ALT_END))) {
// // Offset video memory to another physical address
// // 0xdb8000, 0xdb7000, etc
// page_table[index].PB_addr += 0xd00;
// }
}
// initialize Page Table for User memory mapping
for (index = 0; index < NUM_PTE; index++)
{
// initially, clear all flags
page_table_usermap[index].present = 0;
page_table_usermap[index].read_write = 1;
page_table_usermap[index].user_supervisor = 1;
page_table_usermap[index].write_through = 0;
page_table_usermap[index].cache_disabled = 0;
page_table_usermap[index].accessed = 0;
page_table_usermap[index].dirty = 0;
page_table_usermap[index].pat = 0;
page_table_usermap[index].global = 0;
page_table_usermap[index].avail = 0;
page_table_usermap[index].PB_addr = index;
}
// initialize the first 4MB memory (4kB page, where video memory is)
page_directory[0].pde_KB.present = 1;
page_directory[0].pde_KB.read_write = 0;
page_directory[0].pde_KB.user_supervisor = 0;
page_directory[0].pde_KB.write_through = 0;
page_directory[0].pde_KB.cache_disabled = 0;
page_directory[0].pde_KB.accessed = 0;
page_directory[0].pde_KB.reserved = 0;
page_directory[0].pde_KB.page_size = 0;
page_directory[0].pde_KB.global = 0;
page_directory[0].pde_KB.avail = 0;
page_directory[0].pde_KB.PTB_addr = (unsigned int) page_table >> TB_ADDR_OFFSET;
// initialize the first 4MB-8MB memory (4MB page, KERNEL)
page_directory[1].pde_MB.present = 1;
page_directory[1].pde_MB.read_write = 0;
page_directory[1].pde_MB.user_supervisor = 0;
page_directory[1].pde_MB.write_through = 0;
page_directory[1].pde_MB.cache_disabled = 0;
page_directory[1].pde_MB.accessed = 0;
page_directory[1].pde_MB.dirty = 0;
page_directory[1].pde_MB.page_size = 1;
page_directory[1].pde_MB.global = 1;
page_directory[1].pde_MB.avail = 0;
page_directory[1].pde_MB.pat = 0;
page_directory[1].pde_MB.reserved = 0;
page_directory[1].pde_MB.PB_addr = 1;
// initialize the first 4MB memory (4kB page, where video memory is)
page_directory[PAGE_TABLE_USERMAP_LOCATION].pde_KB.present = 1;
page_directory[PAGE_TABLE_USERMAP_LOCATION].pde_KB.read_write = 1;
page_directory[PAGE_TABLE_USERMAP_LOCATION].pde_KB.user_supervisor = 1;
page_directory[PAGE_TABLE_USERMAP_LOCATION].pde_KB.write_through = 0;
page_directory[PAGE_TABLE_USERMAP_LOCATION].pde_KB.cache_disabled = 0;
page_directory[PAGE_TABLE_USERMAP_LOCATION].pde_KB.accessed = 0;
page_directory[PAGE_TABLE_USERMAP_LOCATION].pde_KB.reserved = 0;
page_directory[PAGE_TABLE_USERMAP_LOCATION].pde_KB.page_size = 0;
page_directory[PAGE_TABLE_USERMAP_LOCATION].pde_KB.global = 0;
page_directory[PAGE_TABLE_USERMAP_LOCATION].pde_KB.avail = 0;
page_directory[PAGE_TABLE_USERMAP_LOCATION].pde_KB.PTB_addr = (unsigned int) page_table_usermap >> TB_ADDR_OFFSET;
// initialize the rest Page Directory
for (index = 2; index < NUM_PDE; index++)
{
if(index == PAGE_TABLE_USERMAP_LOCATION) continue;
// Enable paging present for ACPI related data structures
page_directory[index].pde_MB.present = (
(index == ((uint32_t) rsdp_descriptor >> TB_ADDR_OFFSET_MB))
|| (index == ((uint32_t) rsdt >> TB_ADDR_OFFSET_MB))
|| (index == ((uint32_t) fadt >> TB_ADDR_OFFSET_MB))
|| (index == ((uint32_t) dsdt_s5 >> TB_ADDR_OFFSET_MB))
|| (index >= ((uint32_t) qemu_vga_addr >> TB_ADDR_OFFSET_MB)
&& index < ((uint32_t) (qemu_vga_addr + QEMU_VGA_BANK_SIZE) >> TB_ADDR_OFFSET_MB))
) ? 1 : 0;
page_directory[index].pde_MB.read_write = 0;
page_directory[index].pde_MB.user_supervisor = 0;
page_directory[index].pde_MB.write_through = 0;
page_directory[index].pde_MB.cache_disabled = 0;
page_directory[index].pde_MB.accessed = 0;
page_directory[index].pde_MB.dirty = 0;
page_directory[index].pde_MB.page_size = 1;
page_directory[index].pde_MB.global = 0;
page_directory[index].pde_MB.avail = 0;
page_directory[index].pde_MB.pat = 0;
page_directory[index].pde_MB.reserved = 0;
page_directory[index].pde_MB.PB_addr = index;
}
// note: there might be some problems
asm (
"movl $page_directory, %%eax ;"
"andl $0xFFFFFC00, %%eax ;"
"movl %%eax, %%cr3 ;"
"movl %%cr4, %%eax ;"
"orl $0x00000010, %%eax ;"
"movl %%eax, %%cr4 ;"
"movl %%cr0, %%eax ;"
"orl $0x80000000, %%eax ;"
"movl %%eax, %%cr0 "
: : : "eax", "cc" );
return;
}