From 44650dffd8f82018840922ddbbb6570c8c1e6b08 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Tue, 26 Sep 2017 10:01:36 +1000 Subject: [PATCH] cpu: Adding "variant" support. It is useful to support slightly different variants of the CPU configurations. This adds a "cpu_variant" option. For the mor1k we now have the default mor1k configuration and the "linux" variant which enables the features needed for Linux support on the mor1k. Currently there are no variants for the lm32, but we will likely add a "tiny" variant for usage on the iCE40. --- litex/soc/cores/cpu/lm32/core.py | 3 ++- litex/soc/cores/cpu/mor1kx/core.py | 36 ++++++++++++++++++++++++++---- litex/soc/integration/soc_core.py | 11 +++++---- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/litex/soc/cores/cpu/lm32/core.py b/litex/soc/cores/cpu/lm32/core.py index a6c9f3397..743a61f63 100644 --- a/litex/soc/cores/cpu/lm32/core.py +++ b/litex/soc/cores/cpu/lm32/core.py @@ -6,7 +6,8 @@ from litex.soc.interconnect import wishbone class LM32(Module): - def __init__(self, platform, eba_reset): + def __init__(self, platform, eba_reset, variant=None): + assert variant == None, "No lm32 variants currently supported." self.ibus = i = wishbone.Interface() self.dbus = d = wishbone.Interface() self.interrupt = Signal(32) diff --git a/litex/soc/cores/cpu/mor1kx/core.py b/litex/soc/cores/cpu/mor1kx/core.py index d74e0654d..872300595 100644 --- a/litex/soc/cores/cpu/mor1kx/core.py +++ b/litex/soc/cores/cpu/mor1kx/core.py @@ -6,16 +6,15 @@ from litex.soc.interconnect import wishbone class MOR1KX(Module): - def __init__(self, platform, reset_pc): + def __init__(self, platform, reset_pc, variant=None): + assert variant in (None, "linux"), "Unsupported variant %s" % variant self.ibus = i = wishbone.Interface() self.dbus = d = wishbone.Interface() self.interrupt = Signal(32) # # # - i_adr_o = Signal(32) - d_adr_o = Signal(32) - self.specials += Instance("mor1kx", + cpu_args = dict( p_FEATURE_INSTRUCTIONCACHE="ENABLED", p_OPTION_ICACHE_BLOCK_WIDTH=4, p_OPTION_ICACHE_SET_WIDTH=8, @@ -39,6 +38,35 @@ class MOR1KX(Module): p_OPTION_RESET_PC=reset_pc, p_IBUS_WB_TYPE="B3_REGISTERED_FEEDBACK", p_DBUS_WB_TYPE="B3_REGISTERED_FEEDBACK", + ) + + if variant == None: + # Use the default configuration + pass + elif variant == "linux": + cpu_args.update(dict( + # Linux needs the memory management units. + p_FEATURE_IMMU="ENABLED", + p_FEATURE_DMMU="ENABLED", + # FIXME: Currently we need the or1k timer when we should be + # using the litex timer. + p_FEATURE_TIMER="ENABLED", + )) + # FIXME: Check if these are needed? + use_defaults = ( + "p_FEATURE_SYSCALL", "p_FEATURE_TRAP", "p_FEATURE_RANGE", + "p_FEATURE_OVERFLOW", + ) + for to_remove in use_defaults: + del cpu_args[to_remove] + + else: + assert False, "Unsupported variant %s" % variant + + i_adr_o = Signal(32) + d_adr_o = Signal(32) + self.specials += Instance("mor1kx", + **cpu_args, i_clk=ClockSignal(), i_rst=ResetSignal(), diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py index 1b30c9043..0a9c98b69 100644 --- a/litex/soc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -60,7 +60,7 @@ class SoCCore(Module): "csr": 0x60000000, # (default shadow @0xe0000000) } def __init__(self, platform, clk_freq, - cpu_type="lm32", cpu_reset_address=0x00000000, + cpu_type="lm32", cpu_reset_address=0x00000000, cpu_variant=None, integrated_rom_size=0, integrated_rom_init=[], integrated_sram_size=4096, integrated_main_ram_size=0, integrated_main_ram_init=[], @@ -76,6 +76,7 @@ class SoCCore(Module): self.clk_freq = clk_freq self.cpu_type = cpu_type + self.cpu_variant = cpu_variant if integrated_rom_size: cpu_reset_address = self.mem_map["rom"] self.cpu_reset_address = cpu_reset_address @@ -103,16 +104,18 @@ class SoCCore(Module): if cpu_type is not None: if cpu_type == "lm32": - self.add_cpu_or_bridge(lm32.LM32(platform, self.cpu_reset_address)) + self.add_cpu_or_bridge(lm32.LM32(platform, self.cpu_reset_address, self.cpu_variant)) elif cpu_type == "or1k": - self.add_cpu_or_bridge(mor1kx.MOR1KX(platform, self.cpu_reset_address)) + self.add_cpu_or_bridge(mor1kx.MOR1KX(platform, self.cpu_reset_address, self.cpu_variant)) elif cpu_type == "riscv32": - self.add_cpu_or_bridge(picorv32.PicoRV32(platform, self.cpu_reset_address)) + self.add_cpu_or_bridge(picorv32.PicoRV32(platform, self.cpu_reset_address, self.cpu_variant)) else: raise ValueError("Unsupported CPU type: {}".format(cpu_type)) self.add_wb_master(self.cpu_or_bridge.ibus) self.add_wb_master(self.cpu_or_bridge.dbus) self.config["CPU_TYPE"] = str(cpu_type).upper() + if self.cpu_variant: + self.config["CPU_VARIANT"] = str(cpu_type).upper() if integrated_rom_size: self.submodules.rom = wishbone.SRAM(integrated_rom_size, read_only=True, init=integrated_rom_init)