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)