5f26054582886a070d6414694035fa604780ebcf
[lambdasoc.git] / lambdasoc / soc / cpu.py
1 import os
2
3 from .base import *
4 from ..cpu import CPU
5 from ..periph.intc import InterruptController
6 from ..periph.sram import SRAMPeripheral
7 from ..periph.sdram import SDRAMPeripheral
8 from ..periph.serial import AsyncSerialPeripheral
9 from ..periph.timer import TimerPeripheral
10
11
12 __all__ = ["CPUSoC", "BIOSBuilder"]
13
14
15 class CPUSoC(SoC):
16 cpu = socproperty(CPU)
17 intc = socproperty(InterruptController)
18 rom = socproperty(SRAMPeripheral)
19 ram = socproperty(SRAMPeripheral)
20 sdram = socproperty(SDRAMPeripheral, weak=True)
21 uart = socproperty(AsyncSerialPeripheral)
22 timer = socproperty(TimerPeripheral)
23
24 # TODO: implement a CRG peripheral and expose clock frequencies through CSRs.
25 clk_freq = socproperty(int)
26
27 def build(self, name=None,
28 litedram_dir="build/litedram",
29 build_dir="build/soc", do_build=True,
30 do_init=False):
31 """TODO
32 """
33 plan = BIOSBuilder().prepare(self, build_dir, name,
34 litedram_dir=os.path.abspath(litedram_dir))
35 if not do_build:
36 return plan
37
38 products = plan.execute_local(build_dir)
39 if not do_init:
40 return products
41
42 with products.extract("bios/bios.bin") as bios_filename:
43 with open(bios_filename, "rb") as f:
44 words = iter(lambda: f.read(self.cpu.data_width // 8), b'')
45 bios = [int.from_bytes(w, self.cpu.byteorder) for w in words]
46 self.rom.init = bios
47
48
49 class BIOSBuilder(ConfigBuilder):
50 file_templates = {
51 **ConfigBuilder.file_templates,
52 "{{name}}.config": r"""
53 # {{autogenerated}}
54 CONFIG_CPU_{{soc.cpu.name.upper()}}=y
55 CONFIG_CPU_RESET_ADDR={{hex(soc.cpu.reset_addr)}}
56 CONFIG_CPU_BYTEORDER="{{soc.cpu.byteorder}}"
57 CONFIG_ARCH_{{soc.cpu.arch.upper()}}=y
58 {% if soc.cpu.muldiv == "soft" %}
59 CONFIG_{{soc.cpu.arch.upper()}}_MULDIV_SOFT=y
60 {% else %}
61 CONFIG_{{soc.cpu.arch.upper()}}_MULDIV_SOFT=n
62 {% endif %}
63 CONFIG_ROM_START={{hex(periph_addr(soc.rom))}}
64 CONFIG_ROM_SIZE={{hex(soc.rom.size)}}
65 CONFIG_RAM_START={{hex(periph_addr(soc.ram))}}
66 CONFIG_RAM_SIZE={{hex(soc.ram.size)}}
67 CONFIG_UART_START={{hex(periph_addr(soc.uart))}}
68 CONFIG_UART_IRQNO={{soc.intc.find_index(soc.uart.irq)}}
69 CONFIG_UART_RX_RINGBUF_SIZE_LOG2=7
70 CONFIG_UART_TX_RINGBUF_SIZE_LOG2=7
71 CONFIG_TIMER_START={{hex(periph_addr(soc.timer))}}
72 CONFIG_TIMER_IRQNO={{soc.intc.find_index(soc.timer.irq)}}
73 CONFIG_TIMER_CTR_WIDTH={{soc.timer.width}}
74 CONFIG_CLOCK_FREQ={{soc.clk_freq}}
75
76 {% if soc.sdram is not none %}
77 CONFIG_WITH_SDRAM=y
78 CONFIG_SDRAM_START={{hex(periph_addr(soc.sdram))}}
79 CONFIG_SDRAM_SIZE={{hex(soc.sdram.core.size)}}
80 {% else %}
81 CONFIG_WITH_SDRAM=n
82 {% endif %}
83 """,
84 "litex_config.h": r"""
85 // {{autogenerated}}
86 #ifndef __LITEX_CONFIG_H_LAMBDASOC
87 #define __LITEX_CONFIG_H_LAMBDASOC
88
89 #define LX_CONFIG_TIMER_START {{hex(periph_addr(soc.timer))}}
90
91 {% if soc.sdram is not none %}
92 #define LX_CONFIG_SDRAM_START {{hex(periph_addr(soc.sdram))}}UL
93 #define LX_CONFIG_SDRAM_SIZE {{hex(soc.sdram.core.size)}}UL
94 #define LX_CONFIG_SDRAM_CACHE_SIZE {{soc.sdram._cache.size}}
95 #define LX_CONFIG_MEMTEST_DATA_SIZE 2*1024*1024
96 #define LX_CONFIG_MEMTEST_ADDR_SIZE 65536
97 {% endif %}
98
99 #endif
100 """,
101 }
102 command_templates = [
103 *ConfigBuilder.command_templates,
104 r"""
105 {% if soc.sdram is not none %}
106 litedram_dir={{litedram_dir}}/{{soc.sdram.core.name}}
107 {% endif %}
108 build={{build_dir}}
109 KCONFIG_CONFIG={{build_dir}}/{{name}}.config
110 make -C {{software_dir}}/bios 1>&2
111 """,
112 ]
113
114 def prepare(self, soc, build_dir, name, litedram_dir):
115 if not isinstance(soc, CPUSoC):
116 raise TypeError("SoC must be an instance of CPUSoC, not {!r}"
117 .format(soc))
118 return super().prepare(soc, build_dir, name, litedram_dir=litedram_dir)