Ignore:
File:
1 edited

Legend:

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

    rbabb57e r96d9cdd  
    124124}
    125125
    126 uintptr_t km_map(uintptr_t paddr, size_t size, unsigned int flags)
     126static uintptr_t
     127km_map_aligned(uintptr_t paddr, size_t size, unsigned int flags)
    127128{
    128129        uintptr_t vaddr;
    129         size_t asize;
    130130        size_t align;
    131131        uintptr_t offs;
    132132
    133         asize = ALIGN_UP(size, PAGE_SIZE);
     133        ASSERT(ALIGN_DOWN(paddr, FRAME_SIZE) == paddr);
     134        ASSERT(ALIGN_UP(size, FRAME_SIZE) == size);
     135
     136        /* Enforce natural or at least PAGE_SIZE alignment. */
    134137        align = ispwr2(size) ? size : (1U << (fnzb(size) + 1));
    135         vaddr = km_page_alloc(asize, max(PAGE_SIZE, align));
     138        vaddr = km_page_alloc(size, max(PAGE_SIZE, align));
    136139
    137140        page_table_lock(AS_KERNEL, true);
    138         for (offs = 0; offs < asize; offs += PAGE_SIZE) {
     141        for (offs = 0; offs < size; offs += PAGE_SIZE) {
    139142                page_mapping_insert(AS_KERNEL, vaddr + offs, paddr + offs,
    140143                    flags);
     
    145148}
    146149
    147 uintptr_t km_map_structure(uintptr_t paddr, size_t size, unsigned int flags)
    148 {
    149         size_t offs = paddr - ALIGN_DOWN(paddr, FRAME_SIZE);
     150static void km_unmap_aligned(uintptr_t vaddr, size_t size)
     151{
     152        uintptr_t offs;
     153        ipl_t ipl;
     154
     155        ASSERT(ALIGN_DOWN(vaddr, PAGE_SIZE) == vaddr);
     156        ASSERT(ALIGN_UP(size, PAGE_SIZE) == size);
     157
     158        page_table_lock(AS_KERNEL, true);
     159
     160        ipl = tlb_shootdown_start(TLB_INVL_ASID, ASID_KERNEL, 0, 0);
     161
     162        for (offs = 0; offs < size; offs += PAGE_SIZE)
     163                page_mapping_remove(AS_KERNEL, vaddr + offs);
     164
     165        tlb_invalidate_asid(ASID_KERNEL);
     166
     167        as_invalidate_translation_cache(AS_KERNEL, 0, -1);
     168        tlb_shootdown_finalize(ipl);
     169        page_table_unlock(AS_KERNEL, true);
     170
     171        km_page_free(vaddr, size);
     172}
     173
     174/** Map a piece of physical address space into the virtual address space.
     175 *
     176 * @param paddr         Physical address to be mapped. May be unaligned.
     177 * @param size          Size of area starting at paddr to be mapped.
     178 * @param flags         Protection flags to be used for the mapping.
     179 *
     180 * @return New virtual address mapped to paddr.
     181 */
     182uintptr_t km_map(uintptr_t paddr, size_t size, unsigned int flags)
     183{
    150184        uintptr_t page;
    151 
    152         page = km_map(ALIGN_DOWN(paddr, FRAME_SIZE), size + offs, flags);
     185        size_t offs;
     186
     187        offs = paddr - ALIGN_DOWN(paddr, FRAME_SIZE);
     188        page = km_map_aligned(ALIGN_DOWN(paddr, FRAME_SIZE),
     189            ALIGN_UP(size + offs, FRAME_SIZE), flags);
     190
    153191        return page + offs;
    154192}
    155193
    156 /** Unmap kernen non-identity page.
     194/** Unmap a piece of virtual address space.
     195 *
     196 * @param vaddr         Virtual address to be unmapped. May be unaligned, but
     197 *                      it must a value previously returned by km_map().
     198 * @param size          Size of area starting at vaddr to be unmapped.
     199 */
     200void km_unmap(uintptr_t vaddr, size_t size)
     201{
     202        size_t offs;
     203
     204        offs = vaddr - ALIGN_DOWN(vaddr, PAGE_SIZE);
     205        km_unmap_aligned(ALIGN_DOWN(vaddr, PAGE_SIZE),
     206            ALIGN_UP(size + offs, PAGE_SIZE));
     207}
     208
     209/** Unmap kernel non-identity page.
    157210 *
    158211 * @param[in] page      Non-identity page to be unmapped.
Note: See TracChangeset for help on using the changeset viewer.