Skip to content

Commit

Permalink
fw: rivos: Add Rivos specific changes under FW_RIVOS
Browse files Browse the repository at this point in the history
Rivos specific firmware need requires the following setup before
opensbi firmware execution starts.

1. R-code setup
2. MCRR/MDRR setup from LRAM
3. PMARR setup

Currently, fw_rivos does all 3 operations if FW_RIVOS=y is provided
at runtime. Eventually, #1 should be done by separate R-code stage
code as we need to perform more than jump to LRAM.

Ideally, #2 & #3 should be done stage prior to OpenSBI. In upstream
boot flow U-BOOT SPL can be used to support that. However, Rivos
firmware has already multiple stages boot flow defined. Eventually,
we should be able to drop the code under FW_RIVOS and just load
opensbi as last stage resident M-mode firmware (fw4-m).

Signed-off-by: Atish Patra <atishp@rivosinc.com>
  • Loading branch information
atishp04 committed Aug 23, 2023
1 parent aa7be76 commit 99612b7
Show file tree
Hide file tree
Showing 9 changed files with 178 additions and 2 deletions.
4 changes: 2 additions & 2 deletions firmware/fw_base.ldS
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
}

/* End of the read-write data sections */

. = ALIGN(0x1000); /* Need this to create proper sections */
/* MDRR region needs to be NAPOT regions */
. = ALIGN(1 << LOG2CEIL((SIZEOF(.data) + SIZEOF(.bss))));

PROVIDE(_fw_end = .);
3 changes: 3 additions & 0 deletions firmware/fw_jump.S
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
* Anup Patel <anup.patel@wdc.com>
*/

#ifdef FW_RIVOS
#include "fw_rivos.S"
#endif
#include "fw_base.S"

.section .entry, "ax", %progbits
Expand Down
3 changes: 3 additions & 0 deletions firmware/fw_jump.elf.ldS
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ ENTRY(_start)

