Hi Philippe,
On Tue, Dec 10, 2019 at 9:59 AM Philippe Mathieu-Daudé <[email protected]>
wrote:
> On 12/6/19 11:15 PM, Niek Linnenbank wrote:
> [...]
> > > > +static void orangepi_machine_init(MachineClass *mc)
> > > > +{
> > > > + mc->desc = "Orange Pi PC";
> > > > + mc->init = orangepi_init;
> > > > + mc->units_per_default_bus = 1;
> > > > + mc->min_cpus = AW_H3_NUM_CPUS;
> > > > + mc->max_cpus = AW_H3_NUM_CPUS;
> > > > + mc->default_cpus = AW_H3_NUM_CPUS;
> > >
> > > mc->default_cpu_type =
> ARM_CPU_TYPE_NAME("cortex-a7");
> > >
> > > > + mc->ignore_memory_transaction_failures = true;
> > >
> > > You should not use this flag in new design. See the
> > documentation in
> > > include/hw/boards.h:
> > >
> > > * @ignore_memory_transaction_failures:
> > > * [...] New board models
> > > * should instead use "unimplemented-device" for all
> memory
> > > ranges where
> > > * the guest will attempt to probe for a device that
> > QEMU doesn't
> > > * implement and a stub device is required.
> > >
> > > You already use the "unimplemented-device".
> > >
> > > Thanks, I'm working on this now. I think that at least I'll need
> > to add
> > > all of the devices mentioned in the 4.1 Memory Mapping chapter of
> > the
> > > datasheet
> > > as an unimplemented device. Previously I only added some that I
> > thought
> > > were relevant.
> > >
> > > I added all the missing devices as unimplemented and removed the
> > > ignore_memory_transaction_failures flag
> >
> > I was going to say, "instead of adding *all* the devices regions you
> > can
> > add the likely bus decoding regions", probably:
> >
> > 0x01c0.0000 128KiB AMBA AXI
> > 0x01c2.0000 64KiB AMBA APB
> >
> > But too late.
> >
> >
> > Hehe its okey, I can change it to whichever is preferable: the minimum
> set
> > with unimplemented device entries to get a working linux kernel / u-boot
> or
> > just cover the full memory space from the datasheet. My initial thought
> > was that if
> > we only provide the minimum set, and the linux kernel later adds a new
> > driver for a device
> > which is not marked unimplemented, it will trigger the data abort and
> > potentially resulting in a non-booting kernel.
> >
> > But I'm not sure what is normally done here. I do see other board files
> > using the create_unimplemented_device() function,
> > but I dont know if they are covering the whole memory space or not.
>
> If they don't cover all memory regions, the guest code can trigger a
> data abort indeed. Since we don't know the memory layout of old board,
> they are still supported with ignore_memory_transaction_failures=true,
> so guest still run unaffected.
> We expect new boards to implement the minimum layout.
> As long as your guest is happy and usable, UNIMP devices are fine,
> either as big region or individual device (this requires someone with
> access to the datasheet to verify). If you can add a UNIMP for each
> device - which is what you did - it is even better because the the unimp
> access log will be more useful, having finer granularity.
>
> > I added all the missing devices as unimplemented and removed the
> > ignore_memory_transaction_failures flag
>
> IOW, you already did the best you could do :)
>
> > > from the machine. Now it seems Linux gets a data abort while
> > probing the
> > > uart1 serial device at 0x01c28400,
> >
> > Did you add the UART1 as UNIMP or 16550?
> >
> >
> > I discovered what goes wrong here. See this kernel oops message:
> >
> > [ 1.084985] [f08600f8] *pgd=6f00a811, *pte=01c28653, *ppte=01c28453
> > [ 1.085564] Internal error: : 8 [#1] SMP ARM
> > [ 1.085698] Modules linked in:
> > [ 1.085940] CPU: 0 PID: 1 Comm: swapper/0 Not tainted
> 5.4.0-11747-g2f13437b8917 #4
> > [ 1.085968] Hardware name: Allwinner sun8i Family
> > [ 1.086447] PC is at dw8250_setup_port+0x10/0x10c
> > [ 1.086478] LR is at dw8250_probe+0x500/0x56c
> >
> > It tries to access the UART0 at base address 0x01c28400, which I did
> > provide. The strange
> > thing is that is accesses offset 0xf8, thus address 0x01c284f8. The
> > datasheet does not mention this register
> > but if we provide the 1KiB (0x400) I/O space it should at least read as
> > zero and writes ignored. Unfortunately the emulated
> > serial driver only maps a small portion until 0x1f:
> >
> > (qemu) info mtree
> > ...
> > 0000000001c28000-0000000001c2801f (prio 0, i/o): serial
> > 0000000001c28400-0000000001c2841f (prio 0, i/o): serial
> > 0000000001c28800-0000000001c2881f (prio 0, i/o): serial
> >
> >
> > Apparently, the register that the mainline linux kernel is using is
> > DesignWare specific:
> >
> > drivers/tty/serial/8250/8250_dwlib.c:13:
> >
> > /* Offsets for the DesignWare specific registers */
> > #define DW_UART_DLF<--->0xc0 /* Divisor Latch Fraction Register */
> > #define DW_UART_CPR<--->0xf4 /* Component Parameter Register */
> > #define DW_UART_UCV<--->0xf8 /* UART Component Version */
> >
> > I tried to find a way to increase the memory mapped size of the serial
> > device I created with serial_mm_init(),
> > but I don't think its possible with that interface.
> >
> > I did manage to get it working by overlaying the UART0 with another
> > unimplemented device
> > that does have an I/O size of 0x400, but I guess that is probably not
> > the solution we are looking for?
>
> IMHO this is the correct solution :)
>
> Memory regions have priority. By default a device has priority 0, and
> UNIMP device has priority -1000.
>
> So you can use:
>
> serial_mm_init(get_system_memory(), AW_H3_UART0_REG_BASE, 2,
> s->irq[AW_H3_GIC_SPI_UART0], 115200,
> serial_hd(0), DEVICE_NATIVE_ENDIAN);
> create_unimplemented_device("DesignWare-uart",\
> AW_H3_UART0_REG_BASE,
> 0x400);
>
>
Now it makes much more sense to me, thanks a lot for explaining this!
Allright, I'll use this approach to finish the work for removing
mc->ignore_memory_transaction_failures.
Regards,
Niek
> (Or cleaner, add a create_designware_uart(...) function that does both).
>
> (qemu) info mtree
> ...
> 0000000001c28000-0000000001c2801f (prio 0, i/o): serial
> 0000000001c28000-0000000001c283ff (prio -1000, i/o): DesignWare-uart
>
> You could create an UNIMP region of 0x400 - 0x20 = 0x3e0, but that would
> appear this is a different device, so I don't recommend that.
>
> > I wonder, did any of the other SoC / boards have this problem when
> > removing mc->ignore_memory_transaction_failures?
>
>
--
Niek Linnenbank