/ coreblocks / params / vmem_params.py
vmem_params.py
 1  from typing import Collection
 2  
 3  from coreblocks.arch.isa_consts import SatpMode, SatpLayout, PAGE_SIZE_LOG
 4  
 5  
 6  class VirtualMemoryParameters:
 7      """Parameters for virtual memory support."""
 8  
 9      @staticmethod
10      def max_physical_address_bits(xlen: int, supported_schemes: Collection[SatpMode]) -> int:
11          if xlen == 32 and supported_schemes == {SatpMode.BARE}:
12              return 32  # without virtual memory only lower 32 bits of physical addresses are reachable
13  
14          satp_layout = SatpLayout(xlen)
15          return satp_layout["ppn"].width + PAGE_SIZE_LOG
16  
17      def __init__(
18          self,
19          *,
20          xlen: int,
21          supervisor_mode: bool = False,
22          asidlen: int = 0,
23          supported_schemes: Collection[SatpMode] = (SatpMode.BARE,),
24      ):
25          self.supported_schemes = frozenset(supported_schemes)
26  
27          if SatpMode.BARE not in self.supported_schemes:
28              raise ValueError("Supported virtual memory schemes must include BARE")
29  
30          if not supervisor_mode and self.supported_schemes != {SatpMode.BARE}:
31              raise ValueError("Virtual memory schemes other than BARE require supervisor mode support")
32  
33          if asidlen < 0:
34              raise ValueError(f"ASIDLEN must be non-negative, got {asidlen}")
35  
36          self.satp_layout = SatpLayout(xlen)
37  
38          max_asidlen = self.satp_layout["asid"].width
39          if asidlen > max_asidlen:
40              raise ValueError(f"ASIDLEN={asidlen} exceeds maximum {max_asidlen} for XLEN={xlen}")
41  
42          supported_for_xlen = SatpMode.valid_modes(xlen)
43          if not self.supported_schemes <= supported_for_xlen:
44              raise ValueError(f"Schemes {self.supported_schemes - supported_for_xlen} are not valid for XLEN={xlen}")
45  
46          for mode in self.supported_schemes:
47              dependencies = SatpMode.mode_dependencies(mode)
48              if not dependencies <= self.supported_schemes:
49                  raise ValueError(
50                      f"Schemes {dependencies - self.supported_schemes} are required by {mode} but not supported"
51                  )
52  
53          self.xlen = xlen
54          self.asidlen = asidlen
55          self.max_asid = (1 << asidlen) - 1