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
00038 #include <genarch/mm/page_pt.h>
00039 #include <mm/page.h>
00040 #include <mm/frame.h>
00041 #include <mm/as.h>
00042 #include <synch/mutex.h>
00043 #include <arch/mm/page.h>
00044 #include <arch/mm/as.h>
00045 #include <arch/types.h>
00046 #include <typedefs.h>
00047 #include <memstr.h>
00048 #include <arch.h>
00049
00050 static pte_t *ptl0_create(int flags);
00051 static void ptl0_destroy(pte_t *page_table);
00052
00053 static void pt_lock(as_t *as, bool lock);
00054 static void pt_unlock(as_t *as, bool unlock);
00055
00056 as_operations_t as_pt_operations = {
00057 .page_table_create = ptl0_create,
00058 .page_table_destroy = ptl0_destroy,
00059 .page_table_lock = pt_lock,
00060 .page_table_unlock = pt_unlock
00061 };
00062
00071 pte_t *ptl0_create(int flags)
00072 {
00073 pte_t *src_ptl0, *dst_ptl0;
00074 ipl_t ipl;
00075
00076 dst_ptl0 = (pte_t *) PA2KA(PFN2ADDR(frame_alloc(ONE_FRAME, FRAME_KA | FRAME_PANIC)));
00077
00078 if (flags & FLAG_AS_KERNEL) {
00079 memsetb((__address) dst_ptl0, PAGE_SIZE, 0);
00080 } else {
00081 __address src, dst;
00082
00083
00084
00085
00086
00087 ipl = interrupts_disable();
00088 mutex_lock(&AS_KERNEL->lock);
00089 src_ptl0 = (pte_t *) PA2KA((__address) AS_KERNEL->page_table);
00090
00091 src = (__address) &src_ptl0[PTL0_INDEX(KERNEL_ADDRESS_SPACE_START)];
00092 dst = (__address) &dst_ptl0[PTL0_INDEX(KERNEL_ADDRESS_SPACE_START)];
00093
00094 memsetb((__address) dst_ptl0, PAGE_SIZE, 0);
00095 memcpy((void *) dst, (void *) src, PAGE_SIZE - (src - (__address) src_ptl0));
00096 mutex_unlock(&AS_KERNEL->lock);
00097 interrupts_restore(ipl);
00098 }
00099
00100 return (pte_t *) KA2PA((__address) dst_ptl0);
00101 }
00102
00109 void ptl0_destroy(pte_t *page_table)
00110 {
00111 frame_free(ADDR2PFN((__address) page_table));
00112 }
00113
00122 void pt_lock(as_t *as, bool lock)
00123 {
00124 if (lock)
00125 mutex_lock(&as->lock);
00126 }
00127
00136 void pt_unlock(as_t *as, bool unlock)
00137 {
00138 if (unlock)
00139 mutex_unlock(&as->lock);
00140 }
00141