Changes in kernel/generic/src/mm/km.c [c868e2d:f7f47a7] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/mm/km.c
rc868e2d rf7f47a7 39 39 #include <arch/mm/km.h> 40 40 #include <mm/page.h> 41 #include <mm/frame.h> 42 #include <mm/asid.h> 41 43 #include <config.h> 42 44 #include <typedefs.h> 43 45 #include <lib/ra.h> 44 46 #include <debug.h> 47 #include <arch.h> 45 48 46 49 static ra_arena_t *km_ni_arena; 50 51 #define DEFERRED_PAGES_MAX (PAGE_SIZE / sizeof(uintptr_t)) 52 53 /** Number of freed pages in the deferred buffer. */ 54 static volatile unsigned deferred_pages; 55 /** Buffer of deferred freed pages. */ 56 static uintptr_t deferred_page[DEFERRED_PAGES_MAX]; 57 58 /** Flush the buffer of deferred freed pages. 59 * 60 * @return Number of freed pages. 61 */ 62 static unsigned km_flush_deferred(void) 63 { 64 unsigned i = 0; 65 ipl_t ipl; 66 67 ipl = tlb_shootdown_start(TLB_INVL_ASID, ASID_KERNEL, 0, 0); 68 69 for (i = 0; i < deferred_pages; i++) { 70 page_mapping_remove(AS_KERNEL, deferred_page[i]); 71 km_page_free(deferred_page[i], PAGE_SIZE); 72 } 73 74 tlb_invalidate_asid(ASID_KERNEL); 75 76 as_invalidate_translation_cache(AS_KERNEL, 0, -1); 77 tlb_shootdown_finalize(ipl); 78 79 return i; 80 } 47 81 48 82 /** Architecture dependent setup of identity-mapped kernel memory. */ … … 87 121 } 88 122 123 /** Unmap kernen non-identity page. 124 * 125 * @param[in] page Non-identity page to be unmapped. 126 */ 127 static void km_unmap_deferred(uintptr_t page) 128 { 129 page_table_lock(AS_KERNEL, true); 130 131 if (deferred_pages == DEFERRED_PAGES_MAX) { 132 (void) km_flush_deferred(); 133 deferred_pages = 0; 134 } 135 136 deferred_page[deferred_pages++] = page; 137 138 page_table_unlock(AS_KERNEL, true); 139 } 140 141 /** Create a temporary page. 142 * 143 * The page is mapped read/write to a newly allocated frame of physical memory. 144 * The page must be returned back to the system by a call to 145 * km_temporary_page_put(). 146 * 147 * @param[inout] framep Pointer to a variable which will receive the physical 148 * address of the allocated frame. 149 * @param[in] flags Frame allocation flags. FRAME_NONE or FRAME_NO_RESERVE. 150 * @return Virtual address of the allocated frame. 151 */ 152 uintptr_t km_temporary_page_get(uintptr_t *framep, frame_flags_t flags) 153 { 154 uintptr_t frame; 155 uintptr_t page; 156 157 ASSERT(THREAD); 158 ASSERT(framep); 159 ASSERT(!(flags & ~FRAME_NO_RESERVE)); 160 161 /* 162 * Allocate a frame, preferably from high memory. 163 */ 164 frame = (uintptr_t) frame_alloc(ONE_FRAME, 165 FRAME_HIGHMEM | FRAME_ATOMIC | flags); 166 if (frame) { 167 page = km_page_alloc(PAGE_SIZE, PAGE_SIZE); 168 ASSERT(page); // FIXME 169 page_table_lock(AS_KERNEL, true); 170 page_mapping_insert(AS_KERNEL, page, frame, 171 PAGE_CACHEABLE | PAGE_READ | PAGE_WRITE); 172 page_table_unlock(AS_KERNEL, true); 173 } else { 174 frame = (uintptr_t) frame_alloc_noreserve(ONE_FRAME, 175 FRAME_LOWMEM); 176 page = PA2KA(frame); 177 } 178 179 *framep = frame; 180 return page; 181 } 182 183 /** Destroy a temporary page. 184 * 185 * This function destroys a temporary page previously created by 186 * km_temporary_page_get(). The page destruction may be immediate or deferred. 187 * The frame mapped by the destroyed page is not freed. 188 * 189 * @param[in] page Temporary page to be destroyed. 190 */ 191 void km_temporary_page_put(uintptr_t page) 192 { 193 ASSERT(THREAD); 194 195 if (km_is_non_identity(page)) 196 km_unmap_deferred(page); 197 } 89 198 90 199 /** @}
Note:
See TracChangeset
for help on using the changeset viewer.