forked from xuos/xiuos
TODO: Port ok1028a-c.
This commit is contained in:
@@ -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,110 @@
|
||||
/*
|
||||
* 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 "mmu.h"
|
||||
|
||||
#include "mmio_access.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
extern uint64_t kernel_data_end[];
|
||||
extern uint64_t kernel_data_begin[];
|
||||
|
||||
#define NR_PDE_ENTRIES 512
|
||||
#define L1_TYPE_SEC (2 << 0)
|
||||
#define L1_SECT_DEV ((0B00)<<2) //Device memory
|
||||
#define L1_SECT_AP0 (1 << 6) //Data Access Permissions
|
||||
uint64_t boot_ptable[NR_PTE_ENTRIES] __attribute__((aligned(0x4000))) = { 0 };
|
||||
|
||||
static void build_boot_pgdir()
|
||||
{
|
||||
// dev mem
|
||||
uint64_t dev_mem_end_idx = (DEV_PHYMEM_BASE + DEV_MEM_SZ) >> LEVEL3_PDE_SHIFT;
|
||||
for (uint64_t i = DEV_PHYMEM_BASE >> LEVEL3_PDE_SHIFT; i < dev_mem_end_idx; i++) {
|
||||
boot_pgdir[i] = (i << LEVEL3_PDE_SHIFT) | L1_TYPE_SEC | L1_SECT_DEV | L1_SECT_AP0;
|
||||
boot_pgdir[MMIO_P2V_WO(i << LEVEL3_PDE_SHIFT) >> LEVEL3_PDE_SHIFT] = (i << LEVEL3_PDE_SHIFT) | L1_TYPE_SEC | L1_SECT_DEV | L1_SECT_AP0;
|
||||
}
|
||||
|
||||
// identical mem
|
||||
uint64_t idn_mem_start_idx = PHY_MEM_BASE >> LEVEL3_PDE_SHIFT;
|
||||
uint64_t idn_mem_end_idx = PHY_MEM_STOP >> LEVEL3_PDE_SHIFT;
|
||||
for (uint64_t i = idn_mem_start_idx; i < idn_mem_end_idx; i++) {
|
||||
boot_pgdir[i] = i << LEVEL3_PDE_SHIFT | L1_TYPE_SEC | L1_SECT_AP0;
|
||||
}
|
||||
|
||||
// kern mem
|
||||
uint64_t kern_mem_start_idx = KERN_MEM_BASE >> LEVEL3_PDE_SHIFT;
|
||||
uint64_t kern_mem_end_idx = (KERN_MEM_BASE + (PHY_MEM_STOP - PHY_MEM_BASE)) >> LEVEL3_PDE_SHIFT;
|
||||
for (uint64_t i = kern_mem_start_idx; i < kern_mem_end_idx; i++) {
|
||||
boot_pgdir[i] = V2P(i << LEVEL3_PDE_SHIFT) | L1_TYPE_SEC | L1_SECT_AP0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void load_boot_pgdir()
|
||||
{
|
||||
uint64_t val;
|
||||
|
||||
// DACR_W(0x55555555); // set domain access control as client
|
||||
TTBCR_W(0x0);
|
||||
TTBR0_W((uint64_t)boot_pgdir);
|
||||
|
||||
// Enable paging using read/modify/write
|
||||
SCTLR_R(val);
|
||||
val |= (1 << 0); //EL1 and EL0 stage 1 address translation enabled.
|
||||
val |= (1 << 1); //Alignment check enable
|
||||
val |= (1 << 2); // Cacheability control, for data caching.
|
||||
val |= (1 << 12); // Instruction access Cacheability control
|
||||
val |= (1 << 19); //forced to XN for the EL1&0 translation regime.
|
||||
|
||||
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, (uint64_t)kernel_data_end - (uint64_t)kernel_data_begin);
|
||||
_bss_inited = true;
|
||||
}
|
||||
|
||||
main();
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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_IPS (0 << 32)
|
||||
#define TCR_TG1_4K (0b10 << 30)
|
||||
#define TCR_SH1_INNER (0b11 << 28)
|
||||
#define TCR_ORGN1_IRGN1_WRITEBACK_WRITEALLOC ((0b01 << 26) | (0b01 << 24))
|
||||
#define TCR_TG0_4K (0 << 14)
|
||||
#define TCR_SH0_INNER (0b11 << 12)
|
||||
#define TCR_ORGN0_IRGN0_WRITEBACK_WRITEALLOC ((0b01 << 10) | (0b01 << 8))
|
||||
#define TCR_VALUE \
|
||||
(TCR_IPS | \
|
||||
TCR_TG1_4K | TCR_SH1_INNER | TCR_ORGN1_IRGN1_WRITEBACK_WRITEALLOC | \
|
||||
TCR_TG0_4K | TCR_SH0_INNER | TCR_ORGN0_IRGN0_WRITEBACK_WRITEALLOC)
|
||||
|
||||
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))
|
||||
|
||||
/*
|
||||
TTBCR is used for choosing TTBR0 and TTBR1 as page table register.
|
||||
When TTBCR is set to 0, TTBR0 is selected by default.
|
||||
*/
|
||||
#define TTBCR_R(val) __asm__ volatile("mrs %0, ttbcr_el1" : "=r"(val))
|
||||
#define TTBCR_W(val) __asm__ volatile("msr ttbcr_el1, %0" :: "r"(val))
|
||||
|
||||
/*
|
||||
DACR registers are used to control memory privilage.
|
||||
The domain value is usually 0x01. The memory privilage will be controled by pte AP/APX
|
||||
*/
|
||||
//#define DACR_R(val) __asm__ volatile("mrs %0, dacr_el1" : "=r"(val))
|
||||
//#define DACR_W(val) __asm__ volatile("msr dacr_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))
|
||||
|
||||
|
||||
/* virtual and physical addr translate */
|
||||
#define V2P(a) ((uint64_t)((uint64_t)(a)-KERN_OFFSET))
|
||||
#define P2V(a) ((void*)((void*)(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 V2P, but without casts
|
||||
|
||||
#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,110 @@
|
||||
/*
|
||||
* 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_critical(uintptr_t pgdir_paddr, struct TraceTag* intr_driver_tag)
|
||||
{
|
||||
|
||||
/* 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);
|
||||
|
||||
/* get intr driver */
|
||||
struct XiziTrapDriver* p_intr_driver = AchieveResource(intr_driver_tag);
|
||||
|
||||
p_intr_driver->cpu_irq_disable();
|
||||
TTBR0_W((uint64_t)pgdir_paddr);
|
||||
CLEARTLB(0);
|
||||
p_icache_done->invalidateall();
|
||||
p_dcache_done->flushall();
|
||||
p_intr_driver->cpu_irq_enable();
|
||||
}
|
||||
|
||||
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,
|
||||
|
||||
.LoadPgdirCrit = load_pgdir_critical,
|
||||
.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,112 @@
|
||||
/*
|
||||
* 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 (0x00000000)
|
||||
#define PHY_USER_FREEMEM_BASE (0x30000000)
|
||||
#define PHY_USER_FREEMEM_TOP (0x80000000)
|
||||
#define PHY_MEM_STOP (0x80000000)
|
||||
|
||||
|
||||
/* 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_PTE_SHIFT 30
|
||||
|
||||
#define LEVEL1_PTE_SHIFT 39
|
||||
|
||||
#define NUM_LEVEL3_PDE (1 << (ARCH_BIT - LEVEL3_PDE_SHIFT)) // how many PTE 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_LEVEL3_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 (0x0000000000000000)
|
||||
#define DEV_VRTMEM_BASE (0x0000ffffffffffff)
|
||||
#define DEV_MEM_SZ (0x10000000)
|
||||
|
||||
/* User memory layout */
|
||||
#define USER_STACK_SIZE PAGE_SIZE
|
||||
#define USER_MEM_BASE (0x0000000000000000)
|
||||
#define USER_MEM_TOP DEV_VRTMEM_BASE
|
||||
#define USER_IPC_SPACE_BASE (0x7000000000000000)
|
||||
#define USER_IPC_SPACE_TOP (USER_MEM_TOP - USER_STACK_SIZE)
|
||||
|
||||
/* Kernel memory layout */
|
||||
#define KERN_MEM_BASE (0xffff000000000000) // First kernel virtual address
|
||||
#define KERN_OFFSET (KERN_MEM_BASE - PHY_MEM_BASE)
|
||||
|
||||
#define V2P(a) (((uint64)(a)) - KERN_MEM_BASE)
|
||||
#define P2V(a) ((void *)(((char *)(a)) + KERN_MEM_BASE))
|
||||
|
||||
#define V2P_WO(x) ((x) - KERN_MEM_BASE) // same as V2P, but without casts
|
||||
#define P2V_WO(x) ((x) + KERN_MEM_BASE) // same as P2V, but without casts
|
||||
|
||||
// one beyond the highest possible virtual address.
|
||||
#define MAXVA (KERN_MEM_BASE + (1ULL<<38))
|
||||
|
||||
// qemu puts UART registers here in physical memory.
|
||||
#define UART0 (KERN_MEM_BASE + 0x09000000L)
|
||||
#define UART0_IRQ 33
|
||||
|
||||
// virtio mmio interface
|
||||
#define VIRTIO0 (KERN_MEM_BASE + 0x0a000000L)
|
||||
#define VIRTIO0_IRQ 48
|
||||
|
||||
#define TIMER0_IRQ 27
|
||||
|
||||
// interrupt controller GICv3
|
||||
#define GICV3 (KERN_MEM_BASE + 0x08000000L)
|
||||
#define GICV3_REDIST (KERN_MEM_BASE + 0x080a0000L)
|
||||
|
||||
// map kernel stacks beneath the trampoline,
|
||||
// each surrounded by invalid guard pages.
|
||||
#define PGSIZE 4096 // bytes per page
|
||||
#define KSTACK(p) (MAXVA - ((p)+1) * 2*PGSIZE)
|
||||
|
||||
|
||||
// extract the three 9-bit page table indices from a virtual address.
|
||||
#define PXMASK 0x1FF // 9 bits
|
||||
#define PXSHIFT(level) (39-(level)*9)
|
||||
#define PX(level, va) ((((uint64)(va)) >> PXSHIFT(level)) & PXMASK)
|
||||
|
||||
// clang-format on
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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 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;
|
||||
}
|
||||
Reference in New Issue
Block a user