Skip to content

Add the Hobgoblin platform#296

Merged
arichardson merged 103 commits intoCTSRD-CHERI:devfrom
arichardson:add-hobgoblin-platform
Nov 10, 2025
Merged

Add the Hobgoblin platform#296
arichardson merged 103 commits intoCTSRD-CHERI:devfrom
arichardson:add-hobgoblin-platform

Conversation

@arichardson
Copy link
Member

No description provided.

chrisrauer and others added 30 commits November 10, 2025 08:26
The problem is that the Linux driver expects the master transaction inhibit
bit(R_SPICR_MTI) to be set during driver initialization so that it can
detect the fifo size but QEMU defaults it to zero out of reset.  The
datasheet indicates this bit is active on reset.

See page 25, SPI Control Register section:
https://www.xilinx.com/content/dam/xilinx/support/documents/ip_documentation/axi_quad_spi/v3_2/pg153-axi-quad-spi.pdf

Signed-off-by: Chris Rauer <crauer@google.com>
Message-id: 20230323182811.2641044-1-crauer@google.com
Reviewed-by: Edgar E. Iglesias <edgar@zeroasic.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
FSBL expects the response to CMD58 (READ_OCR) to have the MSB set to 0
(indicating that the card is not idle). However qemu was returning 1
(card is idle). Given that this works on real hardware, update qemu to
match, returning 0.

Signed-off-by: Stuart Menefy <stuart.menefy@codasip.com>
This fixes a problem seen when U-Boot is loaded by FSBL:
 - FSBL has just read data from the SD card, leaving the card in
   transfer state.
 - U-Boot issues CMD0 to switch the card into SPI mode.
 - SD card code returns state _before_ the current command, ie transfer
   state.
 - SSI adaptor code translates this to card is _not_ idle.
This causes U-Boot to fail to initialise the card.

Assuming CMD0 works, then the card is now idle, so ignore the
previous state returned by SD card.

Signed-off-by: Stuart Menefy <stuart.menefy@codasip.com>
Import the Xilinx AXI GPIO code from the Xilinx qemu tree as of
commit f28512b37 ("Merge commit '36eae3a732' into merge").
Signed-off-by: Axel Heider <axel.heider@codasip.com>
Initial support for the Hobgoblin FPGA platform, including:
- Boot ROM and SRAM
- DRAM
- PLIC, CLINT
- UART
- GPIO
- SPI + SD-Card connected to it

Two behaviours are supported at boot time. Either:
 - load the FSBL into ROM, which can access an SD card image to
   load any other code, emulating the hardware boot sequence
 - load the OpenSBI/kernel/FDT as qemu does for other platforms

Which behaviour is used depends on a new machine specific option:
"boot-from-rom".

