mirror of
https://github.com/seL4/seL4.git
synced 2026-03-27 10:29:57 +00:00
tools: consolidate RISC-V + Arm memory base logic
Co-authored-by: Oliver Scott <Oliver.Scott@data61.csiro.au> Co-authored-by: Axel Heider <axel-h@users.noreply.github.com> Signed-off-by: Gerwin Klein <gerwin.klein@proofcraft.systems>
This commit is contained in:
committed by
Gerwin Klein
parent
2296484665
commit
7f562e1633
@@ -3,6 +3,8 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
from typing import List, Set
|
||||
from hardware.memory import Region
|
||||
|
||||
|
||||
class Config:
|
||||
@@ -29,6 +31,15 @@ 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 '''
|
||||
@@ -39,6 +50,20 @@ class ARMConfig(Config):
|
||||
''' 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, None)
|
||||
extra_reserved.add(resv)
|
||||
ret[0] = new
|
||||
|
||||
physBase = ret[0].base
|
||||
|
||||
return ret, extra_reserved, physBase
|
||||
|
||||
|
||||
class RISCVConfig(Config):
|
||||
''' Config class for RISCV '''
|
||||
@@ -50,6 +75,21 @@ class RISCVConfig(Config):
|
||||
of physical memory. Mark it as unavailable. '''
|
||||
return self.MEGA_PAGE_SIZE
|
||||
|
||||
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(), None)
|
||||
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.addrspace_max > (1 << 32):
|
||||
|
||||
@@ -54,43 +54,12 @@ 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.arch == 'riscv':
|
||||
# RISC-V is special: it expects physBase to be
|
||||
# the address that the bootloader is loaded at.
|
||||
physBase = ret[0].base
|
||||
|
||||
if config.get_bootloader_reserve() > 0:
|
||||
resv = Region(ret[0].base, config.get_bootloader_reserve(), None)
|
||||
extra_reserved.add(resv)
|
||||
ret[0].base += config.get_bootloader_reserve()
|
||||
ret[0].size -= config.get_bootloader_reserve()
|
||||
|
||||
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, None)
|
||||
extra_reserved.add(resv)
|
||||
ret[0] = new
|
||||
|
||||
if config.arch != 'riscv':
|
||||
# ARM (and presumably other architectures)
|
||||
# want physBase to be the physical load address of the kernel.
|
||||
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 = get_memory_regions(tree)
|
||||
reserved = parse_reserved_regions(tree.get_path('/reserved-memory'))
|
||||
regions = reserve_regions(regions, reserved)
|
||||
regions, extra_reserved, physBase = align_memory(regions, config)
|
||||
regions, extra_reserved, physBase = config.align_memory(regions)
|
||||
|
||||
return regions, reserved.union(extra_reserved), physBase
|
||||
|
||||
|
||||
Reference in New Issue
Block a user