Changeset 70922c2 in mainline for kernel/generic/src


Ignore:
Timestamp:
2012-02-01T00:09:22Z (14 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ffcc5776
Parents:
cb3dbb63 (diff), 3d4750f (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Mainline changes.

Location:
kernel/generic/src
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/lib/rd.c

    rcb3dbb63 r70922c2  
    5454void init_rd(void *data, size_t size)
    5555{
    56         uintptr_t base = KA2PA((uintptr_t) data);
     56        uintptr_t base = (uintptr_t) data;
    5757        ASSERT((base % FRAME_SIZE) == 0);
    5858       
  • kernel/generic/src/main/kinit.c

    rcb3dbb63 r70922c2  
    5757#include <mm/as.h>
    5858#include <mm/frame.h>
     59#include <mm/km.h>
    5960#include <print.h>
    6061#include <memstr.h>
     
    6869#include <str.h>
    6970#include <sysinfo/stats.h>
     71#include <align.h>
    7072
    7173#ifdef CONFIG_SMP
     
    178180       
    179181        for (i = 0; i < init.cnt; i++) {
    180                 if (init.tasks[i].addr % FRAME_SIZE) {
     182                if (init.tasks[i].paddr % FRAME_SIZE) {
    181183                        printf("init[%zu]: Address is not frame aligned\n", i);
    182184                        programs[i].task = NULL;
     
    199201                str_cpy(namebuf + INIT_PREFIX_LEN,
    200202                    TASK_NAME_BUFLEN - INIT_PREFIX_LEN, name);
    201                
    202                 int rc = program_create_from_image((void *) init.tasks[i].addr,
    203                     namebuf, &programs[i]);
     203
     204                /*
     205                 * Create virtual memory mappings for init task images.
     206                 */
     207                uintptr_t page = km_map(init.tasks[i].paddr,
     208                    init.tasks[i].size,
     209                    PAGE_READ | PAGE_WRITE | PAGE_CACHEABLE);
     210                ASSERT(page);
     211               
     212                int rc = program_create_from_image((void *) page, namebuf,
     213                    &programs[i]);
    204214               
    205215                if (rc == 0) {
     
    224234                         * Assume the last task is the RAM disk.
    225235                         */
    226                         init_rd((void *) init.tasks[i].addr, init.tasks[i].size);
     236                        init_rd((void *) init.tasks[i].paddr, init.tasks[i].size);
    227237                } else
    228238                        printf("init[%zu]: Init binary load failed (error %d)\n", i, rc);
  • kernel/generic/src/main/main.c

    rcb3dbb63 r70922c2  
    151151        size_t i;
    152152        for (i = 0; i < init.cnt; i++) {
    153                 if (PA_OVERLAPS(config.stack_base, config.stack_size,
    154                     init.tasks[i].addr, init.tasks[i].size))
    155                         config.stack_base = ALIGN_UP(init.tasks[i].addr +
    156                             init.tasks[i].size, config.stack_size);
     153                if (overlaps(KA2PA(config.stack_base), config.stack_size,
     154                    init.tasks[i].paddr, init.tasks[i].size)) {
     155                        /*
     156                         * The init task overlaps with the memory behind the
     157                         * kernel image so it must be in low memory and we can
     158                         * use PA2KA on the init task's physical address.
     159                         */
     160                        config.stack_base = ALIGN_UP(
     161                            PA2KA(init.tasks[i].paddr) + init.tasks[i].size,
     162                            config.stack_size);
     163                }
    157164        }
    158165       
  • kernel/generic/src/mm/backend_elf.c

    rcb3dbb63 r70922c2  
    318318                        dirty = true;
    319319                } else {
    320                         frame = KA2PA(base + i * FRAME_SIZE);
     320                        pte_t *pte = page_mapping_find(AS_KERNEL,
     321                            base + i * FRAME_SIZE, true);
     322
     323                        ASSERT(pte);
     324                        ASSERT(PTE_PRESENT(pte));
     325
     326                        frame = PTE_GET_FRAME(pte);
    321327                }       
    322328        } else if (upage >= start_anon) {
  • kernel/generic/src/mm/frame.c

    rcb3dbb63 r70922c2  
    924924                                for (i = 0; i < init.cnt; i++)
    925925                                        if (overlaps(addr, PFN2ADDR(confcount),
    926                                             KA2PA(init.tasks[i].addr),
     926                                            init.tasks[i].paddr,
    927927                                            init.tasks[i].size)) {
    928928                                                overlap = true;
     
    12511251                size_t i;
    12521252                for (i = 0; i < init.cnt; i++) {
    1253                         pfn_t pfn = ADDR2PFN(KA2PA(init.tasks[i].addr));
     1253                        pfn_t pfn = ADDR2PFN(init.tasks[i].paddr);
    12541254                        frame_mark_unavailable(pfn,
    12551255                            SIZE2FRAMES(init.tasks[i].size));
  • kernel/generic/src/mm/km.c

    rcb3dbb63 r70922c2  
    4646#include <debug.h>
    4747#include <arch.h>
     48#include <align.h>
     49#include <macros.h>
     50#include <bitops.h>
    4851
    4952static ra_arena_t *km_ni_arena;
     
    121124}
    122125
    123 /** Unmap kernen non-identity page.
     126static uintptr_t
     127km_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
     149static 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 */
     181uintptr_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 */
     199void 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.
    124209 *
    125210 * @param[in] page      Non-identity page to be unmapped.
     
    165250            FRAME_HIGHMEM | FRAME_ATOMIC | flags);
    166251        if (frame) {
    167                 page = km_page_alloc(PAGE_SIZE, PAGE_SIZE);
     252                page = km_map(frame, PAGE_SIZE,
     253                    PAGE_READ | PAGE_WRITE | PAGE_CACHEABLE);
    168254                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);
    173255        } else {
    174256                frame = (uintptr_t) frame_alloc_noreserve(ONE_FRAME,
  • kernel/generic/src/mm/page.c

    rcb3dbb63 r70922c2  
    6565#include <arch/mm/asid.h>
    6666#include <mm/as.h>
    67 #include <mm/km.h>
    6867#include <mm/frame.h>
    6968#include <arch/barrier.h>
     
    7675#include <errno.h>
    7776#include <align.h>
    78 #include <macros.h>
    79 #include <bitops.h>
    8077
    8178/** Virtual operations for page subsystem. */
     
    8582{
    8683        page_arch_init();
    87 }
    88 
    89 /** Map memory structure
    90  *
    91  * Identity-map memory structure
    92  * considering possible crossings
    93  * of page boundaries.
    94  *
    95  * @param addr Address of the structure.
    96  * @param size Size of the structure.
    97  *
    98  */
    99 void map_structure(uintptr_t addr, size_t size)
    100 {
    101         size_t length = size + (addr - (addr & ~(PAGE_SIZE - 1)));
    102         size_t cnt = length / PAGE_SIZE + (length % PAGE_SIZE > 0);
    103        
    104         size_t i;
    105         for (i = 0; i < cnt; i++)
    106                 page_mapping_insert(AS_KERNEL, addr + i * PAGE_SIZE,
    107                     addr + i * PAGE_SIZE, PAGE_NOT_CACHEABLE | PAGE_WRITE);
    108        
    109         /* Repel prefetched accesses to the old mapping. */
    110         memory_barrier();
    11184}
    11285
     
    193166}
    194167
    195 uintptr_t hw_map(uintptr_t physaddr, size_t size)
    196 {
    197         uintptr_t virtaddr;
    198         size_t asize;
    199         size_t align;
    200         pfn_t i;
    201 
    202         asize = ALIGN_UP(size, PAGE_SIZE);
    203         align = ispwr2(size) ? size : (1U << (fnzb(size) + 1));
    204         virtaddr = km_page_alloc(asize, max(PAGE_SIZE, align));
    205 
    206         page_table_lock(AS_KERNEL, true);
    207         for (i = 0; i < ADDR2PFN(asize); i++) {
    208                 uintptr_t addr = PFN2ADDR(i);
    209                 page_mapping_insert(AS_KERNEL, virtaddr + addr, physaddr + addr,
    210                     PAGE_NOT_CACHEABLE | PAGE_WRITE);
    211         }
    212         page_table_unlock(AS_KERNEL, true);
    213        
    214         return virtaddr;
    215 }
    216 
    217168int page_find_mapping(uintptr_t virt, void **phys)
    218169{
Note: See TracChangeset for help on using the changeset viewer.