forked from Mirrors/opensbi
lib: Implement Hart State Management (HSM) SBI extension
This patch adds support HSM extension. The specification is available at https://github.com/riscv/riscv-sbi-doc. It allows to implement hart hotplug and fixed ordered hart booting in supervisor. Signed-off-by: Atish Patra <atish.patra@wdc.com> Reviewed-by: Anup Patel <anup.patel@wdc.com>
This commit is contained in:
@@ -39,6 +39,7 @@ extern struct sbi_ecall_extension ecall_time;
|
|||||||
extern struct sbi_ecall_extension ecall_rfence;
|
extern struct sbi_ecall_extension ecall_rfence;
|
||||||
extern struct sbi_ecall_extension ecall_ipi;
|
extern struct sbi_ecall_extension ecall_ipi;
|
||||||
extern struct sbi_ecall_extension ecall_vendor;
|
extern struct sbi_ecall_extension ecall_vendor;
|
||||||
|
extern struct sbi_ecall_extension ecall_hsm;
|
||||||
|
|
||||||
u16 sbi_ecall_version_major(void);
|
u16 sbi_ecall_version_major(void);
|
||||||
|
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#define SBI_EXT_TIME 0x54494D45
|
#define SBI_EXT_TIME 0x54494D45
|
||||||
#define SBI_EXT_IPI 0x735049
|
#define SBI_EXT_IPI 0x735049
|
||||||
#define SBI_EXT_RFENCE 0x52464E43
|
#define SBI_EXT_RFENCE 0x52464E43
|
||||||
|
#define SBI_EXT_HSM 0x48534D
|
||||||
|
|
||||||
/* SBI function IDs for BASE extension*/
|
/* SBI function IDs for BASE extension*/
|
||||||
#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
|
#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
|
||||||
@@ -51,6 +52,11 @@
|
|||||||
#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA 0x5
|
#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA 0x5
|
||||||
#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID 0x6
|
#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID 0x6
|
||||||
|
|
||||||
|
/* SBI function IDs for HSM extension */
|
||||||
|
#define SBI_EXT_HSM_HART_START 0x0
|
||||||
|
#define SBI_EXT_HSM_HART_STOP 0x1
|
||||||
|
#define SBI_EXT_HSM_HART_GET_STATUS 0x2
|
||||||
|
|
||||||
#define SBI_HSM_HART_STATUS_STARTED 0x0
|
#define SBI_HSM_HART_STATUS_STARTED 0x0
|
||||||
#define SBI_HSM_HART_STATUS_STOPPED 0x1
|
#define SBI_HSM_HART_STATUS_STOPPED 0x1
|
||||||
#define SBI_HSM_HART_STATUS_START_PENDING 0x2
|
#define SBI_HSM_HART_STATUS_START_PENDING 0x2
|
||||||
|
@@ -18,6 +18,7 @@ libsbi-objs-y += sbi_ecall_base.o
|
|||||||
libsbi-objs-y += sbi_ecall_legacy.o
|
libsbi-objs-y += sbi_ecall_legacy.o
|
||||||
libsbi-objs-y += sbi_ecall_replace.o
|
libsbi-objs-y += sbi_ecall_replace.o
|
||||||
libsbi-objs-y += sbi_ecall_vendor.o
|
libsbi-objs-y += sbi_ecall_vendor.o
|
||||||
|
libsbi-objs-y += sbi_ecall_hsm.o
|
||||||
libsbi-objs-y += sbi_emulate_csr.o
|
libsbi-objs-y += sbi_emulate_csr.o
|
||||||
libsbi-objs-y += sbi_fifo.o
|
libsbi-objs-y += sbi_fifo.o
|
||||||
libsbi-objs-y += sbi_hfence.o
|
libsbi-objs-y += sbi_hfence.o
|
||||||
|
@@ -136,6 +136,9 @@ int sbi_ecall_init(void)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret = sbi_ecall_register_extension(&ecall_base);
|
ret = sbi_ecall_register_extension(&ecall_base);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
ret = sbi_ecall_register_extension(&ecall_hsm);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret = sbi_ecall_register_extension(&ecall_legacy);
|
ret = sbi_ecall_register_extension(&ecall_legacy);
|
||||||
|
51
lib/sbi/sbi_ecall_hsm.c
Normal file
51
lib/sbi/sbi_ecall_hsm.c
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Western Digital Corporation or its affiliates.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Atish Patra <atish.patra@wdc.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sbi/sbi_ecall.h>
|
||||||
|
#include <sbi/sbi_ecall_interface.h>
|
||||||
|
#include <sbi/sbi_error.h>
|
||||||
|
#include <sbi/sbi_version.h>
|
||||||
|
#include <sbi/sbi_hsm.h>
|
||||||
|
#include <sbi/riscv_asm.h>
|
||||||
|
|
||||||
|
static int sbi_ecall_hsm_handler(struct sbi_scratch *scratch,
|
||||||
|
unsigned long extid, unsigned long funcid,
|
||||||
|
unsigned long *args, unsigned long *out_val,
|
||||||
|
struct sbi_trap_info *out_trap)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
int hstate;
|
||||||
|
|
||||||
|
switch (funcid) {
|
||||||
|
case SBI_EXT_HSM_HART_START:
|
||||||
|
ret = sbi_hsm_hart_start(scratch, args[0], args[1], args[2]);
|
||||||
|
break;
|
||||||
|
case SBI_EXT_HSM_HART_STOP:
|
||||||
|
ret = sbi_hsm_hart_stop(scratch, TRUE);
|
||||||
|
break;
|
||||||
|
case SBI_EXT_HSM_HART_GET_STATUS:
|
||||||
|
hstate = sbi_hsm_hart_get_state(scratch, args[0]);
|
||||||
|
ret = sbi_hsm_hart_state_to_status(hstate);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = SBI_ENOTSUPP;
|
||||||
|
};
|
||||||
|
if (ret >= 0) {
|
||||||
|
*out_val = ret;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sbi_ecall_extension ecall_hsm = {
|
||||||
|
.extid_start = SBI_EXT_HSM,
|
||||||
|
.extid_end = SBI_EXT_HSM,
|
||||||
|
.handle = sbi_ecall_hsm_handler,
|
||||||
|
};
|
Reference in New Issue
Block a user