From: Havard Skinnemoen <hskinnemoen@google.com>
To: "Philippe Mathieu-Daudé" <f4bug@amsat.org>
Cc: "Peter Maydell" <peter.maydell@linaro.org>,
qemu-arm <qemu-arm@nongnu.org>,
"QEMU Developers" <qemu-devel@nongnu.org>,
"IS20 Avi Fishman" <Avi.Fishman@nuvoton.com>,
"CS20 KFTing" <kfting@nuvoton.com>,
"Cédric Le Goater" <clg@kaod.org>
Subject: Re: [PATCH v5 09/11] hw/ssi: NPCM7xx Flash Interface Unit device model
Date: Mon, 13 Jul 2020 19:39:16 -0700 [thread overview]
Message-ID: <CAFQmdRbFB-U4rzNP-wzskQFUa3ZYFvCMyf=wxwnPOHVFej8npA@mail.gmail.com> (raw)
In-Reply-To: <739105bb-5915-bf11-10cc-485ce5e94e73@amsat.org>
On Mon, Jul 13, 2020 at 10:39 AM Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
>
> On 7/12/20 7:42 AM, Havard Skinnemoen wrote:
> > On Thu, Jul 9, 2020 at 10:00 AM Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
> >> On 7/9/20 2:36 AM, Havard Skinnemoen wrote:
> >>> This implements a device model for the NPCM7xx SPI flash controller.
> >>>
> >>> Direct reads and writes, and user-mode transactions have been tested in
> >>> various modes. Protection features are not implemented yet.
> >>>
> >>> All the FIU instances are available in the SoC's address space,
> >>> regardless of whether or not they're connected to actual flash chips.
> >>>
> >>> Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
> >>> Reviewed-by: Cédric Le Goater <clg@kaod.org>
> >>> Signed-off-by: Havard Skinnemoen <hskinnemoen@google.com>
> >>> ---
> >>> include/hw/arm/npcm7xx.h | 2 +
> >>> include/hw/ssi/npcm7xx_fiu.h | 100 +++++++
> >>> hw/arm/npcm7xx.c | 53 ++++
> >>> hw/ssi/npcm7xx_fiu.c | 510 +++++++++++++++++++++++++++++++++++
> >>> hw/arm/Kconfig | 1 +
> >>> hw/ssi/Makefile.objs | 1 +
> >>> hw/ssi/trace-events | 9 +
> >>> 7 files changed, 676 insertions(+)
> >>> create mode 100644 include/hw/ssi/npcm7xx_fiu.h
> >>> create mode 100644 hw/ssi/npcm7xx_fiu.c
> [...]
>
> >>> diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
> >>> index 4d227bb74b..c9ff3dab25 100644
> >>> --- a/hw/arm/npcm7xx.c
> >>> +++ b/hw/arm/npcm7xx.c
> >>> @@ -98,6 +98,37 @@ static const hwaddr npcm7xx_uart_addr[] = {
> >>> 0xf0004000,
> >>> };
> >>>
> >>> +static const hwaddr npcm7xx_fiu0_flash_addr[] = {
> >>
> >> So per
> >> https://github.com/Nuvoton-Israel/bootblock/blob/master/SWC_HAL/Chips/npcm750/npcm750.h
> >> this is SPI0 on AHB18,
> >>
> >>> + 0x80000000,
> >>> + 0x88000000,
> >>
> >> CS0 & CS1,
> >>
> >> also listed:
> >>
> >> 0x90000000, // CS2
> >> 0x98000000, // CS3
> >
> > Confirmed with Nuvoton off-list that these do not exist. SPI0 only
> > supports two chip-selects for direct access.
>
> I suppose Novoton confirmed for the particular npcm750, but you aim
> to model the npcm7xx family. I doubt 2 similar IP blocks are that
> different ;) Anyway with a comment this is good.
OK. I'm mostly concerned about modeling the chips I know about for
now. If a chip with four AXI endpoints and four chipselects on SPI0
appears, it will be a fairly small change to move these arrays into
the SoC class struct, but I'd rather not do that without evidence that
such a chip exist.
The IP blocks may be identical for all I know, but they are not wired
up identically, and that's really what matters here in the SoC-level
model.
> >
> > I'll add comments.
> >
> >>> +};
> >>> +
> >>> +static const hwaddr npcm7xx_fiu3_flash_addr[] = {
> >>
> >> Ditto SPI3 on AHB3, and CS0 to CS3.
> >>
> >>> + 0xa0000000,
> >>> + 0xa8000000,
> >>> + 0xb0000000,
> >>> + 0xb8000000,
> >>> +};
> >>> +
> >>> +static const struct {
> >>> + const char *name;
> >>> + hwaddr regs_addr;
> >>> + int cs_count;
> >>> + const hwaddr *flash_addr;
> >>> +} npcm7xx_fiu[] = {
> >>> + {
> >>> + .name = "fiu0",
> >>> + .regs_addr = 0xfb000000,
> >>> + .cs_count = ARRAY_SIZE(npcm7xx_fiu0_flash_addr),
> >>
> >> Hmm without the datasheet, can't tell, but I'd expect 4 CS
> >> regardless.
> >
> > FIU0/SPI0 only has 2 chip selects.
> >
> >>> + .flash_addr = npcm7xx_fiu0_flash_addr,
> >>> + }, {
> >>> + .name = "fiu3",
> >>> + .regs_addr = 0xc0000000,
> >>> + .cs_count = ARRAY_SIZE(npcm7xx_fiu3_flash_addr),
> >>> + .flash_addr = npcm7xx_fiu3_flash_addr,
> >>> + },
> >>> +};
> [...]
>
> >>> +
> >>> + /* Flash chip model expects one transfer per dummy bit, not byte */
> >>> + dummy_cycles =
> >>> + (FIU_DRD_CFG_DBW(drd_cfg) * 8) >> FIU_DRD_CFG_ACCTYPE(drd_cfg);
> >>> + for (i = 0; i < dummy_cycles; i++) {
> >>> + ssi_transfer(fiu->spi, 0);
> >>
> >> Note to self, might worth a ssi_shift_dummy(count) generic method.
> >
> > I'm not a huge fan of this interface to be honest. It requires the
> > flash controller to have intimate knowledge of the flash chip, and if
> > it doesn't predict the dummy phase correctly, or the guest programs
> > the wrong number of dummy cycles, the end result is very different
> > from what you'll see on a real system. I'd love to see something like
> > a number-of-bits parameter to ssi_transfer instead.
>
> Do you mean like these?
>
> - ssi_transfer_bit(bool value);
> - ssi_shift_dummy_bits(size_t bits);
>
> Some interfaces allow bit shifting. SPI doesn't simply because
> nobody had the use :)
I mean I don't like how the semantics of ssi_transfer changes
implicitly in the middle of the transfer. One call shifts a whole
byte, the next 8 shift individual bits, then it's back to bytes again.
If a mistake is made, the flash controller might end up thinking it's
shifting 16 bits, but if the flash device only expects 8 dummy bits,
it will see 8 bits + 8 bytes for a total of 9 bytes of dummies. This
differs a lot from what would happen on a real device.
For example, I wrote up a test for the aspeed flash controller against
a Winbond flash chip in Dual I/O mode. The data ended up getting
shifted by 15 bytes because of, I think, bugs in the dummy logic on
both sides. I took a lot of head scratching to figure out what's going
on.
Here's where aspeed_smc figures it needs to send 2 dummy bytes (aka 16
dummy bits) for a DIO read:
https://elixir.bootlin.com/qemu/latest/source/hw/ssi/aspeed_smc.c#L803
And here's where the Winbond model decides to expect one dummy _bit_:
https://elixir.bootlin.com/qemu/latest/source/hw/block/m25p80.c#L862
The difference is 15 ssi_transfers, which is what I see in the test.
IMO they're both wrong -- they should both expect one dummy byte, or
four dummy cycles in x2 mode. But the real problem, also IMO, is that
they can't even agree on whether one ssi_transfer means one bit or one
byte.
While ssi_shift_dummy_bits is strictly nicer than open-coded loops of
ssi_transfer, it doesn't fix the underlying problem that the dummy
cycles need to be treated specially by both the flash controller model
and the device model, and if they're not 100% synchronized (which is
particularly interesting when you have flash chips with configurable
dummy cycles), the result is like nothing you'd ever see on a real
system.
> >
> >>> + }
> >>> +
> >>> + for (i = 0; i < size; i++) {
> >>> + value |= ssi_transfer(fiu->spi, 0) << (8 * i);
> >>> + }
> >>> +
> [...]
>
> >>> +static const MemoryRegionOps npcm7xx_fiu_flash_ops = {
> >>> + .read = npcm7xx_fiu_flash_read,
> >>> + .write = npcm7xx_fiu_flash_write,
> >>> + .endianness = DEVICE_LITTLE_ENDIAN,
> >>> + .valid = {
> >>> + .min_access_size = 1,
> >>> + .max_access_size = 8,
> >>
> >> Are you sure? Maybe, I can' tell.
> >
> > Real hardware supports 16 bytes, but there's no way to do more than 8
> > in emulation, I think?
>
> That would mean you can plug this device on a 128-bit wide bus,
> and you can transfer 128-bit in a single CPU operation.
Hmm, I see what you mean. It can do 16-byte bursts. I'm not sure if
that looks more like a single 16-byte access or four 4-byte accesses
on the SPI bus. I was assuming it's the former, but I could be wrong.
Havard
next prev parent reply other threads:[~2020-07-14 2:40 UTC|newest]
Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-09 0:35 [PATCH v5 00/11] Add Nuvoton NPCM730/NPCM750 SoCs and two BMC machines Havard Skinnemoen
2020-07-09 0:35 ` [PATCH v5 01/11] hw/misc: Add NPCM7xx System Global Control Registers device model Havard Skinnemoen
2020-07-09 6:04 ` Philippe Mathieu-Daudé
2020-07-09 6:43 ` Havard Skinnemoen
2020-07-09 16:23 ` Philippe Mathieu-Daudé
2020-07-09 17:09 ` Havard Skinnemoen
2020-07-09 17:24 ` Philippe Mathieu-Daudé
2020-07-09 17:42 ` Havard Skinnemoen
2020-07-10 9:31 ` Philippe Mathieu-Daudé
2020-07-11 6:46 ` Havard Skinnemoen
2020-07-12 5:49 ` Havard Skinnemoen
2020-07-09 0:35 ` [PATCH v5 02/11] hw/misc: Add NPCM7xx Clock Controller " Havard Skinnemoen
2020-07-15 7:18 ` Philippe Mathieu-Daudé
2020-07-09 0:36 ` [PATCH v5 03/11] hw/timer: Add NPCM7xx Timer " Havard Skinnemoen
2020-07-15 7:25 ` Philippe Mathieu-Daudé
2020-07-15 23:04 ` Havard Skinnemoen
2020-07-16 8:04 ` Philippe Mathieu-Daudé
2020-07-09 0:36 ` [PATCH v5 04/11] hw/arm: Add NPCM730 and NPCM750 SoC models Havard Skinnemoen
2020-07-09 6:11 ` Philippe Mathieu-Daudé
2020-07-13 15:02 ` Cédric Le Goater
2020-07-14 0:44 ` Havard Skinnemoen
2020-07-14 11:37 ` Philippe Mathieu-Daudé
2020-07-14 16:01 ` Markus Armbruster
2020-07-14 17:11 ` Philippe Mathieu-Daudé
2020-07-15 1:03 ` Havard Skinnemoen
2020-07-15 9:35 ` Markus Armbruster
2020-07-09 0:36 ` [PATCH v5 05/11] hw/arm: Add two NPCM7xx-based machines Havard Skinnemoen
2020-07-09 5:57 ` Philippe Mathieu-Daudé
2020-07-09 6:09 ` Philippe Mathieu-Daudé
2020-07-09 0:36 ` [PATCH v5 06/11] hw/arm: Load -bios image as a boot ROM for npcm7xx Havard Skinnemoen
2020-07-13 17:50 ` Philippe Mathieu-Daudé
2020-07-09 0:36 ` [PATCH v5 07/11] hw/nvram: NPCM7xx OTP device model Havard Skinnemoen
2020-07-09 0:36 ` [PATCH v5 08/11] hw/mem: Stubbed out NPCM7xx Memory Controller model Havard Skinnemoen
2020-07-09 16:29 ` Philippe Mathieu-Daudé
2020-07-09 0:36 ` [PATCH v5 09/11] hw/ssi: NPCM7xx Flash Interface Unit device model Havard Skinnemoen
2020-07-09 17:00 ` Philippe Mathieu-Daudé
2020-07-12 5:42 ` Havard Skinnemoen
2020-07-13 17:38 ` Philippe Mathieu-Daudé
2020-07-14 2:39 ` Havard Skinnemoen [this message]
2020-07-09 0:36 ` [PATCH v5 10/11] hw/arm: Wire up BMC boot flash for npcm750-evb and quanta-gsj Havard Skinnemoen
2020-07-13 14:57 ` Cédric Le Goater
2020-07-13 17:59 ` Philippe Mathieu-Daudé
2020-07-13 18:02 ` Philippe Mathieu-Daudé
2020-07-14 2:56 ` Havard Skinnemoen
2020-07-14 9:16 ` Markus Armbruster
2020-07-14 11:29 ` Philippe Mathieu-Daudé
2020-07-14 16:21 ` Markus Armbruster
2020-07-14 17:16 ` Philippe Mathieu-Daudé
2020-07-15 9:00 ` Markus Armbruster
2020-07-15 10:57 ` Philippe Mathieu-Daudé
2020-07-15 20:54 ` Havard Skinnemoen
2020-07-16 20:56 ` Havard Skinnemoen
2020-07-17 7:48 ` Philippe Mathieu-Daudé
2020-07-17 8:03 ` Thomas Huth
2020-07-17 8:27 ` Philippe Mathieu-Daudé
2020-07-17 9:00 ` Philippe Mathieu-Daudé
2020-07-17 19:18 ` Havard Skinnemoen
2020-07-17 20:21 ` Cédric Le Goater
2020-07-17 20:52 ` Philippe Mathieu-Daudé
2020-07-17 20:57 ` Havard Skinnemoen
2020-07-20 7:58 ` Markus Armbruster
2020-07-15 7:42 ` Cédric Le Goater
2020-07-15 21:19 ` Havard Skinnemoen
2020-07-09 0:36 ` [PATCH v5 11/11] docs/system: Add Nuvoton machine documentation Havard Skinnemoen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAFQmdRbFB-U4rzNP-wzskQFUa3ZYFvCMyf=wxwnPOHVFej8npA@mail.gmail.com' \
--to=hskinnemoen@google.com \
--cc=Avi.Fishman@nuvoton.com \
--cc=clg@kaod.org \
--cc=f4bug@amsat.org \
--cc=kfting@nuvoton.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).