mirror of
https://github.com/seL4/seL4.git
synced 2026-03-27 10:29:57 +00:00
RISC-V: reserve memory for SBI in device tree
Instead of special handling for the SBI region in the kernel, which can be platform specific, treat it as a reserved memory region in the device tree which is sufficient to prevent the kernel from turning the reserved region into kernel untyped caps. Signed-off-by: Kent McLeod <kent@kry10.com>
This commit is contained in:
committed by
Gerwin Klein
parent
6e7e37af06
commit
b657e50b66
@@ -31,7 +31,7 @@
|
||||
|
||||
/* The first physical address to map into the kernel's physical memory
|
||||
* window */
|
||||
#define PADDR_BASE physBase()
|
||||
#define PADDR_BASE ROUND_DOWN(physBase(),22)
|
||||
|
||||
/* The base address in virtual memory to use for the 1:1 physical memory
|
||||
* mapping */
|
||||
@@ -48,15 +48,16 @@
|
||||
|
||||
/* The physical memory address to use for mapping the kernel ELF
|
||||
*
|
||||
* This represents the physical address that the kernel image will be linked to. This needs to
|
||||
* be on a 1gb boundary as we currently require being able to creating a mapping to this address
|
||||
* as the largest frame size */
|
||||
#define KERNEL_ELF_PADDR_BASE UL_CONST(0x84000000)
|
||||
* This represents the physical address that the kernel image will be linked to.
|
||||
* physBase can be any value, but needs to be low enough within a single large page
|
||||
* so that the kernel image doesn't cross a 2^22 mapping boundary.
|
||||
*/
|
||||
#define KERNEL_ELF_PADDR_BASE physBase()
|
||||
/* For use by the linker (only integer constants allowed) */
|
||||
#define KERNEL_ELF_PADDR_BASE_RAW KERNEL_ELF_PADDR_BASE
|
||||
#define KERNEL_ELF_PADDR_BASE_RAW PHYS_BASE_RAW
|
||||
|
||||
/* The base address in virtual memory to use for the kernel ELF mapping */
|
||||
#define KERNEL_ELF_BASE UL_CONST(0xFF800000)
|
||||
#define KERNEL_ELF_BASE (UL_CONST(0xFF800000) + (KERNEL_ELF_PADDR_BASE_RAW & MASK(22)))
|
||||
/* For use by the linker (only integer constants allowed) */
|
||||
#define KERNEL_ELF_BASE_RAW KERNEL_ELF_BASE
|
||||
|
||||
|
||||
@@ -89,12 +89,10 @@
|
||||
#define PPTR_TOP UL_CONST(0xFFFFFFFF80000000)
|
||||
|
||||
/* The physical memory address to use for mapping the kernel ELF */
|
||||
/* This represents the physical address that the kernel image will be linked to. This needs to
|
||||
* be on a 1gb boundary as we currently require being able to creating a mapping to this address
|
||||
* as the largest frame size */
|
||||
#define KERNEL_ELF_PADDR_BASE (physBase() + UL_CONST(0x4000000))
|
||||
/* This represents the physical address that the kernel image will be linked to. */
|
||||
#define KERNEL_ELF_PADDR_BASE physBase()
|
||||
/* For use by the linker (only integer constants allowed) */
|
||||
#define KERNEL_ELF_PADDR_BASE_RAW (PHYS_BASE_RAW + UL_CONST(0x4000000))
|
||||
#define KERNEL_ELF_PADDR_BASE_RAW PHYS_BASE_RAW
|
||||
|
||||
/* The base address in virtual memory to use for the kernel ELF mapping */
|
||||
#define KERNEL_ELF_BASE (PPTR_TOP + (KERNEL_ELF_PADDR_BASE & MASK(30)))
|
||||
|
||||
@@ -108,6 +108,8 @@ BOOT_CODE VISIBLE void map_kernel_window(void)
|
||||
/* mapping of KERNEL_ELF_BASE (virtual address) to kernel's
|
||||
* KERNEL_ELF_PHYS_BASE */
|
||||
assert(CONFIG_PT_LEVELS > 1 && CONFIG_PT_LEVELS <= 4);
|
||||
/* Kernel image finishes before KDEV_BASE */
|
||||
assert(KDEV_BASE >= (word_t)ki_end);
|
||||
|
||||
/* kernel window starts at PPTR_BASE */
|
||||
word_t pptr = PPTR_BASE;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
|
||||
* Copyright 2021, HENSOLDT Cyber
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
@@ -22,4 +23,20 @@
|
||||
reg = <0x00000000 0x2000000 0x00000000 0x0000c0000>;
|
||||
};
|
||||
};
|
||||
|
||||
/* Reserve 2 MiB for SBI at the start of RAM (0x80000000 - 0x80200000). This
|
||||
* is exactly one "megapage" in the MMU table. It leaves plenty of space for
|
||||
* further SBI experimenting, given the known usage (as of June 2021) is:
|
||||
* - BBL: 76 KiB (= 0x13000)
|
||||
* - OpenSBI: 128 KiB (= 0x20000) with PMP protection
|
||||
*/
|
||||
reserved-memory {
|
||||
#address-cells = <0x01>;
|
||||
#size-cells = <0x01>;
|
||||
ranges;
|
||||
sbi@80000000 {
|
||||
reg = <0x80000000 0x200000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -21,4 +21,19 @@
|
||||
reg = <0x00000000 0x2000000 0x00000000 0x0000c0000>;
|
||||
};
|
||||
};
|
||||
/* Reserve 2 MiB for SBI at the start of RAM (0x80000000 - 0x80200000). This
|
||||
* is exactly one "megapage" in the MMU table. It leaves plenty of space for
|
||||
* further SBI experimenting, given the known usage (as of June 2021) is:
|
||||
* - BBL: 76 KiB (= 0x13000)
|
||||
* - OpenSBI: 128 KiB (= 0x20000) with PMP protection
|
||||
*/
|
||||
reserved-memory {
|
||||
#address-cells = <0x01>;
|
||||
#size-cells = <0x01>;
|
||||
ranges;
|
||||
sbi@80000000 {
|
||||
reg = <0x80000000 0x200000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
|
||||
* Copyright 2021, HENSOLDT Cyber
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
@@ -21,4 +22,22 @@
|
||||
reg = <0x00000000 0x2000000 0x00000000 0x000010000>;
|
||||
};
|
||||
};
|
||||
|
||||
reserved-memory {
|
||||
#address-cells = <0x01>;
|
||||
#size-cells = <0x01>;
|
||||
ranges;
|
||||
|
||||
/* Reserve 2 MiB for SBI at the start of RAM (0x80000000 - 0x80200000).
|
||||
* This is exactly one "megapage" in the MMU table. It leaves plenty of
|
||||
* space for further SBI experimenting, given the known usage (as of
|
||||
* June 2021) is:
|
||||
* - BBL: 76 KiB (= 0x13000)
|
||||
* - OpenSBI: 128 KiB (= 0x20000) with PMP protection
|
||||
*/
|
||||
sbi@80000000 {
|
||||
reg = <0x80000000 0x200000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2020, DornerWorks
|
||||
* Copyright 2021, HENSOLDT Cyber
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
@@ -21,4 +22,20 @@
|
||||
reg = <0x00000000 0x2000000 0x00000000 0x000010000>;
|
||||
};
|
||||
};
|
||||
|
||||
/* Reserve 2 MiB for SBI at the start of RAM (0x80000000 - 0x80200000). This
|
||||
* is exactly one "megapage" in the MMU table. It leaves plenty of space for
|
||||
* further SBI experimenting, given the known usage (as of June 2021) is:
|
||||
* - BBL: 76 KiB (= 0x13000)
|
||||
* - OpenSBI: 128 KiB (= 0x20000) with PMP protection
|
||||
*/
|
||||
reserved-memory {
|
||||
#address-cells = <0x01>;
|
||||
#size-cells = <0x01>;
|
||||
ranges;
|
||||
sbi@80000000 {
|
||||
reg = <0x80000000 0x200000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -26,4 +26,26 @@
|
||||
reg = <0x00000000 0x2000000 0x00000000 0x000010000>;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* See https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c for the
|
||||
* QEMU/virt memory map. There are these areas:
|
||||
* - Boot-ROM at 0x1000, len 0xf000
|
||||
* - DRAM at 0x80000000 - end (2 GiB)
|
||||
*
|
||||
* Reserve 2 MiB for SBI at the start of RAM (0x80000000 - 0x80200000). This
|
||||
* is exactly one "megapage" in the MMU table. It leaves plenty of space for
|
||||
* further SBI experimenting, given the known usage (as of June 2021) is:
|
||||
* - BBL: 76 KiB (= 0x13000)
|
||||
* - OpenSBI: 128 KiB (= 0x20000) with PMP protection
|
||||
*/
|
||||
reserved-memory {
|
||||
#address-cells = <0x01>;
|
||||
#size-cells = <0x01>;
|
||||
ranges;
|
||||
sbi@80000000 {
|
||||
reg = <0x80000000 0x200000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -18,4 +18,21 @@
|
||||
reg = <0x2000000 0x10000>;
|
||||
};
|
||||
};
|
||||
|
||||
/* Reserve 2 MiB for SBI at the start of RAM (0x80000000 - 0x80200000). This
|
||||
* is exactly one "megapage" in the MMU table. It leaves plenty of space for
|
||||
* further SBI experimenting, given the known usage (as of June 2021) is:
|
||||
* - BBL: 76 KiB (= 0x13000)
|
||||
* - OpenSBI: 128 KiB (= 0x20000) with PMP protection
|
||||
*/
|
||||
reserved-memory {
|
||||
#address-cells = <0x01>;
|
||||
#size-cells = <0x01>;
|
||||
ranges;
|
||||
sbi@80000000 {
|
||||
reg = <0x80000000 0x200000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -19,6 +19,22 @@
|
||||
};
|
||||
};
|
||||
|
||||
/* Reserve 2 MiB for SBI at the start of RAM (0x80000000 - 0x80200000). This
|
||||
* is exactly one "megapage" in the MMU table. It leaves plenty of space for
|
||||
* further SBI experimenting, given the known usage (as of June 2021) is:
|
||||
* - BBL: 76 KiB (= 0x13000)
|
||||
* - OpenSBI: 128 KiB (= 0x20000) with PMP protection
|
||||
*/
|
||||
reserved-memory {
|
||||
#address-cells = <0x01>;
|
||||
#size-cells = <0x01>;
|
||||
ranges;
|
||||
sbi@40000000 {
|
||||
reg = <0x40000000 0x200000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
|
||||
/delete-node/ memory@80000000;
|
||||
|
||||
L6: memory@40000000 {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2023, UNSW
|
||||
* Copyright 2021, HENSOLDT Cyber
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
@@ -23,4 +24,26 @@
|
||||
reg = <0x00000000 0x2000000 0x00000000 0x0000c0000>;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* See https://github.com/qemu/qemu/blob/master/hw/riscv/spike.c for the
|
||||
* QEMU/Spike memory map. There are these areas:
|
||||
* - Boot-ROM at 0x1000, len 0xf000
|
||||
* - DRAM at 0x80000000 - end (2 GiB)
|
||||
*
|
||||
* Reserve 2 MiB for SBI at the start of RAM (0x80000000 - 0x80200000). This
|
||||
* is exactly one "megapage" in the MMU table. It leaves plenty of space for
|
||||
* further SBI experimenting, given the known usage (as of June 2021) is:
|
||||
* - BBL: 76 KiB (= 0x13000)
|
||||
* - OpenSBI: 128 KiB (= 0x20000) with PMP protection
|
||||
*/
|
||||
reserved-memory {
|
||||
#address-cells = <0x01>;
|
||||
#size-cells = <0x01>;
|
||||
ranges;
|
||||
sbi@80000000 {
|
||||
reg = <0x80000000 0x200000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -21,4 +21,19 @@
|
||||
reg = <0x00000000 0x2000000 0x00000000 0x000010000>;
|
||||
};
|
||||
};
|
||||
/* Reserve 2 MiB for SBI at the start of RAM (0x40000000 - 0x40200000). This
|
||||
* is exactly one "megapage" in the MMU table. It leaves plenty of space for
|
||||
* further SBI experimenting, given the known usage (as of June 2021) is:
|
||||
* - BBL: 76 KiB (= 0x13000)
|
||||
* - OpenSBI: 128 KiB (= 0x20000) with PMP protection
|
||||
*/
|
||||
reserved-memory {
|
||||
#address-cells = <0x01>;
|
||||
#size-cells = <0x01>;
|
||||
ranges;
|
||||
sbi@40000000 {
|
||||
reg = <0x40000000 0x200000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -19,11 +19,6 @@ class Config:
|
||||
''' Used to align the base of physical memory. Returns alignment size in bits. '''
|
||||
return 0
|
||||
|
||||
def get_bootloader_reserve(self) -> int:
|
||||
''' Used to reserve a fixed amount of memory for the bootloader. Offsets
|
||||
the kernel load address by the amount returned in bytes. '''
|
||||
return 0
|
||||
|
||||
def get_page_bits(self) -> int:
|
||||
''' Get page size in bits for this arch '''
|
||||
return 12 # 4096-byte pages
|
||||
@@ -35,15 +30,6 @@ class Config:
|
||||
''' Get page size in bits for mapping devices for this arch '''
|
||||
return self.get_page_bits()
|
||||
|
||||
def align_memory(self, regions: Set[Region]) -> List[Region]:
|
||||
''' Given a set of regions, sort them and align the first so that the
|
||||
ELF loader will be able to load the kernel into it. Will return the
|
||||
aligned memory region list, a set of any regions of memory that were
|
||||
aligned out and the physBase value that the kernel will use. memory
|
||||
region list, a set of any regions of memory that were aligned out and
|
||||
the physBase value that the kernel will use. '''
|
||||
pass
|
||||
|
||||
|
||||
class ARMConfig(Config):
|
||||
''' Config class for ARM '''
|
||||
@@ -57,20 +43,6 @@ class ARMConfig(Config):
|
||||
''' On AArch32 the kernel requires at least super section alignment for physBase. '''
|
||||
return self.SUPERSECTION_BITS
|
||||
|
||||
def align_memory(self, regions: Set[Region]) -> List[Region]:
|
||||
''' Arm wants physBase to be the physical load address of the kernel. '''
|
||||
ret = sorted(regions)
|
||||
extra_reserved = set()
|
||||
|
||||
new = ret[0].align_base(self.get_kernel_phys_align())
|
||||
resv = Region(ret[0].base, new.base - ret[0].base)
|
||||
extra_reserved.add(resv)
|
||||
ret[0] = new
|
||||
|
||||
physBase = ret[0].base
|
||||
|
||||
return ret, extra_reserved, physBase
|
||||
|
||||
|
||||
class RISCVConfig(Config):
|
||||
''' Config class for RISCV '''
|
||||
@@ -79,28 +51,6 @@ class RISCVConfig(Config):
|
||||
MEGAPAGE_BITS_RV64 = 21 # 2^21 = 2 MiByte
|
||||
MEGA_PAGE_SIZE_RV64 = 2**MEGAPAGE_BITS_RV64
|
||||
|
||||
def get_bootloader_reserve(self) -> int:
|
||||
''' OpenSBI reserved the first 2 MiByte of physical memory on rv64,
|
||||
which is exactly a megapage. For rv32 we use the same value for now, as
|
||||
this seems to work nicely - even if this is just half of the 4 MiByte
|
||||
magepages that exist there. '''
|
||||
return self.MEGA_PAGE_SIZE_RV64
|
||||
|
||||
def align_memory(self, regions: Set[Region]) -> List[Region]:
|
||||
''' Currently the RISC-V port expects physBase to be the address that the
|
||||
bootloader is loaded at. To be generalised in the future. '''
|
||||
ret = sorted(regions)
|
||||
extra_reserved = set()
|
||||
|
||||
physBase = ret[0].base
|
||||
|
||||
resv = Region(ret[0].base, self.get_bootloader_reserve())
|
||||
extra_reserved.add(resv)
|
||||
ret[0].base += self.get_bootloader_reserve()
|
||||
ret[0].size -= self.get_bootloader_reserve()
|
||||
|
||||
return ret, extra_reserved, physBase
|
||||
|
||||
def get_device_page_bits(self) -> int:
|
||||
''' Get page size in bits for mapping devices for this arch '''
|
||||
if (self.sel4arch == 'riscv32'):
|
||||
|
||||
@@ -83,12 +83,31 @@ def reserve_regions(regions: Set[Region], reserved: Set[Region]) -> Set[Region]:
|
||||
return ret
|
||||
|
||||
|
||||
def align_memory(regions: Set[Region], config: Config) -> List[Region]:
|
||||
''' Given a set of regions, sort them and align the first so that the
|
||||
ELF loader will be able to load the kernel into it. Will return the
|
||||
aligned memory region list, a set of any regions of memory that were
|
||||
aligned out and the physBase value that the kernel will use. '''
|
||||
|
||||
ret = sorted(regions)
|
||||
extra_reserved = set()
|
||||
|
||||
if config.get_kernel_phys_align() != 0:
|
||||
new = ret[0].align_base(config.get_kernel_phys_align())
|
||||
resv = Region(ret[0].base, new.base - ret[0].base)
|
||||
extra_reserved.add(resv)
|
||||
ret[0] = new
|
||||
|
||||
physBase = ret[0].base
|
||||
return ret, extra_reserved, physBase
|
||||
|
||||
|
||||
def get_physical_memory(tree: FdtParser, config: Config) -> List[Region]:
|
||||
''' returns a list of regions representing physical memory as used by the kernel '''
|
||||
regions = merge_memory_regions(get_memory_regions(tree))
|
||||
reserved = parse_reserved_regions(tree.get_path('/reserved-memory'))
|
||||
regions = reserve_regions(regions, reserved)
|
||||
regions, extra_reserved, physBase = config.align_memory(regions)
|
||||
regions, extra_reserved, physBase = align_memory(regions, config)
|
||||
|
||||
return regions, reserved.union(extra_reserved), physBase
|
||||
|
||||
|
||||
Reference in New Issue
Block a user