aboutsummaryrefslogtreecommitdiff
path: root/arch/i686/paging.c
blob: 9d748ab7528e23618da7d5d420f4d4dd1e8201f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "heap.h"
#include "isr.h"
#include "paging.h"
#include "panic.h"

uint32_t *current_directory;

static void page_fault(struct regs_t *regs)
{
    volatile uint32_t fault_addr;
    asm("mov %%cr2, %0" : "=r"(fault_addr));
    printf("=== Page Fault ===\n");
    printf("Faulting address: 0x%x\n", fault_addr);
    /* dump the regs */
    printf("EAX: 0x%x EBX: 0x%x\n", regs->eax, regs->ebx);
    printf("ECX: 0x%x EDX: 0x%x\n", regs->ecx, regs->edx);
    printf("ESP: 0x%x EBP: 0x%x\n", regs->esp, regs->ebp);
    printf("ESI: 0x%x EDI: 0x%x\n", regs->esi, regs->edi);
    printf("EIP: 0x%x\n", regs->eip);
    panic("Page fault!\n");
}

 void paging_switch_directory(uint32_t *dir)
{
    current_directory = dir;
    extern void do_paging_enable(uint32_t);
    do_paging_enable((uint32_t)current_directory);
}

static uint32_t *identity_map_table(uint32_t start, int flags)
{
    /* make a page table */
    uint32_t *table = kmalloc_a(0x1000);
    /* identity map 4MB */
    for(uint32_t i = start; i < start + 1024; ++i)
    {
        table[i - start] = (i * PAGE_SIZE) | flags;
    }
    return table;
}

void paging_init(void)
{
    uint32_t *kernel_directory = kmalloc_a(0x1000);
    memset(kernel_directory, 0, 0x1000);
    /* blank the kernel directory */
    for(int i = 0; i < 1024; ++i)
    {
        kernel_directory[i] = PAGE_RW;
    }

    /* identity map all 4GB (and allocate all page tables) */
    for(int i = 0; i < 1024; ++i)
        kernel_directory[i] = (uint32_t)identity_map_table(i * 1024, PAGE_PRESENT | PAGE_RW) |
            PAGE_PRESENT | PAGE_RW;

    set_interrupt_handler(14, page_fault);

    paging_switch_directory(kernel_directory);
}