mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2026-08-18 01:21:49 +01:00
lib: sbi: Extend hart protection abstraction to allow ID configuration
There are various ID configuration ISA extensions such as RISC-V Worlds, Supervisor domain ID, QoS ID, etc which need to be re-configured upon domain context switch on a hart. Extend hart protection abstraction to support both memory protection and ID configuration ISA extensions. Signed-off-by: Anup Patel <anup.patel@oss.qualcomm.com> Reviewed-by: Rahul Pathak <rahul.pathak@oss.qualcomm.com> Link: https://lore.kernel.org/r/20260727042504.1743250-5-anup.patel@oss.qualcomm.com Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
@@ -13,6 +13,13 @@
|
|||||||
struct sbi_scratch;
|
struct sbi_scratch;
|
||||||
struct sbi_domain;
|
struct sbi_domain;
|
||||||
|
|
||||||
|
/** Different types of hart protection mechanisms */
|
||||||
|
enum sbi_hart_protection_type {
|
||||||
|
SBI_HART_PROTECTION_TYPE_MEMORY = 0,
|
||||||
|
SBI_HART_PROTECTION_TYPE_ID,
|
||||||
|
SBI_HART_PROTECTION_TYPE_MAX
|
||||||
|
};
|
||||||
|
|
||||||
/** Representation of hart protection mechanism */
|
/** Representation of hart protection mechanism */
|
||||||
struct sbi_hart_protection {
|
struct sbi_hart_protection {
|
||||||
/** List head */
|
/** List head */
|
||||||
@@ -21,6 +28,9 @@ struct sbi_hart_protection {
|
|||||||
/** Name of the hart protection mechanism */
|
/** Name of the hart protection mechanism */
|
||||||
char name[32];
|
char name[32];
|
||||||
|
|
||||||
|
/** Type of the hart protection mechanism */
|
||||||
|
enum sbi_hart_protection_type type;
|
||||||
|
|
||||||
/** Ratings of the hart protection mechanism (higher is better) */
|
/** Ratings of the hart protection mechanism (higher is better) */
|
||||||
unsigned long rating;
|
unsigned long rating;
|
||||||
|
|
||||||
@@ -40,11 +50,11 @@ struct sbi_hart_protection {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the best hart protection mechanism
|
* Get the best hart memory protection mechanism
|
||||||
*
|
*
|
||||||
* @return pointer to best hart protection mechanism
|
* @return pointer to best hart memory protection mechanism
|
||||||
*/
|
*/
|
||||||
struct sbi_hart_protection *sbi_hart_protection_best(void);
|
struct sbi_hart_protection *sbi_hart_memory_protection_best(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a hart protection mechanism
|
* Register a hart protection mechanism
|
||||||
|
|||||||
@@ -425,6 +425,7 @@ static void sbi_hart_pmp_unconfigure(struct sbi_scratch *scratch,
|
|||||||
static struct sbi_hart_protection pmp_protection = {
|
static struct sbi_hart_protection pmp_protection = {
|
||||||
.name = "pmp",
|
.name = "pmp",
|
||||||
.rating = 100,
|
.rating = 100,
|
||||||
|
.type = SBI_HART_PROTECTION_TYPE_MEMORY,
|
||||||
.configure = sbi_hart_oldpmp_configure,
|
.configure = sbi_hart_oldpmp_configure,
|
||||||
.unconfigure = sbi_hart_pmp_unconfigure,
|
.unconfigure = sbi_hart_pmp_unconfigure,
|
||||||
};
|
};
|
||||||
@@ -432,6 +433,7 @@ static struct sbi_hart_protection pmp_protection = {
|
|||||||
static struct sbi_hart_protection epmp_protection = {
|
static struct sbi_hart_protection epmp_protection = {
|
||||||
.name = "epmp",
|
.name = "epmp",
|
||||||
.rating = 200,
|
.rating = 200,
|
||||||
|
.type = SBI_HART_PROTECTION_TYPE_MEMORY,
|
||||||
.configure = sbi_hart_smepmp_configure,
|
.configure = sbi_hart_smepmp_configure,
|
||||||
.unconfigure = sbi_hart_pmp_unconfigure,
|
.unconfigure = sbi_hart_pmp_unconfigure,
|
||||||
.map_range = sbi_hart_smepmp_map_range,
|
.map_range = sbi_hart_smepmp_map_range,
|
||||||
|
|||||||
@@ -10,12 +10,16 @@
|
|||||||
|
|
||||||
static SBI_LIST_HEAD(hart_protection_list);
|
static SBI_LIST_HEAD(hart_protection_list);
|
||||||
|
|
||||||
struct sbi_hart_protection *sbi_hart_protection_best(void)
|
struct sbi_hart_protection *sbi_hart_memory_protection_best(void)
|
||||||
{
|
{
|
||||||
if (sbi_list_empty(&hart_protection_list))
|
struct sbi_hart_protection *pos;
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return sbi_list_first_entry(&hart_protection_list, struct sbi_hart_protection, head);
|
sbi_list_for_each_entry(pos, &hart_protection_list, head) {
|
||||||
|
if (pos->type == SBI_HART_PROTECTION_TYPE_MEMORY)
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sbi_hart_protection_register(struct sbi_hart_protection *hprot)
|
int sbi_hart_protection_register(struct sbi_hart_protection *hprot)
|
||||||
@@ -25,6 +29,8 @@ int sbi_hart_protection_register(struct sbi_hart_protection *hprot)
|
|||||||
|
|
||||||
if (!hprot)
|
if (!hprot)
|
||||||
return SBI_EINVAL;
|
return SBI_EINVAL;
|
||||||
|
if (hprot->type >= SBI_HART_PROTECTION_TYPE_MAX)
|
||||||
|
return SBI_EINVAL;
|
||||||
|
|
||||||
sbi_list_for_each_entry(pos, &hart_protection_list, head) {
|
sbi_list_for_each_entry(pos, &hart_protection_list, head) {
|
||||||
if (hprot->rating > pos->rating) {
|
if (hprot->rating > pos->rating) {
|
||||||
@@ -74,28 +80,97 @@ static void __hart_protection_unconfigure(struct sbi_scratch *scratch,
|
|||||||
int sbi_hart_protection_configure(struct sbi_scratch *scratch,
|
int sbi_hart_protection_configure(struct sbi_scratch *scratch,
|
||||||
struct sbi_domain *dom)
|
struct sbi_domain *dom)
|
||||||
{
|
{
|
||||||
return __hart_protection_configure(scratch, sbi_hart_protection_best(), dom);
|
bool do_configure, memory_protect_done = false;
|
||||||
|
struct sbi_hart_protection *hprot;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
sbi_list_for_each_entry(hprot, &hart_protection_list, head) {
|
||||||
|
do_configure = false;
|
||||||
|
switch (hprot->type) {
|
||||||
|
case SBI_HART_PROTECTION_TYPE_MEMORY:
|
||||||
|
do_configure = !memory_protect_done;
|
||||||
|
memory_protect_done = true;
|
||||||
|
break;
|
||||||
|
case SBI_HART_PROTECTION_TYPE_ID:
|
||||||
|
do_configure = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!do_configure)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret = __hart_protection_configure(scratch, hprot, dom);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sbi_hart_protection_unconfigure(struct sbi_scratch *scratch,
|
void sbi_hart_protection_unconfigure(struct sbi_scratch *scratch,
|
||||||
struct sbi_domain *dom)
|
struct sbi_domain *dom)
|
||||||
{
|
{
|
||||||
__hart_protection_unconfigure(scratch, sbi_hart_protection_best(), dom);
|
|
||||||
|
bool do_unconfigure, memory_protect_done = false;
|
||||||
|
struct sbi_hart_protection *hprot;
|
||||||
|
|
||||||
|
sbi_list_for_each_entry(hprot, &hart_protection_list, head) {
|
||||||
|
do_unconfigure = false;
|
||||||
|
switch (hprot->type) {
|
||||||
|
case SBI_HART_PROTECTION_TYPE_MEMORY:
|
||||||
|
do_unconfigure = !memory_protect_done;
|
||||||
|
memory_protect_done = true;
|
||||||
|
break;
|
||||||
|
case SBI_HART_PROTECTION_TYPE_ID:
|
||||||
|
do_unconfigure = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!do_unconfigure)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
__hart_protection_unconfigure(scratch, hprot, dom);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int sbi_hart_protection_reconfigure(struct sbi_scratch *scratch,
|
int sbi_hart_protection_reconfigure(struct sbi_scratch *scratch,
|
||||||
struct sbi_domain *current_dom,
|
struct sbi_domain *current_dom,
|
||||||
struct sbi_domain *next_dom)
|
struct sbi_domain *next_dom)
|
||||||
{
|
{
|
||||||
struct sbi_hart_protection *hprot = sbi_hart_protection_best();
|
bool do_reconfigure, memory_protect_done = false;
|
||||||
|
struct sbi_hart_protection *hprot;
|
||||||
|
int ret;
|
||||||
|
|
||||||
__hart_protection_unconfigure(scratch, hprot, current_dom);
|
sbi_list_for_each_entry(hprot, &hart_protection_list, head) {
|
||||||
return __hart_protection_configure(scratch, hprot, next_dom);
|
do_reconfigure = false;
|
||||||
|
switch (hprot->type) {
|
||||||
|
case SBI_HART_PROTECTION_TYPE_MEMORY:
|
||||||
|
do_reconfigure = !memory_protect_done;
|
||||||
|
memory_protect_done = true;
|
||||||
|
break;
|
||||||
|
case SBI_HART_PROTECTION_TYPE_ID:
|
||||||
|
do_reconfigure = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!do_reconfigure)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
__hart_protection_unconfigure(scratch, hprot, current_dom);
|
||||||
|
ret = __hart_protection_configure(scratch, hprot, next_dom);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sbi_hart_protection_map_range(unsigned long base, unsigned long size)
|
int sbi_hart_protection_map_range(unsigned long base, unsigned long size)
|
||||||
{
|
{
|
||||||
struct sbi_hart_protection *hprot = sbi_hart_protection_best();
|
struct sbi_hart_protection *hprot = sbi_hart_memory_protection_best();
|
||||||
|
|
||||||
if (!hprot || !hprot->map_range)
|
if (!hprot || !hprot->map_range)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -105,7 +180,7 @@ int sbi_hart_protection_map_range(unsigned long base, unsigned long size)
|
|||||||
|
|
||||||
int sbi_hart_protection_unmap_range(unsigned long base, unsigned long size)
|
int sbi_hart_protection_unmap_range(unsigned long base, unsigned long size)
|
||||||
{
|
{
|
||||||
struct sbi_hart_protection *hprot = sbi_hart_protection_best();
|
struct sbi_hart_protection *hprot = sbi_hart_memory_protection_best();
|
||||||
|
|
||||||
if (!hprot || !hprot->unmap_range)
|
if (!hprot || !hprot->unmap_range)
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+1
-1
@@ -93,7 +93,7 @@ static void sbi_boot_print_general(struct sbi_scratch *scratch)
|
|||||||
sbi_printf("Platform Features : %s\n", str);
|
sbi_printf("Platform Features : %s\n", str);
|
||||||
sbi_printf("Platform HART Count : %u\n",
|
sbi_printf("Platform HART Count : %u\n",
|
||||||
sbi_platform_hart_count(plat));
|
sbi_platform_hart_count(plat));
|
||||||
hprot = sbi_hart_protection_best();
|
hprot = sbi_hart_memory_protection_best();
|
||||||
sbi_printf("Platform HART Protection : %s\n",
|
sbi_printf("Platform HART Protection : %s\n",
|
||||||
(hprot) ? hprot->name : "---");
|
(hprot) ? hprot->name : "---");
|
||||||
idev = sbi_ipi_get_device();
|
idev = sbi_ipi_get_device();
|
||||||
|
|||||||
@@ -470,6 +470,7 @@ static void eswin_eic7700_pmp_unconfigure(struct sbi_scratch *scratch,
|
|||||||
static struct sbi_hart_protection eswin_eic7700_pmp_protection = {
|
static struct sbi_hart_protection eswin_eic7700_pmp_protection = {
|
||||||
.name = "eic7700_pmp",
|
.name = "eic7700_pmp",
|
||||||
.rating = -1UL,
|
.rating = -1UL,
|
||||||
|
.type = SBI_HART_PROTECTION_TYPE_MEMORY,
|
||||||
.configure = eswin_eic7700_pmp_configure,
|
.configure = eswin_eic7700_pmp_configure,
|
||||||
.unconfigure = eswin_eic7700_pmp_unconfigure,
|
.unconfigure = eswin_eic7700_pmp_unconfigure,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user