예제 #1
0
/** \brief Ensures that the page containing addr is mapped.
 * \return Zero on success, negative on failure.
 */
static int ensure_mapping(vaddr_t addr)
{
#if FALSE
    static paddr_t lastaddr;

    /* check if address is in kernel image */
    if (addr >= KERNEL_OFFSET && addr < (vaddr_t)&_end_kernel) {
        return 0;
    }

    /* if address is outside "physical" memory region, fail the access */
    if (addr < MEMORY_OFFSET || addr >= KERNEL_OFFSET) {
        return -1;
    }

    /* we now know we have a valid "physical memory" region address */
    paddr_t paddr = mem_to_phys(addr);
    paddr -= paddr & MEM_PAGE_MASK; // page-align

    /* quick and dirty optimisation: if this address is on the same page as
     * the last time we were called, return immediately */
    if (lastaddr == paddr && lastaddr != 0) {
        return 0;
    }

    int r = paging_map_memory(paddr, MEM_PAGE_SIZE);
    if (r < 0) {
        return r;
    }

    lastaddr = paddr;
#endif /* FALSE */
    return 0;
}
예제 #2
0
/**
 * \brief Reset kernel paging.
 *
 * This function resets the page maps for kernel and memory-space. It clears out
 * all other mappings. Use this only at system bootup!
 */
void paging_arm_reset(lpaddr_t paddr, size_t bytes)
{
    // make sure kernel pagetable is aligned to 16K after relocation
    aligned_kernel_l1_table = (union arm_l1_entry *)ROUND_UP((uintptr_t)kernel_l1_table, ARM_L1_ALIGN);

    // make sure low l2 pagetable is aligned to 1K after relocation
    aligned_low_l2_table = (union arm_l2_entry *)ROUND_UP((uintptr_t)low_l2_table, ARM_L2_ALIGN);

    // Re-map physical memory
    paging_map_memory((uintptr_t)aligned_kernel_l1_table, paddr, bytes);

    // map first MB at granularity of 4K pages
    uint32_t l2_flags = ARM_L2_SMALL_USR_NONE | ARM_L2_SMALL_CACHEABLE | ARM_L2_SMALL_BUFFERABLE;
    paging_map_user_pages_l1((uintptr_t)aligned_kernel_l1_table, MEMORY_OFFSET,
                             mem_to_local_phys((uintptr_t)aligned_low_l2_table));
    for(lpaddr_t pa=0; pa < ARM_L1_SECTION_BYTES; pa += BYTES_PER_PAGE)
    {
        lvaddr_t va = pa + MEMORY_OFFSET;
        paging_set_l2_entry((uintptr_t *)&aligned_low_l2_table[ARM_L2_OFFSET(va)], pa, l2_flags);
    }

    // map high-mem relocated exception vector to corresponding page in low MB
    // core 0: 0xffff0000 -> 0x80000
    // core 1: 0xffff0000 -> 0x81000
    // ...
    paging_map_user_pages_l1((uintptr_t)aligned_kernel_l1_table, ETABLE_ADDR,
            mem_to_local_phys((uintptr_t)aligned_low_l2_table));
    int core_id = hal_get_cpu_id();
    lpaddr_t addr = ETABLE_PHYS_BASE + core_id * BASE_PAGE_SIZE;
    paging_set_l2_entry((uintptr_t *)&aligned_low_l2_table[ARM_L2_OFFSET(ETABLE_ADDR)], addr, l2_flags);

    cp15_write_ttbr1(mem_to_local_phys((uintptr_t)aligned_kernel_l1_table));

    cp15_invalidate_tlb();
}
예제 #3
0
/**
 * \brief Reset kernel paging.
 *
 * This function resets the page maps for kernel and memory-space. It clears out
 * all other mappings. Use this only at system bootup!
 */
void paging_arm_reset(lpaddr_t paddr, size_t bytes)
{
    // make sure kernel pagetable is aligned to 16K after relocation
    aligned_kernel_l1_table = (union arm_l1_entry *)ROUND_UP(
            (uintptr_t)kernel_l1_table, ARM_L1_ALIGN);

    // Re-map physical memory
    //
    paging_map_memory((uintptr_t)aligned_kernel_l1_table , paddr, bytes);

    //map high-mem relocated exception vector to kernel section
    paging_map_kernel_section((uintptr_t)aligned_kernel_l1_table, ETABLE_ADDR,
                              PHYS_MEMORY_START);

    cp15_write_ttbr1(mem_to_local_phys((uintptr_t)aligned_kernel_l1_table));
    cp15_invalidate_tlb();
}
예제 #4
0
파일: init.c 프로젝트: XuNazgul/cmpe295A
/**
 * Entry point called from boot.S for bootstrap processor.
 */
void arch_init(uint32_t     board_id,
               struct atag *atag_base,
               lvaddr_t     elf_file,
               lvaddr_t     alloc_top)
{
    //
    // Assumptions:
    //
    // - MMU and caches are enabled. No lockdowns in caches or TLB.
    // - Kernel has own section starting at KERNEL_OFFSET.
    // - Kernel section includes the highmem relocated exception vector table.
    //


    struct atag * ae = NULL;

    exceptions_init();

    ae = atag_find(atag_base, ATAG_MEM);
    paging_map_memory(0, ae->u.mem.start, ae->u.mem.bytes);

    ae = atag_find(atag_base, ATAG_CMDLINE);
    if (ae != NULL)
    {
        parse_commandline(ae->u.cmdline.cmdline, cmdargs);
        tick_hz = CONSTRAIN(tick_hz, 10, 1000);
    }

    if (board_id == hal_get_board_id())
    {
        errval_t errval;

        serial_console_init(true);

        // do not remove/change this printf: needed by regression harness
        printf("Barrelfish CPU driver starting on ARMv5 Board id 0x%08"PRIx32"\n",
               board_id);
        printf("The address of paging_map_kernel_section is %p\n", 
               paging_map_kernel_section);
        errval = serial_debug_init();
        if (err_is_fail(errval))
        {
            printf("Failed to initialize debug port: %d", serial_debug_port);
        }

        debug(SUBSYS_STARTUP, "alloc_top %08"PRIxLVADDR" %08"PRIxLVADDR"\n",
               alloc_top, alloc_top - KERNEL_OFFSET);
        debug(SUBSYS_STARTUP, "elf_file %08"PRIxLVADDR"\n", elf_file);

        my_core_id = hal_get_cpu_id();
        extern struct kcb bspkcb;
        memset(&bspkcb, 0, sizeof(bspkcb));
        kcb_current = &bspkcb;
        
        pic_init();
        pit_init(tick_hz);
        tsc_init();

        ae = atag_find(atag_base, ATAG_MEM);
                
        // Add unused physical memory to memory map

        phys_mmap_t phys_mmap;

        // Kernel effectively consumes [0...alloc_top]
        // Add region above alloc_top with care to skip exception vector
        // page.
        if (alloc_top < ETABLE_ADDR) {
            phys_mmap_add(&phys_mmap,
                          alloc_top - KERNEL_OFFSET,
                          ETABLE_ADDR - KERNEL_OFFSET);
        }

        phys_mmap_add(&phys_mmap,
                      ETABLE_ADDR - KERNEL_OFFSET + BASE_PAGE_SIZE,
                      ae->u.mem.start + ae->u.mem.bytes);

        ae = atag_find(atag_base, ATAG_VIDEOLFB);
        if (NULL != ae)
        {
            // Remove frame buffer (if present).
            phys_mmap_remove(&phys_mmap,
                             ae->u.videolfb.lfb_base,
                             ae->u.videolfb.lfb_base + ae->u.videolfb.lfb_size);
            assert(!"Not supported");
        }

        ae = atag_find(atag_base, ATAG_INITRD2);
        if (NULL != ae)
        {
            phys_mmap_remove(&phys_mmap,
                             ae->u.initrd2.start,
                             ae->u.initrd2.start + ae->u.initrd2.bytes);

            arm_kernel_startup(&phys_mmap,
                               ae->u.initrd2.start,
                               ae->u.initrd2.bytes);
        }
        else {
            panic("initrd not found\n");
        }
    }
    else {
        panic("Mis-matched board id: [current %"PRIu32", kernel %"PRIu32"]",
              board_id, hal_get_board_id());
    }
}