On Tue, 4 Feb 2025 at 09:21, Bernhard Beschow <shen...@gmail.com> wrote: > > As a first step, implement the bare minimum: CPUs, RAM, interrupt controller, > serial. All other devices of the A53 memory map are represented as > TYPE_UNIMPLEMENTED_DEVICE, i.e. the whole memory map is provided. This allows > for running Linux without it crashing due to invalid memory accesses. > > Signed-off-by: Bernhard Beschow <shen...@gmail.com> > ---
> --- /dev/null > +++ b/docs/system/arm/imx8mp-evk.rst > @@ -0,0 +1,56 @@ > +NXP i.MX 8M Plus Evaluation Kit (``imx8mp-evk``) > +================================================ > + > +The QEMU i.MX 8M Plus EVK board emulation is intended to emulate a plain > i.MX 8M > +Plus system on chip (SoC). All peripherals the real board has such as flash > and > +I2C devices are intended to be added via configuration, e.g. command line. Why do this? If they're on the real hardware board, we should be creating them by default in the machine model in QEMU. Command line options are for devices that are optional and pluggable by the user on the hardware. > +Supported devices > +----------------- > + > +The ``imx8mp-evk`` machine implements the following devices: > + > + * Up to 4 Cortex-A53 Cores "cores" > + * Generic Interrupt Controller (GICv3) > + * 4 UARTs > + > +Boot options > +------------ > + > +The ``imx8mp-evk`` machine can start using the standard -kernel functionality > +for loading a Linux kernel. > + > +Direct Linux Kernel Boot > +'''''''''''''''''''''''' > + > +Probably the easiest way to get started with a whole Linux system on the > machine > +is to generate an image with Buildroot. Version 2024.11.1 is tested at the > time > +of writing and involves two steps. First run the following commands in the > +toplevel directory of the Buildroot source tree: > + > +.. code-block:: bash > + > + $ echo "BR2_TARGET_ROOTFS_CPIO=y" >> configs/freescale_imx8mpevk_defconfig > + $ make freescale_imx8mpevk_defconfig > + $ make > + > +Once finished successfully there is an ``output/image`` subfolder. Navigate > into > +it patch the device tree needs to be patched with the following commands > which > +will remove the ``cpu-idle-states`` properties from CPU nodes: This sentence seems to be confused in the middle -- cut-and-paste error ? > + > +.. code-block:: bash > + > + $ dtc imx8mp-evk.dtb | sed '/cpu-idle-states/d' > imx8mp-evk-patched.dts > + $ dtc imx8mp-evk-patched.dts -o imx8mp-evk-patched.dtb > + > +Now that everything is prepared the newly built image can be run in the QEMU > +``imx8mp-evk`` machine: > +#define NAME_SIZE 20 > + > +static void fsl_imx8mp_init(Object *obj) > +{ > + MachineState *ms = MACHINE(qdev_get_machine()); > + FslImx8mpState *s = FSL_IMX8MP(obj); > + char name[NAME_SIZE]; Better than fixed sized char arrays for object names is to use g_autofree char *name = g_strdup_printf("cpu%d", i); inside the block of each for() loop etc. > + int i; > + > + for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX8MP_NUM_CPUS); i++) { > + snprintf(name, NAME_SIZE, "cpu%d", i); > + object_initialize_child(obj, name, &s->cpu[i], > + ARM_CPU_TYPE_NAME("cortex-a53")); > + } > + > + object_initialize_child(obj, "gic", &s->gic, TYPE_ARM_GICV3); > + > + for (i = 0; i < FSL_IMX8MP_NUM_UARTS; i++) { > + snprintf(name, NAME_SIZE, "uart%d", i + 1); > + object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL); > + } > +} > + > +static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) > +{ > + MachineState *ms = MACHINE(qdev_get_machine()); > + FslImx8mpState *s = FSL_IMX8MP(dev); > + DeviceState *gicdev = DEVICE(&s->gic); > + int i; > + > + if (ms->smp.cpus > FSL_IMX8MP_NUM_CPUS) { > + error_setg(errp, "%s: Only %d CPUs are supported (%d requested)", > + TYPE_FSL_IMX8MP, FSL_IMX8MP_NUM_CPUS, ms->smp.cpus); > + return; > + } > + > + /* CPUs */ > + for (i = 0; i < ms->smp.cpus; i++) { > + /* On uniprocessor, the CBAR is set to 0 */ > + if (ms->smp.cpus > 1) { > + object_property_set_int(OBJECT(&s->cpu[i]), "reset-cbar", > + > fsl_imx8mp_memmap[FSL_IMX8MP_GIC_DIST].addr, > + &error_abort); > + } > + > + /* > + * Magic value from Linux output: "arch_timer: cp15 timer(s) running > at > + * 8.00MHz (phys)". > + */ > + object_property_set_int(OBJECT(&s->cpu[i]), "cntfrq", 8000000, > + &error_abort); This is the CNTFRQ value in Hz. The datasheet actually tells you this, so we don't need to call it a magic number (section 4.11.4.1.6.4 of the i.MX 8M Plus Applications Processor Reference Manual says the base frequency of the system counter is 8MHz). (Incidentally the memory mapped system counter is a stock Arm IP block and I have about 60% of a model of it, I just haven't needed to upstream it yet because in practice no guest software really tries to mess with it. If we turn out to need it for this SoC that would be a reason for me to clean it up and send it out. But I suspect we don't need it in practice.) thanks -- PMM