Hi Edgar,

On 19:17 Fri 12 Sep     , Edgar E. Iglesias wrote:
> On Fri, Sep 12, 2025 at 12:00:11PM +0200, Luc Michel wrote:
> > The following commits will move FDT creation logic from the
> > xlnx-versal-virt machine to the xlnx-versal SoC itself. Prepare this by
> > passing the FDT handle to the SoC before it is realized. If no FDT is
> > passed, a dummy one is created internally as a stub to the fdt function
> > calls.
> > 
> > For now the SoC only creates the two clock nodes. The ones from the
> > xlnx-versal virt machine are renamed with a `old-' prefix and will be
> > removed once they are not referenced anymore.
> 
> 
> Hi Luc,
> 
> 
> 
> > 
> > Signed-off-by: Luc Michel <[email protected]>
> > Reviewed-by: Francisco Iglesias <[email protected]>
> > ---
> >  include/hw/arm/xlnx-versal.h | 12 ++++++++++++
> >  hw/arm/xlnx-versal-virt.c    |  9 ++++++---
> >  hw/arm/xlnx-versal.c         | 28 ++++++++++++++++++++++++++++
> >  3 files changed, 46 insertions(+), 3 deletions(-)
> > 
> > diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
> > index 1f92e314d6c..f2a62b43552 100644
> > --- a/include/hw/arm/xlnx-versal.h
> > +++ b/include/hw/arm/xlnx-versal.h
> > @@ -134,21 +134,33 @@ struct Versal {
> >          XlnxVersalCFrameBcastReg cframe_bcast;
> >  
> >          OrIRQState apb_irq_orgate;
> >      } pmc;
> >  
> > +    struct {
> > +        uint32_t clk_25mhz;
> > +        uint32_t clk_125mhz;
> > +    } phandle;
> > +
> >      struct {
> >          MemoryRegion *mr_ddr;
> > +        void *fdt;
> >      } cfg;
> >  };
> >  
> >  struct VersalClass {
> >      SysBusDeviceClass parent;
> >  
> >      VersalVersion version;
> >  };
> >  
> > +static inline void versal_set_fdt(Versal *s, void *fdt)
> > +{
> > +    g_assert(!qdev_is_realized(DEVICE(s)));
> > +    s->cfg.fdt = fdt;
> > +}
> > +
> 
> Should this be a property of some sort? it looks a little odd to bypass QOM..

fdt being a void* and not an Object*, it's not directly possible AFAIK.
I don't see it being an issue here because the Versal SoC code is
tightly coupled to the versal-virt machine code (the machine is
basically the sole user of the SoC). Even if it was not the case, the
SoC interface is fully specified in xlnx-versal.h and any user can
leverage it just fine. I guess QOM/qdev abstractions are necessary when
we don't include the .h and only rely on the type name (QMP, HPM
use-cases, ...).

[snip]

> > +
> >  static void versal_realize(DeviceState *dev, Error **errp)
> >  {
> >      Versal *s = XLNX_VERSAL_BASE(dev);
> >      qemu_irq pic[XLNX_VERSAL_NR_IRQS];
> >  
> > +    if (s->cfg.fdt == NULL) {
> > +        int fdt_size;
> > +
> > +        s->cfg.fdt = create_device_tree(&fdt_size);
> > +    }
> > +
> > +    s->phandle.clk_25mhz = fdt_add_clk_node(s, "/clk25", 25 * 1000 * 1000);
> > +    s->phandle.clk_125mhz = fdt_add_clk_node(s, "/clk125", 125 * 1000 * 
> > 1000);
> > +
> 
> Should we be adding nodes if s->cfg.fdt wasn't created by us?
> If the user passes a dtb, I wonder if we should just assume the user
> knows what they are doing and use it as is...
> 
> Or do you have use-cases where it makes sense?

Note that the device tree created in the SoC code is just a dummy one to
avoid crashing when the SoC user does not provide one, as stated in the
commit message:

"If no FDT is passed, a dummy one is created internally as a stub to the
fdt function calls."

This code path should not be reached in normal versal-virt machine
use-case. We rely on the one given by the machine code through the
versal_set_fdt function.

Then to answer the question about the user providing a DTB, I stick to
the existing behaviour before the refactoring. s->binfo.get_dtb is still
set in the machine code and provided to the ARM virtual bootloader. The
bootloader uses it only if no DTB is provided by the user.

Thanks

-- 
Luc

Reply via email to