forked from Mirrors/opensbi
lib: sbi: Use a linked list to track domains
This removes the compile-time limit on the number of domains. It also reduces firmware size by about 200 bytes by removing the lookup table. Signed-off-by: Samuel Holland <samuel.holland@sifive.com> Reviewed-by: Anup Patel <anup@brainfault.org>
This commit is contained in:

committed by
Anup Patel

parent
792715e4f3
commit
65f04badf7
@@ -11,6 +11,7 @@
|
|||||||
#define __SBI_DOMAIN_H__
|
#define __SBI_DOMAIN_H__
|
||||||
|
|
||||||
#include <sbi/riscv_locks.h>
|
#include <sbi/riscv_locks.h>
|
||||||
|
#include <sbi/sbi_list.h>
|
||||||
#include <sbi/sbi_types.h>
|
#include <sbi/sbi_types.h>
|
||||||
#include <sbi/sbi_hartmask.h>
|
#include <sbi/sbi_hartmask.h>
|
||||||
#include <sbi/sbi_domain_context.h>
|
#include <sbi/sbi_domain_context.h>
|
||||||
@@ -158,11 +159,10 @@ struct sbi_domain_memregion {
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Maximum number of domains */
|
|
||||||
#define SBI_DOMAIN_MAX_INDEX 32
|
|
||||||
|
|
||||||
/** Representation of OpenSBI domain */
|
/** Representation of OpenSBI domain */
|
||||||
struct sbi_domain {
|
struct sbi_domain {
|
||||||
|
/** Node in linked list of domains */
|
||||||
|
struct sbi_dlist node;
|
||||||
/** Logical index of this domain */
|
/** Logical index of this domain */
|
||||||
u32 index;
|
u32 index;
|
||||||
/** HARTs assigned to this domain */
|
/** HARTs assigned to this domain */
|
||||||
@@ -206,16 +206,12 @@ void sbi_update_hartindex_to_domain(u32 hartindex, struct sbi_domain *dom);
|
|||||||
#define sbi_domain_thishart_ptr() \
|
#define sbi_domain_thishart_ptr() \
|
||||||
sbi_hartindex_to_domain(sbi_hartid_to_hartindex(current_hartid()))
|
sbi_hartindex_to_domain(sbi_hartid_to_hartindex(current_hartid()))
|
||||||
|
|
||||||
/** Index to domain table */
|
/** Head of linked list of domains */
|
||||||
extern struct sbi_domain *domidx_to_domain_table[];
|
extern struct sbi_dlist domain_list;
|
||||||
|
|
||||||
/** Get pointer to sbi_domain from index */
|
|
||||||
#define sbi_index_to_domain(__index) \
|
|
||||||
domidx_to_domain_table[__index]
|
|
||||||
|
|
||||||
/** Iterate over each domain */
|
/** Iterate over each domain */
|
||||||
#define sbi_domain_for_each(__i, __d) \
|
#define sbi_domain_for_each(__d) \
|
||||||
for ((__i) = 0; ((__d) = sbi_index_to_domain(__i)); (__i)++)
|
sbi_list_for_each_entry(__d, &domain_list, node)
|
||||||
|
|
||||||
/** Iterate over each memory region of a domain */
|
/** Iterate over each memory region of a domain */
|
||||||
#define sbi_domain_for_each_memregion(__d, __r) \
|
#define sbi_domain_for_each_memregion(__d, __r) \
|
||||||
|
@@ -13,16 +13,14 @@
|
|||||||
#include <sbi/sbi_hartmask.h>
|
#include <sbi/sbi_hartmask.h>
|
||||||
#include <sbi/sbi_heap.h>
|
#include <sbi/sbi_heap.h>
|
||||||
#include <sbi/sbi_hsm.h>
|
#include <sbi/sbi_hsm.h>
|
||||||
|
#include <sbi/sbi_list.h>
|
||||||
#include <sbi/sbi_math.h>
|
#include <sbi/sbi_math.h>
|
||||||
#include <sbi/sbi_platform.h>
|
#include <sbi/sbi_platform.h>
|
||||||
#include <sbi/sbi_scratch.h>
|
#include <sbi/sbi_scratch.h>
|
||||||
#include <sbi/sbi_string.h>
|
#include <sbi/sbi_string.h>
|
||||||
|
|
||||||
/*
|
SBI_LIST_HEAD(domain_list);
|
||||||
* We allocate an extra element because sbi_domain_for_each() expects
|
|
||||||
* the array to be null-terminated.
|
|
||||||
*/
|
|
||||||
struct sbi_domain *domidx_to_domain_table[SBI_DOMAIN_MAX_INDEX + 1] = { 0 };
|
|
||||||
static u32 domain_count = 0;
|
static u32 domain_count = 0;
|
||||||
static bool domain_finalized = false;
|
static bool domain_finalized = false;
|
||||||
|
|
||||||
@@ -519,10 +517,9 @@ void sbi_domain_dump(const struct sbi_domain *dom, const char *suffix)
|
|||||||
|
|
||||||
void sbi_domain_dump_all(const char *suffix)
|
void sbi_domain_dump_all(const char *suffix)
|
||||||
{
|
{
|
||||||
u32 i;
|
|
||||||
const struct sbi_domain *dom;
|
const struct sbi_domain *dom;
|
||||||
|
|
||||||
sbi_domain_for_each(i, dom) {
|
sbi_domain_for_each(dom) {
|
||||||
sbi_domain_dump(dom, suffix);
|
sbi_domain_dump(dom, suffix);
|
||||||
sbi_printf("\n");
|
sbi_printf("\n");
|
||||||
}
|
}
|
||||||
@@ -541,21 +538,11 @@ int sbi_domain_register(struct sbi_domain *dom,
|
|||||||
return SBI_EINVAL;
|
return SBI_EINVAL;
|
||||||
|
|
||||||
/* Check if domain already discovered */
|
/* Check if domain already discovered */
|
||||||
sbi_domain_for_each(i, tdom) {
|
sbi_domain_for_each(tdom) {
|
||||||
if (tdom == dom)
|
if (tdom == dom)
|
||||||
return SBI_EALREADY;
|
return SBI_EALREADY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Ensure that we have room for Domain Index to
|
|
||||||
* HART ID mapping
|
|
||||||
*/
|
|
||||||
if (SBI_DOMAIN_MAX_INDEX <= domain_count) {
|
|
||||||
sbi_printf("%s: No room for %s\n",
|
|
||||||
__func__, dom->name);
|
|
||||||
return SBI_ENOSPC;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sanitize discovered domain */
|
/* Sanitize discovered domain */
|
||||||
rc = sanitize_domain(dom);
|
rc = sanitize_domain(dom);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
@@ -565,9 +552,10 @@ int sbi_domain_register(struct sbi_domain *dom,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sbi_list_add_tail(&dom->node, &domain_list);
|
||||||
|
|
||||||
/* Assign index to domain */
|
/* Assign index to domain */
|
||||||
dom->index = domain_count++;
|
dom->index = domain_count++;
|
||||||
domidx_to_domain_table[dom->index] = dom;
|
|
||||||
|
|
||||||
/* Initialize spinlock for dom->assigned_harts */
|
/* Initialize spinlock for dom->assigned_harts */
|
||||||
SPIN_LOCK_INIT(dom->assigned_harts_lock);
|
SPIN_LOCK_INIT(dom->assigned_harts_lock);
|
||||||
@@ -692,7 +680,7 @@ int sbi_domain_root_add_memrange(unsigned long addr, unsigned long size,
|
|||||||
int sbi_domain_finalize(struct sbi_scratch *scratch, u32 cold_hartid)
|
int sbi_domain_finalize(struct sbi_scratch *scratch, u32 cold_hartid)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
u32 i, dhart;
|
u32 dhart;
|
||||||
struct sbi_domain *dom;
|
struct sbi_domain *dom;
|
||||||
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
|
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
|
||||||
|
|
||||||
@@ -705,7 +693,7 @@ int sbi_domain_finalize(struct sbi_scratch *scratch, u32 cold_hartid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Startup boot HART of domains */
|
/* Startup boot HART of domains */
|
||||||
sbi_domain_for_each(i, dom) {
|
sbi_domain_for_each(dom) {
|
||||||
/* Domain boot HART index */
|
/* Domain boot HART index */
|
||||||
dhart = sbi_hartid_to_hartindex(dom->boot_hartid);
|
dhart = sbi_hartid_to_hartindex(dom->boot_hartid);
|
||||||
|
|
||||||
|
@@ -107,7 +107,7 @@ int sbi_domain_context_enter(struct sbi_domain *dom)
|
|||||||
|
|
||||||
int sbi_domain_context_exit(void)
|
int sbi_domain_context_exit(void)
|
||||||
{
|
{
|
||||||
u32 i, hartindex = sbi_hartid_to_hartindex(current_hartid());
|
u32 hartindex = sbi_hartid_to_hartindex(current_hartid());
|
||||||
struct sbi_domain *dom;
|
struct sbi_domain *dom;
|
||||||
struct sbi_context *ctx = sbi_domain_context_thishart_ptr();
|
struct sbi_context *ctx = sbi_domain_context_thishart_ptr();
|
||||||
struct sbi_context *dom_ctx, *tmp;
|
struct sbi_context *dom_ctx, *tmp;
|
||||||
@@ -118,7 +118,7 @@ int sbi_domain_context_exit(void)
|
|||||||
* its context on the current hart if valid.
|
* its context on the current hart if valid.
|
||||||
*/
|
*/
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
sbi_domain_for_each(i, dom) {
|
sbi_domain_for_each(dom) {
|
||||||
if (!sbi_hartmask_test_hartindex(hartindex,
|
if (!sbi_hartmask_test_hartindex(hartindex,
|
||||||
dom->possible_harts))
|
dom->possible_harts))
|
||||||
continue;
|
continue;
|
||||||
@@ -140,7 +140,7 @@ int sbi_domain_context_exit(void)
|
|||||||
/* If no previous caller context */
|
/* If no previous caller context */
|
||||||
if (!dom_ctx) {
|
if (!dom_ctx) {
|
||||||
/* Try to find next uninitialized user-defined domain's context */
|
/* Try to find next uninitialized user-defined domain's context */
|
||||||
sbi_domain_for_each(i, dom) {
|
sbi_domain_for_each(dom) {
|
||||||
if (dom == &root || dom == sbi_domain_thishart_ptr())
|
if (dom == &root || dom == sbi_domain_thishart_ptr())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user