13 Commits

Author SHA1 Message Date
f879119605 Обновить platform/generic/cvitek_riscv.c 2026-02-11 02:19:45 +07:00
aedef73d12 Обновить platform/generic/cvitek_riscv.c 2026-02-11 01:41:03 +07:00
92ee61dae4 Обновить platform/generic/cvitek_riscv.c 2026-02-11 01:34:56 +07:00
sophgo-forum-service
6766e9cc96 opensbi: weekly rls 2025.01.24
daa470, [fix](opensbi): add rls_info.txt
b21a54, [test](opensbi): opensbi tailoring (time optimizing)
6ff231, [fix](str): fix riscv suspend section which do not use varivales and functions beyond syspend section.
2025-01-24 14:50:56 +08:00
sophgo-forum-service
3b045ae374 opensbi: weekly rls 2025.01.10
daa470, [fix](opensbi): add rls_info.txt
b21a54, [test](opensbi): opensbi tailoring (time optimizing)
6ff231, [fix](str): fix riscv suspend section which do not use varivales and functions beyond syspend section.

Change-Id: I8c6e7698b475b2d14c02308121f621dafe9b9e36
2025-01-13 16:32:03 +08:00
sophgo-forum-service
fffb4754ee opensbi: weekly rls 2024.10.14
-0f5edb, [fix](str):fix chip id miss and fix suspend bug on rtc
-a068cd, [fix](str): refine rtc suspend/resume process

Change-Id: Ice28701d616192d7d6a6f13621d739dd07424571
2024-10-14 19:27:45 +08:00
sophgo-forum-service
ab9b8f8d10 opensbi: weekly rls 2024.07.20
-0aa741, support cv181x/cv180x suspend to ram.

Change-Id: I64dcb0ff942aa7238a88ef3bd1da2c67f5d089b4
2024-07-20 21:40:47 +08:00
sophgo-forum-service
3fd99912a6 opensbi: weekly rls 2024.06.6
-2da720, Add rst/unrst/reset c906l ecall.

Change-Id: Id1b2de0c5cb4607d46fd4397a78e77109790cc49
2024-06-06 15:17:01 +08:00
sophgo-forum-service
216793f112 (opensbi): Init branch sg200x-dev
Change-Id: If4dd4f7d55a714cff21c4ead4376a4137ee03330
2024-02-14 16:36:52 +08:00
sophgo-forum-service
ba54b0038e note: sync patch from T-Head.
https://github.com/T-head-Semi/opensbi commit: 89182b257c8798e15e4c685c1af0c2862d528d2a
2024-02-14 16:31:42 +08:00
Guo Ren
ba85a8ec52 platform/generic/platform.c: Support qemu poweroff
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
2024-01-10 17:35:55 +08:00
Guo Ren
885df4577a utils: irqchip: Fixup priority init overwrite zero
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
2024-01-10 17:35:47 +08:00
Guo Ren
f67338cc74 thead PMU supported
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
2024-01-10 17:35:39 +08:00
28 changed files with 609 additions and 27 deletions

View File

@@ -1,16 +0,0 @@
AlignConsecutiveAssignments: true
AlignEscapedNewlines: Left
AlignTrailingComments: true
AllowShortFunctionsOnASingleLine: None
BraceWrapping:
AfterFunction: true
BreakBeforeBraces: Custom
BreakStringLiterals: false
ContinuationIndentWidth: 8
Cpp11BracedListStyle: false
IndentWidth: 8
ReflowComments: false
SortIncludes: false
SpacesInContainerLiterals: false
TabWidth: 8
UseTab: Always

View File

@@ -143,6 +143,20 @@ deps-y+=$(libsbi-objs-path-y:.o=.dep)
deps-y+=$(libsbiutils-objs-path-y:.o=.dep)
deps-y+=$(firmware-objs-path-y:.o=.dep)
ifeq (,$(wildcard ${PM_SRAM_BIN_PATH}))
ifeq (${CHIP_ARCH},CV180X)
PM_SRAM_BIN_PATH=${OPENSBI_PATH}/pm_default_cv180x.bin
endif
ifeq (${CHIP_ARCH},CV181X)
PM_SRAM_BIN_PATH=${OPENSBI_PATH}/pm_default_cv181x.bin
endif
else
ifeq ($(filter clean %clean clean%,$(MAKECMDGOALS)),)
$(shell touch -c platform\generic\cvitek_riscv.c > /dev/null)
endif
endif
$(info PM_SRAM_BIN_PATH is '${PM_SRAM_BIN_PATH}')
# Setup platform ABI, ISA and Code Model
ifndef PLATFORM_RISCV_ABI
ifneq ($(PLATFORM_RISCV_TOOLCHAIN_DEFAULT), 1)
@@ -203,6 +217,14 @@ GENFLAGS += $(libsbiutils-genflags-y)
GENFLAGS += $(platform-genflags-y)
GENFLAGS += $(firmware-genflags-y)
define add_define
GENFLAGS += -D$(1)$(if $(value $(1)),=$(value $(1)),)
endef
ifeq (${CONFIG_OPENSBI_FASTBOOT},y)
$(eval $(call add_define,CONFIG_OPENSBI_FASTBOOT))
endif
CFLAGS = -g -Wall -Werror -ffreestanding -nostdlib -fno-strict-aliasing -O2
CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
CFLAGS += -mno-save-restore -mstrict-align
@@ -212,6 +234,13 @@ CFLAGS += $(GENFLAGS)
CFLAGS += $(platform-cflags-y)
CFLAGS += -fno-pie -no-pie
CFLAGS += $(firmware-cflags-y)
CFLAGS += -DPM_SRAM_BIN_PATH=$(PM_SRAM_BIN_PATH)
ifeq ($(CHIP_ARCH),CV180X)
CFLAGS += -DCONFIG_CV180X
endif
ifeq (${CHIP_ARCH},CV181X)
CFLAGS += -DCONFIG_CV181X
endif
CPPFLAGS += $(GENFLAGS)
CPPFLAGS += $(platform-cppflags-y)