This is a manual backport of commit 0ae2b94c569 ("hw/riscv: Add Codasip
Hobgoblin machine") which was written by Axel Heider and Stuart Menefy.

Changes for qemu 6.x:
- use sifive clint instead of aclint
- define RISCV64_BIOS_BIN locally
- different parameters for riscv_load_kernel, riscv_load_fdt,
  riscv_setup_rom_reset_vec, sifive_plic_create
- replace TYPE_SD_CARD_SPI with TYPE_SD_CARD
  use a property to set spi mode
Signed-off-by: Axel Heider <axel.heider@codasip.com>
Co-authored-by: Samuel Obuch <samuel.obuch@codasip.com>
Signed-off-by: Axel Heider <axel.heider@codasip.com>
The Hobgoblin platform has an SRAM block internal to the FPGA.

Signed-off-by: Stuart Menefy <stuart.menefy@codasip.com>
Add code to emulate the MDIO_... registers and communicate with a PHY.
Copy the exiting PHY code from the xilinx_axienet.c, although keep
it in a separate file as a first step to generic PHY infrastructure.

Signed-off-by: Stuart Menefy <stuart.menefy@codasip.com>
The RISC-V PLIC spec allows for both edge and level sensitive interrupts,
however even level sensitive interrupts (which are modelled here) have an
element of edge detection:

  The gateway does not have the facility to retract an interrupt
  request once forwarded to the PLIC core. If a level-sensitive
  interrupt source deasserts the interrupt after the PLIC core
  accepts the request and before the interrupt is serviced, the
  interrupt request remains present in the IP bit of the PLIC core
  and will be serviced by a handler, which will then have to determine
  that the interrupt device no longer requires service.

Model this here.

Signed-off-by: Stuart Menefy <stuart.menefy@codasip.com>
Co-authored-by: Stuart Menefy <stuart.menefy@codasip.com>
Signed-off-by: Axel Heider <axel.heider@codasip.com>
Add four virtio blocks so that various virtual IO devices can be
added.

Co-authored-by: Stuart Menefy <stuart.menefy@codasip.com>
Signed-off-by: Axel Heider <axel.heider@codasip.com>
Currently two versions of the Hobgoblin platform are supported, the
original one using the Genesys 2 hardware, and now the proFPGA. Add an
option to allow the appropriate board to be selected:
  board-type={genesys2|profpga}

Signed-off-by: Stuart Menefy <stuart.menefy@codasip.com>
Increase to match the Genesys 2 FPGA platform.

Signed-off-by: Stuart Menefy <stuart.menefy@codasip.com>
More recent versions of the Hobgloblin FPGA platform default to
having the Xilinx AXI Ethernet (with associated streaming DMA
devices) rather than the Etherlite.

Add option to select the required device (defaulting to AXI Ethernet).

Signed-off-by: Stuart Menefy <stuart.menefy@codasip.com>
Signed-off-by: Axel Heider <axel.heider@codasip.com>
Add the new Codasip timer to the Hobgoblin platform.

Signed-off-by: Stuart Menefy <stuart.menefy@codasip.com>
The get functions registered with object_class_property_add_str()
need to return a string which can be freed by calling g_free().

Signed-off-by: Stuart Menefy <stuart.menefy@codasip.com>
…odel

This was motivated by adding smp support to the proFPGA platform.
The order that qemu initialises itself means that the -smp command
line option is parsed before the machine properties are set, so
checks against the maximum number of cores would happen before knowing
whether this is a Genesys 2 or proFPGA.

So rework the code following the example of the Arm Musca-B1 (although
many other ARM boards use the same technique):
 - make the hobgoblin type an abstract type
 - derive two new types: hobgoblin-genesys2 and hobgoblin-profpga
 - the board type become a member of the hobgloblin class rather
   than the instance of the derived class.

Also switch to using OBJECT_DECLARE_TYPE(), which defines helper macros
to cast between object types, but also some typedefs, which does mean
that the names of the types no longer have _t postfix.

Signed-off-by: Stuart Menefy <stuart.menefy@codasip.com>
Add a flag to mark ROM regions as such.

Signed-off-by: Stuart Menefy <stuart.menefy@codasip.com>
An block of ID registers have been added to the Hobgoblin platform,
allowing software to probe the platform its running on.

Signed-off-by: Stuart Menefy <stuart.menefy@codasip.com>
There is a proposal for additions to the ID registers:
  https://codasip.atlassian.net/wiki/x/cQOLOg
which adds a board ID and version registers for the platform and
core. This change reads those registers and prints them alongside the
existing ID registers.

Signed-off-by: Stuart Menefy <stuart.menefy@codasip.com>
Replace the boolean rom flag with a memory type enum. This allows for
adding more types, such as cheri tagmem.
Add a cheri tagmem type to the memory type enum. Set this type for the
ram regions, qemu will then manage the tags.
qemu-system-riscv64cheri ... -drive if=sd,format=raw,file=card.img

results in this error

qemu-system-riscv64cheri: Drive 'sd0' is already in use because it has
been automatically connected to another device (did you need 'if=none' in
the drive options?)

qemu monitor shows that even without a -drive parameter,

qemu-system-riscv64cheri -M hobgoblin-genesys2

creates sd0 and attaches it

(qemu) info block
none2: [not inserted]
    Removable device: not locked, tray closed

floppy0: [not inserted]
    Removable device: not locked, tray closed

sd0: [not inserted]
    Attached to:      /machine/unattached/device[7]
    Removable device: not locked, tray closed
(qemu) quit
[martin.kaiser@nb282 qemu]$

Try to work around the problem by using the next available block device
instead of hard-coding bus and unit to 0.

"info qtree" in the monitor now looks like this:

(qemu) info qtree
bus: main-system-bus
  type System
  ...
  dev: xlnx.xps-spi, id ""
  gpio-out "sysbus-irq" 2
  num-ss-bits = 1 (0x1)
  mmio 0000000060210000/000000000000007c
  bus: spi
    type SSI
    dev: ssi-sd, id ""
      gpio-in "ssi-gpio-cs" 1
      bus: sd-bus
        type sd-bus
        dev: sd-card, id ""
          spec_version = 2 (0x2)
          drive = "sd0"
          spi = false
        dev: sd-card, id ""
          spec_version = 2 (0x2)
          drive = ""
          spi = true
The fsbl wants to store capabilities in the sram area. Declare this area
as cheri tagmem.

Explain why the boot ram area is not usable as cheri tagmem with qemu's
current tagmem implementation.
TYPE_HOBGOBLIN_MACHINE is derived from TYPE_MACHINE.

Some functions take both MachineState and HobgoblinState pointers as
parameters. Drop the MachineState parameter, it is part of HobgoblinState.
Split the setup of the spi bus and the sd card into two separate
functions.

The sd card uses the spi bus and gpio pins (which we ignore at the
moment). If we add gpio setup for the sd card, having a separate
sd card setup function makes the code easier to read.
Document the current state of support for the sd card's card detect gpio.
We're relying on the defaults of the gpio controller. This seems to work
in practice but we should be aware of this when we run into problems.
Stuart Menefy and others added 27 commits November 10, 2025 08:27
Add properties for the prefetchable memory region, and use there, if
set, to initialise the base and limit registers.

Signed-off-by: Stuart Menefy <stuart.menefy@codasip.com>
Hobgoblinv2 has a larger area, to keep things simple we will extend the
size for both.
Adds the v2 memory map but leaves it unused at present.
Add Hobgoblinv2 specific IRQ's for PCIE
The v2 memory map also changes the values of some IRQs, but this will be
addresses when we split the IRQs.
Move the v1 IRQ's to an array instead of an enum to allow having v2
irqs.
The enum becomes the index into the array.
Change anywhere the enums were being used to instead use them as an
index into the V1 array to prepare for selecting them based on machine
type.
Add the v2 irq values.
Add the PCIE device to the VCU118 hobgoblin2 platform.
Also seperate number of virtio devices based on platform/version type.
Add the fields for the map and irq version to the machine.
Update the helpers to use this rather than hard coded V1.
Add the machines for Hobgoblin v2
Remove unused hc variable in hobgoblin_add_interrupt_controller.
Fix TARGET_CHERI check for riscv32.
A spurious phandle was being allocated for an unused irq_pcie_phandle.
This was never used, but was needed because of the switch from
allocating phandles using ++phandle to phandle++. Update the code
to allocate all phandles using ++phandle and this can be removed.
The kernel device tree has been updated to include details of the
caches and TLBs. Add these to the generated DT.
The latest Hobgoblin device tree in the kernel sources adds extra
nodes, which causes the assigned phandles to change. To make comparisons
easier add placeholders for these extra nodes.
SPI CD is connected to gpio_sd (which is gpio1 in hobgoblin.c)
not gpio_io (gpio0).
Separate out indention changes to make subsequent functional changes
clearer.
Previously the interrupt number was retrieved from irqmap[] using a
hardwired Hobgoblin version number. While in most cases this doesn't
matter, for the Ethernet device on Hobgoblin 2 (the only generated
DT which is currently supported) it was getting this wrong.

So switch to using the HIRQ() macro used in the rest of the source
tree. This would also make it easier to add support for Hobgoblin 1
DT generation.
Replace hard coded values for the Ethernet PHY IRQs with values from
the irqmap.
While PCIe on qemu is DMA coherent, the real Hobgoblin platform is not,
so add the "dma-noncoherent" property to match the hardware, and
ensure that cache synchronisation operations are tested.
Rather than hard coding the address values in the PCIe ranges
property, extract the addresses from the memmap structure. This
makes it clearer what the vales mean, and should make it easier to
support other Hobgoblin variants in the future.
Kernel device trees have removed the "reg-offset" parameter from the
16550 UART, and adjusted the base to compensate. Make the same
changes to the generated DT.
@arichardson arichardson force-pushed the add-hobgoblin-platform branch from d0c1f33 to d86cf13 Compare November 10, 2025 16:31
@arichardson arichardson merged commit d86cf13 into CTSRD-CHERI:dev Nov 10, 2025
0 of 4 checks passed
@arichardson arichardson deleted the add-hobgoblin-platform branch November 10, 2025 16:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants