lib: sbi: Extend sbi_hartmask to support both hartid and hartindex

Currently, the sbi_hartmask is indexed by hartid which puts a
limit on hartid to be less than SBI_HARTMASK_MAX_BITS.

We extend the sbi_hartmask implementation to use hartindex and
support updating sbi_hartmask using hartid. This removes the
limit on hartid and existing code works largely unmodified.

Signed-off-by: Xiang W <wxjstz@126.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
This commit is contained in:
Xiang W
2023-08-31 11:39:30 +08:00
committed by Anup Patel
parent e6125c3c4f
commit 296e70d69d
7 changed files with 105 additions and 60 deletions

View File

@@ -65,7 +65,7 @@ static void update_hartid_to_domain(u32 hartid, struct sbi_domain *dom)
bool sbi_domain_is_assigned_hart(const struct sbi_domain *dom, u32 hartid)
{
if (dom)
return sbi_hartmask_test_hart(hartid, &dom->assigned_harts);
return sbi_hartmask_test_hartid(hartid, &dom->assigned_harts);
return false;
}
@@ -73,18 +73,10 @@ bool sbi_domain_is_assigned_hart(const struct sbi_domain *dom, u32 hartid)
ulong sbi_domain_get_assigned_hartmask(const struct sbi_domain *dom,
ulong hbase)
{
ulong ret, bword, boff;
if (!dom)
return 0;
bword = BIT_WORD(hbase);
boff = BIT_WORD_OFFSET(hbase);
ret = sbi_hartmask_bits(&dom->assigned_harts)[bword++] >> boff;
if (boff && bword < BIT_WORD(SBI_HARTMASK_MAX_BITS)) {
ret |= (sbi_hartmask_bits(&dom->assigned_harts)[bword] &
(BIT(boff) - 1UL)) << (BITS_PER_LONG - boff);
ulong ret = 0;
for (int i = 0; i < 8 * sizeof(ret); i++) {
if (sbi_domain_is_assigned_hart(dom, hbase + i))
ret |= 1 << i;
}
return ret;
@@ -276,7 +268,7 @@ static int sanitize_domain(const struct sbi_platform *plat,
__func__, dom->name);
return SBI_EINVAL;
}
sbi_hartmask_for_each_hart(i, dom->possible_harts) {
sbi_hartmask_for_each_hart(i, j, dom->possible_harts) {
if (!sbi_hartid_valid(i)) {
sbi_printf("%s: %s possible HART mask has invalid "
"hart %d\n", __func__, dom->name, i);
@@ -400,7 +392,7 @@ bool sbi_domain_check_addr_range(const struct sbi_domain *dom,
void sbi_domain_dump(const struct sbi_domain *dom, const char *suffix)
{
u32 i, k;
u32 i, j, k;
unsigned long rstart, rend;
struct sbi_domain_memregion *reg;
@@ -412,7 +404,7 @@ void sbi_domain_dump(const struct sbi_domain *dom, const char *suffix)
k = 0;
sbi_printf("Domain%d HARTs %s: ", dom->index, suffix);
sbi_hartmask_for_each_hart(i, dom->possible_harts)
sbi_hartmask_for_each_hart(i, j, dom->possible_harts)
sbi_printf("%s%d%s", (k++) ? "," : "",
i, sbi_domain_is_assigned_hart(dom, i) ? "*" : "");
sbi_printf("\n");
@@ -495,7 +487,7 @@ void sbi_domain_dump_all(const char *suffix)
int sbi_domain_register(struct sbi_domain *dom,
const struct sbi_hartmask *assign_mask)
{
u32 i;
u32 i, j;
int rc;
struct sbi_domain *tdom;
u32 cold_hartid = current_hartid();
@@ -538,16 +530,16 @@ int sbi_domain_register(struct sbi_domain *dom,
sbi_hartmask_clear_all(&dom->assigned_harts);
/* Assign domain to HART if HART is a possible HART */
sbi_hartmask_for_each_hart(i, assign_mask) {
if (!sbi_hartmask_test_hart(i, dom->possible_harts))
sbi_hartmask_for_each_hart(i, j, assign_mask) {
if (!sbi_hartmask_test_hartid(i, dom->possible_harts))
continue;
tdom = sbi_hartid_to_domain(i);
if (tdom)
sbi_hartmask_clear_hart(i,
sbi_hartmask_clear_hartid(i,
&tdom->assigned_harts);
update_hartid_to_domain(i, dom);
sbi_hartmask_set_hart(i, &dom->assigned_harts);
sbi_hartmask_set_hartid(i, &dom->assigned_harts);
/*
* If cold boot HART is assigned to this domain then
@@ -681,12 +673,12 @@ int sbi_domain_finalize(struct sbi_scratch *scratch, u32 cold_hartid)
continue;
/* Ignore if boot HART not possible for this domain */
if (!sbi_hartmask_test_hart(dhart, dom->possible_harts))
if (!sbi_hartmask_test_hartid(dhart, dom->possible_harts))
continue;
/* Ignore if boot HART assigned different domain */
if (sbi_hartid_to_domain(dhart) != dom ||
!sbi_hartmask_test_hart(dhart, &dom->assigned_harts))
!sbi_hartmask_test_hartid(dhart, &dom->assigned_harts))
continue;
/* Startup boot HART of domain */
@@ -723,6 +715,7 @@ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid)
int rc;
struct sbi_hartmask *root_hmask;
struct sbi_domain_memregion *root_memregs;
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
if (scratch->fw_rw_offset == 0 ||
(scratch->fw_rw_offset & (scratch->fw_rw_offset - 1)) != 0) {
@@ -796,11 +789,9 @@ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid)
root.next_mode = scratch->next_mode;
/* Root domain possible and assigned HARTs */
for (i = 0; i < SBI_HARTMASK_MAX_BITS; i++) {
if (!sbi_hartid_valid(i))
continue;
sbi_hartmask_set_hart(i, root_hmask);
}
for (i = 0; i < plat->hart_count; i++)
sbi_hartmask_set_hartid(sbi_hartindex_to_hartid(i),
root_hmask);
/* Finally register the root domain */
rc = sbi_domain_register(&root, root_hmask);