Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/mm/km.c

    rf7f47a7 rc868e2d  
    3939#include <arch/mm/km.h>
    4040#include <mm/page.h>
    41 #include <mm/frame.h>
    42 #include <mm/asid.h>
    4341#include <config.h>
    4442#include <typedefs.h>
    4543#include <lib/ra.h>
    4644#include <debug.h>
    47 #include <arch.h>
    4845
    4946static 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 }
    8147
    8248/** Architecture dependent setup of identity-mapped kernel memory. */
     
    12187}
    12288
    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 }
    19889
    19990/** @}
Note: See TracChangeset for help on using the changeset viewer.