On 3/6/19 7:51 AM, Markus Armbruster wrote:
> BALATON Zoltan <bala...@eik.bme.hu> writes:
>> On Tue, 5 Mar 2019, Philippe Mathieu-Daudé wrote:
>>> On 2/26/19 8:34 PM, Markus Armbruster wrote:
>>>> Machine "sam460ex" maps its flash memory at address 0xFFF00000.  When
>>>> no image is supplied, its size is 1MiB (0x100000), and 512KiB of ROM
>>>> get mapped on top of its second half.  Else, it's the size of the
>>>> image rounded up to the next multiple of 64KiB.
>>>>
>>>> The rounding is actually useless: pflash_cfi01_realize() fails with
>>>> "failed to read the initial flash content" unless it's a no-op.
>>>>
>>>> I have no idea what happens when the pflash's size exceeds 1MiB.
>>>> Useful outcomes seem unlikely.
>>>
>>> With PFlashCFI02, it depends of the @nb_mappings parameter, which tries
>>> to emulates how the bus connects the pflash (which address lines are
>>> connected).
>>>
>>> PFlashCFI01 doesn't support the feature to remap its content in aliases
>>> (which might look unfortunate, because boards end doing it, in different
>>> ways).
>>
>> I think this is all theoretical at the moment since we don't actually
>> model the flash functions of this board (at least I haven't tested
>> that at all) and unless it somehow uses it in ways I'm unaware of I
>> think currently only the ROM is used.
>>
>>> For this device we have:
>>>
>>>  (qemu) info mtree
>>>  0000000000000000-ffffffffffffffff (prio 0, i/o): system
>>>  00000004fff00000-00000004ffffffff (prio 0, romd): sam460ex.flash
>>>
>>> I'm not familiar with this arch/machine, let's assume the system bus is
>>> 32bit, and the flash has a 8bit word (we have 8 data lines connected to
>>> the pflash).
>>
>> Maybe this can help:
>> https://datasheet.octopart.com/PPC460EX-NUB800T-AMCC-datasheet-11553412.pdf
>> http://www.acube-systems.biz/index.php?page=hardware&pid=5
>>
>> Unfortunately I don't have any more detailed docs where it's explained
>> more but according to the above and in my limited understanding the
>> SoC could handle larger flash chips but this board has 512 MB. We have
>> not changed it now because I'm not sure if it would break anything and
>> I don't have time to test it so Marcus just added a comment to remind
>> about this and we're happy with that for now and could come back to it
>> separately.
> 
> And that's good enough for what I'm trying to do in this series, namely
> getting rid of unwarranted magic around pflash devices.
> 
>>> The 'no image' is 1MiB.
>>>
>>> 1 MiB = 8 Mbit
>>> 8 Mbit / 32 = 2 ^ 18
>>> We need 18 address lines to reach the whole flash.
>>>
>>> What happens if we connect a 2MiB flash? We need 19 addr lines.
>>>
>>> If we only have 18 lines to connect our flash, we can hardwire our last
>>> line as 0 or 1.
>>>
>>> - line #17 hardwired as 0:
>>> Only the bottom part of the flash is accessible (range 0x000000..0x0fffff).
>>> CPU reading 0x4fff00000 read flash offset 0x0.
>>> Using CFI it is still a announced as 2MiB.
>>>
>>> - line #17 hardwired as 1:
>>> Only the top part of the flash is accessible (range 0x100000..0x1fffff).
>>> Can we trigger any operation from the internal state machine (writing to
>>> address 0x555, named @unlock_addr0 in QEMU) since all access are
>>> hardwardwired on top of 1MiB...?
>>> Yes we can, because the pflash only uses 11 bits for it's I/O, so all
>>> writes are masked and hit the I/O internal unit.
>>> CPU reading 0x4fff00000 read flash offset 0x100000
>>>
>>> If we do have 19 lines dedicated to our chip and connect a 512KiB flash,
>>> we 'll use 17 lines and let 2 lines unused.
>>> Regardless the values on the lines #17 and #18, the flash will answer to
>>> the value on lines #0..#16. This might be called MMIO aliasing, and is
>>> what setup the @nb_mappings argument.
>>> This example with nb_mappings=4 would mean:
>>> "I have a 2MiB I/O space and a 512KiB flash, map it and create 3 aliases".
> 
> Physical hardware does address lines.  Hardwiring address lines leaves
> part of the hardware unaddressable.  Not decoding address lines gets the
> same stuff mapped multiple times in the address space.  Address lines is
> also what makes sizes powers of two.

I'm amazed about how you sumarized... Thanks!

