lvaddr_t paging_map_device(lpaddr_t device_base, size_t device_bytes) { // HACK to put device in high memory. // Should likely track these allocations. static lvaddr_t dev_alloc = DEVICE_OFFSET; assert(device_bytes <= BYTES_PER_SECTION); dev_alloc -= BYTES_PER_SECTION; paging_map_device_section((uintptr_t)aligned_kernel_l1_table, dev_alloc, device_base); return dev_alloc; }
/** * \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)aligned_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); //map section containing sysflag registers 1:1 paging_map_device_section((uintptr_t)aligned_kernel_l1_table, sysflagset_base, sysflagset_base); cp15_write_ttbr1(mem_to_local_phys((uintptr_t)aligned_kernel_l1_table)); cp15_invalidate_tlb(); }
lvaddr_t paging_map_device(lpaddr_t device_base, size_t device_bytes) { // HACK to put device in high memory. // Should likely track these allocations. static lvaddr_t dev_alloc = DEVICE_OFFSET; assert(device_bytes <= BYTES_PER_SECTION); dev_alloc -= BYTES_PER_SECTION; printf("paging_map_device_section: 0x%"PRIxLVADDR", 0x%"PRIxLVADDR", " "0x%"PRIxLPADDR".\n", (uintptr_t)aligned_kernel_l1_table, dev_alloc, device_base); paging_map_device_section((uintptr_t)aligned_kernel_l1_table, dev_alloc, device_base); cp15_write_ttbr1(mem_to_local_phys((uintptr_t)aligned_kernel_l1_table)); cp15_invalidate_i_and_d_caches_fast(); cp15_invalidate_tlb(); return dev_alloc; }