//kernel/trunk/arch/amd64/include/interrupt.h |
---|
88,6 → 88,7 |
extern void (* enable_irqs_function)(__u16 irqmask); |
extern void (* eoi_function)(void); |
extern void print_info_errcode(int n, istate_t *istate); |
extern void null_interrupt(int n, istate_t *istate); |
extern void gp_fault(int n, istate_t *istate); |
extern void nm_fault(int n, istate_t *istate); |
//kernel/trunk/arch/amd64/src/pm.c |
---|
171,9 → 171,10 |
idt_setoffset(d, ((__address) interrupt_handlers) + i*interrupt_handler_size); |
exc_register(i, "undef", (iroutine)null_interrupt); |
} |
exc_register(13, "gp_fault", gp_fault); |
exc_register( 7, "nm_fault", nm_fault); |
exc_register(12, "ss_fault", ss_fault); |
exc_register(13, "gp_fault", gp_fault); |
exc_register(14, "ident_mapper", ident_page_fault); |
} |
//kernel/trunk/arch/amd64/src/mm/page.c |
---|
37,7 → 37,40 |
#include <config.h> |
#include <memstr.h> |
#include <interrupt.h> |
#include <print.h> |
#include <panic.h> |
/* Definitions for identity page mapper */ |
pte_t helper_ptl1[512] __attribute__((aligned (PAGE_SIZE))); |
pte_t helper_ptl2[512] __attribute__((aligned (PAGE_SIZE))); |
pte_t helper_ptl3[512] __attribute__((aligned (PAGE_SIZE))); |
extern pte_t ptl_0; /* From boot.S */ |
#define PTL1_PRESENT(ptl0, page) (!(GET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page)) & PAGE_NOT_PRESENT)) |
#define PTL2_PRESENT(ptl1, page) (!(GET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page)) & PAGE_NOT_PRESENT)) |
#define PTL3_PRESENT(ptl2, page) (!(GET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page)) & PAGE_NOT_PRESENT)) |
#define PTL1_ADDR(ptl0, page) ((pte_t *)PA2KA(GET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page)))) |
#define PTL2_ADDR(ptl1, page) ((pte_t *)PA2KA(GET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page)))) |
#define PTL3_ADDR(ptl2, page) ((pte_t *)PA2KA(GET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page)))) |
#define SETUP_PTL1(ptl0, page, tgt) { \ |
SET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page), (__address)KA2PA(tgt)); \ |
SET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ |
} |
#define SETUP_PTL2(ptl1, page, tgt) { \ |
SET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page), (__address)KA2PA(tgt)); \ |
SET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ |
} |
#define SETUP_PTL3(ptl2, page, tgt) { \ |
SET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page), (__address)KA2PA(tgt)); \ |
SET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ |
} |
#define SETUP_FRAME(ptl3, page, tgt) { \ |
SET_FRAME_ADDRESS_ARCH(ptl3, PTL3_INDEX_ARCH(page), (__address)KA2PA(tgt)); \ |
SET_FRAME_FLAGS_ARCH(ptl3, PTL3_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ |
} |
void page_arch_init(void) |
{ |
__address cur; |
62,3 → 95,68 |
write_cr3((__address) AS_KERNEL->page_table); |
} |
} |
/** Identity page mapper |
* |
* We need to map whole physical memory identically before the page subsystem |
* is initializaed. This thing clears page table and fills in the specific |
* items. |
*/ |
void ident_page_fault(int n, istate_t *istate) |
{ |
__address page; |
static __address oldpage = 0; |
pte_t *aptl_1, *aptl_2, *aptl_3; |
page = read_cr2(); |
if (oldpage) { |
/* Unmap old address */ |
aptl_1 = PTL1_ADDR(&ptl_0, oldpage); |
aptl_2 = PTL2_ADDR(aptl_1, oldpage); |
aptl_3 = PTL3_ADDR(aptl_2, oldpage); |
SET_FRAME_FLAGS_ARCH(aptl_3, PTL3_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); |
if (aptl_3 == helper_ptl3) |
SET_PTL3_FLAGS_ARCH(aptl_2, PTL2_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); |
if (aptl_2 == helper_ptl2) |
SET_PTL2_FLAGS_ARCH(aptl_1, PTL1_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); |
if (aptl_1 == helper_ptl1) |
SET_PTL1_FLAGS_ARCH(&ptl_0, PTL0_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); |
} |
if (PTL1_PRESENT(&ptl_0, page)) |
aptl_1 = PTL1_ADDR(&ptl_0, page); |
else { |
SETUP_PTL1(&ptl_0, page, helper_ptl1); |
aptl_1 = helper_ptl1; |
} |
if (PTL2_PRESENT(aptl_1, page)) |
aptl_2 = PTL2_ADDR(aptl_1, page); |
else { |
SETUP_PTL2(aptl_1, page, helper_ptl2); |
aptl_2 = helper_ptl2; |
} |
if (PTL3_PRESENT(aptl_2, page)) |
aptl_3 = PTL3_ADDR(aptl_2, page); |
else { |
SETUP_PTL3(aptl_2, page, helper_ptl3); |
aptl_3 = helper_ptl3; |
} |
SETUP_FRAME(aptl_3, page, page); |
oldpage = page; |
} |
void page_fault(int n, istate_t *istate) |
{ |
__address page; |
page = read_cr2(); |
if (!as_page_fault(page)) { |
print_info_errcode(n, istate); |
printf("Page fault address: %Q\n", page); |
panic("page fault\n"); |
} |
} |
//kernel/trunk/arch/amd64/src/interrupt.c |
---|
42,7 → 42,7 |
#include <proc/scheduler.h> |
#include <proc/thread.h> |
static void print_info_errcode(int n, istate_t *istate) |
void print_info_errcode(int n, istate_t *istate) |
{ |
char *symbol; |
__u64 *x = &istate->stack[0]; |
92,7 → 92,6 |
panic("stack fault\n"); |
} |
void nm_fault(int n, istate_t *istate) |
{ |
#ifdef CONFIG_FPU_LAZY |
102,103 → 101,6 |
#endif |
} |
/* Definitions for identic page mapper */ |
pte_t helper_ptl1[512] __attribute__((aligned (PAGE_SIZE))); |
pte_t helper_ptl2[512] __attribute__((aligned (PAGE_SIZE))); |
pte_t helper_ptl3[512] __attribute__((aligned (PAGE_SIZE))); |
extern pte_t ptl_0; /* From boot.S */ |
#define PTL1_PRESENT(ptl0, page) (!(GET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page)) & PAGE_NOT_PRESENT)) |
#define PTL2_PRESENT(ptl1, page) (!(GET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page)) & PAGE_NOT_PRESENT)) |
#define PTL3_PRESENT(ptl2, page) (!(GET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page)) & PAGE_NOT_PRESENT)) |
#define PTL1_ADDR(ptl0, page) ((pte_t *)PA2KA(GET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page)))) |
#define PTL2_ADDR(ptl1, page) ((pte_t *)PA2KA(GET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page)))) |
#define PTL3_ADDR(ptl2, page) ((pte_t *)PA2KA(GET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page)))) |
#define SETUP_PTL1(ptl0, page, tgt) { \ |
SET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page), (__address)KA2PA(tgt)); \ |
SET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ |
} |
#define SETUP_PTL2(ptl1, page, tgt) { \ |
SET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page), (__address)KA2PA(tgt)); \ |
SET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ |
} |
#define SETUP_PTL3(ptl2, page, tgt) { \ |
SET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page), (__address)KA2PA(tgt)); \ |
SET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ |
} |
#define SETUP_FRAME(ptl3, page, tgt) { \ |
SET_FRAME_ADDRESS_ARCH(ptl3, PTL3_INDEX_ARCH(page), (__address)KA2PA(tgt)); \ |
SET_FRAME_FLAGS_ARCH(ptl3, PTL3_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \ |
} |
/** Identic page mapper |
* |
* We need to map whole physical memory identically before the page subsystem |
* is initializaed. This thing clears page table and fills in the specific |
* items. |
*/ |
void ident_page_fault(int n, istate_t *istate) |
{ |
__address page; |
static __address oldpage = 0; |
pte_t *aptl_1, *aptl_2, *aptl_3; |
page = read_cr2(); |
if (oldpage) { |
/* Unmap old address */ |
aptl_1 = PTL1_ADDR(&ptl_0, oldpage); |
aptl_2 = PTL2_ADDR(aptl_1, oldpage); |
aptl_3 = PTL3_ADDR(aptl_2, oldpage); |
SET_FRAME_FLAGS_ARCH(aptl_3, PTL3_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); |
if (aptl_3 == helper_ptl3) |
SET_PTL3_FLAGS_ARCH(aptl_2, PTL2_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); |
if (aptl_2 == helper_ptl2) |
SET_PTL2_FLAGS_ARCH(aptl_1, PTL1_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); |
if (aptl_1 == helper_ptl1) |
SET_PTL1_FLAGS_ARCH(&ptl_0, PTL0_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT); |
} |
if (PTL1_PRESENT(&ptl_0, page)) |
aptl_1 = PTL1_ADDR(&ptl_0, page); |
else { |
SETUP_PTL1(&ptl_0, page, helper_ptl1); |
aptl_1 = helper_ptl1; |
} |
if (PTL2_PRESENT(aptl_1, page)) |
aptl_2 = PTL2_ADDR(aptl_1, page); |
else { |
SETUP_PTL2(aptl_1, page, helper_ptl2); |
aptl_2 = helper_ptl2; |
} |
if (PTL3_PRESENT(aptl_2, page)) |
aptl_3 = PTL3_ADDR(aptl_2, page); |
else { |
SETUP_PTL3(aptl_2, page, helper_ptl3); |
aptl_3 = helper_ptl3; |
} |
SETUP_FRAME(aptl_3, page, page); |
oldpage = page; |
} |
void page_fault(int n, istate_t *istate) |
{ |
__address page; |
page = read_cr2(); |
if (!as_page_fault(page)) { |
print_info_errcode(n, istate); |
printf("Page fault address: %Q\n", page); |
panic("page fault\n"); |
} |
} |
void tlb_shootdown_ipi(int n, istate_t *istate) |
{ |
trap_virtual_eoi(); |