static void init_page_tables(void) { lpaddr_t (*alloc_phys_aligned)(size_t size, size_t align); if (cpu_is_bsp()) { alloc_phys_aligned = bsp_alloc_phys_aligned; } else { alloc_phys_aligned = app_alloc_phys_aligned; } // Create page table for init const size_t l0_size = VMSAv8_64_PTABLE_NUM_ENTRIES * INIT_L0_SIZE * sizeof(union armv8_ttable_entry); init_l0 = (void *) local_phys_to_mem(alloc_phys_aligned(l0_size, VMSAv8_64_PTABLE_SIZE)); memset(init_l0, 0, l0_size); const size_t l1_size = l0_size * INIT_L1_SIZE; init_l1 = (void *) local_phys_to_mem(alloc_phys_aligned(l1_size, VMSAv8_64_PTABLE_SIZE)); memset(init_l1, 0, l1_size); const size_t l2_size = l1_size * INIT_L2_SIZE; init_l2 = (void *) local_phys_to_mem(alloc_phys_aligned(l2_size, VMSAv8_64_PTABLE_SIZE)); memset(init_l2, 0, l2_size); const size_t l3_size = l2_size * INIT_L3_SIZE; init_l3 = (void *) local_phys_to_mem(alloc_phys_aligned(l3_size, VMSAv8_64_PTABLE_SIZE)); memset(init_l3, 0, l3_size); /* Map pagetables into page CN */ int pagecn_pagemap = 0; /* * AARCH64 has: * * L0 has 1 entry. * L1 has 1 entry. * L2 Coarse has 16 entries (512 * 8B = 4KB). * L3 Coarse has 16*512 entries (512 * 8B = 4KB). * */ printk(LOG_NOTE, "init page tables: l0=%p, l1=%p, l2=%p, l3=%p\n", init_l0, init_l1, init_l2, init_l3); caps_create_new( ObjType_VNode_AARCH64_l0, mem_to_local_phys((lvaddr_t)init_l0), vnode_objsize(ObjType_VNode_AARCH64_l0), 0, my_core_id, caps_locate_slot(CNODE(spawn_state.pagecn), pagecn_pagemap++) ); for (size_t i = 0; i < INIT_L1_SIZE; i++) { size_t objsize_vnode = vnode_objsize(ObjType_VNode_AARCH64_l1); assert(objsize_vnode == BASE_PAGE_SIZE); caps_create_new( ObjType_VNode_AARCH64_l1, mem_to_local_phys((lvaddr_t)init_l1) + (i * objsize_vnode), objsize_vnode, 0, my_core_id, caps_locate_slot(CNODE(spawn_state.pagecn), pagecn_pagemap++) ); } //STARTUP_PROGRESS(); for(size_t i = 0; i < INIT_L2_SIZE; i++) { size_t objsize_vnode = vnode_objsize(ObjType_VNode_AARCH64_l2); assert(objsize_vnode == BASE_PAGE_SIZE); caps_create_new( ObjType_VNode_AARCH64_l2, mem_to_local_phys((lvaddr_t)init_l2) + (i * objsize_vnode), objsize_vnode, 0, my_core_id, caps_locate_slot(CNODE(spawn_state.pagecn), pagecn_pagemap++) ); } // Map L3 into successive slots in pagecn for(size_t i = 0; i < INIT_L3_SIZE; i++) { size_t objsize_vnode = vnode_objsize(ObjType_VNode_AARCH64_l3); assert(objsize_vnode == BASE_PAGE_SIZE); caps_create_new( ObjType_VNode_AARCH64_l3, mem_to_local_phys((lvaddr_t)init_l3) + (i * objsize_vnode), objsize_vnode, 0, my_core_id, caps_locate_slot(CNODE(spawn_state.pagecn), pagecn_pagemap++) ); } /* * Initialize init page tables - this just wires the L0 * entries through to the corresponding L1 entries. */ for(lvaddr_t vaddr = ARMV8_INIT_VBASE; vaddr < ARMV8_INIT_SPACE_LIMIT; vaddr += VMSAv8_64_L0_SIZE) { uintptr_t section = (vaddr - ARMV8_INIT_VBASE) / VMSAv8_64_L0_SIZE; uintptr_t l1_off = section * VMSAv8_64_PTABLE_SIZE; lpaddr_t paddr = mem_to_local_phys((lvaddr_t)init_l1) + l1_off; paging_map_table_l0(init_l0, vaddr, paddr); } /* * Initialize init page tables - this just wires the L1 * entries through to the corresponding L2 entries. */ for(lvaddr_t vaddr = ARMV8_INIT_VBASE; vaddr < ARMV8_INIT_SPACE_LIMIT; vaddr += VMSAv8_64_L1_BLOCK_SIZE) { uintptr_t section = (vaddr - ARMV8_INIT_VBASE) / VMSAv8_64_L1_BLOCK_SIZE; uintptr_t l2_off = section * VMSAv8_64_PTABLE_SIZE; lpaddr_t paddr = mem_to_local_phys((lvaddr_t)init_l2) + l2_off; paging_map_table_l1(init_l1, vaddr, paddr); } /* * Initialize init page tables - this just wires the L2 * entries through to the corresponding L3 entries. */ STATIC_ASSERT(0 == (ARMV8_INIT_VBASE % VMSAv8_64_L2_BLOCK_SIZE), ""); for(lvaddr_t vaddr = ARMV8_INIT_VBASE; vaddr < ARMV8_INIT_SPACE_LIMIT; vaddr += VMSAv8_64_L2_BLOCK_SIZE) { uintptr_t section = (vaddr - ARMV8_INIT_VBASE) / VMSAv8_64_L2_BLOCK_SIZE; uintptr_t l3_off = section * VMSAv8_64_PTABLE_SIZE; lpaddr_t paddr = mem_to_local_phys((lvaddr_t)init_l3) + l3_off; paging_map_table_l2(init_l2, vaddr, paddr); } }
static lvaddr_t alloc_mem_aligned(size_t bytes, size_t align) { return local_phys_to_mem(alloc_phys_aligned(bytes, align)); }
static lvaddr_t alloc_mem(size_t bytes) { return local_phys_to_mem(alloc_phys_aligned(bytes, BASE_PAGE_SIZE)); }
static lpaddr_t alloc_phys(size_t bytes) { return alloc_phys_aligned(bytes, BASE_PAGE_SIZE); }