SECTIONS
{
#ifdef FW_RIVOS
#include "fw_rivos.ldS"
#endif
#include "fw_base.ldS"

PROVIDE(_fw_reloc_end = .);
Expand Down
3 changes: 3 additions & 0 deletions firmware/fw_payload.S
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
* Anup Patel <anup.patel@wdc.com>
*/

#ifdef FW_RIVOS
#include "fw_rivos.S"
#endif
#include "fw_base.S"

.section .entry, "ax", %progbits
Expand Down
3 changes: 3 additions & 0 deletions firmware/fw_payload.elf.ldS
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ ENTRY(_start)

SECTIONS
{
#ifdef FW_RIVOS
#include "fw_rivos.ldS"
#endif
#include "fw_base.ldS"

#ifdef FW_PAYLOAD_OFFSET
Expand Down
96 changes: 96 additions & 0 deletions firmware/fw_rivos.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2020 Rivos Inc.
*
* Authors:
* Atish Patra <atishp@rivosinc.com>
*/

#include <sbi/riscv_asm.h>
#include <sbi/riscv_encoding.h>
#include <sbi/riscv_elf.h>

.section ".rcode.text", "ax"
/* Entry point at the R-code (realistic) reset vector */
.global _rcode_start
_rcode_start:
lla t0, __lram_start_addr
REG_L t1, 0(t0)
csrw CSR_REPC, t1
.long 0x3020000b /* rret */

.section ".lram.text", "ax"

.global _lram_start
_lram_start:
/* PMARR SETUP */
lla t0, __pmarr_1_start_addr
REG_L t1, 0(t0)
ori t1, t1, 3 /* Program WB ((PMARR_BASE_0[7:0]=3)) */
csrw CSR_PMARR_1_BASE, t1

/* PMARR_0 is at LRAM address(0x7f800000). Hence, program the
* PMARR_1 should be programmed for remaining regions.
* TODO: This is hack and supports 2GB of one WB region so
* M-mode firmware can run with WB memory.
* Ideally, we should program only whatever M-mode requires.
* Remaining regions should be configured after parsing
* the device tree. Don't need anything IO region as default
* is UC.
*/

/* PMARR_1_MASK is ~(size - 1) | 1 (1: valid) */
lla t0, __pmarr_1_size
REG_L t1, 0(t0)
addi t1, t1, -1
not t1, t1
ori t1, t1, 1
csrw CSR_PMARR_1_MASK, t1

fence
fence.i
/* We must have a sfence.vma here to flush the TLB. Otherwise, above loads
* happened as UC region and TLB reports next access as uncacheable.
* Regular loads will still be fine but atomics will fail in that case.
* The alternate solution would be load only from the first 8MB region of
* LRAM which is set as WB after reset.
*/
sfence.vma

/* First program the MDRR */
# MxRR mask is ~(size - 1) | 1 (1: valid)
lla t0, _data_start
lla t1, _fw_end
sub t2, t1, t0
addi t2, t2, -1
not t2, t2
ori t2, t2, 1

csrw CSR_MDRR_MASK, t2
csrw CSR_MDRR_BASE, t0

/* Program the MCRR now */
lla t0, _fw_start
lla t1, _fw_rw_start
sub t2, t1, t0
addi t2, t2, -1
not t2, t2
ori t2, t2, 1
csrw CSR_MCRR_1_MASK, t2
csrw CSR_MCRR_1_BASE, t0

lla t3, __fw_payload_fdt_start
REG_L a1, 0(t3)
jr t0

.data
.align 3
__fw_payload_fdt_start:
RISCV_PTR FW_PAYLOAD_FDT_ADDR
__lram_start_addr:
RISCV_PTR 0x7f800000
__pmarr_1_start_addr:
RISCV_PTR 0x80000000
__pmarr_1_size:
RISCV_PTR 0x80000000
22 changes: 22 additions & 0 deletions firmware/fw_rivos.ldS
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2020 Rivosinc
*
* Authors:
* Atish Patra <atishp@rivosinc.com>
*/

#define RCODE_BASE_ADDR 0x06000000
#define LRAM_BASE_ADDR 0x7f800000


. = RCODE_BASE_ADDR;
.rcode.text : {
KEEP(*(.rcode.text))
}

. = LRAM_BASE_ADDR;
.lram.text : {
KEEP(*(.lram.text))
}
6 changes: 6 additions & 0 deletions firmware/objects.mk
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ firmware-cflags-y += -fPIE -pie
firmware-ldflags-y += -Wl,--no-dynamic-linker -Wl,-pie
endif

ifeq ($(FW_RIVOS),y)
firmware-genflags-y += -DFW_RIVOS=$(FW_RIVOS)
endif

ifdef FW_TEXT_START
firmware-genflags-y += -DFW_TEXT_START=$(FW_TEXT_START)
endif
Expand All @@ -35,7 +39,9 @@ firmware-genflags-y += -DFW_FDT_PADDING=$(FW_FDT_PADDING)
endif
endif

ifndef FW_RIVOS
firmware-bins-$(FW_DYNAMIC) += fw_dynamic.bin
endif

firmware-bins-$(FW_JUMP) += fw_jump.bin
ifdef FW_JUMP_ADDR
Expand Down
40 changes: 40 additions & 0 deletions include/sbi/riscv_encoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,46 @@
#define CSR_MVIPH 0x319
#define CSR_MIPH 0x354

/* Rivos CSRs */

/* R-mode CSRs */

#define CSR_RTVEC 0x800
#define CSR_RMODE 0x801
#define CSR_RSCRATCH 0x802
#define CSR_REPC 0x803

/* Rivos Physical Memory Protection (RPMP) CSRs */
#define CSR_MCRR_0_BASE 0x7d8
#define CSR_MCRR_0_MASK 0x7d9
#define CSR_MCRR_1_BASE 0x7da
#define CSR_MCRR_1_MASK 0x7db

#define CSR_MDRR_BASE 0x7d6
#define CSR_MDRR_MASK 0x7d7

/* Physical Memory Attribute range registers(PMARR) CSRs */
#define CSR_PMARR_0_BASE 0x7c2
#define CSR_PMARR_1_BASE 0x7c3
#define CSR_PMARR_2_BASE 0x7c4
#define CSR_PMARR_3_BASE 0x7c5
#define CSR_PMARR_4_BASE 0x7c6
#define CSR_PMARR_5_BASE 0x7c7
#define CSR_PMARR_6_BASE 0x7c8
#define CSR_PMARR_7_BASE 0x7c9
#define CSR_PMARR_8_BASE 0x7ca
#define CSR_PMARR_9_BASE 0x7cb
#define CSR_PMARR_0_MASK 0x7cc
#define CSR_PMARR_1_MASK 0x7cd
#define CSR_PMARR_2_MASK 0x7ce
#define CSR_PMARR_3_MASK 0x7cf
#define CSR_PMARR_4_MASK 0x7d0
#define CSR_PMARR_5_MASK 0x7d1
#define CSR_PMARR_6_MASK 0x7d2
#define CSR_PMARR_7_MASK 0x7d3
#define CSR_PMARR_8_MASK 0x7d4
#define CSR_PMARR_9_MASK 0x7d5

/* ===== Trap/Exception Causes ===== */

#define CAUSE_MISALIGNED_FETCH 0x0
Expand Down

0 comments on commit 99612b7

Please sign in to comment.