Merge pull request #1040 from gsomlo/gls-rocket-smp

Rocket SMP support
This commit is contained in:
enjoy-digital 2021-09-23 10:56:06 +02:00 committed by GitHub
commit c43132f81f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 85 additions and 29 deletions

View File

@ -1,4 +1,18 @@
.section .text, "ax", @progbits
.global boot_helper
.global boot_helper
.global smp_ap_args
.global smp_ap_target
.global smp_ap_ready
boot_helper:
jr x13
// boot core saves args and jump target for ap cores:
sd a0, smp_ap_args, t1
sd a1, smp_ap_args+8, t1
sd a2, smp_ap_args+16, t1
sd a3, smp_ap_target, t1
fence w, w
// notify application cores to proceed with boot:
li t0, 1
sd t0, smp_ap_ready, t1
// boot core now also ready to boot:
jr a3

View File

@ -45,9 +45,12 @@ class Open(Signal): pass
CPU_VARIANTS = {
"standard": "freechips.rocketchip.system.LitexConfig",
"linux": "freechips.rocketchip.system.LitexLinuxConfig",
"linux4": "freechips.rocketchip.system.LitexLinux4Config",
"linuxd": "freechips.rocketchip.system.LitexLinuxDConfig",
"linuxq": "freechips.rocketchip.system.LitexLinuxQConfig",
"full": "freechips.rocketchip.system.LitexFullConfig",
"full4d": "freechips.rocketchip.system.LitexFull4DConfig",
"full4q": "freechips.rocketchip.system.LitexFull4QConfig",
}
# GCC Flags-----------------------------------------------------------------------------------------
@ -55,20 +58,26 @@ CPU_VARIANTS = {
GCC_FLAGS = {
"standard": "-march=rv64imac -mabi=lp64 ",
"linux": "-march=rv64imac -mabi=lp64 ",
"linux4": "-march=rv64imac -mabi=lp64 ",
"linuxd": "-march=rv64imac -mabi=lp64 ",
"linuxq": "-march=rv64imac -mabi=lp64 ",
"full": "-march=rv64imafdc -mabi=lp64 ",
"full4d": "-march=rv64imafdc -mabi=lp64 ",
"full4q": "-march=rv64imafdc -mabi=lp64 ",
}
# AXI Data-Widths ----------------------------------------------------------------------------------
# CPU Size Params ----------------------------------------------------------------------------------
AXI_DATA_WIDTHS = {
# Variant : (mem, mmio)
"standard": ( 64, 64),
"linux": ( 64, 64),
"linuxd": (128, 64),
"linuxq": (256, 64),
"full": ( 64, 64),
CPU_SIZE_PARAMS = {
# Variant : (mem_dw, mmio_dw, num_cores)
"standard": ( 64, 64, 1),
"linux": ( 64, 64, 1),
"linux4": ( 64, 64, 4),
"linuxd": ( 128, 64, 1),
"linuxq": ( 256, 64, 1),
"full": ( 64, 64, 1),
"full4d": ( 128, 64, 4),
"full4q": ( 256, 64, 4),
}
# Rocket RV64 --------------------------------------------------------------------------------------
@ -111,7 +120,7 @@ class RocketRV64(CPU):
self.reset = Signal()
self.interrupt = Signal(4)
mem_dw, mmio_dw = AXI_DATA_WIDTHS[self.variant]
mem_dw, mmio_dw, num_cores = CPU_SIZE_PARAMS[self.variant]
self.mem_axi = mem_axi = axi.AXIInterface(data_width=mem_dw, address_width=32, id_width=4)
self.mmio_axi = mmio_axi = axi.AXIInterface(data_width=mmio_dw, address_width=32, id_width=4)
@ -132,7 +141,6 @@ class RocketRV64(CPU):
i_reset = ResetSignal("sys") | self.reset,
# Debug (ignored).
i_resetctrl_hartIsInReset_0 = Open(),
i_debug_clock = 0,
i_debug_reset = ResetSignal() | self.reset,
o_debug_clockeddmi_dmi_req_ready = Open(),
@ -282,6 +290,8 @@ class RocketRV64(CPU):
o_l2_frontend_bus_axi4_0_r_bits_resp = l2fb_axi.r.resp,
o_l2_frontend_bus_axi4_0_r_bits_last = l2fb_axi.r.last,
)
# additional per-core debug signals:
self.cpu_params.update({'i_resetctrl_hartIsInReset_%s'%i : Open() for i in range(num_cores)})
# Adapt AXI interfaces to Wishbone.
mmio_a2w = ResetInserter()(axi.AXI2Wishbone(mmio_axi, mmio_wb, base_address=0))

View File

@ -2,6 +2,10 @@
.global isr
.global _start
.global smp_ap_args
.global smp_ap_target
.global smp_ap_ready
_start:
j crt_init
nop
@ -54,37 +58,65 @@ trap_entry:
crt_init:
la sp, _fstack
la a0, trap_entry
csrw mtvec, a0
sd zero, smp_ap_ready, t0
la t0, trap_entry
csrw mtvec, t0
smp_select_bp:
csrr a0, mhartid
beqz a0, data_init // hart 0 is bp, everyone else is ap
smp_ap_loop:
ld t0, smp_ap_ready
beqz t0, smp_ap_loop
smp_ap_boot:
fence r, r
fence.i // i$ flush
ld a0, smp_ap_args // hart ID (but next-stage loads its own)
ld a1, smp_ap_args+8 // DTB pointer (if provded by litex bios)
ld a2, smp_ap_args+16
ld a3, smp_ap_target
jr a3
smp_ap_done:
data_init:
la a0, _fdata
la a1, _edata
la a2, _fdata_rom
la t0, _fdata
la t1, _edata
la t2, _fdata_rom
data_loop:
beq a0,a1,data_done
ld a3,0(a2)
sd a3,0(a0)
add a0,a0,8
add a2,a2,8
beq t0,t1,data_done
ld t3,0(t2)
sd t3,0(t0)
add t0,t0,8
add t2,t2,8
j data_loop
data_done:
bss_init:
la a0, _fbss
la a1, _ebss
la t0, _fbss
la t1, _ebss
bss_loop:
beq a0,a1,bss_done
sd zero,0(a0)
add a0,a0,8
beq t0,t1,bss_done
sd zero,0(t0)
add t0,t0,8
j bss_loop
bss_done:
call plic_init // initialize external interrupt controller
li a0, 0x800 // external interrupt sources only (using LiteX timer);
li t0, 0x800 // external interrupt sources only (using LiteX timer);
// NOTE: must still enable mstatus.MIE!
csrw mie,a0
csrw mie,t0
call main
inf_loop:
j inf_loop
.bss
smp_ap_args:
.dword 0
.dword 0
.dword 0
smp_ap_target:
.dword 0
smp_ap_ready:
.dword 0