diff --git a/tools/hardware/config.py b/tools/hardware/config.py index 4a70bdb89..da9829a85 100644 --- a/tools/hardware/config.py +++ b/tools/hardware/config.py @@ -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): diff --git a/tools/hardware/utils/memory.py b/tools/hardware/utils/memory.py index afbab9a01..b68c5a285 100644 --- a/tools/hardware/utils/memory.py +++ b/tools/hardware/utils/memory.py @@ -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