Files
seL4/tools/hardware/config.py
Axel Heider c036e6c676 python: use KernelSel4Arch instead of KernelArch
Drop optional parameter 'arch' and make 'sel4arch' a required parameter
to avoid implicit assumptions.

Signed-off-by: Axel Heider <axelheider@gmx.de>
2021-12-03 10:26:41 +11:00

120 lines
4.4 KiB
Python

#
# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
#
# SPDX-License-Identifier: GPL-2.0-only
#
from typing import List, Set
from hardware.memory import Region
class Config:
''' Abstract config class '''
arch = 'unknown'
def __init__(self, sel4arch, addrspace_max):
self.sel4arch = sel4arch
self.addrspace_max = addrspace_max
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
def get_smallest_kernel_object_alignment(self) -> int:
return 4 # seL4_MinUntypedBits is 4 for all configurations
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 '''
arch = 'arm'
SUPERSECTION_BITS = 24 # 2^24 = 16 MiByte
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 '''
arch = 'riscv'
MEGAPAGE_BITS_RV32 = 22 # 2^22 = 4 MiByte
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'):
# 4MiB device pages
return self.MEGAPAGE_BITS_RV32
elif (self.sel4arch == 'riscv64'):
# 2MiB device pages for sv39 and sv48
return self.MEGAPAGE_BITS_RV64
raise ValueError('Unsupported sel4arch "{}" specified.'.format(self.sel4arch))
def get_arch_config(sel4arch: str, addrspace_max: int) -> Config:
''' Return an appropriate Config object for the given architecture '''
if sel4arch in ['aarch32', 'aarch64', 'arm_hyp']:
return ARMConfig(sel4arch, addrspace_max)
elif sel4arch in ['riscv32', 'riscv64']:
return RISCVConfig(sel4arch, addrspace_max)
else:
raise ValueError('Unsupported sel4arch "{}" specified.'.format(sel4arch))