00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #include <arch/mm/page.h>
00036 #include <genarch/mm/page_pt.h>
00037 #include <arch/mm/frame.h>
00038 #include <mm/frame.h>
00039 #include <mm/page.h>
00040 #include <mm/as.h>
00041 #include <arch/types.h>
00042 #include <align.h>
00043 #include <config.h>
00044 #include <func.h>
00045 #include <arch/interrupt.h>
00046 #include <arch/asm.h>
00047 #include <debug.h>
00048 #include <memstr.h>
00049 #include <print.h>
00050 #include <interrupt.h>
00051
00052 void page_arch_init(void)
00053 {
00054 __address cur;
00055 int flags;
00056
00057 if (config.cpu_active == 1) {
00058 page_mapping_operations = &pt_mapping_operations;
00059
00060
00061
00062
00063 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
00064 flags = PAGE_CACHEABLE;
00065 if ((PA2KA(cur) >= config.base) && (PA2KA(cur) < config.base + config.kernel_size))
00066 flags |= PAGE_GLOBAL;
00067 page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
00068 }
00069
00070 exc_register(14, "page_fault", (iroutine) page_fault);
00071 write_cr3((__address) AS_KERNEL->page_table);
00072 }
00073 else {
00074 write_cr3((__address) AS_KERNEL->page_table);
00075 }
00076
00077 paging_on();
00078 }
00079
00080
00081 __address hw_map(__address physaddr, size_t size)
00082 {
00083 if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
00084 panic("Unable to map physical memory %p (%d bytes)", physaddr, size)
00085
00086 __address virtaddr = PA2KA(last_frame);
00087 pfn_t i;
00088 for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
00089 page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE);
00090
00091 last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
00092
00093 return virtaddr;
00094 }
00095
00096 void page_fault(int n, istate_t *istate)
00097 {
00098 __address page;
00099 pf_access_t access;
00100
00101 page = read_cr2();
00102
00103 if (istate->error_word & PFERR_CODE_RSVD)
00104 panic("Reserved bit set in page directory.\n");
00105
00106 if (istate->error_word & PFERR_CODE_RW)
00107 access = PF_ACCESS_WRITE;
00108 else
00109 access = PF_ACCESS_READ;
00110
00111 if (as_page_fault(page, access, istate) == AS_PF_FAULT) {
00112 fault_if_from_uspace(istate, "Page fault: %#x", page);
00113
00114 PRINT_INFO_ERRCODE(istate);
00115 printf("page fault address: %#x\n", page);
00116 panic("page fault\n");
00117 }
00118 }
00119