> QEMU device models are software.  Emulating address lines faithfully
> there takes extra effort.  A hack job that simply maps whatever size
> wherever is easier.  It's why we could do 7919 sectors of 5323 bytes for
> a size of 42152837 bytes, and map it at address 0x12345678.
> 
> Of course, none of our boards is that nuts.  But this one exudes a bit
> of a nutty flavor: with "-drive if=pflash,format=raw,file=1G.img", it
> happily maps 1G at address 0x4fff00000.  info mtree:
> 
>     address-space: memory
>       0000000000000000-ffffffffffffffff (prio 0, i/o): system
>         0000000000000000-000000001fffffff (prio 0, i/o): sdram-containers
>           0000000000000000-000000001fffffff (prio 0, i/o): alias 
> ppc4xx.sdram0 @ppc4xx.sdram 0000000000000000-000000001fffffff
>         0000000400000000-000000040003ffff (prio 0, ram): ppc440.l2cache_ram
>         00000004bffd0000-00000004bffd00ff (prio 0, i/o): ohci
>         00000004bffd0400-00000004bffd13ff (prio 0, i/o): ehci
>           00000004bffd0400-00000004bffd040f (prio 0, i/o): capabilities
>           00000004bffd0410-00000004bffd0453 (prio 0, i/o): operational
>           00000004bffd0454-00000004bffd046b (prio 0, i/o): ports
>         00000004ef600300-00000004ef600307 (prio 0, i/o): serial
>         00000004ef600700-00000004ef600711 (prio 0, i/o): ppc4xx-i2c
>         00000004ef600800-00000004ef600811 (prio 0, i/o): ppc4xx-i2c
> --->    00000004fff00000-000000053fefffff (prio 0, romd): sam460ex.flash
>         0000000c08000000-0000000c0800ffff (prio 0, i/o): alias isa_mmio @io 
> 0000000000000000-000000000000ffff
>         0000000c0ec00000-0000000c0ec800fe (prio 0, i/o): pci-container
>           0000000c0ec00000-0000000c0ec00003 (prio 0, i/o): pci-conf-idx
>           0000000c0ec00004-0000000c0ec00007 (prio 0, i/o): pci-conf-data
>           0000000c0ec80000-0000000c0ec800fe (prio 0, i/o): pci.reg
> 
> Looks like there's plenty of space before we crash into pci-container.
> Still, boards emulating real hardware should not take such liberties.

Good catch, this is a Chip Select slot and is limited to the max
addressing the bus allow to this CS.

>>> Back to the architecture, what matters here is that the CPU reset vector
>>> is always user-controlled (mapped on a flash device).
>>> This arch has reset_vector @0x4fffffffc.
>>> You could also map a 256KiB pflash at 0x4fffc0000, as long as the reset
>>> vector is covered. If you map it at 0x4fff00000 or 0x4fff80000 it won't!
>>>
>>> This explanation is not arch-specific (adapting the reset vector to each
>>> arch).
>>>
>>>>
>>>> I guess memory at the end of the address space remains unmapped when
>>>> it's smaller than 1MiB.  Again, useful outcomes seem unlikely.
>>>
>>> If you map a 512KiB flash at 0x4fff00000, then the reset vector is not
>>> covered. At 0x4fff80000 it is.
>>
>> Yes, I said the same before but this would be a separate patch and
>> would need more testing so it wasn't included in this series. Since it
>> works as it is now this can wait until later when it can be cleaned
>> up. If we want to model the actual board we don't have to consider
>> different flash sizes than the 512 MB that the board has so everything
>> else is probably "overthinking" it.
> 
> Isn't modelling the actual board why we have the virtual board in the
> first place?  But I digress...
> 
> [...]
>>>> The physical hardware appears to have 512KiB of flash memory:
>>>> https://eu.mouser.com/datasheet/2/268/atmel_AT49BV040B-1180330.pdf
>>>>
>>>> For now, just set the flash memory size to 1MiB regardless of image
>>>> size, and document the mess.
>>>>
>>>> Cc: BALATON Zoltan <bala...@eik.bme.hu>
>>>> Signed-off-by: Markus Armbruster <arm...@redhat.com>
>>>> ---
>>>>  hw/ppc/sam460ex.c | 41 ++++++++++++++++++++++++++---------------
>>>>  1 file changed, 26 insertions(+), 15 deletions(-)
>>>>
>>>> diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
>>>> index 75250d49e4..0c919529f8 100644
>>>> --- a/hw/ppc/sam460ex.c
>>>> +++ b/hw/ppc/sam460ex.c
>>>> @@ -91,32 +91,43 @@ struct boot_info {
>>>>
>>>>  static int sam460ex_load_uboot(void)
>>>>  {
>>>> +    /*
>>>> +     * This first creates 1MiB of flash memory mapped at the end of
>>>> +     * the 32-bit address space (0xFFF00000..0xFFFFFFFF).
>>>> +     *
>>>> +     * If_PFLASH unit 0 is defined, the flash memory is initialized
>>>> +     * from that block backend.
>>>> +     *
>>>> +     * Else, it's initialized to zero.  And then 512KiB of ROM get
>>>> +     * mapped on top of its second half (0xFFF80000..0xFFFFFFFF),
>>>> +     * initialized from u-boot-sam460-20100605.bin.
>>>
>>> I think the correct check is:
>>>
>>>    if (! something_mapped_at(0x4fffffffc)) {
>>>        rom_map("u-boot-sam460.bin",
>>>                0x500000000 - sizeof("u-boot-sam460.bin"));
>>>    }
>>>
>>> Maybe:
>>>
>>>    if (!memory_region_present(get_system_memory(), 0x4fffffffc)) {
>>>        /* Current uboot ROM is 512KiB */
>>>        /* TODO check [0x500000000 - 512KiB,0x500000000 - 1] unmapped */
>>>        rom_add_file_fixed(UBOOT_FILENAME,
>>>                           UBOOT_LOAD_BASE | ((hwaddr)FLASH_BASE_H << 32),
>>>                           -1);
>>>    }
> 
> I think this should be addressed in separate patches.  This one merely
> kills bad magic around pflash, such as inheriting the flash's size from
> the block backend without sanity checking.

"... let him speak now or forever hold his peace."

Reply via email to