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:
Gerwin Klein
2021-08-23 17:57:35 +10:00
committed by Gerwin Klein
parent 2296484665
commit 7f562e1633
2 changed files with 41 additions and 32 deletions

View File

@@ -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):

View File

@@ -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