soc_core/cpu: move memory map override to CPUs, select reset_address after eventual...
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Sat, 28 Sep 2019 12:13:39 +0000 (14:13 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Sat, 28 Sep 2019 12:15:48 +0000 (14:15 +0200)
litex/soc/cores/cpu/mor1kx/core.py
litex/soc/cores/cpu/rocket/core.py
litex/soc/integration/soc_core.py

index 5532a04354726bd3ca6c852c8fe4765256c2aa86..46f55e65131c9339e4c787fbfd3a1af10e535d93 100644 (file)
@@ -24,6 +24,18 @@ class MOR1KX(Module):
     def endianness(self):
         return "big"
 
+    @property
+    def mem_map_linux(self):
+        # Mainline Linux OpenRISC arch code requires Linux kernel to be loaded at the physical
+        # address of 0x0. As we are running Linux from the MAIN_RAM region - move it to satisfy
+        # that requirement.
+        return {
+            "main_ram" : 0x00000000,
+            "rom"      : 0x10000000,
+            "sram"     : 0x50000000,
+            "csr"      : 0x60000000,
+        }
+
     @property
     def gcc_triple(self):
         return "or1k-elf"
@@ -67,6 +79,9 @@ class MOR1KX(Module):
         self.dbus = d = wishbone.Interface()
         self.interrupt = Signal(32)
 
+        if variant == "linux":
+            self.mem_map = self.mem_map_linux
+
         # # #
 
         cpu_args = dict(
index a9334aa38e1e381b5fc400f8ba25297b8476548e..a048c3ce82991300cc9543b51f20e84518781e30 100644 (file)
@@ -57,6 +57,15 @@ class RocketRV64(Module):
     def endianness(self):
         return "little"
 
+    @property
+    def mem_map(self):
+        # Rocket reserves the first 256Mbytes for internal use, so we must change default mem_map.
+        return {
+            "rom"  : 0x10000000,
+            "sram" : 0x11000000,
+            "csr"  : 0x12000000,
+        }
+
     @property
     def gcc_triple(self):
         return ("riscv64-unknown-elf")
@@ -100,7 +109,7 @@ class RocketRV64(Module):
 
         # # #
 
-        self.cpu_params += dict(
+        self.cpu_params = dict(
             # clock, reset
             i_clock=ClockSignal(),
             i_reset=ResetSignal() | self.reset,
index f0ec4c975e79ba2275fd9370558a6d462a63df83..51a319dea7947a5b8a76343327ca9c1a23fad87b 100644 (file)
@@ -192,39 +192,19 @@ class SoCCore(Module):
         self._csr_masters = []
 
         # Parameters managment ---------------------------------------------------------------------
+        if cpu_type == "None":
+            cpu_type = None
 
-        # NOTE: RocketChip reserves the first 256Mbytes for internal use,
-        #       so we must change default mem_map;
-        #       Also, CSRs *must* be 64-bit aligned.
+        # FIXME: On RocketChip, CSRs *must* be 64-bit aligned.
         if cpu_type == "rocket":
-            self.soc_mem_map["rom"]  = 0x10000000
-            self.soc_mem_map["sram"] = 0x11000000
-            self.soc_mem_map["csr"]  = 0x12000000
             csr_alignment = 64
 
-        # Mainline Linux OpenRISC arch code requires Linux kernel to be loaded
-        # at the physical address of 0x0. As we are running Linux from the
-        # MAIN_RAM region - move it to satisfy that requirement.
-        if cpu_type == "mor1kx" and cpu_variant == "linux":
-            self.soc_mem_map["main_ram"] = 0x00000000
-            self.soc_mem_map["rom"]      = 0x10000000
-            self.soc_mem_map["sram"]     = 0x50000000
-            self.soc_mem_map["csr"]      = 0x60000000
-
-        if cpu_type == "None":
-            cpu_type = None
-
         if not with_wishbone:
             self.soc_mem_map["csr"]  = 0x00000000
 
         self.cpu_type    = cpu_type
         self.cpu_variant = cpu.check_format_cpu_variant(cpu_variant)
 
-        if integrated_rom_size:
-            cpu_reset_address = self.soc_mem_map["rom"]
-        self.cpu_reset_address = cpu_reset_address
-        self.config["CPU_RESET_ADDR"] = self.cpu_reset_address
-
         self.shadow_base = shadow_base
 
         self.integrated_rom_size = integrated_rom_size
@@ -263,11 +243,19 @@ class SoCCore(Module):
         if cpu_type is not None:
             if cpu_variant is not None:
                 self.config["CPU_VARIANT"] = str(cpu_variant.split('+')[0]).upper()
-            # CPU selection / instance
+            # Check type
             if cpu_type not in cpu.CPUS.keys():
                 raise ValueError("Unsupported CPU type: {}".format(cpu_type))
+            # Add the CPU
             self.add_cpu(cpu.CPUS[cpu_type](platform, self.cpu_variant))
-            self.cpu.set_reset_address(cpu_reset_address)
+
+            # Override Memory Map (if needed by CPU)
+            if hasattr(self.cpu, "mem_map"):
+                self.soc_mem_map.update(self.cpu.mem_map)
+
+            # Set reset address
+            self.cpu.set_reset_address(self.soc_mem_map["rom"] if integrated_rom_size else cpu_reset_address)
+            self.config["CPU_RESET_ADDR"] = self.cpu.reset_address
 
             # Add Instruction/Data buses as Wisbone masters
             self.add_wb_master(self.cpu.ibus)
@@ -455,7 +443,7 @@ class SoCCore(Module):
 
     def register_rom(self, interface, rom_size=0xa000):
         self.add_wb_slave(self.soc_mem_map["rom"], interface, rom_size)
-        self.add_memory_region("rom", self.cpu_reset_address, rom_size)
+        self.add_memory_region("rom", self.cpu.reset_address, rom_size)
 
     def get_memory_regions(self):
         return self._memory_regions