soc.cpu: add CPUSoC and BIOSBuilder
authorJean-François Nguyen <jf@lambdaconcept.com>
Thu, 26 Mar 2020 11:27:02 +0000 (12:27 +0100)
committerJean-François Nguyen <jf@lambdaconcept.com>
Thu, 26 Mar 2020 11:27:02 +0000 (12:27 +0100)
.gitmodules [new file with mode: 0644]
lambdasoc/soc/cpu.py [new file with mode: 0644]
lambdasoc/software/__init__.py [new file with mode: 0644]
lambdasoc/software/bios [new submodule]

diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..d1c001b
--- /dev/null
@@ -0,0 +1,3 @@
+[submodule "lambdasoc/software/bios"]
+       path = lambdasoc/software/bios
+       url = git@github.com:lambdaconcept/lambdasoc-bios
diff --git a/lambdasoc/soc/cpu.py b/lambdasoc/soc/cpu.py
new file mode 100644 (file)
index 0000000..dac9624
--- /dev/null
@@ -0,0 +1,84 @@
+from .base import *
+from ..cpu import CPU
+from ..periph.intc import InterruptController
+from ..periph.sram import SRAMPeripheral
+from ..periph.serial import AsyncSerialPeripheral
+from ..periph.timer import TimerPeripheral
+
+
+__all__ = ["CPUSoC", "BIOSBuilder"]
+
+
+class CPUSoC(SoC):
+    cpu    = socproperty(CPU)
+    intc   = socproperty(InterruptController)
+    rom    = socproperty(SRAMPeripheral)
+    ram    = socproperty(SRAMPeripheral) # TODO: abstract class for storage peripherals.
+    uart   = socproperty(AsyncSerialPeripheral)
+    timer  = socproperty(TimerPeripheral)
+
+    # TODO: implement a CRG peripheral and expose clock frequencies through CSRs.
+    clk_freq = socproperty(int)
+
+    def build(self, name=None,
+              build_dir="build/soc", do_build=True,
+              do_init=False):
+        """TODO
+        """
+        plan = BIOSBuilder().prepare(self, build_dir, name)
+        if not do_build:
+            return plan
+
+        products = plan.execute_local(build_dir)
+        if not do_init:
+            return products
+
+        with products.extract("bios.bin") as bios_filename:
+            with open(bios_filename, "rb") as f:
+                words = iter(lambda: f.read(self.cpu.data_width // 8), b'')
+                bios  = [int.from_bytes(w, self.cpu.byteorder) for w in words]
+        self.rom.init = bios
+
+
+class BIOSBuilder(ConfigBuilder):
+    file_templates = {
+        **ConfigBuilder.file_templates,
+        "{{name}}.config": r"""
+            # {{autogenerated}}
+            CONFIG_CPU_{{soc.cpu.name.upper()}}=y
+            CONFIG_CPU_RESET_ADDR={{hex(soc.cpu.reset_addr)}}
+            CONFIG_CPU_BYTEORDER="{{soc.cpu.byteorder}}"
+            CONFIG_ARCH_{{soc.cpu.arch.upper()}}=y
+            {% if soc.cpu.muldiv == "soft" %}
+            CONFIG_{{soc.cpu.arch.upper()}}_MULDIV_SOFT=y
+            {% else %}
+            CONFIG_{{soc.cpu.arch.upper()}}_MULDIV_SOFT=n
+            {% endif %}
+            CONFIG_ROM_START={{hex(periph_addr(soc.rom))}}
+            CONFIG_ROM_SIZE={{hex(soc.rom.size)}}
+            CONFIG_RAM_START={{hex(periph_addr(soc.ram))}}
+            CONFIG_RAM_SIZE={{hex(soc.ram.size)}}
+            CONFIG_UART_START={{hex(periph_addr(soc.uart))}}
+            CONFIG_UART_IRQNO={{soc.intc.find_index(soc.uart.irq)}}
+            CONFIG_UART_RX_RINGBUF_SIZE_LOG2=7
+            CONFIG_UART_TX_RINGBUF_SIZE_LOG2=7
+            CONFIG_TIMER_START={{hex(periph_addr(soc.timer))}}
+            CONFIG_TIMER_IRQNO={{soc.intc.find_index(soc.timer.irq)}}
+            CONFIG_TIMER_CTR_WIDTH={{soc.timer.width}}
+            CONFIG_CLOCK_FREQ={{soc.clk_freq}}
+        """,
+    }
+    command_templates = [
+        *ConfigBuilder.command_templates,
+        r"""
+            build={{build_dir}}
+            KCONFIG_CONFIG={{build_dir}}/{{name}}.config
+            make -C {{software_dir}}/bios
+        """,
+    ]
+
+    def prepare(self, soc, build_dir, name):
+        if not isinstance(soc, CPUSoC):
+            raise TypeError("SoC must be an instance of CPUSoC, not {!r}"
+                            .format(soc))
+        return super().prepare(soc, build_dir, name)
diff --git a/lambdasoc/software/__init__.py b/lambdasoc/software/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/lambdasoc/software/bios b/lambdasoc/software/bios
new file mode 160000 (submodule)
index 0000000..38c21eb
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit 38c21eb2b3302710f553de6d0708aa10b228d82b