View File

@@ -52,6 +52,7 @@ has following details:
* **next_mode** - Privilege mode of the next booting stage for this
domain. This can be either S-mode or U-mode.
* **system_reset_allowed** - Is domain allowed to reset the system?
* **system_suspend_allowed** - Is domain allowed to suspend the system?
The memory regions represented by **regions** in **struct sbi_domain** have
following additional constraints to align with RISC-V PMP requirements:
@@ -91,6 +92,7 @@ following manner:
* **next_mode** - Next booting stage mode in coldboot HART scratch space
is the next mode for the ROOT domain
* **system_reset_allowed** - The ROOT domain is allowed to reset the system
* **system_suspend_allowed** - The ROOT domain is allowed to suspend the system
Domain Effects
--------------
@@ -187,6 +189,8 @@ The DT properties of a domain instance DT node are as follows:
stage mode of coldboot HART** is used as default value.
* **system-reset-allowed** (Optional) - A boolean flag representing
whether the domain instance is allowed to do system reset.
* **system-suspend-allowed** (Optional) - A boolean flag representing
whether the domain instance is allowed to do system suspend.
### Assigning HART To Domain Instance
@@ -252,6 +256,7 @@ be done:
next-addr = <0x0 0x80100000>;
next-mode = <0x0>;
system-reset-allowed;
system-suspend-allowed;
};
udomain: untrusted-domain {

View File

@@ -78,6 +78,8 @@ struct sbi_domain {
unsigned long next_mode;
/** Is domain allowed to reset the system */
bool system_reset_allowed;
/** Is domain allowed to suspend the system */
bool system_suspend_allowed;
};
/** The root domain instance */

View File

@@ -39,6 +39,7 @@ extern struct sbi_ecall_extension ecall_ipi;
extern struct sbi_ecall_extension ecall_vendor;
extern struct sbi_ecall_extension ecall_hsm;
extern struct sbi_ecall_extension ecall_srst;
extern struct sbi_ecall_extension ecall_susp;
u16 sbi_ecall_version_major(void);

View File

@@ -28,6 +28,7 @@
#define SBI_EXT_RFENCE 0x52464E43
#define SBI_EXT_HSM 0x48534D
#define SBI_EXT_SRST 0x53525354
#define SBI_EXT_SUSP 0x53555350
/* SBI function IDs for BASE extension*/
#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
@@ -37,6 +38,9 @@
#define SBI_EXT_BASE_GET_MVENDORID 0x4
#define SBI_EXT_BASE_GET_MARCHID 0x5
#define SBI_EXT_BASE_GET_MIMPID 0x6
#define SBI_EXT_BASE_RESET_C906L 0x7
#define SBI_EXT_BASE_RST_C906L 0x8
#define SBI_EXT_BASE_UNRST_C906L 0x9
/* SBI function IDs for TIME extension*/
#define SBI_EXT_TIME_SET_TIMER 0x0
@@ -108,6 +112,13 @@
#define SBI_ERR_INVALID_ADDRESS -5
#define SBI_ERR_ALREADY_AVAILABLE -6
/* SBI function IDs for SUSP extension */
#define SBI_EXT_SUSP_SUSPEND 0x0
#define SBI_SUSP_SLEEP_TYPE_SUSPEND 0x0
#define SBI_SUSP_SLEEP_TYPE_LAST SBI_SUSP_SLEEP_TYPE_SUSPEND
#define SBI_SUSP_PLATFORM_SLEEP_START 0x80000000
#define SBI_LAST_ERR SBI_ERR_ALREADY_AVAILABLE
/* clang-format on */

View File

@@ -57,9 +57,13 @@ void sbi_hsm_hart_resume_start(struct sbi_scratch *scratch);
void sbi_hsm_hart_resume_finish(struct sbi_scratch *scratch);
int sbi_hsm_hart_suspend(struct sbi_scratch *scratch, u32 suspend_type,
ulong raddr, ulong rmode, ulong priv);
int sbi_hsm_hart_change_state(struct sbi_scratch *scratch, long oldstate,
long newstate);
int __sbi_hsm_hart_get_state(u32 hartid);
int sbi_hsm_hart_get_state(const struct sbi_domain *dom, u32 hartid);
int sbi_hsm_hart_interruptible_mask(const struct sbi_domain *dom,
ulong hbase, ulong *out_hmask);
void __sbi_hsm_suspend_non_ret_save(struct sbi_scratch *scratch);
void sbi_hsm_prepare_next_jump(struct sbi_scratch *scratch, u32 hartid);
#endif

View File

@@ -32,4 +32,30 @@ bool sbi_system_reset_supported(u32 reset_type, u32 reset_reason);
void __noreturn sbi_system_reset(u32 reset_type, u32 reset_reason);
/** System suspend device */
struct sbi_system_suspend_device {
/** Name of the system suspend device */
char name[32];
/* Check whether sleep type is supported by the device */
int (*system_suspend_check)(u32 sleep_type);
/**
* Suspend the system
*
* @sleep_type: The sleep type identifier passed to the SBI call.
* @mmode_resume_addr:
* This is the same as sbi_scratch.warmboot_addr. Some platforms
* may not be able to return from system_suspend(), so they will
* jump directly to this address instead. Platforms which can
* return from system_suspend() may ignore this parameter.
*/
int (*system_suspend)(u32 sleep_type, unsigned long mmode_resume_addr);
};
const struct sbi_system_suspend_device *sbi_system_suspend_get_device(void);
void sbi_system_suspend_set_device(struct sbi_system_suspend_device *dev);
bool sbi_system_suspend_supported(u32 sleep_type);
int sbi_system_suspend(u32 sleep_type, ulong resume_addr, ulong opaque);
#endif

View File

@@ -22,6 +22,7 @@ libsbi-objs-y += sbi_ecall_hsm.o
libsbi-objs-y += sbi_ecall_legacy.o
libsbi-objs-y += sbi_ecall_replace.o
libsbi-objs-y += sbi_ecall_vendor.o
libsbi-objs-y += sbi_ecall_susp.o
libsbi-objs-y += sbi_emulate_csr.o
libsbi-objs-y += sbi_fifo.o
libsbi-objs-y += sbi_hart.o

View File

@@ -34,6 +34,7 @@ struct sbi_domain root = {
.possible_harts = &root_hmask,
.regions = root_memregs,
.system_reset_allowed = TRUE,
.system_suspend_allowed = TRUE,
};
bool sbi_domain_is_assigned_hart(const struct sbi_domain *dom, u32 hartid)
@@ -383,6 +384,8 @@ void sbi_domain_dump(const struct sbi_domain *dom, const char *suffix)
sbi_printf("Domain%d SysReset %s: %s\n",
dom->index, suffix, (dom->system_reset_allowed) ? "yes" : "no");
sbi_printf("Domain%d SysSuspend %s: %s\n",
dom->index, suffix, (dom->system_suspend_allowed) ? "yes" : "no");
}
void sbi_domain_dump_all(const char *suffix)

