Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[patch-axel-12] rework physical address space limits #52

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
13 changes: 7 additions & 6 deletions include/arch/riscv/arch/32/mode/hardware.h
Original file line number Diff line number Diff line change
@@ -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,13 +48,14 @@

/* 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

/* 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 & MASK(22)))

/* The base address in virtual memory to use for the kernel device
* mapping region. These are mapped in the kernel page table. */
6 changes: 2 additions & 4 deletions include/arch/riscv/arch/64/mode/hardware.h
Original file line number Diff line number Diff line change
@@ -89,10 +89,8 @@
#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

/* 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)))
2 changes: 2 additions & 0 deletions src/arch/riscv/kernel/vspace.c
Original file line number Diff line number Diff line change
@@ -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;
17 changes: 17 additions & 0 deletions src/plat/ariane/overlay-ariane.dts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
* Copyright 2021, HENSOLDT Cyber
*
* SPDX-License-Identifier: GPL-2.0-only
*/
@@ -9,4 +10,20 @@
seL4,kernel-devices =
&{/soc/interrupt-controller@c000000};
};

/* 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 changes: 19 additions & 0 deletions src/plat/hifive/overlay-hifive.dts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
* Copyright 2021, HENSOLDT Cyber
*
* SPDX-License-Identifier: GPL-2.0-only
*/
@@ -9,4 +10,22 @@
seL4,kernel-devices =
&{/soc/interrupt-controller@c000000};
};

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;
};
};
};
19 changes: 18 additions & 1 deletion src/plat/polarfire/overlay-polarfire.dts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
/*
* Copyright 2020, DornerWorks
* Copyright 2021, HENSOLDT Cyber
*
* SPDX-License-Identifier: GPL-2.0-only
*/
@@ -9,4 +10,20 @@
seL4,kernel-devices =
&{/soc/interrupt-controller@c000000};
};

/* 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;
};
};
};
4 changes: 3 additions & 1 deletion src/plat/rocketchip/config.cmake
Original file line number Diff line number Diff line change
@@ -14,7 +14,9 @@ if(KernelPlatformRocketchip)
config_set(KernelRiscVPlatform RISCV_PLAT "rocketchip")
config_set(KernelPlatformFirstHartID FIRST_HART_ID 0)
config_set(KernelOpenSBIPlatform OPENSBI_PLATFORM "generic")
list(APPEND KernelDTSList "tools/dts/rocketchip.dts")
list(
APPEND KernelDTSList "tools/dts/rocketchip.dts" "src/plat/rocketchip/overlay-rocketchip.dts"
)
# This is an experimental platform that supports accessing peripherals, but
# the status of support for external interrupts via a PLIC is unclear and
# may differ depending on the version that is synthesized. Declaring no
29 changes: 29 additions & 0 deletions src/plat/rocketchip/overlay-rocketchip.dts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
* Copyright 2021, HENSOLDT Cyber
*
* SPDX-License-Identifier: GPL-2.0-or-later or BSD-3-Clause
*/

/ {
chosen {
seL4,kernel-devices =
&{/soc/interrupt-controller@c000000};
};

/* 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;
};
};
};
3 changes: 3 additions & 0 deletions src/plat/spike/config.cmake
Original file line number Diff line number Diff line change
@@ -26,6 +26,9 @@ if(KernelPlatformSpike)
else()
list(APPEND KernelDTSList "tools/dts/spike.dts")
endif()

list(APPEND KernelDTSList "src/plat/spike/overlay-spike.dts")

declare_default_headers(
TIMER_FREQUENCY 10000000 PLIC_MAX_NUM_INT 0
INTERRUPT_CONTROLLER drivers/irq/riscv_plic_dummy.h
29 changes: 29 additions & 0 deletions src/plat/spike/overlay-spike.dts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2021, HENSOLDT Cyber
*
* SPDX-License-Identifier: GPL-2.0-or-later or BSD-3-Clause
*/

/ {
/*
* 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;
};
};
};
50 changes: 0 additions & 50 deletions tools/hardware/config.py
Original file line number Diff line number Diff line change
@@ -25,11 +25,6 @@ def get_kernel_phys_align(self) -> int:
''' 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
@@ -41,15 +36,6 @@ def get_device_page_bits(self) -> int:
''' 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 '''
@@ -60,20 +46,6 @@ def get_kernel_phys_align(self) -> int:
''' on ARM the ELF loader expects to be able to map a supersection page to load the kernel. '''
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 '''
@@ -82,28 +54,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'):
21 changes: 20 additions & 1 deletion tools/hardware/utils/memory.py
Original file line number Diff line number Diff line change
@@ -87,12 +87,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