[PATCH 7/9] platform: generic: Add mechanism to match via mvendorid
Christoph Müllner
christoph.muellner at vrull.eu
Thu Mar 28 07:12:33 PDT 2024
[adding the list]
On Wed, Mar 27, 2024 at 12:32 PM Vivian Wang <uwu at dram.page> wrote:
>
> On 3/27/24 18:11, Christoph Müllner wrote:
> > Currently, all platforms and their overrides are matched
> > via FDT-compatible strings. While this is the right approach,
> > we are sometimes confronted with platforms that don't provide
> > the necessary FDT-compatible strings.
>
> In that case, wouldn't it be easier to just provide a different FDT? If
> anything, probing mvendorid makes it much harder to fix things later on
> since it will match all future T-Head cores.
>
> I know Linux has some mvendorid-probing code, but those are for
> situations so early in boot that FDT code isn't working yet. It wouldn't
> be necessary here at all.
MAEE probing is needed before setting up the page table (this is about
PTE bits).
So, I think this qualifies for CSR probing during early boot (and
that's how it is implemented in Linux).
>
> Vivian "dram"
>
> > To still be able to match a platforms, let's add a secondary
> > matching mechanism for the MVENDORID CSR.
> >
> > Signed-off-by: Christoph Müllner <christoph.muellner at vrull.eu>
> > ---
> > platform/generic/include/platform_override.h | 1 +
> > platform/generic/platform.c | 38 ++++++++++++++++++--
> > 2 files changed, 36 insertions(+), 3 deletions(-)
> >
> > diff --git a/platform/generic/include/platform_override.h b/platform/generic/include/platform_override.h
> > index 6802126..a968346 100644
> > --- a/platform/generic/include/platform_override.h
> > +++ b/platform/generic/include/platform_override.h
> > @@ -17,6 +17,7 @@
> >
> > struct platform_override {
> > const struct fdt_match *match_table;
> > + const unsigned long *match_vendor_ids;
> > u64 (*features)(const struct fdt_match *match);
> > u64 (*tlbr_flush_limit)(const struct fdt_match *match);
> > u32 (*tlb_num_entries)(const struct fdt_match *match);
> > diff --git a/platform/generic/platform.c b/platform/generic/platform.c
> > index 07fa9cc..e1b97c8 100644
> > --- a/platform/generic/platform.c
> > +++ b/platform/generic/platform.c
> > @@ -36,12 +36,28 @@ extern unsigned long platform_override_modules_size;
> > static const struct platform_override *generic_plat = NULL;
> > static const struct fdt_match *generic_plat_match = NULL;
> >
> > -static void fw_platform_lookup_special(void *fdt, int root_offset)
> > +static unsigned long vendor_id_match(unsigned long vendor_id,
> > + const unsigned long *vendor_ids)
> > +{
> > + const unsigned long *vid_ptr = vendor_ids;
> > +
> > + while (*vid_ptr) {
> > + if (*vid_ptr == vendor_id)
> > + return vendor_id;
> > +
> > + vid_ptr++;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static void fw_platform_lookup_override(void *fdt, int root_offset)
> > {
> > const struct platform_override *plat;
> > const struct fdt_match *match;
> > int pos;
> >
> > + /* First try to find a FDT match. */
> > for (pos = 0; pos < platform_override_modules_size; pos++) {
> > plat = platform_override_modules[pos];
> > if (!plat->match_table)
> > @@ -53,7 +69,23 @@ static void fw_platform_lookup_special(void *fdt, int root_offset)
> >
> > generic_plat = plat;
> > generic_plat_match = match;
> > - break;
> > + return;
> > + }
> > +
> > + /* No match via FDT -> try matching the vendor ID. */
> > + const unsigned long vendor_id = csr_read(CSR_MVENDORID);
> > + for (pos = 0; pos < platform_override_modules_size; pos++) {
> > + plat = platform_override_modules[pos];
> > + if (!plat->match_vendor_ids)
> > + continue;
> > +
> > + unsigned long match = vendor_id_match(vendor_id, plat->match_vendor_ids);
> > + if (!match)
> > + continue;
> > +
> > + generic_plat = plat;
> > + generic_plat_match = NULL;
> > + return;
> > }
> > }
> >
> > @@ -154,7 +186,7 @@ unsigned long fw_platform_init(unsigned long arg0, unsigned long arg1,
> > if (root_offset < 0)
> > goto fail;
> >
> > - fw_platform_lookup_special(fdt, root_offset);
> > + fw_platform_lookup_override(fdt, root_offset);
> >
> > if (generic_plat && generic_plat->fw_init)
> > generic_plat->fw_init(fdt, generic_plat_match);
>
>
More information about the opensbi
mailing list