View File

@@ -168,6 +168,9 @@ int sbi_ecall_init(void)
if (ret)
return ret;
ret = sbi_ecall_register_extension(&ecall_vendor);
if (ret)
return ret;
ret = sbi_ecall_register_extension(&ecall_susp);
if (ret)
return ret;

View File

@@ -14,6 +14,7 @@
#include <sbi/sbi_trap.h>
#include <sbi/sbi_version.h>
#include <sbi/riscv_asm.h>
#include <sbi/riscv_io.h>
static int sbi_ecall_base_probe(unsigned long extid, unsigned long *out_val)
{
@@ -32,6 +33,41 @@ static int sbi_ecall_base_probe(unsigned long extid, unsigned long *out_val)
return 0;
}
#define SEC_SYS_BASE (0x020B0000)
static int sbi_ecall_base_rst_c906l(void)
{
unsigned int value;
value = readl((void *)0x3003024);
writel((value & (~(1 << 6))), (void *)0x3003024);
return 0;
}
static int sbi_ecall_base_unrst_c906l(const unsigned long address)
{
unsigned int value;
value = readl((void *)SEC_SYS_BASE + 0x04);
writel((value | (1 << 13)), (void *)SEC_SYS_BASE + 0x04);
writel(address, (void *)SEC_SYS_BASE + 0x20);
writel((address >> 32), (void *)SEC_SYS_BASE + 0x24);
value = readl((void *)0x3003024);
writel((value | (1 << 6)), (void *)0x3003024);
return 0;
}
static int sbi_ecall_base_reset_c906l(const unsigned long address)
{
sbi_ecall_base_rst_c906l();
sbi_ecall_base_unrst_c906l(address);
return 0;
}
static int sbi_ecall_base_handler(unsigned long extid, unsigned long funcid,
const struct sbi_trap_regs *regs,
unsigned long *out_val,
@@ -65,6 +101,16 @@ static int sbi_ecall_base_handler(unsigned long extid, unsigned long funcid,
case SBI_EXT_BASE_PROBE_EXT:
ret = sbi_ecall_base_probe(regs->a0, out_val);
break;
case SBI_EXT_BASE_RESET_C906L:
ret = sbi_ecall_base_reset_c906l(regs->a0);
*out_val = regs->a0;
break;
case SBI_EXT_BASE_RST_C906L:
ret = sbi_ecall_base_rst_c906l();
break;
case SBI_EXT_BASE_UNRST_C906L:
ret = sbi_ecall_base_unrst_c906l(regs->a0);
break;
default:
ret = SBI_ENOTSUPP;
}

60
lib/sbi/sbi_ecall_susp.c Normal file
View File

@@ -0,0 +1,60 @@
// SPDX-License-Identifier: BSD-2-Clause
#include <sbi/sbi_ecall.h>
#include <sbi/sbi_ecall_interface.h>
#include <sbi/sbi_error.h>
#include <sbi/sbi_trap.h>
#include <sbi/sbi_system.h>
static int sbi_ecall_susp_handler(unsigned long extid, unsigned long funcid,
const struct sbi_trap_regs *regs,
unsigned long *out_val,
struct sbi_trap_info *out_trap)
{
int ret = SBI_ENOTSUPP;
if (funcid == SBI_EXT_SUSP_SUSPEND)
ret = sbi_system_suspend(regs->a0, regs->a1, regs->a2);
if (ret >= 0) {
*out_val = ret;
ret = 0;
}
return ret;
}
static bool susp_available(void)
{
u32 type;
/*
* At least one suspend type should be supported by the
* platform for the SBI SUSP extension to be usable.
*/
for (type = 0; type <= SBI_SUSP_SLEEP_TYPE_LAST; type++) {
if (sbi_system_suspend_supported(type))
return true;
}
return false;
}
struct sbi_ecall_extension ecall_susp;
static int sbi_ecall_susp_register_extensions(unsigned long extid, unsigned long *out_val)
{
if (!susp_available()) {
*out_val = 0;
return 0;
}
*out_val = 1;
return 0;
}
struct sbi_ecall_extension ecall_susp = {
.extid_start = SBI_EXT_SUSP,
.extid_end = SBI_EXT_SUSP,
.probe = sbi_ecall_susp_register_extensions,
.handle = sbi_ecall_susp_handler,
};

View File

@@ -36,8 +36,25 @@ struct sbi_hsm_data {
unsigned long saved_mie;
unsigned long saved_mip;
};
#define __sbi_hsm_hart_change_state(hdata, oldstate, newstate) \
({ \
long state = atomic_cmpxchg(&(hdata)->state, oldstate, newstate); \
if (state != (oldstate)) \
sbi_printf("%s: ERR: The hart is in invalid state [%lu]\n", \
__func__, state); \
state == (oldstate); \
})
static inline int __sbi_hsm_hart_get_state(u32 hartid)
int sbi_hsm_hart_change_state(struct sbi_scratch *scratch, long oldstate,
long newstate)
{
struct sbi_hsm_data *hdata = sbi_scratch_offset_ptr(scratch,
hart_data_offset);
return __sbi_hsm_hart_change_state(hdata, oldstate, newstate);
}
int __sbi_hsm_hart_get_state(u32 hartid)
{
struct sbi_hsm_data *hdata;
struct sbi_scratch *scratch;
@@ -322,7 +339,7 @@ static int __sbi_hsm_suspend_ret_default(struct sbi_scratch *scratch)
return 0;
}
static void __sbi_hsm_suspend_non_ret_save(struct sbi_scratch *scratch)
void __sbi_hsm_suspend_non_ret_save(struct sbi_scratch *scratch)
{
struct sbi_hsm_data *hdata = sbi_scratch_offset_ptr(scratch,
hart_data_offset);

View File

@@ -58,6 +58,7 @@ static void sbi_boot_print_general(struct sbi_scratch *scratch)
const struct sbi_timer_device *tdev;
const struct sbi_console_device *cdev;
const struct sbi_system_reset_device *srdev;
const struct sbi_system_suspend_device *susp_dev;
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
if (scratch->options & SBI_SCRATCH_NO_BOOT_PRINTS)
@@ -85,6 +86,9 @@ static void sbi_boot_print_general(struct sbi_scratch *scratch)
srdev = sbi_system_reset_get_device();
sbi_printf("Platform SysReset Device : %s\n",
(srdev) ? srdev->name : "---");
susp_dev = sbi_system_suspend_get_device();
sbi_printf("Platform Suspend Device : %s\n",
(susp_dev) ? susp_dev->name : "---");
/* Firmware details */
sbi_printf("Firmware Base : 0x%lx\n", scratch->fw_start);
@@ -221,7 +225,9 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
{
int rc;
unsigned long *init_count;
#ifndef CONFIG_OPENSBI_FASTBOOT
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
#endif
/* Note: This has to be first thing in coldboot init sequence */
rc = sbi_scratch_init(scratch);
@@ -242,20 +248,25 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
if (rc)
sbi_hart_hang();
#ifndef CONFIG_OPENSBI_FASTBOOT
rc = sbi_platform_early_init(plat, TRUE);
if (rc)
sbi_hart_hang();
#endif
rc = sbi_hart_init(scratch, TRUE);
if (rc)
sbi_hart_hang();
#ifndef CONFIG_OPENSBI_FASTBOOT
rc = sbi_console_init(scratch);
if (rc)
sbi_hart_hang();
#endif
sbi_boot_print_banner(scratch);
#ifndef CONFIG_OPENSBI_FASTBOOT
rc = sbi_platform_irqchip_init(plat, TRUE);
if (rc) {
sbi_printf("%s: platform irqchip init failed (error %d)\n",
@@ -268,6 +279,7 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
sbi_printf("%s: ipi init failed (error %d)\n", __func__, rc);
sbi_hart_hang();
}
#endif
rc = sbi_tlb_init(scratch, TRUE);
if (rc) {
@@ -315,12 +327,14 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
* Note: Platform final initialization should be last so that
* it sees correct domain assignment and PMP configuration.
*/
#ifndef CONFIG_OPENSBI_FASTBOOT
rc = sbi_platform_final_init(plat, TRUE);
if (rc) {
sbi_printf("%s: platform final init failed (error %d)\n",
__func__, rc);
sbi_hart_hang();
}
#endif
sbi_boot_print_hart(scratch, hartid);

View File

@@ -42,6 +42,7 @@ bool sbi_system_reset_supported(u32 reset_type, u32 reset_reason)
return FALSE;
}
#include <sbi/riscv_io.h>
void __noreturn sbi_system_reset(u32 reset_type, u32 reset_reason)
{
ulong hbase = 0, hmask;
@@ -66,6 +67,93 @@ void __noreturn sbi_system_reset(u32 reset_type, u32 reset_reason)
reset_dev && reset_dev->system_reset)
reset_dev->system_reset(reset_type, reset_reason);
writew(0x5555, (void *)0x100000); // qemu poweroff
/* If platform specific reset did not work then do sbi_exit() */
sbi_exit(scratch);
}
static const struct sbi_system_suspend_device *suspend_dev;
const struct sbi_system_suspend_device *sbi_system_suspend_get_device(void)
{
return suspend_dev;
}
void sbi_system_suspend_set_device(struct sbi_system_suspend_device *dev)
{
if (!dev || suspend_dev)
return;
suspend_dev = dev;
}
bool sbi_system_suspend_supported(u32 sleep_type)
{
return suspend_dev && suspend_dev->system_suspend_check &&
suspend_dev->system_suspend_check(sleep_type) == 0;
}
int sbi_system_suspend(u32 sleep_type, ulong resume_addr, ulong opaque)
{
const struct sbi_domain *dom = sbi_domain_thishart_ptr();
struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
void (*jump_warmboot)(void) = (void (*)(void))scratch->warmboot_addr;
//unsigned int hartid = current_hartid();
unsigned long prev_mode;
//unsigned long i, j;
int ret;
if (!dom || !dom->system_suspend_allowed)
return SBI_EFAIL;
if (!suspend_dev || !suspend_dev->system_suspend ||
!suspend_dev->system_suspend_check)
return SBI_EFAIL;
ret = suspend_dev->system_suspend_check(sleep_type);
if (ret != SBI_OK)
return ret;
prev_mode = (csr_read(CSR_MSTATUS) & MSTATUS_MPP) >> MSTATUS_MPP_SHIFT;
if (prev_mode != PRV_S && prev_mode != PRV_U)
return SBI_EFAIL;
//FIX ME: hartindex to hart
//sbi_hartmask_for_each_hartindex(j, &dom->assigned_harts) {
// //i = sbi_hartindex_to_hartid(j);
// if (i == hartid)
// continue;
// if (__sbi_hsm_hart_get_state(i) != SBI_HSM_STATE_STOPPED)
// return SBI_ERR_DENIED;
//}
if (!sbi_domain_check_addr(dom, resume_addr, prev_mode,
SBI_DOMAIN_EXECUTE))
return SBI_EINVALID_ADDR;
if (!sbi_hsm_hart_change_state(scratch, SBI_HSM_STATE_STARTED,
SBI_HSM_STATE_SUSPENDED))
return SBI_EFAIL;
/* Prepare for resume */
scratch->next_mode = prev_mode;
scratch->next_addr = resume_addr;
scratch->next_arg1 = opaque;
__sbi_hsm_suspend_non_ret_save(scratch);
/* Suspend */
ret = suspend_dev->system_suspend(sleep_type, scratch->warmboot_addr);
if (ret != SBI_OK) {
if (!sbi_hsm_hart_change_state(scratch, SBI_HSM_STATE_SUSPENDED,
SBI_HSM_STATE_STARTED))
sbi_hart_hang();
return ret;
}
/* Resume */
jump_warmboot();
__builtin_unreachable();
}

View File

@@ -398,6 +398,13 @@ static int __fdt_parse_domain(void *fdt, int domain_offset, void *opaque)
else
dom->system_reset_allowed = FALSE;
/* Read "system-suspend-allowed" DT property */
if (fdt_get_property(fdt, domain_offset,
"system-suspend-allowed", NULL))
dom->system_suspend_allowed = TRUE;
else
dom->system_suspend_allowed = FALSE;
/* Find /cpus DT node */
cpus_offset = fdt_path_offset(fdt, "/cpus");
if (cpus_offset < 0)

View File

@@ -94,7 +94,7 @@ int plic_cold_irqchip_init(struct plic_data *plic)
/* Configure default priorities of all IRQs */
for (i = 1; i <= plic->num_src; i++)
plic_set_priority(plic, i, 0);
plic_set_priority(plic, i, 1);
return 0;
}

1
lib/utils/serial/fdt_serial_uart8250.c Normal file → Executable file
View File

@@ -26,6 +26,7 @@ static int serial_uart8250_init(void *fdt, int nodeoff,
}
static const struct fdt_match serial_uart8250_match[] = {
{ .compatible = "snps,dw-apb-uart" },
{ .compatible = "ns16550" },
{ .compatible = "ns16550a" },
{ },

View File

@@ -101,7 +101,7 @@ int uart8250_init(unsigned long base, u32 in_freq, u32 baudrate, u32 reg_shift,
uart8250_in_freq = in_freq;
uart8250_baudrate = baudrate;
bdiv = uart8250_in_freq / (16 * uart8250_baudrate);
bdiv = (uart8250_in_freq + 8 * uart8250_baudrate) / (16 * uart8250_baudrate);
/* Disable all interrupts */
set_reg(UART_IER_OFFSET, 0x00);

View File

@@ -15,7 +15,9 @@
#define CLINT_TIMER_MAX_NR 16
static unsigned long clint_timer_count = 0;
static struct clint_data clint_timer[CLINT_TIMER_MAX_NR];
static struct clint_data clint_timer[CLINT_TIMER_MAX_NR] = {
{.addr = 0x74000000, .first_hartid = 0, .hart_count = 1, .has_64bit_mmio = 0, },
};
static int timer_clint_cold_init(void *fdt, int nodeoff,
const struct fdt_match *match)
@@ -29,9 +31,11 @@ static int timer_clint_cold_init(void *fdt, int nodeoff,
if (1 < clint_timer_count)
ctmaster = &clint_timer[0];
rc = fdt_parse_clint_node(fdt, nodeoff, TRUE, ct);
if (rc)
return rc;
if (clint_timer_count != 1) {
rc = fdt_parse_clint_node(fdt, nodeoff, TRUE, ct);
if (rc)
return rc;
}
return clint_cold_timer_init(ct, ctmaster);
}

View File

@@ -28,7 +28,8 @@ else
# This needs to be 2MB aligned for 64-bit system
FW_JUMP_ADDR=$(shell printf "0x%X" $$(($(FW_TEXT_START) + 0x200000)))
endif
FW_JUMP_FDT_ADDR=$(shell printf "0x%X" $$(($(FW_TEXT_START) + 0x2200000)))
#set FDT_ADDR 0xB0000000
FW_JUMP_FDT_ADDR=$(shell printf "0x%X" $$(($(FW_TEXT_START) + 0x30000000)))
FW_PAYLOAD=y
ifeq ($(PLATFORM_RISCV_XLEN), 32)
# This needs to be 4MB aligned for 32-bit system

View File

@@ -0,0 +1,111 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2020 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
#include <platform_override.h>
#include <sbi_utils/fdt/fdt_helper.h>
#include <sbi_utils/fdt/fdt_fixup.h>
#include <sbi/sbi_system.h>
#include <sbi/sbi_ecall_interface.h>
#include <sbi/sbi_string.h>
#include <sbi/sbi_types.h>
#include <sbi/sbi_error.h>
#include <sbi/riscv_asm.h>
#include <sbi/riscv_io.h>
__asm__(".section .rodata\n"
".global suspend_sram_entry\n"
".global suspend_sram_end\n"
".type suspend_sram_entry, @object\n"
".type suspend_sram_end, @object\n"
".align 4\n"
"suspend_sram_entry:\n"
".incbin \"" STRINGIFY(PM_SRAM_BIN_PATH) "\"\n"
".align 4\n"
"suspend_sram_end:\n"
".text\n");
#define RTC_SRAM_FLAG_ADDR 0x05026ff8
#ifdef CONFIG_CV180X
#define SUSPEND_SRAM_ENTRY 0x3C000000
#endif
#ifdef CONFIG_CV181X
#define SUSPEND_SRAM_ENTRY 0xC030000
#endif
#define SUSPEND_SRAM_ENTRY 0xC030000
#define memcpy sbi_memcpy
static void rtc_latch_pinmux_settings(void)
{
writel(0x2, (void *)0x50250ac);
writel(0x0, (void *)0x5027084);
//TODO
}
static void rtc_power_saving_settings_for_suspend(void)
{
//TODO
}
static int cvitek_sbi_system_suspend_check(u32 sleep_type)
{
return sleep_type == SBI_SUSP_SLEEP_TYPE_SUSPEND ? 0 : SBI_EINVAL;
}
static int cvitek_sbi_system_suspend(u32 sleep_type,
unsigned long mmode_resume_addr)
{
void (*suspend)(void) = (void *)SUSPEND_SRAM_ENTRY;
if (sleep_type != SBI_SUSP_SLEEP_TYPE_SUSPEND)
return SBI_EINVAL;
rtc_latch_pinmux_settings();
rtc_power_saving_settings_for_suspend();
/* store warmboot entry for resume*/
writel(mmode_resume_addr, (void *)RTC_SRAM_FLAG_ADDR);
writel(readl((void *)0x03002000) | 0x10, (void *)0x03002000); //enable TPU clock
memcpy((void *)SUSPEND_SRAM_ENTRY, suspend_sram_entry, suspend_sram_end - suspend_sram_entry);
asm volatile("fence.i" ::: "memory");
asm volatile("fence rw,rw\n\t");
suspend();
wfi();
return SBI_OK;
}
static struct sbi_system_suspend_device cvitek_sbi_suspend_device = {
.name = "cvi-suspend",
.system_suspend_check = cvitek_sbi_system_suspend_check,
.system_suspend = cvitek_sbi_system_suspend,
};
static int cvitek_riscv_early_init(bool cold_boot, const struct fdt_match *match)
{
sbi_system_suspend_set_device(&cvitek_sbi_suspend_device);
return 0;
}
static const struct fdt_match cvitek_riscv_match[] = {
{ .compatible = "cvitek,cv180x" },
{ .compatible = "cvitek,cv181x" },
{ .compatible = "cvitek,sg200x" }
};
const struct platform_override cvitek_riscv = {
.match_table = cvitek_riscv_match,
.early_init = cvitek_riscv_early_init,
};

View File

@@ -12,6 +12,11 @@
#include <sbi/sbi_types.h>
extern const struct platform_override sifive_fu540;
extern const struct platform_override cvitek_riscv;
extern u8 suspend_sram_entry[];
extern u8 suspend_sram_end[];
struct platform_override {
const struct fdt_match *match_table;
u64 (*features)(const struct fdt_match *match);

View File

@@ -9,3 +9,4 @@
platform-objs-y += platform.o
platform-objs-y += sifive_fu540.o
platform-objs-y += cvitek_riscv.o

View File

@@ -22,10 +22,9 @@
#include <sbi_utils/ipi/fdt_ipi.h>
#include <sbi_utils/reset/fdt_reset.h>
extern const struct platform_override sifive_fu540;
static const struct platform_override *special_platforms[] = {
&sifive_fu540,
&cvitek_riscv,
};
static const struct platform_override *generic_plat = NULL;
@@ -184,7 +183,166 @@ static u64 generic_tlbr_flush_limit(void)
return SBI_PLATFORM_TLB_RANGE_FLUSH_LIMIT_DEFAULT;
}
#include <sbi/sbi_trap.h>
#define CSR_MCOUNTERWEN 0x7c9
static void sbi_thead_pmu_init(void)
{
unsigned long interrupts;
interrupts = csr_read(CSR_MIDELEG) | (1 << 17);
csr_write(CSR_MIDELEG, interrupts);
/* CSR_MCOUNTEREN has already been set in mstatus_init() */
csr_write(CSR_MCOUNTERWEN, 0xffffffff);
csr_write(CSR_MHPMEVENT3, 1);
csr_write(CSR_MHPMEVENT4, 2);
csr_write(CSR_MHPMEVENT5, 3);
csr_write(CSR_MHPMEVENT6, 4);
csr_write(CSR_MHPMEVENT7, 5);
csr_write(CSR_MHPMEVENT8, 6);
csr_write(CSR_MHPMEVENT9, 7);
csr_write(CSR_MHPMEVENT10, 8);
csr_write(CSR_MHPMEVENT11, 9);
csr_write(CSR_MHPMEVENT12, 10);
csr_write(CSR_MHPMEVENT13, 11);
csr_write(CSR_MHPMEVENT14, 12);
csr_write(CSR_MHPMEVENT15, 13);
csr_write(CSR_MHPMEVENT16, 14);
csr_write(CSR_MHPMEVENT17, 15);
csr_write(CSR_MHPMEVENT18, 16);
csr_write(CSR_MHPMEVENT19, 17);
csr_write(CSR_MHPMEVENT20, 18);
csr_write(CSR_MHPMEVENT21, 19);
csr_write(CSR_MHPMEVENT22, 20);
csr_write(CSR_MHPMEVENT23, 21);
csr_write(CSR_MHPMEVENT24, 22);
csr_write(CSR_MHPMEVENT25, 23);
csr_write(CSR_MHPMEVENT26, 24);
csr_write(CSR_MHPMEVENT27, 25);
csr_write(CSR_MHPMEVENT28, 26);
}
static void sbi_thead_pmu_map(unsigned long idx, unsigned long event_id)
{
switch (idx) {
case 3:
csr_write(CSR_MHPMEVENT3, event_id);
break;
case 4:
csr_write(CSR_MHPMEVENT4, event_id);
break;
case 5:
csr_write(CSR_MHPMEVENT5, event_id);
break;
case 6:
csr_write(CSR_MHPMEVENT6, event_id);
break;
case 7:
csr_write(CSR_MHPMEVENT7, event_id);
break;
case 8:
csr_write(CSR_MHPMEVENT8, event_id);
break;
case 9:
csr_write(CSR_MHPMEVENT9, event_id);
break;
case 10:
csr_write(CSR_MHPMEVENT10, event_id);
break;
case 11:
csr_write(CSR_MHPMEVENT11, event_id);
break;
case 12:
csr_write(CSR_MHPMEVENT12, event_id);
break;
case 13:
csr_write(CSR_MHPMEVENT13, event_id);
break;
case 14:
csr_write(CSR_MHPMEVENT14, event_id);
break;
case 15:
csr_write(CSR_MHPMEVENT15, event_id);
break;
case 16:
csr_write(CSR_MHPMEVENT16, event_id);
break;
case 17:
csr_write(CSR_MHPMEVENT17, event_id);
break;
case 18:
csr_write(CSR_MHPMEVENT18, event_id);
break;
case 19:
csr_write(CSR_MHPMEVENT19, event_id);
break;
case 20:
csr_write(CSR_MHPMEVENT20, event_id);
break;
case 21:
csr_write(CSR_MHPMEVENT21, event_id);
break;
case 22:
csr_write(CSR_MHPMEVENT22, event_id);
break;
case 23:
csr_write(CSR_MHPMEVENT23, event_id);
break;
case 24:
csr_write(CSR_MHPMEVENT24, event_id);
break;
case 25:
csr_write(CSR_MHPMEVENT25, event_id);
break;
case 26:
csr_write(CSR_MHPMEVENT26, event_id);
break;
case 27:
csr_write(CSR_MHPMEVENT27, event_id);
break;
case 28:
csr_write(CSR_MHPMEVENT28, event_id);
break;
case 29:
csr_write(CSR_MHPMEVENT29, event_id);
break;
case 30:
csr_write(CSR_MHPMEVENT30, event_id);
break;
case 31:
csr_write(CSR_MHPMEVENT31, event_id);
break;
}
}
static void sbi_thead_pmu_set(unsigned long type, unsigned long idx, unsigned long event_id)
{
switch (type) {
case 2:
sbi_thead_pmu_map(idx, event_id);
break;
default:
sbi_thead_pmu_init();
break;
}
}
static int thead_vendor_ext_provider(long extid, long funcid,
const struct sbi_trap_regs *regs, unsigned long *out_value,
struct sbi_trap_info *out_trap)
{
switch (extid) {
case 0x09000001:
sbi_thead_pmu_set(regs->a0, regs->a1, regs->a2);
break;
default:
while(1);
}
return 0;
}
const struct sbi_platform_operations platform_ops = {
.vendor_ext_provider = thead_vendor_ext_provider,
.early_init = generic_early_init,
.final_init = generic_final_init,
.early_exit = generic_early_exit,

BIN
pm_default_cv180x.bin Executable file

Binary file not shown.

BIN
pm_default_cv181x.bin Executable file

Binary file not shown.