Ignore:
File:
1 edited

Legend:

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

    r03cdd2b rf7f47a7  
    4646#include <debug.h>
    4747#include <arch.h>
    48 #include <align.h>
    49 #include <macros.h>
    50 #include <bitops.h>
    5148
    5249static ra_arena_t *km_ni_arena;
     
    124121}
    125122
    126 static uintptr_t
    127 km_map_aligned(uintptr_t paddr, size_t size, unsigned int flags)
    128 {
    129         uintptr_t vaddr;
    130         size_t align;
    131         uintptr_t offs;
    132 
    133         ASSERT(ALIGN_DOWN(paddr, FRAME_SIZE) == paddr);
    134         ASSERT(ALIGN_UP(size, FRAME_SIZE) == size);
    135 
    136         align = ispwr2(size) ? size : (1U << (fnzb(size) + 1));
    137         vaddr = km_page_alloc(size, max(PAGE_SIZE, align));
    138 
    139         page_table_lock(AS_KERNEL, true);
    140         for (offs = 0; offs < size; offs += PAGE_SIZE) {
    141                 page_mapping_insert(AS_KERNEL, vaddr + offs, paddr + offs,
    142                     flags);
    143         }
    144         page_table_unlock(AS_KERNEL, true);
    145        
    146         return vaddr;
    147 }
    148 
    149 static void km_unmap_aligned(uintptr_t vaddr, size_t size)
    150 {
    151         uintptr_t offs;
    152         ipl_t ipl;
    153 
    154         ASSERT(ALIGN_DOWN(vaddr, PAGE_SIZE) == vaddr);
    155         ASSERT(ALIGN_UP(size, PAGE_SIZE) == size);
    156 
    157         page_table_lock(AS_KERNEL, true);
    158 
    159         ipl = tlb_shootdown_start(TLB_INVL_ASID, ASID_KERNEL, 0, 0);
    160 
    161         for (offs = 0; offs < size; offs += PAGE_SIZE)
    162                 page_mapping_remove(AS_KERNEL, vaddr + offs);
    163 
    164         tlb_invalidate_asid(ASID_KERNEL);
    165 
    166         as_invalidate_translation_cache(AS_KERNEL, 0, -1);
    167         tlb_shootdown_finalize(ipl);
    168         page_table_unlock(AS_KERNEL, true);
    169 
    170         km_page_free(vaddr, size);
    171 }
    172 
    173 /** Map a piece of physical address space into the virtual address space.
    174  *
    175  * @param paddr         Physical address to be mapped. May be unaligned.
    176  * @param size          Size of area starting at paddr to be mapped.
    177  * @param flags         Protection flags to be used for the mapping.
    178  *
    179  * @return New virtual address mapped to paddr.
    180  */
    181 uintptr_t km_map(uintptr_t paddr, size_t size, unsigned int flags)
    182 {
    183         uintptr_t page;
    184         size_t offs;
    185 
    186         offs = paddr - ALIGN_DOWN(paddr, FRAME_SIZE);
    187         page = km_map_aligned(ALIGN_DOWN(paddr, FRAME_SIZE),
    188             ALIGN_UP(size + offs, FRAME_SIZE), flags);
    189 
    190         return page + offs;
    191 }
    192 
    193 /** Unmap a piece of virtual address space.
    194  *
    195  * @param vaddr         Virtual address to be unmapped. May be unaligned, but
    196  *                      it must a value previously returned by km_map().
    197  * @param size          Size of area starting at vaddr to be unmapped.
    198  */
    199 void km_unmap(uintptr_t vaddr, size_t size)
    200 {
    201         size_t offs;
    202 
    203         offs = vaddr - ALIGN_DOWN(vaddr, PAGE_SIZE);
    204         km_unmap_aligned(ALIGN_DOWN(vaddr, PAGE_SIZE),
    205             ALIGN_UP(size + offs, PAGE_SIZE));
    206 }
    207 
    208 /** Unmap kernel non-identity page.
     123/** Unmap kernen non-identity page.
    209124 *
    210125 * @param[in] page      Non-identity page to be unmapped.
     
    250165            FRAME_HIGHMEM | FRAME_ATOMIC | flags);
    251166        if (frame) {
    252                 page = km_map(frame, PAGE_SIZE,
    253                     PAGE_READ | PAGE_WRITE | PAGE_CACHEABLE);
     167                page = km_page_alloc(PAGE_SIZE, PAGE_SIZE);
    254168                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);
    255173        } else {
    256174                frame = (uintptr_t) frame_alloc_noreserve(ONE_FRAME,
Note: See TracChangeset for help on using the changeset viewer.