dac96244623b23c6e37f6cd9bd7dc913d12651b5
[lambdasoc.git] / lambdasoc / soc / cpu.py
1 from .base import *
2 from ..cpu import CPU
3 from ..periph.intc import InterruptController
4 from ..periph.sram import SRAMPeripheral
5 from ..periph.serial import AsyncSerialPeripheral
6 from ..periph.timer import TimerPeripheral
7
8
9 __all__ = ["CPUSoC", "BIOSBuilder"]
10
11
12 class CPUSoC(SoC):
13 cpu = socproperty(CPU)
14 intc = socproperty(InterruptController)
15 rom = socproperty(SRAMPeripheral)
16 ram = socproperty(SRAMPeripheral) # TODO: abstract class for storage peripherals.
17 uart = socproperty(AsyncSerialPeripheral)
18 timer = socproperty(TimerPeripheral)
19
20 # TODO: implement a CRG peripheral and expose clock frequencies through CSRs.
21 clk_freq = socproperty(int)
22
23 def build(self, name=None,
24 build_dir="build/soc", do_build=True,
25 do_init=False):
26 """TODO
27 """
28 plan = BIOSBuilder().prepare(self, build_dir, name)
29 if not do_build:
30 return plan
31
32 products = plan.execute_local(build_dir)
33 if not do_init:
34 return products
35
36 with products.extract("bios.bin") as bios_filename:
37 with open(bios_filename, "rb") as f:
38 words = iter(lambda: f.read(self.cpu.data_width // 8), b'')
39 bios = [int.from_bytes(w, self.cpu.byteorder) for w in words]
40 self.rom.init = bios
41
42
43 class BIOSBuilder(ConfigBuilder):
44 file_templates = {
45 **ConfigBuilder.file_templates,
46 "{{name}}.config": r"""
47 # {{autogenerated}}
48 CONFIG_CPU_{{soc.cpu.name.upper()}}=y
49 CONFIG_CPU_RESET_ADDR={{hex(soc.cpu.reset_addr)}}
50 CONFIG_CPU_BYTEORDER="{{soc.cpu.byteorder}}"
51 CONFIG_ARCH_{{soc.cpu.arch.upper()}}=y
52 {% if soc.cpu.muldiv == "soft" %}
53 CONFIG_{{soc.cpu.arch.upper()}}_MULDIV_SOFT=y
54 {% else %}
55 CONFIG_{{soc.cpu.arch.upper()}}_MULDIV_SOFT=n
56 {% endif %}
57 CONFIG_ROM_START={{hex(periph_addr(soc.rom))}}
58 CONFIG_ROM_SIZE={{hex(soc.rom.size)}}
59 CONFIG_RAM_START={{hex(periph_addr(soc.ram))}}
60 CONFIG_RAM_SIZE={{hex(soc.ram.size)}}
61 CONFIG_UART_START={{hex(periph_addr(soc.uart))}}
62 CONFIG_UART_IRQNO={{soc.intc.find_index(soc.uart.irq)}}
63 CONFIG_UART_RX_RINGBUF_SIZE_LOG2=7
64 CONFIG_UART_TX_RINGBUF_SIZE_LOG2=7
65 CONFIG_TIMER_START={{hex(periph_addr(soc.timer))}}
66 CONFIG_TIMER_IRQNO={{soc.intc.find_index(soc.timer.irq)}}
67 CONFIG_TIMER_CTR_WIDTH={{soc.timer.width}}
68 CONFIG_CLOCK_FREQ={{soc.clk_freq}}
69 """,
70 }
71 command_templates = [
72 *ConfigBuilder.command_templates,
73 r"""
74 build={{build_dir}}
75 KCONFIG_CONFIG={{build_dir}}/{{name}}.config
76 make -C {{software_dir}}/bios
77 """,
78 ]
79
80 def prepare(self, soc, build_dir, name):
81 if not isinstance(soc, CPUSoC):
82 raise TypeError("SoC must be an instance of CPUSoC, not {!r}"
83 .format(soc))
84 return super().prepare(soc, build_dir, name)