mirror of
https://github.com/riscv-software-src/opensbi
synced 2025-09-13 05:26:04 +01:00
Compare commits
No commits in common. "master" and "v1.7" have entirely different histories.
@ -1,4 +1,4 @@
|
|||||||
# SPDX-License-Identifier: BSD-2-Clause
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
# See here for more information about the format and editor support:
|
# See here for more information about the format and editor support:
|
||||||
# https://editorconfig.org/
|
# https://editorconfig.org/
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@ processor from ETH Zurich. To this end, Ariane has been equipped with a
|
|||||||
different L1 cache subsystem that follows a write-through protocol and that has
|
different L1 cache subsystem that follows a write-through protocol and that has
|
||||||
support for cache invalidations and atomics.
|
support for cache invalidations and atomics.
|
||||||
|
|
||||||
To build platform specific library and firmwares, provide the *PLATFORM=generic*
|
To build platform specific library and firmwares, provide the
|
||||||
parameter to the top level `make` command.
|
*PLATFORM=fpga/openpiton* parameter to the top level `make` command.
|
||||||
|
|
||||||
Platform Options
|
Platform Options
|
||||||
----------------
|
----------------
|
||||||
@ -21,7 +21,7 @@ Building Ariane FPGA Platform
|
|||||||
**Linux Kernel Payload**
|
**Linux Kernel Payload**
|
||||||
|
|
||||||
```
|
```
|
||||||
make PLATFORM=generic FW_PAYLOAD_PATH=<linux_build_directory>/arch/riscv/boot/Image
|
make PLATFORM=fpga/openpiton FW_PAYLOAD_PATH=<linux_build_directory>/arch/riscv/boot/Image
|
||||||
```
|
```
|
||||||
|
|
||||||
Booting Ariane FPGA Platform
|
Booting Ariane FPGA Platform
|
||||||
|
@ -47,7 +47,6 @@ RISC-V Platforms Using Generic Platform
|
|||||||
* **SiFive HiFive Unleashed** (*[sifive_fu540.md]*)
|
* **SiFive HiFive Unleashed** (*[sifive_fu540.md]*)
|
||||||
* **Spike** (*[spike.md]*)
|
* **Spike** (*[spike.md]*)
|
||||||
* **T-HEAD C9xx series Processors** (*[thead-c9xx.md]*)
|
* **T-HEAD C9xx series Processors** (*[thead-c9xx.md]*)
|
||||||
* **OpenPiton FPGA SoC** (*[fpga-openpiton.md]*)
|
|
||||||
|
|
||||||
[andes-ae350.md]: andes-ae350.md
|
[andes-ae350.md]: andes-ae350.md
|
||||||
[qemu_virt.md]: qemu_virt.md
|
[qemu_virt.md]: qemu_virt.md
|
||||||
@ -56,4 +55,3 @@ RISC-V Platforms Using Generic Platform
|
|||||||
[sifive_fu540.md]: sifive_fu540.md
|
[sifive_fu540.md]: sifive_fu540.md
|
||||||
[spike.md]: spike.md
|
[spike.md]: spike.md
|
||||||
[thead-c9xx.md]: thead-c9xx.md
|
[thead-c9xx.md]: thead-c9xx.md
|
||||||
[fpga-openpiton.md]: fpga-openpiton.md
|
|
||||||
|
@ -31,6 +31,10 @@ OpenSBI currently supports the following virtual and hardware platforms:
|
|||||||
* **Spike**: Platform support for the Spike emulator. More
|
* **Spike**: Platform support for the Spike emulator. More
|
||||||
details on this platform can be found in the file *[spike.md]*.
|
details on this platform can be found in the file *[spike.md]*.
|
||||||
|
|
||||||
|
* **OpenPiton FPGA SoC**: Platform support OpenPiton research platform based
|
||||||
|
on ariane core. More details on this platform can be found in the file
|
||||||
|
*[fpga-openpiton.md]*.
|
||||||
|
|
||||||
* **Shakti C-class SoC Platform**: Platform support for Shakti C-class
|
* **Shakti C-class SoC Platform**: Platform support for Shakti C-class
|
||||||
processor based SOCs. More details on this platform can be found in the
|
processor based SOCs. More details on this platform can be found in the
|
||||||
file *[shakti_cclass.md]*.
|
file *[shakti_cclass.md]*.
|
||||||
@ -52,5 +56,6 @@ comments to facilitate the implementation.
|
|||||||
[andes-ae350.md]: andes-ae350.md
|
[andes-ae350.md]: andes-ae350.md
|
||||||
[thead-c910.md]: thead-c910.md
|
[thead-c910.md]: thead-c910.md
|
||||||
[spike.md]: spike.md
|
[spike.md]: spike.md
|
||||||
|
[fpga-openpiton.md]: fpga-openpiton.md
|
||||||
[shakti_cclass.md]: shakti_cclass.md
|
[shakti_cclass.md]: shakti_cclass.md
|
||||||
[renesas-rzfive.md]: renesas-rzfive.md
|
[renesas-rzfive.md]: renesas-rzfive.md
|
||||||
|
@ -1,28 +1 @@
|
|||||||
# SPDX-License-Identifier: BSD-2-Clause
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
menu "Stack Protector Support"
|
|
||||||
|
|
||||||
config STACK_PROTECTOR
|
|
||||||
bool "Stack Protector buffer overflow detection"
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
This option turns on the "stack-protector" compiler feature.
|
|
||||||
|
|
||||||
config STACK_PROTECTOR_STRONG
|
|
||||||
bool "Strong Stack Protector"
|
|
||||||
depends on STACK_PROTECTOR
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
Turn on the "stack-protector" with "-fstack-protector-strong" option.
|
|
||||||
Like -fstack-protector but includes additional functions to be
|
|
||||||
protected.
|
|
||||||
|
|
||||||
config STACK_PROTECTOR_ALL
|
|
||||||
bool "Almighty Stack Protector"
|
|
||||||
depends on STACK_PROTECTOR
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
Turn on the "stack-protector" with "-fstack-protector-all" option.
|
|
||||||
Like -fstack-protector except that all functions are protected.
|
|
||||||
|
|
||||||
endmenu
|
|
||||||
|
@ -76,21 +76,21 @@ _sc_fail:
|
|||||||
li t0, FW_TEXT_START /* link start */
|
li t0, FW_TEXT_START /* link start */
|
||||||
lla t1, _fw_start /* load start */
|
lla t1, _fw_start /* load start */
|
||||||
sub t2, t1, t0 /* load offset */
|
sub t2, t1, t0 /* load offset */
|
||||||
lla t0, __rela_dyn_start
|
lla t0, __rel_dyn_start
|
||||||
lla t1, __rela_dyn_end
|
lla t1, __rel_dyn_end
|
||||||
beq t0, t1, _relocate_done
|
beq t0, t1, _relocate_done
|
||||||
2:
|
2:
|
||||||
REG_L t5, __SIZEOF_LONG__(t0) /* t5 <-- relocation info:type */
|
REG_L t5, REGBYTES(t0) /* t5 <-- relocation info:type */
|
||||||
li t3, R_RISCV_RELATIVE /* reloc type R_RISCV_RELATIVE */
|
li t3, R_RISCV_RELATIVE /* reloc type R_RISCV_RELATIVE */
|
||||||
bne t5, t3, 3f
|
bne t5, t3, 3f
|
||||||
REG_L t3, 0(t0)
|
REG_L t3, 0(t0)
|
||||||
REG_L t5, (__SIZEOF_LONG__ * 2)(t0) /* t5 <-- addend */
|
REG_L t5, (REGBYTES * 2)(t0) /* t5 <-- addend */
|
||||||
add t5, t5, t2
|
add t5, t5, t2
|
||||||
add t3, t3, t2
|
add t3, t3, t2
|
||||||
REG_S t5, 0(t3) /* store runtime address to the GOT entry */
|
REG_S t5, 0(t3) /* store runtime address to the GOT entry */
|
||||||
|
|
||||||
3:
|
3:
|
||||||
addi t0, t0, (__SIZEOF_LONG__ * 3)
|
addi t0, t0, (REGBYTES * 3)
|
||||||
blt t0, t1, 2b
|
blt t0, t1, 2b
|
||||||
_relocate_done:
|
_relocate_done:
|
||||||
/* At this point we are running from link address */
|
/* At this point we are running from link address */
|
||||||
@ -736,27 +736,6 @@ _reset_regs:
|
|||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.section .rodata
|
|
||||||
.Lstack_corrupt_msg:
|
|
||||||
.string "stack smashing detected\n"
|
|
||||||
|
|
||||||
/* This will be called when the stack corruption is detected */
|
|
||||||
.section .text
|
|
||||||
.align 3
|
|
||||||
.globl __stack_chk_fail
|
|
||||||
.type __stack_chk_fail, %function
|
|
||||||
__stack_chk_fail:
|
|
||||||
la a0, .Lstack_corrupt_msg
|
|
||||||
call sbi_panic
|
|
||||||
|
|
||||||
/* Initial value of the stack guard variable */
|
|
||||||
.section .data
|
|
||||||
.align 3
|
|
||||||
.globl __stack_chk_guard
|
|
||||||
.type __stack_chk_guard, %object
|
|
||||||
__stack_chk_guard:
|
|
||||||
RISCV_PTR 0x95B5FF5A
|
|
||||||
|
|
||||||
#ifdef FW_FDT_PATH
|
#ifdef FW_FDT_PATH
|
||||||
.section .rodata
|
.section .rodata
|
||||||
.align 4
|
.align 4
|
||||||
|
@ -47,9 +47,9 @@
|
|||||||
. = ALIGN(0x1000); /* Ensure next section is page aligned */
|
. = ALIGN(0x1000); /* Ensure next section is page aligned */
|
||||||
|
|
||||||
.rela.dyn : {
|
.rela.dyn : {
|
||||||
PROVIDE(__rela_dyn_start = .);
|
PROVIDE(__rel_dyn_start = .);
|
||||||
*(.rela*)
|
*(.rela*)
|
||||||
PROVIDE(__rela_dyn_end = .);
|
PROVIDE(__rel_dyn_end = .);
|
||||||
}
|
}
|
||||||
|
|
||||||
PROVIDE(_rodata_end = .);
|
PROVIDE(_rodata_end = .);
|
||||||
|
@ -66,12 +66,3 @@ endif
|
|||||||
ifdef FW_OPTIONS
|
ifdef FW_OPTIONS
|
||||||
firmware-genflags-y += -DFW_OPTIONS=$(FW_OPTIONS)
|
firmware-genflags-y += -DFW_OPTIONS=$(FW_OPTIONS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_STACK_PROTECTOR),y)
|
|
||||||
stack-protector-cflags-$(CONFIG_STACK_PROTECTOR) := -fstack-protector
|
|
||||||
stack-protector-cflags-$(CONFIG_STACK_PROTECTOR_STRONG) := -fstack-protector-strong
|
|
||||||
stack-protector-cflags-$(CONFIG_STACK_PROTECTOR_ALL) := -fstack-protector-all
|
|
||||||
else
|
|
||||||
stack-protector-cflags-y := -fno-stack-protector
|
|
||||||
endif
|
|
||||||
firmware-cflags-y += $(stack-protector-cflags-y)
|
|
||||||
|
@ -97,18 +97,3 @@ _boot_a0:
|
|||||||
RISCV_PTR 0
|
RISCV_PTR 0
|
||||||
_boot_a1:
|
_boot_a1:
|
||||||
RISCV_PTR 0
|
RISCV_PTR 0
|
||||||
|
|
||||||
/* This will be called when the stack corruption is detected */
|
|
||||||
.section .text
|
|
||||||
.align 3
|
|
||||||
.globl __stack_chk_fail
|
|
||||||
.type __stack_chk_fail, %function
|
|
||||||
.equ __stack_chk_fail, _start_hang
|
|
||||||
|
|
||||||
/* Initial value of the stack guard variable */
|
|
||||||
.section .data
|
|
||||||
.align 3
|
|
||||||
.globl __stack_chk_guard
|
|
||||||
.type __stack_chk_guard, %object
|
|
||||||
__stack_chk_guard:
|
|
||||||
RISCV_PTR 0x95B5FF5A
|
|
||||||
|
@ -46,13 +46,6 @@ static inline void sbi_ecall_console_puts(const char *str)
|
|||||||
sbi_strlen(str), (unsigned long)str, 0, 0, 0, 0);
|
sbi_strlen(str), (unsigned long)str, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sbi_ecall_shutdown(void)
|
|
||||||
{
|
|
||||||
sbi_ecall(SBI_EXT_SRST, SBI_EXT_SRST_RESET,
|
|
||||||
SBI_SRST_RESET_TYPE_SHUTDOWN, SBI_SRST_RESET_REASON_NONE,
|
|
||||||
0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define wfi() \
|
#define wfi() \
|
||||||
do { \
|
do { \
|
||||||
__asm__ __volatile__("wfi" ::: "memory"); \
|
__asm__ __volatile__("wfi" ::: "memory"); \
|
||||||
@ -61,6 +54,7 @@ static inline void sbi_ecall_shutdown(void)
|
|||||||
void test_main(unsigned long a0, unsigned long a1)
|
void test_main(unsigned long a0, unsigned long a1)
|
||||||
{
|
{
|
||||||
sbi_ecall_console_puts("\nTest payload running\n");
|
sbi_ecall_console_puts("\nTest payload running\n");
|
||||||
sbi_ecall_shutdown();
|
|
||||||
sbi_ecall_console_puts("sbi_ecall_shutdown failed to execute.\n");
|
while (1)
|
||||||
|
wfi();
|
||||||
}
|
}
|
||||||
|
@ -122,50 +122,6 @@ enum {
|
|||||||
RV_DBTR_DECLARE_BIT_MASK(MC, TYPE, 4),
|
RV_DBTR_DECLARE_BIT_MASK(MC, TYPE, 4),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* ICOUNT - Match Control Type Register */
|
|
||||||
enum {
|
|
||||||
RV_DBTR_DECLARE_BIT(ICOUNT, ACTION, 0),
|
|
||||||
RV_DBTR_DECLARE_BIT(ICOUNT, U, 6),
|
|
||||||
RV_DBTR_DECLARE_BIT(ICOUNT, S, 7),
|
|
||||||
RV_DBTR_DECLARE_BIT(ICOUNT, PENDING, 8),
|
|
||||||
RV_DBTR_DECLARE_BIT(ICOUNT, M, 9),
|
|
||||||
RV_DBTR_DECLARE_BIT(ICOUNT, COUNT, 10),
|
|
||||||
RV_DBTR_DECLARE_BIT(ICOUNT, HIT, 24),
|
|
||||||
RV_DBTR_DECLARE_BIT(ICOUNT, VU, 25),
|
|
||||||
RV_DBTR_DECLARE_BIT(ICOUNT, VS, 26),
|
|
||||||
#if __riscv_xlen == 64
|
|
||||||
RV_DBTR_DECLARE_BIT(ICOUNT, DMODE, 59),
|
|
||||||
RV_DBTR_DECLARE_BIT(ICOUNT, TYPE, 60),
|
|
||||||
#elif __riscv_xlen == 32
|
|
||||||
RV_DBTR_DECLARE_BIT(ICOUNT, DMODE, 27),
|
|
||||||
RV_DBTR_DECLARE_BIT(ICOUNT, TYPE, 28),
|
|
||||||
#else
|
|
||||||
#error "Unknown __riscv_xlen"
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
RV_DBTR_DECLARE_BIT_MASK(ICOUNT, ACTION, 6),
|
|
||||||
RV_DBTR_DECLARE_BIT_MASK(ICOUNT, U, 1),
|
|
||||||
RV_DBTR_DECLARE_BIT_MASK(ICOUNT, S, 1),
|
|
||||||
RV_DBTR_DECLARE_BIT_MASK(ICOUNT, PENDING, 1),
|
|
||||||
RV_DBTR_DECLARE_BIT_MASK(ICOUNT, M, 1),
|
|
||||||
RV_DBTR_DECLARE_BIT_MASK(ICOUNT, COUNT, 14),
|
|
||||||
RV_DBTR_DECLARE_BIT_MASK(ICOUNT, HIT, 1),
|
|
||||||
RV_DBTR_DECLARE_BIT_MASK(ICOUNT, VU, 1),
|
|
||||||
RV_DBTR_DECLARE_BIT_MASK(ICOUNT, VS, 1),
|
|
||||||
#if __riscv_xlen == 64
|
|
||||||
RV_DBTR_DECLARE_BIT_MASK(ICOUNT, DMODE, 1),
|
|
||||||
RV_DBTR_DECLARE_BIT_MASK(ICOUNT, TYPE, 4),
|
|
||||||
#elif __riscv_xlen == 32
|
|
||||||
RV_DBTR_DECLARE_BIT_MASK(ICOUNT, DMODE, 1),
|
|
||||||
RV_DBTR_DECLARE_BIT_MASK(ICOUNT, TYPE, 4),
|
|
||||||
#else
|
|
||||||
#error "Unknown __riscv_xlen"
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/* MC6 - Match Control 6 Type Register */
|
/* MC6 - Match Control 6 Type Register */
|
||||||
enum {
|
enum {
|
||||||
RV_DBTR_DECLARE_BIT(MC6, LOAD, 0),
|
RV_DBTR_DECLARE_BIT(MC6, LOAD, 0),
|
||||||
|
@ -1291,8 +1291,6 @@
|
|||||||
#define SHIFT_FUNCT3 12
|
#define SHIFT_FUNCT3 12
|
||||||
|
|
||||||
#define MASK_RS1 0xf8000
|
#define MASK_RS1 0xf8000
|
||||||
#define MASK_RS2 0x1f00000
|
|
||||||
#define MASK_RD 0xf80
|
|
||||||
|
|
||||||
#define MASK_CSR 0xfff00000
|
#define MASK_CSR 0xfff00000
|
||||||
#define SHIFT_CSR 20
|
#define SHIFT_CSR 20
|
||||||
@ -1317,6 +1315,13 @@
|
|||||||
|
|
||||||
#define INSN_LEN(insn) (INSN_IS_16BIT(insn) ? 2 : 4)
|
#define INSN_LEN(insn) (INSN_IS_16BIT(insn) ? 2 : 4)
|
||||||
|
|
||||||
|
#if __riscv_xlen == 64
|
||||||
|
#define LOG_REGBYTES 3
|
||||||
|
#else
|
||||||
|
#define LOG_REGBYTES 2
|
||||||
|
#endif
|
||||||
|
#define REGBYTES (1 << LOG_REGBYTES)
|
||||||
|
|
||||||
#define SH_VSEW 3
|
#define SH_VSEW 3
|
||||||
#define SH_VIEW 12
|
#define SH_VIEW 12
|
||||||
#define SH_VD 7
|
#define SH_VD 7
|
||||||
@ -1351,17 +1356,28 @@
|
|||||||
#define SHIFT_RIGHT(x, y) \
|
#define SHIFT_RIGHT(x, y) \
|
||||||
((y) < 0 ? ((x) << -(y)) : ((x) >> (y)))
|
((y) < 0 ? ((x) << -(y)) : ((x) >> (y)))
|
||||||
|
|
||||||
|
#define REG_MASK \
|
||||||
|
((1 << (5 + LOG_REGBYTES)) - (1 << LOG_REGBYTES))
|
||||||
|
|
||||||
|
#define REG_OFFSET(insn, pos) \
|
||||||
|
(SHIFT_RIGHT((insn), (pos) - LOG_REGBYTES) & REG_MASK)
|
||||||
|
|
||||||
|
#define REG_PTR(insn, pos, regs) \
|
||||||
|
(ulong *)((ulong)(regs) + REG_OFFSET(insn, pos))
|
||||||
|
|
||||||
#define GET_FUNC3(insn) ((insn & MASK_FUNCT3) >> SHIFT_FUNCT3)
|
#define GET_FUNC3(insn) ((insn & MASK_FUNCT3) >> SHIFT_FUNCT3)
|
||||||
#define GET_RM(insn) GET_FUNC3(insn)
|
#define GET_RM(insn) GET_FUNC3(insn)
|
||||||
#define GET_RS1_NUM(insn) ((insn & MASK_RS1) >> SH_RS1)
|
#define GET_RS1_NUM(insn) ((insn & MASK_RS1) >> 15)
|
||||||
#define GET_RS2_NUM(insn) ((insn & MASK_RS2) >> SH_RS2)
|
|
||||||
#define GET_RS1S_NUM(insn) RVC_RS1S(insn)
|
|
||||||
#define GET_RS2S_NUM(insn) RVC_RS2S(insn)
|
|
||||||
#define GET_RS2C_NUM(insn) RVC_RS2(insn)
|
|
||||||
#define GET_RD_NUM(insn) ((insn & MASK_RD) >> SH_RD)
|
|
||||||
#define GET_CSR_NUM(insn) ((insn & MASK_CSR) >> SHIFT_CSR)
|
#define GET_CSR_NUM(insn) ((insn & MASK_CSR) >> SHIFT_CSR)
|
||||||
#define GET_AQRL(insn) ((insn & MASK_AQRL) >> SHIFT_AQRL)
|
#define GET_AQRL(insn) ((insn & MASK_AQRL) >> SHIFT_AQRL)
|
||||||
|
|
||||||
|
#define GET_RS1(insn, regs) (*REG_PTR(insn, SH_RS1, regs))
|
||||||
|
#define GET_RS2(insn, regs) (*REG_PTR(insn, SH_RS2, regs))
|
||||||
|
#define GET_RS1S(insn, regs) (*REG_PTR(RVC_RS1S(insn), 0, regs))
|
||||||
|
#define GET_RS2S(insn, regs) (*REG_PTR(RVC_RS2S(insn), 0, regs))
|
||||||
|
#define GET_RS2C(insn, regs) (*REG_PTR(insn, SH_RS2C, regs))
|
||||||
|
#define GET_SP(regs) (*REG_PTR(2, 0, regs))
|
||||||
|
#define SET_RD(insn, regs, val) (*REG_PTR(insn, SH_RD, regs) = (val))
|
||||||
#define IMM_I(insn) ((s32)(insn) >> 20)
|
#define IMM_I(insn) ((s32)(insn) >> 20)
|
||||||
#define IMM_S(insn) (((s32)(insn) >> 25 << 5) | \
|
#define IMM_S(insn) (((s32)(insn) >> 25 << 5) | \
|
||||||
(s32)(((insn) >> 7) & 0x1f))
|
(s32)(((insn) >> 7) & 0x1f))
|
||||||
|
@ -14,13 +14,13 @@
|
|||||||
# define _conv_cast(type, val) ((type)(val))
|
# define _conv_cast(type, val) ((type)(val))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define __BSWAP16(x) ((((x) & 0x00ff) << 8) | \
|
#define BSWAP16(x) ((((x) & 0x00ff) << 8) | \
|
||||||
(((x) & 0xff00) >> 8))
|
(((x) & 0xff00) >> 8))
|
||||||
#define __BSWAP32(x) ((((x) & 0x000000ff) << 24) | \
|
#define BSWAP32(x) ((((x) & 0x000000ff) << 24) | \
|
||||||
(((x) & 0x0000ff00) << 8) | \
|
(((x) & 0x0000ff00) << 8) | \
|
||||||
(((x) & 0x00ff0000) >> 8) | \
|
(((x) & 0x00ff0000) >> 8) | \
|
||||||
(((x) & 0xff000000) >> 24))
|
(((x) & 0xff000000) >> 24))
|
||||||
#define __BSWAP64(x) ((((x) & 0x00000000000000ffULL) << 56) | \
|
#define BSWAP64(x) ((((x) & 0x00000000000000ffULL) << 56) | \
|
||||||
(((x) & 0x000000000000ff00ULL) << 40) | \
|
(((x) & 0x000000000000ff00ULL) << 40) | \
|
||||||
(((x) & 0x0000000000ff0000ULL) << 24) | \
|
(((x) & 0x0000000000ff0000ULL) << 24) | \
|
||||||
(((x) & 0x00000000ff000000ULL) << 8) | \
|
(((x) & 0x00000000ff000000ULL) << 8) | \
|
||||||
@ -29,10 +29,6 @@
|
|||||||
(((x) & 0x00ff000000000000ULL) >> 40) | \
|
(((x) & 0x00ff000000000000ULL) >> 40) | \
|
||||||
(((x) & 0xff00000000000000ULL) >> 56))
|
(((x) & 0xff00000000000000ULL) >> 56))
|
||||||
|
|
||||||
#define BSWAP64(x) ({ uint64_t _sv = (x); __BSWAP64(_sv); })
|
|
||||||
#define BSWAP32(x) ({ uint32_t _sv = (x); __BSWAP32(_sv); })
|
|
||||||
#define BSWAP16(x) ({ uint16_t _sv = (x); __BSWAP16(_sv); })
|
|
||||||
|
|
||||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* CPU(little-endian) */
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* CPU(little-endian) */
|
||||||
#define cpu_to_be16(x) _conv_cast(uint16_t, BSWAP16(x))
|
#define cpu_to_be16(x) _conv_cast(uint16_t, BSWAP16(x))
|
||||||
#define cpu_to_be32(x) _conv_cast(uint32_t, BSWAP32(x))
|
#define cpu_to_be32(x) _conv_cast(uint32_t, BSWAP32(x))
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
({ \
|
({ \
|
||||||
register ulong tinfo asm("a3") = (ulong)trap; \
|
register ulong tinfo asm("a3") = (ulong)trap; \
|
||||||
register ulong ttmp asm("a4"); \
|
register ulong ttmp asm("a4"); \
|
||||||
register ulong mtvec = (ulong)sbi_hart_expected_trap; \
|
register ulong mtvec = sbi_hart_expected_trap_addr(); \
|
||||||
register ulong ret = 0; \
|
register ulong ret = 0; \
|
||||||
((struct sbi_trap_info *)(trap))->cause = 0; \
|
((struct sbi_trap_info *)(trap))->cause = 0; \
|
||||||
asm volatile( \
|
asm volatile( \
|
||||||
@ -37,7 +37,7 @@
|
|||||||
({ \
|
({ \
|
||||||
register ulong tinfo asm("a3") = (ulong)trap; \
|
register ulong tinfo asm("a3") = (ulong)trap; \
|
||||||
register ulong ttmp asm("a4"); \
|
register ulong ttmp asm("a4"); \
|
||||||
register ulong mtvec = (ulong)sbi_hart_expected_trap; \
|
register ulong mtvec = sbi_hart_expected_trap_addr(); \
|
||||||
((struct sbi_trap_info *)(trap))->cause = 0; \
|
((struct sbi_trap_info *)(trap))->cause = 0; \
|
||||||
asm volatile( \
|
asm volatile( \
|
||||||
"add %[ttmp], %[tinfo], zero\n" \
|
"add %[ttmp], %[tinfo], zero\n" \
|
||||||
|
@ -134,6 +134,10 @@ int sbi_hart_reinit(struct sbi_scratch *scratch);
|
|||||||
int sbi_hart_init(struct sbi_scratch *scratch, bool cold_boot);
|
int sbi_hart_init(struct sbi_scratch *scratch, bool cold_boot);
|
||||||
|
|
||||||
extern void (*sbi_hart_expected_trap)(void);
|
extern void (*sbi_hart_expected_trap)(void);
|
||||||
|
static inline ulong sbi_hart_expected_trap_addr(void)
|
||||||
|
{
|
||||||
|
return (ulong)sbi_hart_expected_trap;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int sbi_hart_mhpm_mask(struct sbi_scratch *scratch);
|
unsigned int sbi_hart_mhpm_mask(struct sbi_scratch *scratch);
|
||||||
void sbi_hart_delegation_dump(struct sbi_scratch *scratch,
|
void sbi_hart_delegation_dump(struct sbi_scratch *scratch,
|
||||||
|
@ -160,28 +160,4 @@ static inline void sbi_list_del_init(struct sbi_dlist *entry)
|
|||||||
&pos->member != (head); \
|
&pos->member != (head); \
|
||||||
pos = sbi_list_entry(pos->member.next, typeof(*pos), member))
|
pos = sbi_list_entry(pos->member.next, typeof(*pos), member))
|
||||||
|
|
||||||
/**
|
|
||||||
* Iterate over list of given type safe against removal of list entry
|
|
||||||
* @param pos the type * to use as a loop cursor.
|
|
||||||
* @param n another type * to use as temporary storage.
|
|
||||||
* @param head the head for your list.
|
|
||||||
* @param member the name of the list_struct within the struct.
|
|
||||||
*/
|
|
||||||
#define sbi_list_for_each_entry_safe(pos, n, head, member) \
|
|
||||||
for (pos = sbi_list_entry((head)->next, typeof(*pos), member), \
|
|
||||||
n = sbi_list_entry(pos->member.next, typeof(*pos), member); \
|
|
||||||
&pos->member != (head); \
|
|
||||||
pos = n, n = sbi_list_entry(pos->member.next, typeof(*pos), member))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Iterate over list of given type in reverse order
|
|
||||||
* @param pos the type * to use as a loop cursor.
|
|
||||||
* @param head the head for your list.
|
|
||||||
* @param member the name of the list_struct within the struct.
|
|
||||||
*/
|
|
||||||
#define sbi_list_for_each_entry_reverse(pos, head, member) \
|
|
||||||
for (pos = sbi_list_entry((head)->prev, typeof(*pos), member); \
|
|
||||||
&pos->member != (head); \
|
|
||||||
pos = sbi_list_entry(pos->member.prev, typeof(*pos), member))
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -127,75 +127,70 @@
|
|||||||
|
|
||||||
/** Representation of register state at time of trap/interrupt */
|
/** Representation of register state at time of trap/interrupt */
|
||||||
struct sbi_trap_regs {
|
struct sbi_trap_regs {
|
||||||
union {
|
/** zero register state */
|
||||||
unsigned long gprs[32];
|
unsigned long zero;
|
||||||
struct {
|
/** ra register state */
|
||||||
/** zero register state */
|
unsigned long ra;
|
||||||
unsigned long zero;
|
/** sp register state */
|
||||||
/** ra register state */
|
unsigned long sp;
|
||||||
unsigned long ra;
|
/** gp register state */
|
||||||
/** sp register state */
|
unsigned long gp;
|
||||||
unsigned long sp;
|
/** tp register state */
|
||||||
/** gp register state */
|
unsigned long tp;
|
||||||
unsigned long gp;
|
/** t0 register state */
|
||||||
/** tp register state */
|
unsigned long t0;
|
||||||
unsigned long tp;
|
/** t1 register state */
|
||||||
/** t0 register state */
|
unsigned long t1;
|
||||||
unsigned long t0;
|
/** t2 register state */
|
||||||
/** t1 register state */
|
unsigned long t2;
|
||||||
unsigned long t1;
|
/** s0 register state */
|
||||||
/** t2 register state */
|
unsigned long s0;
|
||||||
unsigned long t2;
|
/** s1 register state */
|
||||||
/** s0 register state */
|
unsigned long s1;
|
||||||
unsigned long s0;
|
/** a0 register state */
|
||||||
/** s1 register state */
|
unsigned long a0;
|
||||||
unsigned long s1;
|
/** a1 register state */
|
||||||
/** a0 register state */
|
unsigned long a1;
|
||||||
unsigned long a0;
|
/** a2 register state */
|
||||||
/** a1 register state */
|
unsigned long a2;
|
||||||
unsigned long a1;
|
/** a3 register state */
|
||||||
/** a2 register state */
|
unsigned long a3;
|
||||||
unsigned long a2;
|
/** a4 register state */
|
||||||
/** a3 register state */
|
unsigned long a4;
|
||||||
unsigned long a3;
|
/** a5 register state */
|
||||||
/** a4 register state */
|
unsigned long a5;
|
||||||
unsigned long a4;
|
/** a6 register state */
|
||||||
/** a5 register state */
|
unsigned long a6;
|
||||||
unsigned long a5;
|
/** a7 register state */
|
||||||
/** a6 register state */
|
unsigned long a7;
|
||||||
unsigned long a6;
|
/** s2 register state */
|
||||||
/** a7 register state */
|
unsigned long s2;
|
||||||
unsigned long a7;
|
/** s3 register state */
|
||||||
/** s2 register state */
|
unsigned long s3;
|
||||||
unsigned long s2;
|
/** s4 register state */
|
||||||
/** s3 register state */
|
unsigned long s4;
|
||||||
unsigned long s3;
|
/** s5 register state */
|
||||||
/** s4 register state */
|
unsigned long s5;
|
||||||
unsigned long s4;
|
/** s6 register state */
|
||||||
/** s5 register state */
|
unsigned long s6;
|
||||||
unsigned long s5;
|
/** s7 register state */
|
||||||
/** s6 register state */
|
unsigned long s7;
|
||||||
unsigned long s6;
|
/** s8 register state */
|
||||||
/** s7 register state */
|
unsigned long s8;
|
||||||
unsigned long s7;
|
/** s9 register state */
|
||||||
/** s8 register state */
|
unsigned long s9;
|
||||||
unsigned long s8;
|
/** s10 register state */
|
||||||
/** s9 register state */
|
unsigned long s10;
|
||||||
unsigned long s9;
|
/** s11 register state */
|
||||||
/** s10 register state */
|
unsigned long s11;
|
||||||
unsigned long s10;
|
/** t3 register state */
|
||||||
/** s11 register state */
|
unsigned long t3;
|
||||||
unsigned long s11;
|
/** t4 register state */
|
||||||
/** t3 register state */
|
unsigned long t4;
|
||||||
unsigned long t3;
|
/** t5 register state */
|
||||||
/** t4 register state */
|
unsigned long t5;
|
||||||
unsigned long t4;
|
/** t6 register state */
|
||||||
/** t5 register state */
|
unsigned long t6;
|
||||||
unsigned long t5;
|
|
||||||
/** t6 register state */
|
|
||||||
unsigned long t6;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
/** mepc register state */
|
/** mepc register state */
|
||||||
unsigned long mepc;
|
unsigned long mepc;
|
||||||
/** mstatus register state */
|
/** mstatus register state */
|
||||||
@ -204,21 +199,6 @@ struct sbi_trap_regs {
|
|||||||
unsigned long mstatusH;
|
unsigned long mstatusH;
|
||||||
};
|
};
|
||||||
|
|
||||||
_Static_assert(
|
|
||||||
sizeof(((struct sbi_trap_regs *)0)->gprs) ==
|
|
||||||
offsetof(struct sbi_trap_regs, t6) +
|
|
||||||
sizeof(((struct sbi_trap_regs *)0)->t6),
|
|
||||||
"struct sbi_trap_regs's layout differs between gprs and named members");
|
|
||||||
|
|
||||||
#define REG_VAL(idx, regs) ((regs)->gprs[(idx)])
|
|
||||||
|
|
||||||
#define GET_RS1(insn, regs) REG_VAL(GET_RS1_NUM(insn), regs)
|
|
||||||
#define GET_RS2(insn, regs) REG_VAL(GET_RS2_NUM(insn), regs)
|
|
||||||
#define GET_RS1S(insn, regs) REG_VAL(GET_RS1S_NUM(insn), regs)
|
|
||||||
#define GET_RS2S(insn, regs) REG_VAL(GET_RS2S_NUM(insn), regs)
|
|
||||||
#define GET_RS2C(insn, regs) REG_VAL(GET_RS2C_NUM(insn), regs)
|
|
||||||
#define SET_RD(insn, regs, val) (REG_VAL(GET_RD_NUM(insn), regs) = (val))
|
|
||||||
|
|
||||||
/** Representation of trap details */
|
/** Representation of trap details */
|
||||||
struct sbi_trap_info {
|
struct sbi_trap_info {
|
||||||
/** cause Trap exception cause */
|
/** cause Trap exception cause */
|
||||||
|
@ -7,12 +7,10 @@
|
|||||||
#ifndef __SBI_VISIBILITY_H__
|
#ifndef __SBI_VISIBILITY_H__
|
||||||
#define __SBI_VISIBILITY_H__
|
#define __SBI_VISIBILITY_H__
|
||||||
|
|
||||||
#ifndef __DTS__
|
|
||||||
/*
|
/*
|
||||||
* Declare all global objects with hidden visibility so access is PC-relative
|
* Declare all global objects with hidden visibility so access is PC-relative
|
||||||
* instead of going through the GOT.
|
* instead of going through the GOT.
|
||||||
*/
|
*/
|
||||||
#pragma GCC visibility push(hidden)
|
#pragma GCC visibility push(hidden)
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -336,19 +336,6 @@ static void dbtr_trigger_setup(struct sbi_dbtr_trigger *trig,
|
|||||||
if (__test_bit(RV_DBTR_BIT(MC6, VS), &tdata1))
|
if (__test_bit(RV_DBTR_BIT(MC6, VS), &tdata1))
|
||||||
__set_bit(RV_DBTR_BIT(TS, VS), &trig->state);
|
__set_bit(RV_DBTR_BIT(TS, VS), &trig->state);
|
||||||
break;
|
break;
|
||||||
case RISCV_DBTR_TRIG_ICOUNT:
|
|
||||||
if (__test_bit(RV_DBTR_BIT(ICOUNT, U), &tdata1))
|
|
||||||
__set_bit(RV_DBTR_BIT(TS, U), &trig->state);
|
|
||||||
|
|
||||||
if (__test_bit(RV_DBTR_BIT(ICOUNT, S), &tdata1))
|
|
||||||
__set_bit(RV_DBTR_BIT(TS, S), &trig->state);
|
|
||||||
|
|
||||||
if (__test_bit(RV_DBTR_BIT(ICOUNT, VU), &tdata1))
|
|
||||||
__set_bit(RV_DBTR_BIT(TS, VU), &trig->state);
|
|
||||||
|
|
||||||
if (__test_bit(RV_DBTR_BIT(ICOUNT, VS), &tdata1))
|
|
||||||
__set_bit(RV_DBTR_BIT(TS, VS), &trig->state);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
sbi_dprintf("%s: Unknown type (tdata1: 0x%lx Type: %ld)\n",
|
sbi_dprintf("%s: Unknown type (tdata1: 0x%lx Type: %ld)\n",
|
||||||
__func__, tdata1, TDATA1_GET_TYPE(tdata1));
|
__func__, tdata1, TDATA1_GET_TYPE(tdata1));
|
||||||
@ -392,16 +379,6 @@ static void dbtr_trigger_enable(struct sbi_dbtr_trigger *trig)
|
|||||||
update_bit(state & RV_DBTR_BIT_MASK(TS, S),
|
update_bit(state & RV_DBTR_BIT_MASK(TS, S),
|
||||||
RV_DBTR_BIT(MC6, S), &trig->tdata1);
|
RV_DBTR_BIT(MC6, S), &trig->tdata1);
|
||||||
break;
|
break;
|
||||||
case RISCV_DBTR_TRIG_ICOUNT:
|
|
||||||
update_bit(state & RV_DBTR_BIT_MASK(TS, VU),
|
|
||||||
RV_DBTR_BIT(ICOUNT, VU), &trig->tdata1);
|
|
||||||
update_bit(state & RV_DBTR_BIT_MASK(TS, VS),
|
|
||||||
RV_DBTR_BIT(ICOUNT, VS), &trig->tdata1);
|
|
||||||
update_bit(state & RV_DBTR_BIT_MASK(TS, U),
|
|
||||||
RV_DBTR_BIT(ICOUNT, U), &trig->tdata1);
|
|
||||||
update_bit(state & RV_DBTR_BIT_MASK(TS, S),
|
|
||||||
RV_DBTR_BIT(ICOUNT, S), &trig->tdata1);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -441,12 +418,6 @@ static void dbtr_trigger_disable(struct sbi_dbtr_trigger *trig)
|
|||||||
__clear_bit(RV_DBTR_BIT(MC6, U), &trig->tdata1);
|
__clear_bit(RV_DBTR_BIT(MC6, U), &trig->tdata1);
|
||||||
__clear_bit(RV_DBTR_BIT(MC6, S), &trig->tdata1);
|
__clear_bit(RV_DBTR_BIT(MC6, S), &trig->tdata1);
|
||||||
break;
|
break;
|
||||||
case RISCV_DBTR_TRIG_ICOUNT:
|
|
||||||
__clear_bit(RV_DBTR_BIT(ICOUNT, VU), &trig->tdata1);
|
|
||||||
__clear_bit(RV_DBTR_BIT(ICOUNT, VS), &trig->tdata1);
|
|
||||||
__clear_bit(RV_DBTR_BIT(ICOUNT, U), &trig->tdata1);
|
|
||||||
__clear_bit(RV_DBTR_BIT(ICOUNT, S), &trig->tdata1);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -470,7 +441,6 @@ static int dbtr_trigger_supported(unsigned long type)
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case RISCV_DBTR_TRIG_MCONTROL:
|
case RISCV_DBTR_TRIG_MCONTROL:
|
||||||
case RISCV_DBTR_TRIG_MCONTROL6:
|
case RISCV_DBTR_TRIG_MCONTROL6:
|
||||||
case RISCV_DBTR_TRIG_ICOUNT:
|
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -492,11 +462,6 @@ static int dbtr_trigger_valid(unsigned long type, unsigned long tdata)
|
|||||||
!(tdata & RV_DBTR_BIT_MASK(MC6, M)))
|
!(tdata & RV_DBTR_BIT_MASK(MC6, M)))
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
break;
|
||||||
case RISCV_DBTR_TRIG_ICOUNT:
|
|
||||||
if (!(tdata & RV_DBTR_BIT_MASK(ICOUNT, DMODE)) &&
|
|
||||||
!(tdata & RV_DBTR_BIT_MASK(ICOUNT, M)))
|
|
||||||
return 1;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -563,10 +528,6 @@ int sbi_dbtr_read_trig(unsigned long smode,
|
|||||||
for_each_trig_entry(shmem_base, trig_count, typeof(*entry), entry) {
|
for_each_trig_entry(shmem_base, trig_count, typeof(*entry), entry) {
|
||||||
xmit = &entry->data;
|
xmit = &entry->data;
|
||||||
trig = INDEX_TO_TRIGGER((_idx + trig_idx_base));
|
trig = INDEX_TO_TRIGGER((_idx + trig_idx_base));
|
||||||
csr_write(CSR_TSELECT, trig->index);
|
|
||||||
trig->tdata1 = csr_read(CSR_TDATA1);
|
|
||||||
trig->tdata2 = csr_read(CSR_TDATA2);
|
|
||||||
trig->tdata3 = csr_read(CSR_TDATA3);
|
|
||||||
xmit->tstate = cpu_to_lle(trig->state);
|
xmit->tstate = cpu_to_lle(trig->state);
|
||||||
xmit->tdata1 = cpu_to_lle(trig->tdata1);
|
xmit->tdata1 = cpu_to_lle(trig->tdata1);
|
||||||
xmit->tdata2 = cpu_to_lle(trig->tdata2);
|
xmit->tdata2 = cpu_to_lle(trig->tdata2);
|
||||||
|
@ -49,10 +49,10 @@ static void mstatus_init(struct sbi_scratch *scratch)
|
|||||||
|
|
||||||
csr_write(CSR_MSTATUS, mstatus_val);
|
csr_write(CSR_MSTATUS, mstatus_val);
|
||||||
|
|
||||||
/* Disable user mode usage of all perf counters except TM */
|
/* Disable user mode usage of all perf counters except default ones (CY, TM, IR) */
|
||||||
if (misa_extension('S') &&
|
if (misa_extension('S') &&
|
||||||
sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_10)
|
sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_10)
|
||||||
csr_write(CSR_SCOUNTEREN, 0x02);
|
csr_write(CSR_SCOUNTEREN, 7);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OpenSBI doesn't use any PMU counters in M-mode.
|
* OpenSBI doesn't use any PMU counters in M-mode.
|
||||||
|
@ -16,9 +16,7 @@
|
|||||||
|
|
||||||
/* Minimum size and alignment of heap allocations */
|
/* Minimum size and alignment of heap allocations */
|
||||||
#define HEAP_ALLOC_ALIGN 64
|
#define HEAP_ALLOC_ALIGN 64
|
||||||
|
#define HEAP_HOUSEKEEPING_FACTOR 16
|
||||||
/* Number of heap nodes to allocate at once */
|
|
||||||
#define HEAP_NODE_BATCH_SIZE 8
|
|
||||||
|
|
||||||
struct heap_node {
|
struct heap_node {
|
||||||
struct sbi_dlist head;
|
struct sbi_dlist head;
|
||||||
@ -30,50 +28,20 @@ struct sbi_heap_control {
|
|||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
unsigned long base;
|
unsigned long base;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
unsigned long resv;
|
unsigned long hkbase;
|
||||||
|
unsigned long hksize;
|
||||||
struct sbi_dlist free_node_list;
|
struct sbi_dlist free_node_list;
|
||||||
struct sbi_dlist free_space_list;
|
struct sbi_dlist free_space_list;
|
||||||
struct sbi_dlist used_space_list;
|
struct sbi_dlist used_space_list;
|
||||||
struct heap_node init_free_space_node;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sbi_heap_control global_hpctrl;
|
struct sbi_heap_control global_hpctrl;
|
||||||
|
|
||||||
static bool alloc_nodes(struct sbi_heap_control *hpctrl)
|
|
||||||
{
|
|
||||||
size_t size = HEAP_NODE_BATCH_SIZE * sizeof(struct heap_node);
|
|
||||||
struct heap_node *n, *new = NULL;
|
|
||||||
|
|
||||||
/* alloc_with_align() requires at most two free nodes */
|
|
||||||
if (hpctrl->free_node_list.next != hpctrl->free_node_list.prev)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
sbi_list_for_each_entry_reverse(n, &hpctrl->free_space_list, head) {
|
|
||||||
if (n->size >= size) {
|
|
||||||
n->size -= size;
|
|
||||||
if (!n->size) {
|
|
||||||
sbi_list_del(&n->head);
|
|
||||||
sbi_list_add_tail(&n->head, &hpctrl->free_node_list);
|
|
||||||
}
|
|
||||||
new = (void *)(n->addr + n->size);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!new)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < HEAP_NODE_BATCH_SIZE; i++)
|
|
||||||
sbi_list_add_tail(&new[i].head, &hpctrl->free_node_list);
|
|
||||||
hpctrl->resv += size;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *alloc_with_align(struct sbi_heap_control *hpctrl,
|
static void *alloc_with_align(struct sbi_heap_control *hpctrl,
|
||||||
size_t align, size_t size)
|
size_t align, size_t size)
|
||||||
{
|
{
|
||||||
void *ret = NULL;
|
void *ret = NULL;
|
||||||
struct heap_node *n, *np;
|
struct heap_node *n, *np, *rem;
|
||||||
unsigned long lowest_aligned;
|
unsigned long lowest_aligned;
|
||||||
size_t pad;
|
size_t pad;
|
||||||
|
|
||||||
@ -85,10 +53,6 @@ static void *alloc_with_align(struct sbi_heap_control *hpctrl,
|
|||||||
|
|
||||||
spin_lock(&hpctrl->lock);
|
spin_lock(&hpctrl->lock);
|
||||||
|
|
||||||
/* Ensure at least two free nodes are available for use below */
|
|
||||||
if (!alloc_nodes(hpctrl))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
np = NULL;
|
np = NULL;
|
||||||
sbi_list_for_each_entry(n, &hpctrl->free_space_list, head) {
|
sbi_list_for_each_entry(n, &hpctrl->free_space_list, head) {
|
||||||
lowest_aligned = ROUNDUP(n->addr, align);
|
lowest_aligned = ROUNDUP(n->addr, align);
|
||||||
@ -103,34 +67,55 @@ static void *alloc_with_align(struct sbi_heap_control *hpctrl,
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (pad) {
|
if (pad) {
|
||||||
|
if (sbi_list_empty(&hpctrl->free_node_list)) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
n = sbi_list_first_entry(&hpctrl->free_node_list,
|
n = sbi_list_first_entry(&hpctrl->free_node_list,
|
||||||
struct heap_node, head);
|
struct heap_node, head);
|
||||||
sbi_list_del(&n->head);
|
sbi_list_del(&n->head);
|
||||||
|
|
||||||
n->addr = np->addr;
|
if ((size + pad < np->size) &&
|
||||||
n->size = pad;
|
!sbi_list_empty(&hpctrl->free_node_list)) {
|
||||||
sbi_list_add_tail(&n->head, &np->head);
|
rem = sbi_list_first_entry(&hpctrl->free_node_list,
|
||||||
|
struct heap_node, head);
|
||||||
|
sbi_list_del(&rem->head);
|
||||||
|
rem->addr = np->addr + (size + pad);
|
||||||
|
rem->size = np->size - (size + pad);
|
||||||
|
sbi_list_add_tail(&rem->head,
|
||||||
|
&hpctrl->free_space_list);
|
||||||
|
} else if (size + pad != np->size) {
|
||||||
|
/* Can't allocate, return n */
|
||||||
|
sbi_list_add(&n->head, &hpctrl->free_node_list);
|
||||||
|
ret = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
np->addr += pad;
|
n->addr = lowest_aligned;
|
||||||
np->size -= pad;
|
n->size = size;
|
||||||
|
sbi_list_add_tail(&n->head, &hpctrl->used_space_list);
|
||||||
|
|
||||||
|
np->size = pad;
|
||||||
|
ret = (void *)n->addr;
|
||||||
|
} else {
|
||||||
|
if ((size < np->size) &&
|
||||||
|
!sbi_list_empty(&hpctrl->free_node_list)) {
|
||||||
|
n = sbi_list_first_entry(&hpctrl->free_node_list,
|
||||||
|
struct heap_node, head);
|
||||||
|
sbi_list_del(&n->head);
|
||||||
|
n->addr = np->addr;
|
||||||
|
n->size = size;
|
||||||
|
np->addr += size;
|
||||||
|
np->size -= size;
|
||||||
|
sbi_list_add_tail(&n->head, &hpctrl->used_space_list);
|
||||||
|
ret = (void *)n->addr;
|
||||||
|
} else if (size == np->size) {
|
||||||
|
sbi_list_del(&np->head);
|
||||||
|
sbi_list_add_tail(&np->head, &hpctrl->used_space_list);
|
||||||
|
ret = (void *)np->addr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size < np->size) {
|
|
||||||
n = sbi_list_first_entry(&hpctrl->free_node_list,
|
|
||||||
struct heap_node, head);
|
|
||||||
sbi_list_del(&n->head);
|
|
||||||
|
|
||||||
n->addr = np->addr + size;
|
|
||||||
n->size = np->size - size;
|
|
||||||
sbi_list_add(&n->head, &np->head);
|
|
||||||
|
|
||||||
np->size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
sbi_list_del(&np->head);
|
|
||||||
sbi_list_add_tail(&np->head, &hpctrl->used_space_list);
|
|
||||||
ret = (void *)np->addr;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
spin_unlock(&hpctrl->lock);
|
spin_unlock(&hpctrl->lock);
|
||||||
|
|
||||||
@ -231,32 +216,44 @@ unsigned long sbi_heap_free_space_from(struct sbi_heap_control *hpctrl)
|
|||||||
|
|
||||||
unsigned long sbi_heap_used_space_from(struct sbi_heap_control *hpctrl)
|
unsigned long sbi_heap_used_space_from(struct sbi_heap_control *hpctrl)
|
||||||
{
|
{
|
||||||
return hpctrl->size - hpctrl->resv - sbi_heap_free_space();
|
return hpctrl->size - hpctrl->hksize - sbi_heap_free_space();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long sbi_heap_reserved_space_from(struct sbi_heap_control *hpctrl)
|
unsigned long sbi_heap_reserved_space_from(struct sbi_heap_control *hpctrl)
|
||||||
{
|
{
|
||||||
return hpctrl->resv;
|
return hpctrl->hksize;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sbi_heap_init_new(struct sbi_heap_control *hpctrl, unsigned long base,
|
int sbi_heap_init_new(struct sbi_heap_control *hpctrl, unsigned long base,
|
||||||
unsigned long size)
|
unsigned long size)
|
||||||
{
|
{
|
||||||
|
unsigned long i;
|
||||||
struct heap_node *n;
|
struct heap_node *n;
|
||||||
|
|
||||||
/* Initialize heap control */
|
/* Initialize heap control */
|
||||||
SPIN_LOCK_INIT(hpctrl->lock);
|
SPIN_LOCK_INIT(hpctrl->lock);
|
||||||
hpctrl->base = base;
|
hpctrl->base = base;
|
||||||
hpctrl->size = size;
|
hpctrl->size = size;
|
||||||
hpctrl->resv = 0;
|
hpctrl->hkbase = hpctrl->base;
|
||||||
|
hpctrl->hksize = hpctrl->size / HEAP_HOUSEKEEPING_FACTOR;
|
||||||
|
hpctrl->hksize &= ~((unsigned long)HEAP_BASE_ALIGN - 1);
|
||||||
SBI_INIT_LIST_HEAD(&hpctrl->free_node_list);
|
SBI_INIT_LIST_HEAD(&hpctrl->free_node_list);
|
||||||
SBI_INIT_LIST_HEAD(&hpctrl->free_space_list);
|
SBI_INIT_LIST_HEAD(&hpctrl->free_space_list);
|
||||||
SBI_INIT_LIST_HEAD(&hpctrl->used_space_list);
|
SBI_INIT_LIST_HEAD(&hpctrl->used_space_list);
|
||||||
|
|
||||||
|
/* Prepare free node list */
|
||||||
|
for (i = 0; i < (hpctrl->hksize / sizeof(*n)); i++) {
|
||||||
|
n = (struct heap_node *)(hpctrl->hkbase + (sizeof(*n) * i));
|
||||||
|
n->addr = n->size = 0;
|
||||||
|
sbi_list_add_tail(&n->head, &hpctrl->free_node_list);
|
||||||
|
}
|
||||||
|
|
||||||
/* Prepare free space list */
|
/* Prepare free space list */
|
||||||
n = &hpctrl->init_free_space_node;
|
n = sbi_list_first_entry(&hpctrl->free_node_list,
|
||||||
n->addr = base;
|
struct heap_node, head);
|
||||||
n->size = size;
|
sbi_list_del(&n->head);
|
||||||
|
n->addr = hpctrl->hkbase + hpctrl->hksize;
|
||||||
|
n->size = hpctrl->size - hpctrl->hksize;
|
||||||
sbi_list_add_tail(&n->head, &hpctrl->free_space_list);
|
sbi_list_add_tail(&n->head, &hpctrl->free_space_list);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -30,7 +30,7 @@ int sbi_illegal_atomic(ulong insn, struct sbi_trap_regs *regs)
|
|||||||
{ \
|
{ \
|
||||||
register ulong tinfo asm("a3"); \
|
register ulong tinfo asm("a3"); \
|
||||||
register ulong mstatus = 0; \
|
register ulong mstatus = 0; \
|
||||||
register ulong mtvec = (ulong)sbi_hart_expected_trap; \
|
register ulong mtvec = sbi_hart_expected_trap_addr(); \
|
||||||
type ret = 0; \
|
type ret = 0; \
|
||||||
trap->cause = 0; \
|
trap->cause = 0; \
|
||||||
asm volatile( \
|
asm volatile( \
|
||||||
@ -57,7 +57,7 @@ int sbi_illegal_atomic(ulong insn, struct sbi_trap_regs *regs)
|
|||||||
{ \
|
{ \
|
||||||
register ulong tinfo asm("a3"); \
|
register ulong tinfo asm("a3"); \
|
||||||
register ulong mstatus = 0; \
|
register ulong mstatus = 0; \
|
||||||
register ulong mtvec = (ulong)sbi_hart_expected_trap; \
|
register ulong mtvec = sbi_hart_expected_trap_addr(); \
|
||||||
type ret = 0; \
|
type ret = 0; \
|
||||||
trap->cause = 0; \
|
trap->cause = 0; \
|
||||||
asm volatile( \
|
asm volatile( \
|
||||||
|
@ -780,7 +780,6 @@ static int pmu_ctr_find_hw(struct sbi_pmu_hart_state *phs,
|
|||||||
continue;
|
continue;
|
||||||
/* We found a valid counter that is not started yet */
|
/* We found a valid counter that is not started yet */
|
||||||
ctr_idx = cbase;
|
ctr_idx = cbase;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
{ \
|
{ \
|
||||||
register ulong tinfo asm("a3"); \
|
register ulong tinfo asm("a3"); \
|
||||||
register ulong mstatus = 0; \
|
register ulong mstatus = 0; \
|
||||||
register ulong mtvec = (ulong)sbi_hart_expected_trap; \
|
register ulong mtvec = sbi_hart_expected_trap_addr(); \
|
||||||
type ret = 0; \
|
type ret = 0; \
|
||||||
trap->cause = 0; \
|
trap->cause = 0; \
|
||||||
asm volatile( \
|
asm volatile( \
|
||||||
@ -51,7 +51,7 @@
|
|||||||
{ \
|
{ \
|
||||||
register ulong tinfo asm("a3") = (ulong)trap; \
|
register ulong tinfo asm("a3") = (ulong)trap; \
|
||||||
register ulong mstatus = 0; \
|
register ulong mstatus = 0; \
|
||||||
register ulong mtvec = (ulong)sbi_hart_expected_trap; \
|
register ulong mtvec = sbi_hart_expected_trap_addr(); \
|
||||||
trap->cause = 0; \
|
trap->cause = 0; \
|
||||||
asm volatile( \
|
asm volatile( \
|
||||||
"add %[tinfo], %[taddr], zero\n" \
|
"add %[tinfo], %[taddr], zero\n" \
|
||||||
@ -121,7 +121,7 @@ ulong sbi_get_insn(ulong mepc, struct sbi_trap_info *trap)
|
|||||||
register ulong tinfo asm("a3");
|
register ulong tinfo asm("a3");
|
||||||
register ulong ttmp asm("a4");
|
register ulong ttmp asm("a4");
|
||||||
register ulong mstatus = 0;
|
register ulong mstatus = 0;
|
||||||
register ulong mtvec = (ulong)sbi_hart_expected_trap;
|
register ulong mtvec = sbi_hart_expected_trap_addr();
|
||||||
ulong insn = 0;
|
ulong insn = 0;
|
||||||
|
|
||||||
trap->cause = 0;
|
trap->cause = 0;
|
||||||
|
@ -84,27 +84,23 @@ static int fdt_translate_address(const void *fdt, uint64_t reg, int parent,
|
|||||||
uint64_t *addr)
|
uint64_t *addr)
|
||||||
{
|
{
|
||||||
int i, rlen;
|
int i, rlen;
|
||||||
int cell_parent_addr, cell_child_addr, cell_size;
|
int cell_addr, cell_size;
|
||||||
const fdt32_t *ranges;
|
const fdt32_t *ranges;
|
||||||
uint64_t offset, caddr = 0, paddr = 0, rsize = 0;
|
uint64_t offset, caddr = 0, paddr = 0, rsize = 0;
|
||||||
|
|
||||||
|
cell_addr = fdt_address_cells(fdt, parent);
|
||||||
|
if (cell_addr < 1)
|
||||||
|
return SBI_ENODEV;
|
||||||
|
|
||||||
|
cell_size = fdt_size_cells(fdt, parent);
|
||||||
|
if (cell_size < 0)
|
||||||
|
return SBI_ENODEV;
|
||||||
|
|
||||||
ranges = fdt_getprop(fdt, parent, "ranges", &rlen);
|
ranges = fdt_getprop(fdt, parent, "ranges", &rlen);
|
||||||
if (ranges && rlen > 0) {
|
if (ranges && rlen > 0) {
|
||||||
cell_child_addr = fdt_address_cells(fdt, parent);
|
for (i = 0; i < cell_addr; i++)
|
||||||
if (cell_child_addr < 1)
|
|
||||||
return SBI_ENODEV;
|
|
||||||
|
|
||||||
cell_parent_addr = fdt_address_cells(fdt, fdt_parent_offset(fdt, parent));
|
|
||||||
if (cell_parent_addr < 1)
|
|
||||||
return SBI_ENODEV;
|
|
||||||
|
|
||||||
cell_size = fdt_size_cells(fdt, parent);
|
|
||||||
if (cell_size < 0)
|
|
||||||
return SBI_ENODEV;
|
|
||||||
|
|
||||||
for (i = 0; i < cell_child_addr; i++)
|
|
||||||
caddr = (caddr << 32) | fdt32_to_cpu(*ranges++);
|
caddr = (caddr << 32) | fdt32_to_cpu(*ranges++);
|
||||||
for (i = 0; i < cell_parent_addr; i++)
|
for (i = 0; i < cell_addr; i++)
|
||||||
paddr = (paddr << 32) | fdt32_to_cpu(*ranges++);
|
paddr = (paddr << 32) | fdt32_to_cpu(*ranges++);
|
||||||
for (i = 0; i < cell_size; i++)
|
for (i = 0; i < cell_size; i++)
|
||||||
rsize = (rsize << 32) | fdt32_to_cpu(*ranges++);
|
rsize = (rsize << 32) | fdt32_to_cpu(*ranges++);
|
||||||
|
@ -133,9 +133,10 @@ int uart8250_init(unsigned long base, u32 in_freq, u32 baudrate, u32 reg_shift,
|
|||||||
set_reg(UART_FCR_OFFSET, 0x01);
|
set_reg(UART_FCR_OFFSET, 0x01);
|
||||||
/* No modem control DTR RTS */
|
/* No modem control DTR RTS */
|
||||||
set_reg(UART_MCR_OFFSET, 0x00);
|
set_reg(UART_MCR_OFFSET, 0x00);
|
||||||
/* Clear line status and read receive buffer */
|
/* Clear line status */
|
||||||
if (get_reg(UART_LSR_OFFSET) & UART_LSR_DR)
|
get_reg(UART_LSR_OFFSET);
|
||||||
get_reg(UART_RBR_OFFSET);
|
/* Read receive buffer */
|
||||||
|
get_reg(UART_RBR_OFFSET);
|
||||||
/* Set scratchpad */
|
/* Set scratchpad */
|
||||||
set_reg(UART_SCR_OFFSET, 0x00);
|
set_reg(UART_SCR_OFFSET, 0x00);
|
||||||
|
|
||||||
|
10
platform/fpga/openpiton/Kconfig
Normal file
10
platform/fpga/openpiton/Kconfig
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
config PLATFORM_OPENPITON_FPGA
|
||||||
|
bool
|
||||||
|
select FDT
|
||||||
|
select IPI_MSWI
|
||||||
|
select IRQCHIP_PLIC
|
||||||
|
select SERIAL_UART8250
|
||||||
|
select TIMER_MTIMER
|
||||||
|
default y
|
0
platform/fpga/openpiton/configs/defconfig
Normal file
0
platform/fpga/openpiton/configs/defconfig
Normal file
41
platform/fpga/openpiton/objects.mk
Normal file
41
platform/fpga/openpiton/objects.mk
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020 Western Digital Corporation or its affiliates.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Compiler flags
|
||||||
|
platform-cppflags-y =
|
||||||
|
platform-cflags-y =
|
||||||
|
platform-asflags-y =
|
||||||
|
platform-ldflags-y =
|
||||||
|
|
||||||
|
# Objects to build
|
||||||
|
platform-objs-y += platform.o
|
||||||
|
|
||||||
|
PLATFORM_RISCV_XLEN = 64
|
||||||
|
|
||||||
|
# Blobs to build
|
||||||
|
FW_JUMP=n
|
||||||
|
|
||||||
|
ifeq ($(PLATFORM_RISCV_XLEN), 32)
|
||||||
|
# This needs to be 4MB aligned for 32-bit support
|
||||||
|
FW_JUMP_ADDR=0x80400000
|
||||||
|
else
|
||||||
|
# This needs to be 2MB aligned for 64-bit support
|
||||||
|
FW_JUMP_ADDR=0x80200000
|
||||||
|
endif
|
||||||
|
FW_JUMP_FDT_ADDR=0x82200000
|
||||||
|
|
||||||
|
# Firmware with payload configuration.
|
||||||
|
FW_PAYLOAD=y
|
||||||
|
|
||||||
|
ifeq ($(PLATFORM_RISCV_XLEN), 32)
|
||||||
|
# This needs to be 4MB aligned for 32-bit support
|
||||||
|
FW_PAYLOAD_OFFSET=0x400000
|
||||||
|
else
|
||||||
|
# This needs to be 2MB aligned for 64-bit support
|
||||||
|
FW_PAYLOAD_OFFSET=0x200000
|
||||||
|
endif
|
||||||
|
FW_PAYLOAD_FDT_ADDR=0x82200000
|
||||||
|
FW_PAYLOAD_ALIGN=0x1000
|
@ -3,7 +3,12 @@
|
|||||||
* Copyright (c) 2020 Western Digital Corporation or its affiliates.
|
* Copyright (c) 2020 Western Digital Corporation or its affiliates.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <platform_override.h>
|
#include <sbi/riscv_asm.h>
|
||||||
|
#include <sbi/riscv_encoding.h>
|
||||||
|
#include <sbi/riscv_io.h>
|
||||||
|
#include <sbi/sbi_const.h>
|
||||||
|
#include <sbi/sbi_hart.h>
|
||||||
|
#include <sbi/sbi_platform.h>
|
||||||
#include <sbi_utils/fdt/fdt_helper.h>
|
#include <sbi_utils/fdt/fdt_helper.h>
|
||||||
#include <sbi_utils/fdt/fdt_fixup.h>
|
#include <sbi_utils/fdt/fdt_fixup.h>
|
||||||
#include <sbi_utils/ipi/aclint_mswi.h>
|
#include <sbi_utils/ipi/aclint_mswi.h>
|
||||||
@ -11,19 +16,19 @@
|
|||||||
#include <sbi_utils/serial/uart8250.h>
|
#include <sbi_utils/serial/uart8250.h>
|
||||||
#include <sbi_utils/timer/aclint_mtimer.h>
|
#include <sbi_utils/timer/aclint_mtimer.h>
|
||||||
|
|
||||||
#define OPENPITON_DEFAULT_UART_ADDR 0xfff0c2c000ULL
|
#define OPENPITON_DEFAULT_UART_ADDR 0xfff0c2c000
|
||||||
#define OPENPITON_DEFAULT_UART_FREQ 60000000
|
#define OPENPITON_DEFAULT_UART_FREQ 60000000
|
||||||
#define OPENPITON_DEFAULT_UART_BAUDRATE 115200
|
#define OPENPITON_DEFAULT_UART_BAUDRATE 115200
|
||||||
#define OPENPITON_DEFAULT_UART_REG_SHIFT 0
|
#define OPENPITON_DEFAULT_UART_REG_SHIFT 0
|
||||||
#define OPENPITON_DEFAULT_UART_REG_WIDTH 1
|
#define OPENPITON_DEFAULT_UART_REG_WIDTH 1
|
||||||
#define OPENPITON_DEFAULT_UART_REG_OFFSET 0
|
#define OPENPITON_DEFAULT_UART_REG_OFFSET 0
|
||||||
#define OPENPITON_DEFAULT_UART_CAPS 0
|
#define OPENPITON_DEFAULT_UART_CAPS 0
|
||||||
#define OPENPITON_DEFAULT_PLIC_ADDR 0xfff1100000ULL
|
#define OPENPITON_DEFAULT_PLIC_ADDR 0xfff1100000
|
||||||
#define OPENPITON_DEFAULT_PLIC_SIZE (0x200000 + \
|
#define OPENPITON_DEFAULT_PLIC_SIZE (0x200000 + \
|
||||||
(OPENPITON_DEFAULT_HART_COUNT * 0x1000))
|
(OPENPITON_DEFAULT_HART_COUNT * 0x1000))
|
||||||
#define OPENPITON_DEFAULT_PLIC_NUM_SOURCES 2
|
#define OPENPITON_DEFAULT_PLIC_NUM_SOURCES 2
|
||||||
#define OPENPITON_DEFAULT_HART_COUNT 3
|
#define OPENPITON_DEFAULT_HART_COUNT 3
|
||||||
#define OPENPITON_DEFAULT_CLINT_ADDR 0xfff1020000ULL
|
#define OPENPITON_DEFAULT_CLINT_ADDR 0xfff1020000
|
||||||
#define OPENPITON_DEFAULT_ACLINT_MTIMER_FREQ 1000000
|
#define OPENPITON_DEFAULT_ACLINT_MTIMER_FREQ 1000000
|
||||||
#define OPENPITON_DEFAULT_ACLINT_MSWI_ADDR \
|
#define OPENPITON_DEFAULT_ACLINT_MSWI_ADDR \
|
||||||
(OPENPITON_DEFAULT_CLINT_ADDR + CLINT_MSWI_OFFSET)
|
(OPENPITON_DEFAULT_CLINT_ADDR + CLINT_MSWI_OFFSET)
|
||||||
@ -31,12 +36,12 @@
|
|||||||
(OPENPITON_DEFAULT_CLINT_ADDR + CLINT_MTIMER_OFFSET)
|
(OPENPITON_DEFAULT_CLINT_ADDR + CLINT_MTIMER_OFFSET)
|
||||||
|
|
||||||
static struct platform_uart_data uart = {
|
static struct platform_uart_data uart = {
|
||||||
(unsigned long)OPENPITON_DEFAULT_UART_ADDR,
|
OPENPITON_DEFAULT_UART_ADDR,
|
||||||
OPENPITON_DEFAULT_UART_FREQ,
|
OPENPITON_DEFAULT_UART_FREQ,
|
||||||
OPENPITON_DEFAULT_UART_BAUDRATE,
|
OPENPITON_DEFAULT_UART_BAUDRATE,
|
||||||
};
|
};
|
||||||
static struct plic_data plic = {
|
static struct plic_data plic = {
|
||||||
.addr = (unsigned long)OPENPITON_DEFAULT_PLIC_ADDR,
|
.addr = OPENPITON_DEFAULT_PLIC_ADDR,
|
||||||
.size = OPENPITON_DEFAULT_PLIC_SIZE,
|
.size = OPENPITON_DEFAULT_PLIC_SIZE,
|
||||||
.num_src = OPENPITON_DEFAULT_PLIC_NUM_SOURCES,
|
.num_src = OPENPITON_DEFAULT_PLIC_NUM_SOURCES,
|
||||||
.flags = PLIC_FLAG_ARIANE_BUG,
|
.flags = PLIC_FLAG_ARIANE_BUG,
|
||||||
@ -48,7 +53,7 @@ static struct plic_data plic = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct aclint_mswi_data mswi = {
|
static struct aclint_mswi_data mswi = {
|
||||||
.addr = (unsigned long)OPENPITON_DEFAULT_ACLINT_MSWI_ADDR,
|
.addr = OPENPITON_DEFAULT_ACLINT_MSWI_ADDR,
|
||||||
.size = ACLINT_MSWI_SIZE,
|
.size = ACLINT_MSWI_SIZE,
|
||||||
.first_hartid = 0,
|
.first_hartid = 0,
|
||||||
.hart_count = OPENPITON_DEFAULT_HART_COUNT,
|
.hart_count = OPENPITON_DEFAULT_HART_COUNT,
|
||||||
@ -56,10 +61,10 @@ static struct aclint_mswi_data mswi = {
|
|||||||
|
|
||||||
static struct aclint_mtimer_data mtimer = {
|
static struct aclint_mtimer_data mtimer = {
|
||||||
.mtime_freq = OPENPITON_DEFAULT_ACLINT_MTIMER_FREQ,
|
.mtime_freq = OPENPITON_DEFAULT_ACLINT_MTIMER_FREQ,
|
||||||
.mtime_addr = (unsigned long)OPENPITON_DEFAULT_ACLINT_MTIMER_ADDR +
|
.mtime_addr = OPENPITON_DEFAULT_ACLINT_MTIMER_ADDR +
|
||||||
ACLINT_DEFAULT_MTIME_OFFSET,
|
ACLINT_DEFAULT_MTIME_OFFSET,
|
||||||
.mtime_size = ACLINT_DEFAULT_MTIME_SIZE,
|
.mtime_size = ACLINT_DEFAULT_MTIME_SIZE,
|
||||||
.mtimecmp_addr = (unsigned long)OPENPITON_DEFAULT_ACLINT_MTIMER_ADDR +
|
.mtimecmp_addr = OPENPITON_DEFAULT_ACLINT_MTIMER_ADDR +
|
||||||
ACLINT_DEFAULT_MTIMECMP_OFFSET,
|
ACLINT_DEFAULT_MTIMECMP_OFFSET,
|
||||||
.mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE,
|
.mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE,
|
||||||
.first_hartid = 0,
|
.first_hartid = 0,
|
||||||
@ -74,7 +79,7 @@ static int openpiton_early_init(bool cold_boot)
|
|||||||
{
|
{
|
||||||
const void *fdt;
|
const void *fdt;
|
||||||
struct platform_uart_data uart_data = { 0 };
|
struct platform_uart_data uart_data = { 0 };
|
||||||
struct plic_data plic_data = plic;
|
struct plic_data plic_data;
|
||||||
unsigned long aclint_freq;
|
unsigned long aclint_freq;
|
||||||
uint64_t clint_addr;
|
uint64_t clint_addr;
|
||||||
int rc;
|
int rc;
|
||||||
@ -151,23 +156,25 @@ static int openpiton_timer_init(void)
|
|||||||
return aclint_mtimer_cold_init(&mtimer, NULL);
|
return aclint_mtimer_cold_init(&mtimer, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int openhwgroup_openpiton_platform_init(const void *fdt, int nodeoff, const struct fdt_match *match)
|
/*
|
||||||
{
|
* Platform descriptor.
|
||||||
generic_platform_ops.early_init = openpiton_early_init;
|
*/
|
||||||
generic_platform_ops.timer_init = openpiton_timer_init;
|
const struct sbi_platform_operations platform_ops = {
|
||||||
generic_platform_ops.ipi_init = openpiton_ipi_init;
|
.early_init = openpiton_early_init,
|
||||||
generic_platform_ops.irqchip_init = openpiton_irqchip_init;
|
.final_init = openpiton_final_init,
|
||||||
generic_platform_ops.final_init = openpiton_final_init;
|
.irqchip_init = openpiton_irqchip_init,
|
||||||
|
.ipi_init = openpiton_ipi_init,
|
||||||
return 0;
|
.timer_init = openpiton_timer_init,
|
||||||
}
|
|
||||||
|
|
||||||
static const struct fdt_match openhwgroup_openpiton_match[] = {
|
|
||||||
{ .compatible = "openpiton,cva6platform" },
|
|
||||||
{ },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct fdt_driver openhwgroup_openpiton = {
|
const struct sbi_platform platform = {
|
||||||
.match_table = openhwgroup_openpiton_match,
|
.opensbi_version = OPENSBI_VERSION,
|
||||||
.init = openhwgroup_openpiton_platform_init,
|
.platform_version = SBI_PLATFORM_VERSION(0x0, 0x01),
|
||||||
|
.name = "OPENPITON RISC-V",
|
||||||
|
.features = SBI_PLATFORM_DEFAULT_FEATURES,
|
||||||
|
.hart_count = OPENPITON_DEFAULT_HART_COUNT,
|
||||||
|
.hart_stack_size = SBI_PLATFORM_DEFAULT_HART_STACK_SIZE,
|
||||||
|
.heap_size =
|
||||||
|
SBI_PLATFORM_DEFAULT_HEAP_SIZE(OPENPITON_DEFAULT_HART_COUNT),
|
||||||
|
.platform_ops_addr = (unsigned long)&platform_ops
|
||||||
};
|
};
|
@ -36,10 +36,6 @@ config PLATFORM_ANDES_AE350
|
|||||||
select ANDES_PMA
|
select ANDES_PMA
|
||||||
default n
|
default n
|
||||||
|
|
||||||
config PLATFORM_OPENHWGROUP_OPENPITON
|
|
||||||
bool "OpenHWGroup Openpiton support"
|
|
||||||
default n
|
|
||||||
|
|
||||||
config PLATFORM_RENESAS_RZFIVE
|
config PLATFORM_RENESAS_RZFIVE
|
||||||
bool "Renesas RZ/Five support"
|
bool "Renesas RZ/Five support"
|
||||||
select ANDES_PMA
|
select ANDES_PMA
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// SPDX-License-Identifier: BSD-2-Clause
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 Renesas Electronics Corp.
|
* Copyright (C) 2023 Renesas Electronics Corp.
|
||||||
* Copyright (c) 2024 Andes Technology Corporation
|
* Copyright (c) 2024 Andes Technology Corporation
|
||||||
|
@ -7,7 +7,6 @@ CONFIG_PLATFORM_SOPHGO_SG2042=y
|
|||||||
CONFIG_PLATFORM_STARFIVE_JH7110=y
|
CONFIG_PLATFORM_STARFIVE_JH7110=y
|
||||||
CONFIG_PLATFORM_THEAD=y
|
CONFIG_PLATFORM_THEAD=y
|
||||||
CONFIG_PLATFORM_MIPS_P8700=y
|
CONFIG_PLATFORM_MIPS_P8700=y
|
||||||
CONFIG_PLATFORM_OPENHWGROUP_OPENPITON=y
|
|
||||||
CONFIG_FDT_CPPC=y
|
CONFIG_FDT_CPPC=y
|
||||||
CONFIG_FDT_CPPC_RPMI=y
|
CONFIG_FDT_CPPC_RPMI=y
|
||||||
CONFIG_FDT_GPIO=y
|
CONFIG_FDT_GPIO=y
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2024 Andes Technology Corporation
|
* Copyright (C) 2024 Andes Technology Corporation
|
||||||
*/
|
*/
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2023 Renesas Electronics Corp.
|
* Copyright (C) 2023 Renesas Electronics Corp.
|
||||||
*/
|
*/
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
|
||||||
*
|
|
||||||
* Copyright (c) 2025 MIPS
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
.text
|
|
||||||
.align 12
|
|
||||||
.globl mips_warm_boot
|
|
||||||
mips_warm_boot:
|
|
||||||
j _start_warm
|
|
||||||
.align 2
|
|
@ -4,5 +4,5 @@
|
|||||||
|
|
||||||
ifeq ($(PLATFORM_RISCV_XLEN), 64)
|
ifeq ($(PLATFORM_RISCV_XLEN), 64)
|
||||||
carray-platform_override_modules-$(CONFIG_PLATFORM_MIPS_P8700) += mips_p8700
|
carray-platform_override_modules-$(CONFIG_PLATFORM_MIPS_P8700) += mips_p8700
|
||||||
platform-objs-$(CONFIG_PLATFORM_MIPS_P8700) += mips/p8700.o mips/mips_warm_boot.o
|
platform-objs-$(CONFIG_PLATFORM_MIPS_P8700) += mips/p8700.o
|
||||||
endif
|
endif
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
#include <mips/p8700.h>
|
#include <mips/p8700.h>
|
||||||
#include <mips/mips-cm.h>
|
#include <mips/mips-cm.h>
|
||||||
|
|
||||||
extern void mips_warm_boot(void);
|
|
||||||
|
|
||||||
static unsigned long mips_csr_read_num(int csr_num)
|
static unsigned long mips_csr_read_num(int csr_num)
|
||||||
{
|
{
|
||||||
#define switchcase_csr_read(__csr_num, __val) \
|
#define switchcase_csr_read(__csr_num, __val) \
|
||||||
@ -152,9 +150,6 @@ static int mips_hart_start(u32 hartid, ulong saddr)
|
|||||||
if (hartid == 0)
|
if (hartid == 0)
|
||||||
return SBI_ENOTSUPP;
|
return SBI_ENOTSUPP;
|
||||||
|
|
||||||
/* Change reset base to mips_warm_boot */
|
|
||||||
write_gcr_co_reset_base(hartid, (unsigned long)mips_warm_boot, local_p);
|
|
||||||
|
|
||||||
if (cpu_hart(hartid) == 0) {
|
if (cpu_hart(hartid) == 0) {
|
||||||
/* Ensure its coherency is disabled */
|
/* Ensure its coherency is disabled */
|
||||||
write_gcr_co_coherence(hartid, 0, local_p);
|
write_gcr_co_coherence(hartid, 0, local_p);
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
#
|
|
||||||
# SPDX-License-Identifier: BSD-2-Clause
|
|
||||||
#
|
|
||||||
# Copyright (c) 2020 Western Digital Corporation or its affiliates.
|
|
||||||
#
|
|
||||||
|
|
||||||
carray-platform_override_modules-$(CONFIG_PLATFORM_OPENHWGROUP_OPENPITON) += openhwgroup_openpiton
|
|
||||||
platform-objs-$(CONFIG_PLATFORM_OPENHWGROUP_OPENPITON) += openhwgroup/openpiton.o
|
|
@ -245,8 +245,6 @@ int generic_final_init(bool cold_boot)
|
|||||||
fdt_fixups(fdt);
|
fdt_fixups(fdt);
|
||||||
fdt_domain_fixup(fdt);
|
fdt_domain_fixup(fdt);
|
||||||
|
|
||||||
fdt_pack(fdt);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// SPDX-License-Identifier: BSD-2-Clause
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 Renesas Electronics Corp.
|
* Copyright (C) 2022 Renesas Electronics Corp.
|
||||||
*
|
*
|
||||||
|
@ -102,6 +102,7 @@ build_opensbi() {
|
|||||||
BUILD_PLATFORM_SUBDIR+=("nuclei/ux600")
|
BUILD_PLATFORM_SUBDIR+=("nuclei/ux600")
|
||||||
BUILD_PLATFORM_SUBDIR+=("kendryte/k210")
|
BUILD_PLATFORM_SUBDIR+=("kendryte/k210")
|
||||||
BUILD_PLATFORM_SUBDIR+=("fpga/ariane")
|
BUILD_PLATFORM_SUBDIR+=("fpga/ariane")
|
||||||
|
BUILD_PLATFORM_SUBDIR+=("fpga/openpiton")
|
||||||
BUILD_PLATFORM_SUBDIR+=("generic")
|
BUILD_PLATFORM_SUBDIR+=("generic")
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user