From 788d3248d2251c7329022b92959b3f8481674239 Mon Sep 17 00:00:00 2001 From: Piotr Wegrzyn Date: Thu, 8 Aug 2024 13:53:41 +0000 Subject: [PATCH 1/3] Support loading initialized data in asm tests --- test/asm/exception_mem.asm | 2 ++ test/asm/fibonacci_mem.asm | 3 ++ test/asm/init_regs.s | 7 +++++ test/asm/interrupt.asm | 11 +++++-- test/asm/link.ld | 3 +- test/asm/wfi_int.asm | 7 ++++- test/test_core.py | 60 +++++++++++++++++++++++--------------- 7 files changed, 65 insertions(+), 28 deletions(-) diff --git a/test/asm/exception_mem.asm b/test/asm/exception_mem.asm index c3556e795..4964f135d 100644 --- a/test/asm/exception_mem.asm +++ b/test/asm/exception_mem.asm @@ -9,3 +9,5 @@ sw x2, 4(x0) sw x1, 4(x0) /* TODO: actually check the side fx */ li x2, 9 +.section .bss +.skip 0x8 diff --git a/test/asm/fibonacci_mem.asm b/test/asm/fibonacci_mem.asm index 9986aca76..0db8b2130 100644 --- a/test/asm/fibonacci_mem.asm +++ b/test/asm/fibonacci_mem.asm @@ -24,3 +24,6 @@ loop: bne x3, x4, loop infloop: j infloop + +.section .bss +.skip 0xC diff --git a/test/asm/init_regs.s b/test/asm/init_regs.s index 5c27a365b..48c767bd8 100644 --- a/test/asm/init_regs.s +++ b/test/asm/init_regs.s @@ -1,3 +1,4 @@ +.macro INIT_REGS_LOAD # load the initial states of registers # the value of a register `n` is assumed to be stored under address `0x100 + n * 4`. lw x1, 0x104(x0) @@ -31,3 +32,9 @@ lw x29,0x174(x0) lw x30,0x178(x0) lw x31,0x17c(x0) +.endm + +.macro INIT_REGS_ALLOCATION +.org 0x100 +.skip 0x80 +.endm diff --git a/test/asm/interrupt.asm b/test/asm/interrupt.asm index 02388127f..ccf079245 100644 --- a/test/asm/interrupt.asm +++ b/test/asm/interrupt.asm @@ -1,7 +1,9 @@ - _start: - .include "init_regs.s" +.include "init_regs.s" -# fibonacci spiced with interrupt handler (also with fibonacci) +_start: + INIT_REGS_LOAD + + # fibonacci spiced with interrupt handler (also with fibonacci) li x1, 0x200 csrw mtvec, x1 li x27, 0 # handler count @@ -98,3 +100,6 @@ fail: .org 0x200 j int_handler li x31, 0xae # should never happen + +.bss + INIT_REGS_ALLOCATION diff --git a/test/asm/link.ld b/test/asm/link.ld index 9ceab42eb..b8c136191 100644 --- a/test/asm/link.ld +++ b/test/asm/link.ld @@ -5,7 +5,8 @@ start = 0; SECTIONS { .text : { *(.text) } - . = 0x100000000; /* start from 2**32 - trick to emulate Harvard architecture (.bss addresses will start from 0) */ + . = 0x100000000; /* start from 2**32 - trick to emulate Harvard architecture (memory addresses will start from 0) */ + .data : { *(.data) } .bss : { *(.bss) } _end = .; } diff --git a/test/asm/wfi_int.asm b/test/asm/wfi_int.asm index 3f50000c4..838e0b5f8 100644 --- a/test/asm/wfi_int.asm +++ b/test/asm/wfi_int.asm @@ -1,5 +1,7 @@ +.include "init_regs.s" + _start: - .include "init_regs.s" + INIT_REGS_LOAD li x1, 0x100 # set handler vector csrw mtvec, x1 @@ -26,3 +28,6 @@ skip: .org 0x100 j handler + +.data + INIT_REGS_ALLOCATION diff --git a/test/test_core.py b/test/test_core.py index d9cf4655d..4e8497eb4 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -12,7 +12,6 @@ from coreblocks.params.configurations import CoreConfiguration, basic_core_config, full_core_config from coreblocks.peripherals.wishbone import WishboneMemorySlave -from typing import Optional import random import subprocess import tempfile @@ -20,13 +19,10 @@ class CoreTestElaboratable(Elaboratable): - def __init__(self, gen_params: GenParams, instr_mem: list[int] = [0], data_mem: Optional[list[int]] = None): + def __init__(self, gen_params: GenParams, instr_mem: list[int] = [0], data_mem: list[int] = []): self.gen_params = gen_params self.instr_mem = instr_mem - if data_mem is None: - self.data_mem = [0] * (2**10) - else: - self.data_mem = data_mem + self.data_mem = data_mem def elaborate(self, platform): m = Module() @@ -71,12 +67,10 @@ def get_arch_reg_val(self, reg_id): class TestCoreAsmSourceBase(TestCoreBase): base_dir: str = "test/asm/" - def prepare_source(self, filename): - bin_src = [] + def prepare_source(self, filename, *, c_extension=False): with ( tempfile.NamedTemporaryFile() as asm_tmp, tempfile.NamedTemporaryFile() as ld_tmp, - tempfile.NamedTemporaryFile() as bin_tmp, ): subprocess.check_call( [ @@ -84,7 +78,7 @@ def prepare_source(self, filename): "-mabi=ilp32", # Specified manually, because toolchains from most distributions don't support new extensioins # and this test should be accessible locally. - "-march=rv32im_zicsr", + f"-march=rv32im{'c' if c_extension else ''}_zicsr", "-I", self.base_dir, "-o", @@ -104,16 +98,36 @@ def prepare_source(self, filename): ld_tmp.name, ] ) - subprocess.check_call( - ["riscv64-unknown-elf-objcopy", "-O", "binary", "-j", ".text", ld_tmp.name, bin_tmp.name] - ) - code = bin_tmp.read() - for word_idx in range(0, len(code), 4): - word = code[word_idx : word_idx + 4] - bin_instr = int.from_bytes(word, "little") - bin_src.append(bin_instr) - return bin_src + def load_section(section: str): + with tempfile.NamedTemporaryFile() as bin_tmp: + bin = [] + + subprocess.check_call( + [ + "riscv64-unknown-elf-objcopy", + "-O", + "binary", + "-j", + section, + "--set-section-flags", + f"{section}=alloc,load,contents", + ld_tmp.name, + bin_tmp.name, + ] + ) + + data = bin_tmp.read() + for word_idx in range(0, len(data), 4): + word = data[word_idx : word_idx + 4] + bin.append(int.from_bytes(word, "little")) + + return bin + + return { + "text": load_section(".text"), + "data": load_section(".data") + load_section(".bss"), + } @parameterized_class( @@ -146,7 +160,8 @@ def test_asm_source(self): self.gen_params = GenParams(self.configuration) bin_src = self.prepare_source(self.source_file) - self.m = CoreTestElaboratable(self.gen_params, instr_mem=bin_src) + self.m = CoreTestElaboratable(self.gen_params, instr_mem=bin_src["text"], data_mem=bin_src["data"]) + with self.run_simulation(self.m) as sim: sim.add_sync_process(self.run_and_check) @@ -269,10 +284,9 @@ def do_interrupt(): def test_interrupted_prog(self): bin_src = self.prepare_source(self.source_file) - data_mem = [0] * (2**10) for reg_id, val in self.start_regvals.items(): - data_mem[self.reg_init_mem_offset // 4 + reg_id] = val - self.m = CoreTestElaboratable(self.gen_params, instr_mem=bin_src, data_mem=data_mem) + bin_src["data"][self.reg_init_mem_offset // 4 + reg_id] = val + self.m = CoreTestElaboratable(self.gen_params, instr_mem=bin_src["text"], data_mem=bin_src["data"]) with self.run_simulation(self.m) as sim: sim.add_sync_process(self.run_with_interrupt_process) sim.add_sync_process(self.clear_level_interrupt_procsess) From bf8b0e42b5c879e550c58daeb12b5298dadc99f5 Mon Sep 17 00:00:00 2001 From: Piotr Wegrzyn Date: Fri, 9 Aug 2024 19:32:46 +0000 Subject: [PATCH 2/3] Move .bss to common .data section in liker --- test/asm/link.ld | 3 +-- test/test_core.py | 7 +------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/test/asm/link.ld b/test/asm/link.ld index b8c136191..e47674779 100644 --- a/test/asm/link.ld +++ b/test/asm/link.ld @@ -6,7 +6,6 @@ SECTIONS { .text : { *(.text) } . = 0x100000000; /* start from 2**32 - trick to emulate Harvard architecture (memory addresses will start from 0) */ - .data : { *(.data) } - .bss : { *(.bss) } + .data : { *(.data) *(.bss) } _end = .; } diff --git a/test/test_core.py b/test/test_core.py index 4e8497eb4..e988b1437 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -110,8 +110,6 @@ def load_section(section: str): "binary", "-j", section, - "--set-section-flags", - f"{section}=alloc,load,contents", ld_tmp.name, bin_tmp.name, ] @@ -124,10 +122,7 @@ def load_section(section: str): return bin - return { - "text": load_section(".text"), - "data": load_section(".data") + load_section(".bss"), - } + return {"text": load_section(".text"), "data": load_section(".data")} @parameterized_class( From f88861146b8535f6e0b81453c02fc45c0b8ae8a3 Mon Sep 17 00:00:00 2001 From: Piotr Wegrzyn Date: Fri, 9 Aug 2024 20:27:56 +0000 Subject: [PATCH 3/3] Move init regs to separate section --- test/asm/init_regs.s | 3 ++- test/asm/interrupt.asm | 3 +-- test/asm/link.ld | 10 ++++++++-- test/asm/wfi_int.asm | 3 +-- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/test/asm/init_regs.s b/test/asm/init_regs.s index 48c767bd8..853a40a15 100644 --- a/test/asm/init_regs.s +++ b/test/asm/init_regs.s @@ -35,6 +35,7 @@ .endm .macro INIT_REGS_ALLOCATION -.org 0x100 +.section .init_regs, "a", @nobits .skip 0x80 +.previous .endm diff --git a/test/asm/interrupt.asm b/test/asm/interrupt.asm index ccf079245..a3b59b30e 100644 --- a/test/asm/interrupt.asm +++ b/test/asm/interrupt.asm @@ -101,5 +101,4 @@ fail: j int_handler li x31, 0xae # should never happen -.bss - INIT_REGS_ALLOCATION +INIT_REGS_ALLOCATION diff --git a/test/asm/link.ld b/test/asm/link.ld index e47674779..c77c5fef8 100644 --- a/test/asm/link.ld +++ b/test/asm/link.ld @@ -6,6 +6,12 @@ SECTIONS { .text : { *(.text) } . = 0x100000000; /* start from 2**32 - trick to emulate Harvard architecture (memory addresses will start from 0) */ - .data : { *(.data) *(.bss) } - _end = .; + .data : { + *(.data) + *(.bss) + + . = _end_init_regs > . ? 0x1000 : .; /* skip .init_regs origin allocation if not used */ + *(.init_regs) + _end_init_regs = .; + } } diff --git a/test/asm/wfi_int.asm b/test/asm/wfi_int.asm index 838e0b5f8..39ceda94a 100644 --- a/test/asm/wfi_int.asm +++ b/test/asm/wfi_int.asm @@ -29,5 +29,4 @@ skip: .org 0x100 j handler -.data - INIT_REGS_ALLOCATION +INIT_REGS_ALLOCATION