Merge branch 'armv8' of https://gitlink.org.cn/tuyuyang/xiuos into armv8
This commit is contained in:
@@ -1,4 +1,10 @@
|
||||
ifneq ($(findstring $(BOARD), ok1028a-c), )
|
||||
SRC_DIR := armv8-a
|
||||
endif
|
||||
ifneq ($(findstring $(BOARD), imx6q-sabrelite zynq7000-zc702), )
|
||||
SRC_DIR := armv7-a
|
||||
endif
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
SRC_DIR := cortex-a72
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,3 @@
|
||||
SRC_FILES := bootmmu.c mmu.c pagetable_attr.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
/**
|
||||
* @file bootmmu.c
|
||||
* @brief build pagetable and enable mmu in boot time
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2024.04.26
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: bootmmu.c
|
||||
Description: build pagetable and enable mmu in boot time
|
||||
Others:
|
||||
History:
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. first version
|
||||
*************************************************/
|
||||
#include "core.h"
|
||||
#include "memlayout.h"
|
||||
#include "mmio_access.h"
|
||||
#include "mmu.h"
|
||||
#include "registers.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
extern uint64_t kernel_data_end[];
|
||||
extern uint64_t kernel_data_begin[];
|
||||
|
||||
#define NR_PDE_ENTRIES (1 << 9)
|
||||
|
||||
#define L2_TYPE_TAB 2
|
||||
#define L2_PTE_VALID 1
|
||||
|
||||
#define L3_TYPE_TAB 2
|
||||
#define L3_PTE_VALID 1
|
||||
|
||||
#define L4_TYPE_PAGE (3 << 0)
|
||||
#define L4_PTE_DEV ((0b00) << 2) // Device memory
|
||||
#define L4_PTE_AF (1 << 10) // Data Access Permissions
|
||||
|
||||
#define IDX_MASK (0b111111111)
|
||||
#define L3_PDE_INDEX(idx) ((idx << LEVEL3_PDE_SHIFT) & L3_IDX_MASK)
|
||||
|
||||
uint64_t boot_l2pgdir[NUM_LEVEL2_PDE] __attribute__((aligned(0x1000))) = { 0 };
|
||||
// uint64_t boot_lowspace_l2pgdir[NUM_LEVEL2_PDE] __attribute__((aligned(0x4000))) = { 0 };
|
||||
// uint64_t boot_highspace_l2pgdir[NUM_LEVEL2_PDE] __attribute__((aligned(0x4000))) = { 0 };
|
||||
|
||||
uint64_t boot_dev_l3pgdir[NUM_LEVEL3_PDE] __attribute__((aligned(0x1000))) = { 0 };
|
||||
// uint64_t boot_identical_dev_l3pgdir[NUM_LEVEL3_PDE] __attribute__((aligned(0x4000))) = { 0 };
|
||||
uint64_t boot_virt_dev_l3pgdir[NUM_LEVEL3_PDE] __attribute__((aligned(0x1000))) = { 0 };
|
||||
uint64_t boot_kern_l3pgdir[NUM_LEVEL3_PDE] __attribute__((aligned(0x1000))) = { 0 };
|
||||
// uint64_t boot_identical_kern_l3pgdir[NUM_LEVEL3_PDE] __attribute__((aligned(0x4000))) = { 0 };
|
||||
uint64_t boot_virt_kern_l3pgdir[NUM_LEVEL3_PDE] __attribute__((aligned(0x1000))) = { 0 };
|
||||
|
||||
uint64_t boot_dev_l4pgdirs[NUM_LEVEL3_PDE][NUM_LEVEL4_PTE] __attribute__((aligned(0x1000))) = { 0 };
|
||||
uint64_t boot_kern_l4pgdirs[NUM_LEVEL3_PDE][NUM_LEVEL4_PTE] __attribute__((aligned(0x1000))) = { 0 };
|
||||
// uint64_t boot_mem_l4pgdirs[NUM_LEVEL3_PDE][NUM_LEVEL4_PTE] __attribute__((aligned(0x1000))) = { 0 };
|
||||
|
||||
static void build_boot_pgdir()
|
||||
{
|
||||
uint64_t dev_phy_mem_base = DEV_PHYMEM_BASE;
|
||||
// dev mem
|
||||
boot_l2pgdir[(dev_phy_mem_base >> LEVEL2_PDE_SHIFT) & IDX_MASK] = (uint64_t)boot_dev_l3pgdir | L2_TYPE_TAB | L2_PTE_VALID;
|
||||
boot_l2pgdir[(MMIO_P2V_WO(dev_phy_mem_base) >> LEVEL2_PDE_SHIFT) & IDX_MASK] = (uint64_t)boot_dev_l3pgdir | L2_TYPE_TAB | L2_PTE_VALID;
|
||||
// boot_lowspace_l2pgdir[(dev_phy_mem_base >> LEVEL2_PDE_SHIFT) & IDX_MASK] = (uint64_t)boot_identical_dev_l3pgdir | L2_TYPE_TAB | L2_PTE_VALID;
|
||||
// boot_highspace_l2pgdir[(MMIO_P2V_WO(dev_phy_mem_base) >> LEVEL2_PDE_SHIFT) & IDX_MASK] = (uint64_t)boot_identical_dev_l3pgdir | L2_TYPE_TAB | L2_PTE_VALID;
|
||||
|
||||
uint64_t cur_mem_paddr = (uint64_t)DEV_PHYMEM_BASE & ((uint64_t)IDX_MASK << (uint64_t)LEVEL2_PDE_SHIFT);
|
||||
for (size_t i = 0; i < NUM_LEVEL3_PDE; i++) {
|
||||
boot_dev_l3pgdir[i] = (uint64_t)boot_dev_l4pgdirs[i] | L3_TYPE_TAB | L3_PTE_VALID;
|
||||
// boot_identical_dev_l3pgdir[i] = (uint64_t)boot_dev_l4pgdirs[i] | L3_TYPE_TAB | L3_PTE_VALID;
|
||||
// boot_virt_dev_l3pgdir[i] = (uint64_t)boot_dev_l4pgdirs[i] | L3_TYPE_TAB | L3_PTE_VALID;
|
||||
|
||||
for (size_t j = 0; j < NUM_LEVEL4_PTE; j++) {
|
||||
// boot_dev_l4pgdirs[i][j] = dev_phy_mem_base | L4_TYPE_PAGE | L4_PTE_DEV | L4_PTE_AF;
|
||||
boot_dev_l4pgdirs[i][j] = cur_mem_paddr | L4_TYPE_PAGE | L4_PTE_DEV | L4_PTE_AF;
|
||||
|
||||
// dev_phy_mem_base += PAGE_SIZE;
|
||||
cur_mem_paddr += PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
// identical mem
|
||||
// uint64_t phy_mem_base = PHY_MEM_BASE;
|
||||
boot_l2pgdir[(PHY_MEM_BASE >> LEVEL2_PDE_SHIFT) & IDX_MASK] = (uint64_t)boot_kern_l3pgdir | L2_TYPE_TAB | L2_PTE_VALID;
|
||||
boot_l2pgdir[(P2V_WO(PHY_MEM_BASE) >> LEVEL2_PDE_SHIFT) & IDX_MASK] = (uint64_t)boot_kern_l3pgdir | L2_TYPE_TAB | L2_PTE_VALID;
|
||||
// boot_lowspace_l2pgdir[(PHY_MEM_BASE >> LEVEL2_PDE_SHIFT) & IDX_MASK] = (uint64_t)boot_identical_kern_l3pgdir | L2_TYPE_TAB | L2_PTE_VALID;
|
||||
// boot_highspace_l2pgdir[(KERN_MEM_BASE >> LEVEL2_PDE_SHIFT) & IDX_MASK] = (uint64_t)boot_identical_kern_l3pgdir | L2_TYPE_TAB | L2_PTE_VALID;
|
||||
|
||||
cur_mem_paddr = (uint64_t)PHY_MEM_BASE & ((uint64_t)IDX_MASK << (uint64_t)LEVEL2_PDE_SHIFT);
|
||||
for (size_t i = 0; i < NUM_LEVEL3_PDE; i++) {
|
||||
boot_kern_l3pgdir[i] = (uint64_t)boot_kern_l4pgdirs[i] | L3_TYPE_TAB | L3_PTE_VALID;
|
||||
// boot_identical_kern_l3pgdir[i] = (uint64_t)boot_kern_l4pgdirs[i] | L3_TYPE_TAB | L3_PTE_VALID;
|
||||
// boot_kern_l3pgdir[i] = (uint64_t)boot_kern_l4pgdirs[i] | L3_TYPE_TAB | L3_PTE_VALID;
|
||||
// boot_virt_kern_l3pgdir[i] = (uint64_t)boot_kern_l4pgdirs[i] | L3_TYPE_TAB | L3_PTE_VALID;
|
||||
|
||||
for (size_t j = 0; j < NUM_LEVEL4_PTE; j++) {
|
||||
boot_kern_l4pgdirs[i][j] = cur_mem_paddr | L4_TYPE_PAGE | L4_PTE_AF;
|
||||
|
||||
cur_mem_paddr += PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
// dev mem
|
||||
// uint64_t dev_mem_end_pgd = PGD_INDEX(DEV_PHYMEM_BASE + DEV_MEM_SZ);
|
||||
// for (uint64_t i = PGD_INDEX(DEV_PHYMEM_BASE); i < dev_mem_end_idx; i++) {
|
||||
// boot_pgdir[i] = (uint64_t)boot_dev_l3dir[used_boot_dev_l3dir_idx] | L3_TYPE_SEC | L3_SECT_DEV | L3_SECT_AP0;
|
||||
// boot_pgdir[PGD_INDEX(MMIO_P2V_WO(PGD_INDEX_TO_PA(i)))] = (uint64_t)boot_dev_l3dir[used_boot_dev_l3dir_idx] | L3_TYPE_SEC | L3_SECT_DEV | L3_SECT_AP0;
|
||||
// used_boot_dev_l3dir_idx++;
|
||||
|
||||
// for (int64_t j = 0; j < 0b111111111; j++) {
|
||||
// boot_dev_l3dir[i][j] = (uint64_t)boot_dev_l4dir[used_boot_dev_l4dir_idx] | ();
|
||||
// // uint64_t dev_mem_end_pmd = PMD_INDEX(DEV_PHYMEM_BASE + DEV_MEM_SZ);
|
||||
// // for (uint64_t j = PMD_INDEX(DEV_PHYMEM_BASE); j < dev_mem_end_pmd; j++) {
|
||||
// // boot_pmd[j] = PGD_INDEX_TO_PA(j) | L4_TYPE_SEC | L4_SECT_DEV | L4_SECT_AP0;
|
||||
// // boot_pmd[PGD_INDEX(MMIO_P2V_WO(PGD_INDEX_TO_PA(j)))] = PGD_INDEX_TO_PA(j) | L4_TYPE_SEC | L4_SECT_DEV | L4_SECT_AP0;
|
||||
// // }
|
||||
// for (uint64_t k = 0; k < 0b111111111; k++) {
|
||||
// boot_dev_l4dir[j][k] = DEV_PHYMEM_BASE
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
static void load_boot_pgdir()
|
||||
{
|
||||
uint64_t val;
|
||||
|
||||
// TTBR0_W((uintptr_t)boot_lowspace_l2pgdir);
|
||||
// TTBR1_W((uintptr_t)boot_highspace_l2pgdir);
|
||||
TTBR0_W((uintptr_t)boot_l2pgdir);
|
||||
TTBR1_W(0);
|
||||
|
||||
TCR_W(TCR_VALUE);
|
||||
MAIR_W((MT_DEVICE_nGnRnE << (8 * AI_DEVICE_nGnRnE_IDX)) | (MT_NORMAL_NC << (8 * AI_NORMAL_NC_IDX)));
|
||||
|
||||
// Enable paging using read/modify/write
|
||||
SCTLR_R(val);
|
||||
val |= (1 << 0); // EL1 and EL0 stage 1 address translation enabled.
|
||||
|
||||
SCTLR_W(val);
|
||||
|
||||
// flush all TLB
|
||||
DSB();
|
||||
CLEARTLB(0);
|
||||
ISB();
|
||||
}
|
||||
|
||||
extern void main(void);
|
||||
static bool _bss_inited = false;
|
||||
void bootmain()
|
||||
{
|
||||
build_boot_pgdir();
|
||||
load_boot_pgdir();
|
||||
__asm__ __volatile__("add sp, sp, %0" ::"r"(KERN_MEM_BASE - PHY_MEM_BASE));
|
||||
if (!_bss_inited) {
|
||||
memset(&kernel_data_begin, 0x00, (size_t)((uint64_t)kernel_data_end - (uint64_t)kernel_data_begin));
|
||||
uintptr_t kde = (uintptr_t)kernel_data_end;
|
||||
_bss_inited = true;
|
||||
}
|
||||
main();
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file mmu.h
|
||||
* @brief mmu related configure and registers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2024-04-26
|
||||
*/
|
||||
/*************************************************
|
||||
File name: mmu.h
|
||||
Description: mmu related configure and registers
|
||||
Others:
|
||||
History:
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. first version
|
||||
*************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "memlayout.h"
|
||||
#include "page_table_entry.h"
|
||||
|
||||
// #define TCR_SH1_INNER (0b11 << 28)
|
||||
// #define TCR_ORGN1_IRGN1_WRITEBACK_WRITEALLOC ((0b01 << 26) | (0b01 << 24))
|
||||
// #define TCR_SH0_INNER (0b11 << 12)
|
||||
// #define TCR_ORGN0_IRGN0_WRITEBACK_WRITEALLOC ((0b01 << 10) | (0b01 << 8))
|
||||
#define TCR_IPS (0 << 0)
|
||||
#define TCR_TG1_4K (0b10 << 30)
|
||||
#define TCR_TOSZ (0b11001 << 0)
|
||||
#define TCR_T1SZ (0b11001 << 16)
|
||||
#define TCR_TG0_4K (0 << 14)
|
||||
|
||||
#define TCR_VALUE \
|
||||
(TCR_IPS | TCR_TG1_4K | TCR_TG0_4K | TCR_TOSZ | TCR_T1SZ)
|
||||
|
||||
enum AccessPermission {
|
||||
AccessPermission_NoAccess = 0,
|
||||
AccessPermission_KernelOnly = 1, // EL1
|
||||
AccessPermission_Reserved = 2,
|
||||
AccessPermission_KernelUser = 3, // EL1&EL0
|
||||
};
|
||||
|
||||
void GetDevPteAttr(uintptr_t* attr);
|
||||
void GetUsrPteAttr(uintptr_t* attr);
|
||||
void GetUsrDevPteAttr(uintptr_t* attr);
|
||||
void GetKernPteAttr(uintptr_t* attr);
|
||||
void GetPdeAttr(uintptr_t* attr);
|
||||
|
||||
/*
|
||||
Enable MMU, cache, write buffer, etc.
|
||||
*/
|
||||
#define SCTLR_R(val) __asm__ volatile("mrs %0, sctlr_el1" : "=r"(val))
|
||||
#define SCTLR_W(val) __asm__ volatile("msr sctlr_el1, %0" ::"r"(val))
|
||||
|
||||
/*
|
||||
Read and write mmu pagetable register base addr
|
||||
*/
|
||||
#define TTBR0_R(val) __asm__ volatile("mrs %0, ttbr0_el1" : "=r"(val))
|
||||
#define TTBR0_W(val) __asm__ volatile("msr ttbr0_el1, %0" ::"r"(val))
|
||||
|
||||
/*
|
||||
Read and write mmu pagetable register base addr
|
||||
*/
|
||||
#define TTBR1_R(val) __asm__ volatile("mrs %0, ttbr1_el1" : "=r"(val))
|
||||
#define TTBR1_W(val) __asm__ volatile("msr ttbr1_el1, %0" ::"r"(val))
|
||||
|
||||
/*
|
||||
Translation Control Register(TCR)
|
||||
*/
|
||||
#define TCR_R(val) __asm__ volatile("mrs %0, tcr_el1" : "=r"(val))
|
||||
#define TCR_W(val) __asm__ volatile("msr tcr_el1, %0" ::"r"(val))
|
||||
|
||||
#define MAIR_R(val) __asm__ volatile("mrs %0, mair_el1" : "=r"(val))
|
||||
#define MAIR_W(val) __asm__ volatile("msr mair_el1, %0" ::"r"(val))
|
||||
|
||||
/*
|
||||
Flush TLB when loading a new page table.
|
||||
@note If nG is not set in the pte attribute, process switching need flush tlb.
|
||||
*/
|
||||
#define CLEARTLB(val) __asm__ volatile("tlbi vmalle1")
|
||||
|
||||
/*
|
||||
When nG is set in the pte attribute, the process is assigned an ASID, which is stored in the lower 8 bits of the CONTEXTIDR register.
|
||||
When the process switches, the flush TLB is no longer required anymore.
|
||||
*/
|
||||
#define CONTEXTIDR_R(val) __asm__ volatile("mrs %0, contextidr_el1" : "=r"(val))
|
||||
#define CONTEXTIDR_W(val) __asm__ volatile("msr contextidr_el1, %0" ::"r"(val))
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#include <stdint.h>
|
||||
__attribute__((always_inline)) static inline uint64_t v2p(void* a) { return ((uint64_t)(a)) - KERN_MEM_BASE; }
|
||||
__attribute__((always_inline)) static inline void* p2v(uint64_t a) { return (void*)((a) + KERN_MEM_BASE); }
|
||||
#endif
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2012, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file page_table_entry.h
|
||||
* @brief mmu related configure and registers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2024-04-25
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: page_table_entry.h
|
||||
Description: mmu related configure and registers
|
||||
Others: take imx_platform_sdk sdk/core/src/mmu.c for references
|
||||
https://github.com/flit/imx6_platform_sdk
|
||||
History:
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. modify the L1-level page table name and properties name to apply hardkernel implementation
|
||||
*************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef union {
|
||||
uintptr_t entry;
|
||||
struct {
|
||||
uint64_t desc_type : 2; // (Invalid, PageTable, Section, SuperSection)/(Invalid, Table, Block)
|
||||
//uint64_t B : 1; // Bufferable
|
||||
// uint64_t C : 1; // Cacheable
|
||||
uint64_t XN : 1; // Execute-not
|
||||
//uint64_t Domain : 4; // Domain
|
||||
uint64_t _impl_defined : 1; // Implementation defined, should be zero.
|
||||
uint64_t AP1_0 : 2; // Access permissions AP
|
||||
uint64_t TEX : 3; // TEX remap ==attr_idx The memory type, Device or Normal.
|
||||
uint64_t AP2 : 1; // Access permissions AP[2]
|
||||
uint64_t S : 1; // Shareable
|
||||
uint64_t NG : 1; // Not-global
|
||||
uint64_t _zero : 1; // Should be zero.
|
||||
uint64_t NS : 1; // Non-secure
|
||||
uint64_t section_addr :36 ; // Section Physical base address
|
||||
uint64_t AF : 1; // Access flag
|
||||
};
|
||||
} __attribute__((packed)) PageDirEntry;
|
||||
|
||||
typedef union {
|
||||
uint64_t entry;
|
||||
struct {
|
||||
uint64_t desc_type : 2; // (Invalid, Reserved,4kb, 16kb 64kb )
|
||||
// uint64_t B : 1; // Bufferable
|
||||
//uint64_t C : 1; // Cacheable
|
||||
uint64_t AP1_0 : 2;//Access permissions
|
||||
uint64_t TEX : 3;//TEX remap ==attr_idx The memory type, Device or Normal.
|
||||
uint64_t AP2 : 1;
|
||||
uint64_t S : 1; // Shareable
|
||||
uint64_t NG : 1; // Not-global
|
||||
uint64_t page_addr :36 ;
|
||||
uint64_t AF : 1; // Access flag
|
||||
};
|
||||
} __attribute__((packed)) PageTblEntry;
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
/**
|
||||
* @file mmu.c
|
||||
* @brief mmu operations
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2024.04.26
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: mmu.c
|
||||
Description: mmu operations
|
||||
Others:
|
||||
History:
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. first version
|
||||
*************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mmu.h"
|
||||
|
||||
#include "cache_common_ope.h"
|
||||
#include "mmu_common.h"
|
||||
#include "trap_common.h"
|
||||
|
||||
// extern struct MmuCommonDone mmu_common_done;
|
||||
static struct MmuDriverRightGroup right_group;
|
||||
|
||||
void load_pgdir(uintptr_t pgdir_paddr)
|
||||
{
|
||||
/* get cache driver */
|
||||
struct ICacheDone* p_icache_done = AchieveResource(&right_group.icache_driver_tag);
|
||||
struct DCacheDone* p_dcache_done = AchieveResource(&right_group.dcache_driver_tag);
|
||||
|
||||
TTBR0_W((uint64_t)pgdir_paddr);
|
||||
CLEARTLB(0);
|
||||
p_icache_done->invalidateall();
|
||||
p_dcache_done->flushall();
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) inline static void _tlb_flush(uintptr_t va)
|
||||
{
|
||||
__asm__ volatile("tlbi vae1is, %0" ::"r"(va));
|
||||
}
|
||||
|
||||
static void tlb_flush_range(uintptr_t vstart, int len)
|
||||
{
|
||||
uintptr_t vaddr = vstart;
|
||||
uintptr_t vend = vaddr + len;
|
||||
for (; vaddr < vend; vaddr += PAGE_SIZE) {
|
||||
_tlb_flush(vaddr);
|
||||
}
|
||||
}
|
||||
|
||||
static void tlb_flush_all()
|
||||
{
|
||||
CLEARTLB(0);
|
||||
}
|
||||
|
||||
static struct MmuCommonDone mmu_common_done = {
|
||||
.MmuDevPteAttr = GetDevPteAttr,
|
||||
.MmuPdeAttr = GetPdeAttr,
|
||||
.MmuUsrPteAttr = GetUsrPteAttr,
|
||||
.MmuUsrDevPteAttr = GetUsrDevPteAttr,
|
||||
.MmuKernPteAttr = GetKernPteAttr,
|
||||
|
||||
.LoadPgdir = load_pgdir,
|
||||
.TlbFlushAll = tlb_flush_all,
|
||||
.TlbFlush = tlb_flush_range,
|
||||
};
|
||||
|
||||
struct MmuCommonDone* hardkernel_mmu_init(struct TraceTag* hardkernel_tag, char* icache_name, char* dcache_name)
|
||||
{
|
||||
/* init right group for mmu driver */
|
||||
AchieveResourceTag(&right_group.icache_driver_tag, hardkernel_tag, icache_name);
|
||||
AchieveResourceTag(&right_group.dcache_driver_tag, hardkernel_tag, dcache_name);
|
||||
|
||||
return &mmu_common_done;
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file memlayout.h
|
||||
* @brief virtual memory and physical memory layout
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2024-04-25
|
||||
*/
|
||||
/*************************************************
|
||||
File name: memlayout.h
|
||||
Description: virtual memory and physical memory layout
|
||||
Others:
|
||||
History:
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. first version
|
||||
*************************************************/
|
||||
#pragma once
|
||||
|
||||
// Memory layout
|
||||
// clang-format off
|
||||
|
||||
#define ARCH_BIT 64
|
||||
|
||||
/* A72 physical memory layout */
|
||||
#define PHY_MEM_BASE (0x0000000040000000ULL)
|
||||
#define PHY_USER_FREEMEM_BASE (0x0000000044000000ULL)
|
||||
#define PHY_USER_FREEMEM_TOP (0x0000000048000000ULL)
|
||||
#define PHY_MEM_STOP (0x0000000048000000ULL)
|
||||
|
||||
/* PTE-PAGE_SIZE */
|
||||
#define LEVEL4_PTE_SHIFT 12
|
||||
#define LEVEL4_PTE_SIZE (1 << LEVEL4_PTE_SHIFT)
|
||||
|
||||
/* PDE-SECTION_SIZE */
|
||||
#define LEVEL3_PDE_SHIFT 21
|
||||
#define LEVEL3_PDE_SIZE (1 << LEVEL3_PDE_SHIFT)
|
||||
|
||||
#define LEVEL2_PDE_SHIFT 30
|
||||
#define LEVEL2_PDE_SIZE (1 << LEVEL2_PDE_SHIFT)
|
||||
|
||||
#define LEVEL1_PTE_SHIFT 39
|
||||
|
||||
#define NUM_LEVEL2_PDE (1 << (LEVEL1_PTE_SHIFT - LEVEL2_PDE_SHIFT))
|
||||
#define NUM_LEVEL3_PDE (1 << (LEVEL2_PDE_SHIFT - LEVEL3_PDE_SHIFT)) // how many PDE in a PT
|
||||
#define NUM_LEVEL4_PTE (1 << (LEVEL3_PDE_SHIFT - LEVEL4_PTE_SHIFT)) // how many PTE in a PT
|
||||
#define NUM_TOPLEVEL_PDE NUM_LEVEL2_PDE
|
||||
|
||||
#define PAGE_SIZE LEVEL4_PTE_SIZE
|
||||
#define MAX_NR_FREE_PAGES ((PHY_MEM_STOP - PHY_MEM_BASE) >> LEVEL4_PTE_SHIFT)
|
||||
|
||||
/* Deivce memory layout */
|
||||
#define DEV_PHYMEM_BASE (0x0000000000000000ULL)
|
||||
#define DEV_VRTMEM_BASE (0x0000004000000000ULL)
|
||||
#define DEV_MEM_SZ (0x0000000010000000ULL)
|
||||
|
||||
/* User memory layout */
|
||||
#define USER_STACK_SIZE PAGE_SIZE
|
||||
#define USER_MEM_BASE (0x0000000000000000ULL)
|
||||
#define USER_MEM_TOP DEV_VRTMEM_BASE
|
||||
#define USER_IPC_SPACE_BASE (0x0000003000000000ULL)
|
||||
#define USER_IPC_USE_ALLOCATOR_WATERMARK (0x0000003000010000ULL)
|
||||
#define USER_IPC_SPACE_TOP (USER_MEM_TOP - USER_STACK_SIZE)
|
||||
|
||||
/* Kernel memory layout */
|
||||
#define KERN_MEM_BASE (0x0000006040000000ULL) // First kernel virtual address
|
||||
#define KERN_OFFSET (KERN_MEM_BASE - PHY_MEM_BASE)
|
||||
|
||||
#define V2P(a) (((uint64_t)(a)) - KERN_OFFSET)
|
||||
#define P2V(a) ((void *)(((char *)(a)) + KERN_OFFSET))
|
||||
|
||||
#define V2P_WO(x) ((x) - KERN_OFFSET) // same as V2P, but without casts
|
||||
#define P2V_WO(x) ((x) + KERN_OFFSET) // same as P2V, but without casts
|
||||
|
||||
#define TIMER0_IRQ 27
|
||||
|
||||
// clang-format on
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
/**
|
||||
* @file pagetable_attr.c
|
||||
* @brief mmu entry attributes
|
||||
* @version 1.
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2023.04.26
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: pagetable_attr.c
|
||||
Description: mmu entry attributes
|
||||
Others:
|
||||
History:
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. first version
|
||||
*************************************************/
|
||||
#include "mmu.h"
|
||||
#include "mmu_common.h"
|
||||
|
||||
// void GetUsrPteAttr(uintptr_t* attr)
|
||||
// {
|
||||
// static char init = 0;
|
||||
// static PageTblEntry usr_pte_attr;
|
||||
// if (init == 0) {
|
||||
// init = 1;
|
||||
|
||||
// usr_pte_attr.entry = 0;
|
||||
// usr_pte_attr.desc_type = PAGE_4K;
|
||||
// usr_pte_attr.B = 1;
|
||||
// usr_pte_attr.C = 1;
|
||||
// usr_pte_attr.S = 1;
|
||||
// usr_pte_attr.AP1_0 = AccessPermission_KernelUser;
|
||||
// }
|
||||
// *attr = usr_pte_attr.entry;
|
||||
// }
|
||||
|
||||
void GetUsrPteAttr(uintptr_t* attr)
|
||||
{
|
||||
static char init = 0;
|
||||
if (init == 0) {
|
||||
init = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void GetUsrDevPteAttr(uintptr_t* attr)
|
||||
{
|
||||
// static char init = 0;
|
||||
// static PageTblEntry usr_pte_attr;
|
||||
// if (init == 0) {
|
||||
// init = 1;
|
||||
|
||||
// usr_pte_attr.entry = 0;
|
||||
// usr_pte_attr.desc_type = PAGE_4K;
|
||||
// usr_pte_attr.AP1_0 = AccessPermission_KernelUser;
|
||||
// }
|
||||
// *attr = usr_pte_attr.entry;
|
||||
}
|
||||
|
||||
void GetDevPteAttr(uintptr_t* attr)
|
||||
{
|
||||
// static char init = 0;
|
||||
// static PageTblEntry dev_pte_attr;
|
||||
// if (init == 0) {
|
||||
// init = 1;
|
||||
|
||||
// dev_pte_attr.entry = 0;
|
||||
// dev_pte_attr.desc_type = PAGE_4K;
|
||||
// dev_pte_attr.AP1_0 = AccessPermission_KernelOnly;
|
||||
// }
|
||||
// *attr = dev_pte_attr.entry;
|
||||
}
|
||||
|
||||
void GetKernPteAttr(uintptr_t* attr)
|
||||
{
|
||||
// static char init = 0;
|
||||
// static PageTblEntry kern_pte_attr;
|
||||
// if (init == 0) {
|
||||
// init = 1;
|
||||
|
||||
// kern_pte_attr.entry = 0;
|
||||
// kern_pte_attr.desc_type = PAGE_4K;
|
||||
// kern_pte_attr.B = 1;
|
||||
// kern_pte_attr.C = 1;
|
||||
// kern_pte_attr.S = 1;
|
||||
// kern_pte_attr.AP1_0 = AccessPermission_KernelOnly;
|
||||
// }
|
||||
// *attr = kern_pte_attr.entry;
|
||||
}
|
||||
|
||||
void GetPdeAttr(uintptr_t* attr)
|
||||
{
|
||||
// *attr = PAGE_DIR_COARSE;
|
||||
}
|
||||
@@ -19,8 +19,7 @@ struct MmuDriverRightGroup {
|
||||
struct TraceTag intr_driver_tag;
|
||||
};
|
||||
|
||||
struct MmuCommonDone
|
||||
{
|
||||
struct MmuCommonDone {
|
||||
void (*MmuDevPteAttr)(uintptr_t* attr);
|
||||
void (*MmuPdeAttr)(uintptr_t* attr);
|
||||
void (*MmuUsrPteAttr)(uintptr_t* attr);
|
||||
|
||||
Reference in New Issue
Block a user