Skip to content

Commit 30178cf

Browse files
author
matthew.gui
committed
conf/evalsoc: sync opensbi evalsoc.c.
Signed-off-by: matthew.gui <guibing@nuclei.com>
1 parent 82e03df commit 30178cf

1 file changed

Lines changed: 72 additions & 0 deletions

File tree

conf/evalsoc/opensbi/evalsoc.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,86 @@
99

1010
#include <platform_override.h>
1111
#include <sbi/riscv_asm.h>
12+
#include <sbi/sbi_bitops.h>
13+
#include <sbi/sbi_console.h>
1214
#include <sbi_utils/fdt/fdt_helper.h>
1315
#include <sbi_utils/fdt/fdt_fixup.h>
16+
#include <libfdt.h>
1417

1518
extern unsigned long clint_offset_quirk;
19+
static uint32_t guest_index_bits = 0;
20+
static uint32_t hw_smsi_align_bits = 0;
21+
1622
static const struct fdt_match nuclei_evalsoc_match[] = {
1723
{ .compatible = "nuclei,evalsoc" },
1824
{ .compatible = "nuclei,eval-soc" },
1925
{ .compatible = "nuclei,placeholder" },
2026
{ },
2127
};
2228

29+
static int nuclei_evalsoc_get_geilen(void)
30+
{
31+
int val;
32+
33+
if (!misa_extension('H'))
34+
return 0;
35+
csr_write(CSR_HGEIE, -1UL);
36+
val = sbi_fls(csr_read(CSR_HGEIE));
37+
csr_write(CSR_HGEIE, 0);
38+
39+
return val;
40+
}
41+
42+
static void fdt_imsic_guest_index_fixup(void *fdt)
43+
{
44+
int offset, len, i;
45+
const uint32_t *prop;
46+
47+
if (!fdt)
48+
return;
49+
50+
offset = -1;
51+
for (i = 0; i < 2; i++) {
52+
offset = fdt_node_offset_by_compatible(fdt, offset, "riscv,imsics");
53+
if (offset < 0) {
54+
return;
55+
}
56+
57+
prop = fdt_getprop(fdt, offset, "riscv,guest-index-bits", &len);
58+
if (prop) {
59+
break;
60+
}
61+
}
62+
if (!prop)
63+
return;
64+
guest_index_bits = fdt32_to_cpu(*prop);
65+
/*
66+
* hw_smsi_align_bits = upper(log2(GEILEN+1)),
67+
* if GEILEN=3 then hw_smsi_align_bits=2,
68+
* if GEILEN=4 then hw_smsi_align_bits=3.
69+
*/
70+
hw_smsi_align_bits = sbi_fls(nuclei_evalsoc_get_geilen()) + 1;
71+
if (guest_index_bits != hw_smsi_align_bits) {
72+
fdt_setprop_u32(fdt, offset, "riscv,guest-index-bits", hw_smsi_align_bits);
73+
}
74+
}
75+
2376
static int nuclei_evalsoc_final_init(bool cold_boot,
2477
const struct fdt_match *match)
2578
{
2679
if (cold_boot) { // Add cold boot initial steps
80+
/*
81+
* on nuclei_evalsoc_early_init stage, console has not been initialized,
82+
* if need to update dts riscv,guest-index-bits prop, print related info here.
83+
*/
84+
if (guest_index_bits != hw_smsi_align_bits) {
85+
sbi_printf("Warning: dts prop riscv,guest-index-bits "
86+
"does not match with HW parameter GEILEN.\n");
87+
sbi_printf("Now update dts prop riscv,guest-index-bits "
88+
"from %d to %d to adapt HW.\n", guest_index_bits, hw_smsi_align_bits);
89+
sbi_printf("More details refer to https://github.com/"
90+
"Nuclei-Software/nuclei-linux-sdk/issues/36.\n");
91+
}
2792
}
2893

2994
// Check mcfg_info.tee to see whether tee present
@@ -59,6 +124,13 @@ static int nuclei_evalsoc_early_init(bool cold_boot,
59124
*/
60125
clint_offset_quirk = 0x1000;
61126

127+
if (cold_boot) {
128+
void *fdt;
129+
130+
fdt = fdt_get_address();
131+
fdt_imsic_guest_index_fixup(fdt);
132+
}
133+
62134
return 0;
63135
}
64136

0 commit comments

Comments
 (0)