* [PATCH v2 01/17] docs/system/arm: Add Description for NPCM8XX SoC
2024-12-26 8:27 [PATCH v2 00/17] hw/arm: Add NPCM8XX Support Hao Wu
@ 2024-12-26 8:27 ` Hao Wu
2025-02-04 16:16 ` Peter Maydell
2024-12-26 8:27 ` [PATCH v2 02/17] roms: Update vbootrom to 1287b6e Hao Wu
` (15 subsequent siblings)
16 siblings, 1 reply; 35+ messages in thread
From: Hao Wu @ 2024-12-26 8:27 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair, Hao Wu
NPCM8XX SoC is the successor of the NPCM7XX. It features quad-core
Cortex-A35 (Armv8, 64-bit) CPUs and some additional peripherals.
Signed-off-by: Hao Wu <wuhaotsh@google.com>
---
docs/system/arm/nuvoton.rst | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
index 05059378e5..0a1916fb99 100644
--- a/docs/system/arm/nuvoton.rst
+++ b/docs/system/arm/nuvoton.rst
@@ -1,12 +1,13 @@
Nuvoton iBMC boards (``kudo-bmc``, ``mori-bmc``, ``npcm750-evb``, ``quanta-gbs-bmc``, ``quanta-gsj``)
=====================================================================================================
-The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
+The `Nuvoton iBMC`_ chips are a family of ARM-based SoCs that are
designed to be used as Baseboard Management Controllers (BMCs) in various
-servers. They all feature one or two ARM Cortex-A9 CPU cores, as well as an
-assortment of peripherals targeted for either Enterprise or Data Center /
-Hyperscale applications. The former is a superset of the latter, so NPCM750 has
-all the peripherals of NPCM730 and more.
+servers. Currently there are two families: NPCM7XX series and
+NPCM8XX series. NPCM7XX series feature one or two ARM Cortex-A9 CPU cores,
+while NPCM8XX feature 4 ARM Cortex-A35 CPU cores. Both series contain a
+different assortment of peripherals targeted for either Enterprise or Data
+Center / Hyperscale applications.
.. _Nuvoton iBMC: https://www.nuvoton.com/products/cloud-computing/ibmc/
@@ -27,6 +28,8 @@ There are also two more SoCs, NPCM710 and NPCM705, which are single-core
variants of NPCM750 and NPCM730, respectively. These are currently not
supported by QEMU.
+The NPCM8xx SoC is the successor of the NPCM7xx SoC.
+
Supported devices
-----------------
@@ -62,6 +65,8 @@ Missing devices
* System Wake-up Control (SWC)
* Shared memory (SHM)
* eSPI slave interface
+ * Block-tranfer interface (8XX only)
+ * Virtual UART (8XX only)
* Ethernet controller (GMAC)
* USB device (USBD)
@@ -76,6 +81,11 @@ Missing devices
* Video capture
* Encoding compression engine
* Security features
+ * I3C buses (8XX only)
+ * Temperator sensor interface (8XX only)
+ * Virtual UART (8XX only)
+ * Flash monitor (8XX only)
+ * JTAG master (8XX only)
Boot options
------------
--
2.47.1.613.gc27f4b7a9f-goog
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 01/17] docs/system/arm: Add Description for NPCM8XX SoC
2024-12-26 8:27 ` [PATCH v2 01/17] docs/system/arm: Add Description for NPCM8XX SoC Hao Wu
@ 2025-02-04 16:16 ` Peter Maydell
0 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2025-02-04 16:16 UTC (permalink / raw)
To: Hao Wu
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, hskinnemoen,
venture, pbonzini, jasowang, alistair
On Thu, 26 Dec 2024 at 08:28, Hao Wu <wuhaotsh@google.com> wrote:
>
> NPCM8XX SoC is the successor of the NPCM7XX. It features quad-core
> Cortex-A35 (Armv8, 64-bit) CPUs and some additional peripherals.
This should go at the end of the series, once you've added
the new machine types it documents.
> Signed-off-by: Hao Wu <wuhaotsh@google.com>
> ---
> docs/system/arm/nuvoton.rst | 20 +++++++++++++++-----
> 1 file changed, 15 insertions(+), 5 deletions(-)
>
> diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
> index 05059378e5..0a1916fb99 100644
> --- a/docs/system/arm/nuvoton.rst
> +++ b/docs/system/arm/nuvoton.rst
> @@ -1,12 +1,13 @@
> Nuvoton iBMC boards (``kudo-bmc``, ``mori-bmc``, ``npcm750-evb``, ``quanta-gbs-bmc``, ``quanta-gsj``)
> =====================================================================================================
You should add the names of the new boards in the title.
> -The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
> +The `Nuvoton iBMC`_ chips are a family of ARM-based SoCs that are
> designed to be used as Baseboard Management Controllers (BMCs) in various
> -servers. They all feature one or two ARM Cortex-A9 CPU cores, as well as an
> -assortment of peripherals targeted for either Enterprise or Data Center /
> -Hyperscale applications. The former is a superset of the latter, so NPCM750 has
> -all the peripherals of NPCM730 and more.
> +servers. Currently there are two families: NPCM7XX series and
> +NPCM8XX series. NPCM7XX series feature one or two ARM Cortex-A9 CPU cores,
> +while NPCM8XX feature 4 ARM Cortex-A35 CPU cores. Both series contain a
> +different assortment of peripherals targeted for either Enterprise or Data
> +Center / Hyperscale applications.
The correct capitalization for "Arm" is "Arm".
>
> .. _Nuvoton iBMC: https://www.nuvoton.com/products/cloud-computing/ibmc/
>
> @@ -27,6 +28,8 @@ There are also two more SoCs, NPCM710 and NPCM705, which are single-core
> variants of NPCM750 and NPCM730, respectively. These are currently not
> supported by QEMU.
>
> +The NPCM8xx SoC is the successor of the NPCM7xx SoC.
There should be a bullet-point list below here which
lists the new machine types.
> +
> Supported devices
> -----------------
>
> @@ -62,6 +65,8 @@ Missing devices
> * System Wake-up Control (SWC)
> * Shared memory (SHM)
> * eSPI slave interface
> + * Block-tranfer interface (8XX only)
Typo: "transfer"
> + * Virtual UART (8XX only)
>
> * Ethernet controller (GMAC)
> * USB device (USBD)
> @@ -76,6 +81,11 @@ Missing devices
> * Video capture
> * Encoding compression engine
> * Security features
> + * I3C buses (8XX only)
> + * Temperator sensor interface (8XX only)
Typo: "Temperature"
> + * Virtual UART (8XX only)
> + * Flash monitor (8XX only)
> + * JTAG master (8XX only)
thanks
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v2 02/17] roms: Update vbootrom to 1287b6e
2024-12-26 8:27 [PATCH v2 00/17] hw/arm: Add NPCM8XX Support Hao Wu
2024-12-26 8:27 ` [PATCH v2 01/17] docs/system/arm: Add Description for NPCM8XX SoC Hao Wu
@ 2024-12-26 8:27 ` Hao Wu
2025-02-04 16:30 ` Peter Maydell
2024-12-26 8:27 ` [PATCH v2 03/17] pc-bios: Add NPCM8XX vBootrom Hao Wu
` (14 subsequent siblings)
16 siblings, 1 reply; 35+ messages in thread
From: Hao Wu @ 2024-12-26 8:27 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair, Hao Wu
This newer vbootrom supports NPCM8xx. Similar to the NPCM7XX one
it supports loading the UBoot from the SPI device and not more.
We updated the npcm7xx bootrom to be compiled from this version.
Signed-off-by: Hao Wu <wuhaotsh@google.com>
---
pc-bios/npcm7xx_bootrom.bin | Bin 768 -> 768 bytes
roms/vbootrom | 2 +-
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/pc-bios/npcm7xx_bootrom.bin b/pc-bios/npcm7xx_bootrom.bin
index 38f89d1b97b0c2e133af2a9fbed0521be132065b..903f126636f9ef5d1100c056656ccfb2b32e5e10 100644
GIT binary patch
delta 90
zcmZo*Yhc^(l+nU*!D9x6DNkDr=09a-2ztoGz`#|*F#jn7L;r()|Np;c0m>C1$z?$0
Ywog`Ma%Vh0Ig_b-VgU<}A_D>d06Rh+WdHyG
delta 69
zcmZo*Yhc^(lu^NO!D9x2$xoRb7CdZGnE#ZCA@Cs+0|QqL!~CZV4E+!GPG)41X52Pe
SmdTy*+~icIZXQJj1ONb5*AzJb
diff --git a/roms/vbootrom b/roms/vbootrom
index 0c37a43527..1287b6e42e 160000
--- a/roms/vbootrom
+++ b/roms/vbootrom
@@ -1 +1 @@
-Subproject commit 0c37a43527f0ee2b9584e7fb2fdc805e902635ac
+Subproject commit 1287b6e42e839ba2ab0f06268c5b53ae60df3537
--
2.47.1.613.gc27f4b7a9f-goog
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 02/17] roms: Update vbootrom to 1287b6e
2024-12-26 8:27 ` [PATCH v2 02/17] roms: Update vbootrom to 1287b6e Hao Wu
@ 2025-02-04 16:30 ` Peter Maydell
0 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2025-02-04 16:30 UTC (permalink / raw)
To: Hao Wu
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, hskinnemoen,
venture, pbonzini, jasowang, alistair
On Thu, 26 Dec 2024 at 08:28, Hao Wu <wuhaotsh@google.com> wrote:
>
> This newer vbootrom supports NPCM8xx. Similar to the NPCM7XX one
> it supports loading the UBoot from the SPI device and not more.
>
> We updated the npcm7xx bootrom to be compiled from this version.
>
> Signed-off-by: Hao Wu <wuhaotsh@google.com>
> ---
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v2 03/17] pc-bios: Add NPCM8XX vBootrom
2024-12-26 8:27 [PATCH v2 00/17] hw/arm: Add NPCM8XX Support Hao Wu
2024-12-26 8:27 ` [PATCH v2 01/17] docs/system/arm: Add Description for NPCM8XX SoC Hao Wu
2024-12-26 8:27 ` [PATCH v2 02/17] roms: Update vbootrom to 1287b6e Hao Wu
@ 2024-12-26 8:27 ` Hao Wu
2025-02-04 16:31 ` Peter Maydell
2024-12-26 8:27 ` [PATCH v2 04/17] hw/ssi: Make flash size a property in NPCM7XX FIU Hao Wu
` (13 subsequent siblings)
16 siblings, 1 reply; 35+ messages in thread
From: Hao Wu @ 2024-12-26 8:27 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair, Hao Wu
The bootrom is a minimal bootrom used to load an NPCM8XX image.
The source code is located in the same repo as the NPCM7XX one:
github.com/google/vbootrom/tree/master/npcm8xx.
Signed-off-by: Hao Wu <wuhaotsh@google.com>
---
MAINTAINERS | 1 +
pc-bios/README | 8 ++++----
pc-bios/meson.build | 1 +
pc-bios/npcm8xx_bootrom.bin | Bin 0 -> 608 bytes
roms/Makefile | 6 ++++++
5 files changed, 12 insertions(+), 4 deletions(-)
create mode 100644 pc-bios/npcm8xx_bootrom.bin
diff --git a/MAINTAINERS b/MAINTAINERS
index 38a290e9c2..14bfadabbb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -872,6 +872,7 @@ F: include/hw/*/npcm*
F: tests/qtest/npcm*
F: tests/qtest/adm1266-test.c
F: pc-bios/npcm7xx_bootrom.bin
+F: pc-bios/npcm8xx_bootrom.bin
F: roms/vbootrom
F: docs/system/arm/nuvoton.rst
F: tests/functional/test_arm_quanta_gsj.py
diff --git a/pc-bios/README b/pc-bios/README
index 7ffb2f43a4..700dcaab52 100644
--- a/pc-bios/README
+++ b/pc-bios/README
@@ -70,10 +70,10 @@
source code also contains code reused from other projects described here:
https://github.com/riscv/opensbi/blob/master/ThirdPartyNotices.md.
-- npcm7xx_bootrom.bin is a simplified, free (Apache 2.0) boot ROM for Nuvoton
- NPCM7xx BMC devices. It currently implements the bare minimum to load, parse,
- initialize and run boot images stored in SPI flash, but may grow more
- features over time as needed. The source code is available at:
+- npcm{7xx,8xx}_bootrom.bin is a simplified, free (Apache 2.0) boot ROM for
+ Nuvoton NPCM7xx/8xx BMC devices. It currently implements the bare minimum to
+ load, parse, initialize and run boot images stored in SPI flash, but may grow
+ more features over time as needed. The source code is available at:
https://github.com/google/vbootrom
- hppa-firmware.img (32-bit) and hppa-firmware64.img (64-bit) are firmware
diff --git a/pc-bios/meson.build b/pc-bios/meson.build
index 4823dff189..d282c43658 100644
--- a/pc-bios/meson.build
+++ b/pc-bios/meson.build
@@ -80,6 +80,7 @@ blobs = [
'opensbi-riscv32-generic-fw_dynamic.bin',
'opensbi-riscv64-generic-fw_dynamic.bin',
'npcm7xx_bootrom.bin',
+ 'npcm8xx_bootrom.bin',
'vof.bin',
'vof-nvram.bin',
]
diff --git a/pc-bios/npcm8xx_bootrom.bin b/pc-bios/npcm8xx_bootrom.bin
new file mode 100644
index 0000000000000000000000000000000000000000..6370d6475635c4d445d2b927311edcd591949c82
GIT binary patch
literal 608
zcmdUrKTE?<6vfX=0{*3B5ET?nwWA^;qEk()n=Xb9-4dxoSBrz#p|QJQL~zokn{Eyc
z?PBXUkU+aB?k?IbNQftG5ej|*FC2c{bKkr7zLy3jhNxj`gc_y5h&V=Ru)PgZC)Y`f
zTqA9Am28qL<U6@cMtA>Hlr*^&hT#;re-)dpxT0U42|O+cWOcx=B;{6xXH04vx?cjm
z+%U{oFx!aPpV3>ZKz0i$XA-yq{f}<H?{MHBq+VwIvR9WmcL(xr1vuIRGELcRC-S+P
zl3%RlR5(6+1;xg_<~xR#bPItDN1*Hp^{JyNs7o*BMq0Q9q1#>x4;|pb<NWIbQ8wb1
zTac^<ebj^E^Ig<?U?(PO-w>w;l#@9zGd|z-rs*H@V-o%PEV)D-)8n2%DyH5@w_^Y8
LH5R3RMV#gjxYTW}
literal 0
HcmV?d00001
diff --git a/roms/Makefile b/roms/Makefile
index 31e4b97c98..beff58d9d5 100644
--- a/roms/Makefile
+++ b/roms/Makefile
@@ -34,6 +34,7 @@ find-cross-gcc = $(firstword $(wildcard $(patsubst %ld,%gcc,$(call find-cross-ld
# finally strip off path + toolname so we get the prefix
find-cross-prefix = $(subst gcc,,$(notdir $(call find-cross-gcc,$(1))))
+aarch64_cross_prefix := $(call find-cross-prefix,aarch64)
arm_cross_prefix := $(call find-cross-prefix,arm)
powerpc64_cross_prefix := $(call find-cross-prefix,powerpc64)
powerpc_cross_prefix := $(call find-cross-prefix,powerpc)
@@ -66,6 +67,7 @@ default help:
@echo " u-boot.e500 -- update u-boot.e500"
@echo " u-boot.sam460 -- update u-boot.sam460"
@echo " npcm7xx_bootrom -- update vbootrom for npcm7xx"
+ @echo " npcm8xx_bootrom -- update vbootrom for npcm8xx"
@echo " efi -- update UEFI (edk2) platform firmware"
@echo " opensbi32-generic -- update OpenSBI for 32-bit generic machine"
@echo " opensbi64-generic -- update OpenSBI for 64-bit generic machine"
@@ -194,6 +196,10 @@ npcm7xx_bootrom:
$(MAKE) -C vbootrom CROSS_COMPILE=$(arm_cross_prefix)
cp vbootrom/npcm7xx_bootrom.bin ../pc-bios/npcm7xx_bootrom.bin
+npcm8xx_bootrom:
+ $(MAKE) -C vbootrom CROSS_COMPILE=$(aarch64_cross_prefix)
+ cp vbootrom/npcm8xx_bootrom.bin ../pc-bios/npcm8xx_bootrom.bin
+
hppa-firmware:
$(MAKE) -C seabios-hppa parisc
cp seabios-hppa/out/hppa-firmware.img ../pc-bios/
--
2.47.1.613.gc27f4b7a9f-goog
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 03/17] pc-bios: Add NPCM8XX vBootrom
2024-12-26 8:27 ` [PATCH v2 03/17] pc-bios: Add NPCM8XX vBootrom Hao Wu
@ 2025-02-04 16:31 ` Peter Maydell
0 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2025-02-04 16:31 UTC (permalink / raw)
To: Hao Wu
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, hskinnemoen,
venture, pbonzini, jasowang, alistair
On Thu, 26 Dec 2024 at 08:28, Hao Wu <wuhaotsh@google.com> wrote:
>
> The bootrom is a minimal bootrom used to load an NPCM8XX image.
> The source code is located in the same repo as the NPCM7XX one:
> github.com/google/vbootrom/tree/master/npcm8xx.
>
> Signed-off-by: Hao Wu <wuhaotsh@google.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v2 04/17] hw/ssi: Make flash size a property in NPCM7XX FIU
2024-12-26 8:27 [PATCH v2 00/17] hw/arm: Add NPCM8XX Support Hao Wu
` (2 preceding siblings ...)
2024-12-26 8:27 ` [PATCH v2 03/17] pc-bios: Add NPCM8XX vBootrom Hao Wu
@ 2024-12-26 8:27 ` Hao Wu
2025-02-04 15:42 ` Peter Maydell
2024-12-26 8:27 ` [PATCH v2 05/17] hw/misc: Rename npcm7xx_gcr to npcm_gcr Hao Wu
` (12 subsequent siblings)
16 siblings, 1 reply; 35+ messages in thread
From: Hao Wu @ 2024-12-26 8:27 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair, Hao Wu
This allows different FIUs to have different flash sizes, useful
in NPCM8XX which has multiple different sized FIU modules.
Signed-off-by: Hao Wu <wuhaotsh@google.com>
---
hw/arm/npcm7xx.c | 6 ++++++
hw/ssi/npcm7xx_fiu.c | 11 +++++++----
include/hw/ssi/npcm7xx_fiu.h | 1 +
3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 386b2c35e9..2d6e08b72b 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -292,17 +292,21 @@ static const struct {
hwaddr regs_addr;
int cs_count;
const hwaddr *flash_addr;
+ size_t flash_size;
} npcm7xx_fiu[] = {
{
.name = "fiu0",
.regs_addr = 0xfb000000,
.cs_count = ARRAY_SIZE(npcm7xx_fiu0_flash_addr),
.flash_addr = npcm7xx_fiu0_flash_addr,
+ .flash_size = 128 * MiB,
+
}, {
.name = "fiu3",
.regs_addr = 0xc0000000,
.cs_count = ARRAY_SIZE(npcm7xx_fiu3_flash_addr),
.flash_addr = npcm7xx_fiu3_flash_addr,
+ .flash_size = 128 * MiB,
},
};
@@ -735,6 +739,8 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
object_property_set_int(OBJECT(sbd), "cs-count",
npcm7xx_fiu[i].cs_count, &error_abort);
+ object_property_set_int(OBJECT(sbd), "flash-size",
+ npcm7xx_fiu[i].flash_size, &error_abort);
sysbus_realize(sbd, &error_abort);
sysbus_mmio_map(sbd, 0, npcm7xx_fiu[i].regs_addr);
diff --git a/hw/ssi/npcm7xx_fiu.c b/hw/ssi/npcm7xx_fiu.c
index 21fc489038..ccdce67fa9 100644
--- a/hw/ssi/npcm7xx_fiu.c
+++ b/hw/ssi/npcm7xx_fiu.c
@@ -28,9 +28,6 @@
#include "trace.h"
-/* Up to 128 MiB of flash may be accessed directly as memory. */
-#define NPCM7XX_FIU_FLASH_WINDOW_SIZE (128 * MiB)
-
/* Each module has 4 KiB of register space. Only a fraction of it is used. */
#define NPCM7XX_FIU_CTRL_REGS_SIZE (4 * KiB)
@@ -507,6 +504,11 @@ static void npcm7xx_fiu_realize(DeviceState *dev, Error **errp)
return;
}
+ if (s->flash_size == 0) {
+ error_setg(errp, "%s: flash size must be set", dev->canonical_path);
+ return;
+ }
+
s->spi = ssi_create_bus(dev, "spi");
s->cs_lines = g_new0(qemu_irq, s->cs_count);
qdev_init_gpio_out_named(DEVICE(s), s->cs_lines, "cs", s->cs_count);
@@ -525,7 +527,7 @@ static void npcm7xx_fiu_realize(DeviceState *dev, Error **errp)
flash->fiu = s;
memory_region_init_io(&flash->direct_access, OBJECT(s),
&npcm7xx_fiu_flash_ops, &s->flash[i], "flash",
- NPCM7XX_FIU_FLASH_WINDOW_SIZE);
+ s->flash_size);
sysbus_init_mmio(sbd, &flash->direct_access);
}
}
@@ -543,6 +545,7 @@ static const VMStateDescription vmstate_npcm7xx_fiu = {
static const Property npcm7xx_fiu_properties[] = {
DEFINE_PROP_INT32("cs-count", NPCM7xxFIUState, cs_count, 0),
+ DEFINE_PROP_SIZE("flash-size", NPCM7xxFIUState, flash_size, 0),
};
static void npcm7xx_fiu_class_init(ObjectClass *klass, void *data)
diff --git a/include/hw/ssi/npcm7xx_fiu.h b/include/hw/ssi/npcm7xx_fiu.h
index a3a1704289..1785ea16f4 100644
--- a/include/hw/ssi/npcm7xx_fiu.h
+++ b/include/hw/ssi/npcm7xx_fiu.h
@@ -60,6 +60,7 @@ struct NPCM7xxFIUState {
int32_t cs_count;
int32_t active_cs;
qemu_irq *cs_lines;
+ size_t flash_size;
NPCM7xxFIUFlash *flash;
SSIBus *spi;
--
2.47.1.613.gc27f4b7a9f-goog
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 04/17] hw/ssi: Make flash size a property in NPCM7XX FIU
2024-12-26 8:27 ` [PATCH v2 04/17] hw/ssi: Make flash size a property in NPCM7XX FIU Hao Wu
@ 2025-02-04 15:42 ` Peter Maydell
0 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2025-02-04 15:42 UTC (permalink / raw)
To: Hao Wu
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair
On Thu, 26 Dec 2024 at 08:28, Hao Wu <wuhaotsh@google.com> wrote:
>
> This allows different FIUs to have different flash sizes, useful
> in NPCM8XX which has multiple different sized FIU modules.
>
> Signed-off-by: Hao Wu <wuhaotsh@google.com>
> ---
> hw/arm/npcm7xx.c | 6 ++++++
> hw/ssi/npcm7xx_fiu.c | 11 +++++++----
> include/hw/ssi/npcm7xx_fiu.h | 1 +
> 3 files changed, 14 insertions(+), 4 deletions(-)
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v2 05/17] hw/misc: Rename npcm7xx_gcr to npcm_gcr
2024-12-26 8:27 [PATCH v2 00/17] hw/arm: Add NPCM8XX Support Hao Wu
` (3 preceding siblings ...)
2024-12-26 8:27 ` [PATCH v2 04/17] hw/ssi: Make flash size a property in NPCM7XX FIU Hao Wu
@ 2024-12-26 8:27 ` Hao Wu
2025-02-04 15:43 ` Peter Maydell
2024-12-26 8:27 ` [PATCH v2 06/17] hw/misc: Move NPCM7XX GCR to NPCM GCR Hao Wu
` (11 subsequent siblings)
16 siblings, 1 reply; 35+ messages in thread
From: Hao Wu @ 2024-12-26 8:27 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair, Hao Wu
NPCM7XX and NPCM8XX have a different set of GCRs and the GCR module
needs to fit both. This commit changes the name of the GCR module.
Future commits will add the support for NPCM8XX GCRs.
Signed-off-by: Hao Wu <wuhaotsh@google.com>
---
hw/misc/meson.build | 2 +-
hw/misc/{npcm7xx_gcr.c => npcm_gcr.c} | 2 +-
include/hw/arm/npcm7xx.h | 2 +-
include/hw/misc/{npcm7xx_gcr.h => npcm_gcr.h} | 6 +++---
4 files changed, 6 insertions(+), 6 deletions(-)
rename hw/misc/{npcm7xx_gcr.c => npcm_gcr.c} (99%)
rename include/hw/misc/{npcm7xx_gcr.h => npcm_gcr.h} (96%)
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index d02d96e403..9bab048849 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -68,7 +68,7 @@ system_ss.add(when: 'CONFIG_IMX', if_true: files(
))
system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files(
'npcm7xx_clk.c',
- 'npcm7xx_gcr.c',
+ 'npcm_gcr.c',
'npcm7xx_mft.c',
'npcm7xx_pwm.c',
'npcm7xx_rng.c',
diff --git a/hw/misc/npcm7xx_gcr.c b/hw/misc/npcm_gcr.c
similarity index 99%
rename from hw/misc/npcm7xx_gcr.c
rename to hw/misc/npcm_gcr.c
index 07464a4dc9..826fd41123 100644
--- a/hw/misc/npcm7xx_gcr.c
+++ b/hw/misc/npcm_gcr.c
@@ -16,7 +16,7 @@
#include "qemu/osdep.h"
-#include "hw/misc/npcm7xx_gcr.h"
+#include "hw/misc/npcm_gcr.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index 4e0d210188..510170471e 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -24,7 +24,7 @@
#include "hw/i2c/npcm7xx_smbus.h"
#include "hw/mem/npcm7xx_mc.h"
#include "hw/misc/npcm7xx_clk.h"
-#include "hw/misc/npcm7xx_gcr.h"
+#include "hw/misc/npcm_gcr.h"
#include "hw/misc/npcm7xx_mft.h"
#include "hw/misc/npcm7xx_pwm.h"
#include "hw/misc/npcm7xx_rng.h"
diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm_gcr.h
similarity index 96%
rename from include/hw/misc/npcm7xx_gcr.h
rename to include/hw/misc/npcm_gcr.h
index c0bbdda77e..9b4998950c 100644
--- a/include/hw/misc/npcm7xx_gcr.h
+++ b/include/hw/misc/npcm_gcr.h
@@ -13,8 +13,8 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
-#ifndef NPCM7XX_GCR_H
-#define NPCM7XX_GCR_H
+#ifndef NPCM_GCR_H
+#define NPCM_GCR_H
#include "exec/memory.h"
#include "hw/sysbus.h"
@@ -70,4 +70,4 @@ struct NPCM7xxGCRState {
#define TYPE_NPCM7XX_GCR "npcm7xx-gcr"
OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxGCRState, NPCM7XX_GCR)
-#endif /* NPCM7XX_GCR_H */
+#endif /* NPCM_GCR_H */
--
2.47.1.613.gc27f4b7a9f-goog
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 05/17] hw/misc: Rename npcm7xx_gcr to npcm_gcr
2024-12-26 8:27 ` [PATCH v2 05/17] hw/misc: Rename npcm7xx_gcr to npcm_gcr Hao Wu
@ 2025-02-04 15:43 ` Peter Maydell
0 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2025-02-04 15:43 UTC (permalink / raw)
To: Hao Wu
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair
q
On Thu, 26 Dec 2024 at 08:28, Hao Wu <wuhaotsh@google.com> wrote:
>
> NPCM7XX and NPCM8XX have a different set of GCRs and the GCR module
> needs to fit both. This commit changes the name of the GCR module.
> Future commits will add the support for NPCM8XX GCRs.
>
> Signed-off-by: Hao Wu <wuhaotsh@google.com>
> ---
> hw/misc/meson.build | 2 +-
> hw/misc/{npcm7xx_gcr.c => npcm_gcr.c} | 2 +-
> include/hw/arm/npcm7xx.h | 2 +-
> include/hw/misc/{npcm7xx_gcr.h => npcm_gcr.h} | 6 +++---
> 4 files changed, 6 insertions(+), 6 deletions(-)
> rename hw/misc/{npcm7xx_gcr.c => npcm_gcr.c} (99%)
> rename include/hw/misc/{npcm7xx_gcr.h => npcm_gcr.h} (96%)
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v2 06/17] hw/misc: Move NPCM7XX GCR to NPCM GCR
2024-12-26 8:27 [PATCH v2 00/17] hw/arm: Add NPCM8XX Support Hao Wu
` (4 preceding siblings ...)
2024-12-26 8:27 ` [PATCH v2 05/17] hw/misc: Rename npcm7xx_gcr to npcm_gcr Hao Wu
@ 2024-12-26 8:27 ` Hao Wu
2025-02-04 15:45 ` Peter Maydell
2024-12-26 8:27 ` [PATCH v2 07/17] hw/misc: Add nr_regs and cold_reset_values " Hao Wu
` (10 subsequent siblings)
16 siblings, 1 reply; 35+ messages in thread
From: Hao Wu @ 2024-12-26 8:27 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair, Hao Wu
A lot of NPCM7XX and NPCM8XX GCR modules share the same code,
this commit moves the NPCM7XX GCR to NPCM GCR for these
properties.
Signed-off-by: Hao Wu <wuhaotsh@google.com>
---
hw/misc/npcm_gcr.c | 92 +++++++++++++++++++++-----------------
hw/misc/trace-events | 6 +--
include/hw/arm/npcm7xx.h | 2 +-
include/hw/misc/npcm_gcr.h | 7 +--
4 files changed, 59 insertions(+), 48 deletions(-)
diff --git a/hw/misc/npcm_gcr.c b/hw/misc/npcm_gcr.c
index 826fd41123..0959f2e5c4 100644
--- a/hw/misc/npcm_gcr.c
+++ b/hw/misc/npcm_gcr.c
@@ -84,10 +84,10 @@ static const uint32_t cold_reset_values[NPCM7XX_GCR_NR_REGS] = {
[NPCM7XX_GCR_USB2PHYCTL] = 0x034730e4,
};
-static uint64_t npcm7xx_gcr_read(void *opaque, hwaddr offset, unsigned size)
+static uint64_t npcm_gcr_read(void *opaque, hwaddr offset, unsigned size)
{
uint32_t reg = offset / sizeof(uint32_t);
- NPCM7xxGCRState *s = opaque;
+ NPCMGCRState *s = opaque;
if (reg >= NPCM7XX_GCR_NR_REGS) {
qemu_log_mask(LOG_GUEST_ERROR,
@@ -96,19 +96,19 @@ static uint64_t npcm7xx_gcr_read(void *opaque, hwaddr offset, unsigned size)
return 0;
}
- trace_npcm7xx_gcr_read(offset, s->regs[reg]);
+ trace_npcm_gcr_read(offset, s->regs[reg]);
return s->regs[reg];
}
-static void npcm7xx_gcr_write(void *opaque, hwaddr offset,
+static void npcm_gcr_write(void *opaque, hwaddr offset,
uint64_t v, unsigned size)
{
uint32_t reg = offset / sizeof(uint32_t);
- NPCM7xxGCRState *s = opaque;
+ NPCMGCRState *s = opaque;
uint32_t value = v;
- trace_npcm7xx_gcr_write(offset, value);
+ trace_npcm_gcr_write(offset, value);
if (reg >= NPCM7XX_GCR_NR_REGS) {
qemu_log_mask(LOG_GUEST_ERROR,
@@ -142,9 +142,9 @@ static void npcm7xx_gcr_write(void *opaque, hwaddr offset,
s->regs[reg] = value;
}
-static const struct MemoryRegionOps npcm7xx_gcr_ops = {
- .read = npcm7xx_gcr_read,
- .write = npcm7xx_gcr_write,
+static const struct MemoryRegionOps npcm_gcr_ops = {
+ .read = npcm_gcr_read,
+ .write = npcm_gcr_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 4,
@@ -155,7 +155,7 @@ static const struct MemoryRegionOps npcm7xx_gcr_ops = {
static void npcm7xx_gcr_enter_reset(Object *obj, ResetType type)
{
- NPCM7xxGCRState *s = NPCM7XX_GCR(obj);
+ NPCMGCRState *s = NPCM_GCR(obj);
QEMU_BUILD_BUG_ON(sizeof(s->regs) != sizeof(cold_reset_values));
@@ -165,10 +165,10 @@ static void npcm7xx_gcr_enter_reset(Object *obj, ResetType type)
s->regs[NPCM7XX_GCR_INTCR3] = s->reset_intcr3;
}
-static void npcm7xx_gcr_realize(DeviceState *dev, Error **errp)
+static void npcm_gcr_realize(DeviceState *dev, Error **errp)
{
ERRP_GUARD();
- NPCM7xxGCRState *s = NPCM7XX_GCR(dev);
+ NPCMGCRState *s = NPCM_GCR(dev);
uint64_t dram_size;
Object *obj;
@@ -210,55 +210,65 @@ static void npcm7xx_gcr_realize(DeviceState *dev, Error **errp)
s->reset_intcr3 |= ctz64(dram_size / NPCM7XX_GCR_MIN_DRAM_SIZE) << 8;
}
-static void npcm7xx_gcr_init(Object *obj)
+static void npcm_gcr_init(Object *obj)
{
- NPCM7xxGCRState *s = NPCM7XX_GCR(obj);
+ NPCMGCRState *s = NPCM_GCR(obj);
- memory_region_init_io(&s->iomem, obj, &npcm7xx_gcr_ops, s,
- TYPE_NPCM7XX_GCR, 4 * KiB);
+ memory_region_init_io(&s->iomem, obj, &npcm_gcr_ops, s,
+ TYPE_NPCM_GCR, 4 * KiB);
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
}
-static const VMStateDescription vmstate_npcm7xx_gcr = {
- .name = "npcm7xx-gcr",
- .version_id = 0,
- .minimum_version_id = 0,
+static const VMStateDescription vmstate_npcm_gcr = {
+ .name = "npcm-gcr",
+ .version_id = 1,
+ .minimum_version_id = 1,
.fields = (const VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, NPCM7xxGCRState, NPCM7XX_GCR_NR_REGS),
+ VMSTATE_UINT32_ARRAY(regs, NPCMGCRState, NPCM7XX_GCR_NR_REGS),
VMSTATE_END_OF_LIST(),
},
};
-static const Property npcm7xx_gcr_properties[] = {
- DEFINE_PROP_UINT32("disabled-modules", NPCM7xxGCRState, reset_mdlr, 0),
- DEFINE_PROP_UINT32("power-on-straps", NPCM7xxGCRState, reset_pwron, 0),
+static const Property npcm_gcr_properties[] = {
+ DEFINE_PROP_UINT32("disabled-modules", NPCMGCRState, reset_mdlr, 0),
+ DEFINE_PROP_UINT32("power-on-straps", NPCMGCRState, reset_pwron, 0),
};
-static void npcm7xx_gcr_class_init(ObjectClass *klass, void *data)
+static void npcm_gcr_class_init(ObjectClass *klass, void *data)
{
- ResettableClass *rc = RESETTABLE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
QEMU_BUILD_BUG_ON(NPCM7XX_GCR_REGS_END > NPCM7XX_GCR_NR_REGS);
+ dc->realize = npcm_gcr_realize;
+ dc->vmsd = &vmstate_npcm_gcr;
+
+ device_class_set_props(dc, npcm_gcr_properties);
+}
+
+static void npcm7xx_gcr_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
+ QEMU_BUILD_BUG_ON(NPCM7XX_GCR_REGS_END != NPCM7XX_GCR_NR_REGS);
dc->desc = "NPCM7xx System Global Control Registers";
- dc->realize = npcm7xx_gcr_realize;
- dc->vmsd = &vmstate_npcm7xx_gcr;
rc->phases.enter = npcm7xx_gcr_enter_reset;
- device_class_set_props(dc, npcm7xx_gcr_properties);
}
-static const TypeInfo npcm7xx_gcr_info = {
- .name = TYPE_NPCM7XX_GCR,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(NPCM7xxGCRState),
- .instance_init = npcm7xx_gcr_init,
- .class_init = npcm7xx_gcr_class_init,
+static const TypeInfo npcm_gcr_info[] = {
+ {
+ .name = TYPE_NPCM_GCR,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(NPCMGCRState),
+ .instance_init = npcm_gcr_init,
+ .class_init = npcm_gcr_class_init,
+ .abstract = true,
+ },
+ {
+ .name = TYPE_NPCM7XX_GCR,
+ .parent = TYPE_NPCM_GCR,
+ .class_init = npcm7xx_gcr_class_init,
+ },
};
-
-static void npcm7xx_gcr_register_type(void)
-{
- type_register_static(&npcm7xx_gcr_info);
-}
-type_init(npcm7xx_gcr_register_type);
+DEFINE_TYPES(npcm_gcr_info)
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index b9fbcb0924..f2d498e862 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -134,9 +134,9 @@ mos6522_read(uint64_t addr, const char *name, unsigned val) "reg=0x%"PRIx64 " [%
npcm7xx_clk_read(uint64_t offset, uint32_t value) " offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
npcm7xx_clk_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
-# npcm7xx_gcr.c
-npcm7xx_gcr_read(uint64_t offset, uint32_t value) " offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
-npcm7xx_gcr_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
+# npcm_gcr.c
+npcm_gcr_read(uint64_t offset, uint32_t value) " offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
+npcm_gcr_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
# npcm7xx_mft.c
npcm7xx_mft_read(const char *name, uint64_t offset, uint16_t value) "%s: offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index 510170471e..2e708471ec 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -89,7 +89,7 @@ struct NPCM7xxState {
MemoryRegion ram3;
MemoryRegion *dram;
- NPCM7xxGCRState gcr;
+ NPCMGCRState gcr;
NPCM7xxCLKState clk;
NPCM7xxTimerCtrlState tim[3];
NPCM7xxADCState adc;
diff --git a/include/hw/misc/npcm_gcr.h b/include/hw/misc/npcm_gcr.h
index 9b4998950c..6d3d00d260 100644
--- a/include/hw/misc/npcm_gcr.h
+++ b/include/hw/misc/npcm_gcr.h
@@ -55,7 +55,7 @@
*/
#define NPCM7XX_GCR_NR_REGS (0x148 / sizeof(uint32_t))
-struct NPCM7xxGCRState {
+typedef struct NPCMGCRState {
SysBusDevice parent;
MemoryRegion iomem;
@@ -65,9 +65,10 @@ struct NPCM7xxGCRState {
uint32_t reset_pwron;
uint32_t reset_mdlr;
uint32_t reset_intcr3;
-};
+} NPCMGCRState;
+#define TYPE_NPCM_GCR "npcm-gcr"
#define TYPE_NPCM7XX_GCR "npcm7xx-gcr"
-OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxGCRState, NPCM7XX_GCR)
+OBJECT_DECLARE_SIMPLE_TYPE(NPCMGCRState, NPCM_GCR)
#endif /* NPCM_GCR_H */
--
2.47.1.613.gc27f4b7a9f-goog
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 06/17] hw/misc: Move NPCM7XX GCR to NPCM GCR
2024-12-26 8:27 ` [PATCH v2 06/17] hw/misc: Move NPCM7XX GCR to NPCM GCR Hao Wu
@ 2025-02-04 15:45 ` Peter Maydell
0 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2025-02-04 15:45 UTC (permalink / raw)
To: Hao Wu
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, hskinnemoen,
venture, pbonzini, jasowang, alistair
On Thu, 26 Dec 2024 at 08:28, Hao Wu <wuhaotsh@google.com> wrote:
>
> A lot of NPCM7XX and NPCM8XX GCR modules share the same code,
> this commit moves the NPCM7XX GCR to NPCM GCR for these
> properties.
>
> Signed-off-by: Hao Wu <wuhaotsh@google.com>
> ---
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v2 07/17] hw/misc: Add nr_regs and cold_reset_values to NPCM GCR
2024-12-26 8:27 [PATCH v2 00/17] hw/arm: Add NPCM8XX Support Hao Wu
` (5 preceding siblings ...)
2024-12-26 8:27 ` [PATCH v2 06/17] hw/misc: Move NPCM7XX GCR to NPCM GCR Hao Wu
@ 2024-12-26 8:27 ` Hao Wu
2025-02-04 15:48 ` Peter Maydell
2024-12-26 8:27 ` [PATCH v2 08/17] hw/misc: Add support for NPCM8XX GCR Hao Wu
` (9 subsequent siblings)
16 siblings, 1 reply; 35+ messages in thread
From: Hao Wu @ 2024-12-26 8:27 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair, Hao Wu
These 2 values are different between NPCM7XX and NPCM8XX
GCRs. So we add them to the class and assign different values
to them.
Signed-off-by: Hao Wu <wuhaotsh@google.com>
---
hw/misc/npcm_gcr.c | 24 +++++++++++++++---------
include/hw/misc/npcm_gcr.h | 13 +++++++++++--
2 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/hw/misc/npcm_gcr.c b/hw/misc/npcm_gcr.c
index 0959f2e5c4..295073ba14 100644
--- a/hw/misc/npcm_gcr.c
+++ b/hw/misc/npcm_gcr.c
@@ -69,7 +69,7 @@ enum NPCM7xxGCRRegisters {
NPCM7XX_GCR_REGS_END,
};
-static const uint32_t cold_reset_values[NPCM7XX_GCR_NR_REGS] = {
+static const uint32_t npcm7xx_cold_reset_values[NPCM7XX_GCR_NR_REGS] = {
[NPCM7XX_GCR_PDID] = 0x04a92750, /* Poleg A1 */
[NPCM7XX_GCR_MISCPE] = 0x0000ffff,
[NPCM7XX_GCR_SPSWC] = 0x00000003,
@@ -88,8 +88,9 @@ static uint64_t npcm_gcr_read(void *opaque, hwaddr offset, unsigned size)
{
uint32_t reg = offset / sizeof(uint32_t);
NPCMGCRState *s = opaque;
+ NPCMGCRClass *c = NPCM_GCR_GET_CLASS(s);
- if (reg >= NPCM7XX_GCR_NR_REGS) {
+ if (reg >= c->nr_regs) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: offset 0x%04" HWADDR_PRIx " out of range\n",
__func__, offset);
@@ -106,11 +107,12 @@ static void npcm_gcr_write(void *opaque, hwaddr offset,
{
uint32_t reg = offset / sizeof(uint32_t);
NPCMGCRState *s = opaque;
+ NPCMGCRClass *c = NPCM_GCR_GET_CLASS(s);
uint32_t value = v;
- trace_npcm_gcr_write(offset, value);
+ trace_npcm_gcr_write(offset, v);
- if (reg >= NPCM7XX_GCR_NR_REGS) {
+ if (reg >= c->nr_regs) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: offset 0x%04" HWADDR_PRIx " out of range\n",
__func__, offset);
@@ -156,10 +158,10 @@ static const struct MemoryRegionOps npcm_gcr_ops = {
static void npcm7xx_gcr_enter_reset(Object *obj, ResetType type)
{
NPCMGCRState *s = NPCM_GCR(obj);
+ NPCMGCRClass *c = NPCM_GCR_GET_CLASS(obj);
- QEMU_BUILD_BUG_ON(sizeof(s->regs) != sizeof(cold_reset_values));
-
- memcpy(s->regs, cold_reset_values, sizeof(s->regs));
+ memcpy(s->regs, c->cold_reset_values, c->nr_regs * sizeof(uint32_t));
+ /* These 3 registers are at the same location in both 7xx and 8xx. */
s->regs[NPCM7XX_GCR_PWRON] = s->reset_pwron;
s->regs[NPCM7XX_GCR_MDLR] = s->reset_mdlr;
s->regs[NPCM7XX_GCR_INTCR3] = s->reset_intcr3;
@@ -224,7 +226,7 @@ static const VMStateDescription vmstate_npcm_gcr = {
.version_id = 1,
.minimum_version_id = 1,
.fields = (const VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, NPCMGCRState, NPCM7XX_GCR_NR_REGS),
+ VMSTATE_UINT32_ARRAY(regs, NPCMGCRState, NPCM_GCR_MAX_NR_REGS),
VMSTATE_END_OF_LIST(),
},
};
@@ -238,7 +240,6 @@ static void npcm_gcr_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- QEMU_BUILD_BUG_ON(NPCM7XX_GCR_REGS_END > NPCM7XX_GCR_NR_REGS);
dc->realize = npcm_gcr_realize;
dc->vmsd = &vmstate_npcm_gcr;
@@ -247,13 +248,17 @@ static void npcm_gcr_class_init(ObjectClass *klass, void *data)
static void npcm7xx_gcr_class_init(ObjectClass *klass, void *data)
{
+ NPCMGCRClass *c = NPCM_GCR_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
ResettableClass *rc = RESETTABLE_CLASS(klass);
+ QEMU_BUILD_BUG_ON(NPCM7XX_GCR_REGS_END > NPCM_GCR_MAX_NR_REGS);
QEMU_BUILD_BUG_ON(NPCM7XX_GCR_REGS_END != NPCM7XX_GCR_NR_REGS);
dc->desc = "NPCM7xx System Global Control Registers";
rc->phases.enter = npcm7xx_gcr_enter_reset;
+ c->nr_regs = NPCM7XX_GCR_NR_REGS;
+ c->cold_reset_values = npcm7xx_cold_reset_values;
}
static const TypeInfo npcm_gcr_info[] = {
@@ -262,6 +267,7 @@ static const TypeInfo npcm_gcr_info[] = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(NPCMGCRState),
.instance_init = npcm_gcr_init,
+ .class_size = sizeof(NPCMGCRClass),
.class_init = npcm_gcr_class_init,
.abstract = true,
},
diff --git a/include/hw/misc/npcm_gcr.h b/include/hw/misc/npcm_gcr.h
index 6d3d00d260..9af24e5cdc 100644
--- a/include/hw/misc/npcm_gcr.h
+++ b/include/hw/misc/npcm_gcr.h
@@ -18,6 +18,7 @@
#include "exec/memory.h"
#include "hw/sysbus.h"
+#include "qom/object.h"
/*
* NPCM7XX PWRON STRAP bit fields
@@ -53,6 +54,7 @@
* Number of registers in our device state structure. Don't change this without
* incrementing the version_id in the vmstate.
*/
+#define NPCM_GCR_MAX_NR_REGS NPCM7XX_GCR_NR_REGS
#define NPCM7XX_GCR_NR_REGS (0x148 / sizeof(uint32_t))
typedef struct NPCMGCRState {
@@ -60,15 +62,22 @@ typedef struct NPCMGCRState {
MemoryRegion iomem;
- uint32_t regs[NPCM7XX_GCR_NR_REGS];
+ uint32_t regs[NPCM_GCR_MAX_NR_REGS];
uint32_t reset_pwron;
uint32_t reset_mdlr;
uint32_t reset_intcr3;
} NPCMGCRState;
+typedef struct NPCMGCRClass {
+ SysBusDeviceClass parent;
+
+ size_t nr_regs;
+ const uint32_t *cold_reset_values;
+} NPCMGCRClass;
+
#define TYPE_NPCM_GCR "npcm-gcr"
#define TYPE_NPCM7XX_GCR "npcm7xx-gcr"
-OBJECT_DECLARE_SIMPLE_TYPE(NPCMGCRState, NPCM_GCR)
+OBJECT_DECLARE_TYPE(NPCMGCRState, NPCMGCRClass, NPCM_GCR)
#endif /* NPCM_GCR_H */
--
2.47.1.613.gc27f4b7a9f-goog
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 07/17] hw/misc: Add nr_regs and cold_reset_values to NPCM GCR
2024-12-26 8:27 ` [PATCH v2 07/17] hw/misc: Add nr_regs and cold_reset_values " Hao Wu
@ 2025-02-04 15:48 ` Peter Maydell
0 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2025-02-04 15:48 UTC (permalink / raw)
To: Hao Wu
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, hskinnemoen,
venture, pbonzini, jasowang, alistair
On Thu, 26 Dec 2024 at 08:28, Hao Wu <wuhaotsh@google.com> wrote:
>
> These 2 values are different between NPCM7XX and NPCM8XX
> GCRs. So we add them to the class and assign different values
> to them.
>
> Signed-off-by: Hao Wu <wuhaotsh@google.com>
> ---
> hw/misc/npcm_gcr.c | 24 +++++++++++++++---------
> include/hw/misc/npcm_gcr.h | 13 +++++++++++--
> 2 files changed, 26 insertions(+), 11 deletions(-)
>
> @@ -156,10 +158,10 @@ static const struct MemoryRegionOps npcm_gcr_ops = {
> static void npcm7xx_gcr_enter_reset(Object *obj, ResetType type)
> {
> NPCMGCRState *s = NPCM_GCR(obj);
> + NPCMGCRClass *c = NPCM_GCR_GET_CLASS(obj);
>
> - QEMU_BUILD_BUG_ON(sizeof(s->regs) != sizeof(cold_reset_values));
> -
> - memcpy(s->regs, cold_reset_values, sizeof(s->regs));
> + memcpy(s->regs, c->cold_reset_values, c->nr_regs * sizeof(uint32_t));
Previously we had a compile-time assert that we were copying
the right amount of data. Making this a class-specific
thing means we can't assert at compile time any more, but
I think it's still worth a runtime assert that we aren't
copying more data than will fit into s->regs.
Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v2 08/17] hw/misc: Add support for NPCM8XX GCR
2024-12-26 8:27 [PATCH v2 00/17] hw/arm: Add NPCM8XX Support Hao Wu
` (6 preceding siblings ...)
2024-12-26 8:27 ` [PATCH v2 07/17] hw/misc: Add nr_regs and cold_reset_values " Hao Wu
@ 2024-12-26 8:27 ` Hao Wu
2025-02-04 15:49 ` Peter Maydell
2024-12-26 8:27 ` [PATCH v2 09/17] hw/misc: Store DRAM size in NPCM8XX GCR Module Hao Wu
` (8 subsequent siblings)
16 siblings, 1 reply; 35+ messages in thread
From: Hao Wu @ 2024-12-26 8:27 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair, Hao Wu
Signed-off-by: Hao Wu <wuhaotsh@google.com>
---
hw/misc/npcm_gcr.c | 131 ++++++++++++++++++++++++++++++++++++-
include/hw/misc/npcm_gcr.h | 6 +-
2 files changed, 134 insertions(+), 3 deletions(-)
diff --git a/hw/misc/npcm_gcr.c b/hw/misc/npcm_gcr.c
index 295073ba14..52d0fa07ea 100644
--- a/hw/misc/npcm_gcr.c
+++ b/hw/misc/npcm_gcr.c
@@ -1,5 +1,5 @@
/*
- * Nuvoton NPCM7xx System Global Control Registers.
+ * Nuvoton NPCM7xx/8xx System Global Control Registers.
*
* Copyright 2020 Google LLC
*
@@ -84,6 +84,118 @@ static const uint32_t npcm7xx_cold_reset_values[NPCM7XX_GCR_NR_REGS] = {
[NPCM7XX_GCR_USB2PHYCTL] = 0x034730e4,
};
+enum NPCM8xxGCRRegisters {
+ NPCM8XX_GCR_PDID,
+ NPCM8XX_GCR_PWRON,
+ NPCM8XX_GCR_MISCPE = 0x014 / sizeof(uint32_t),
+ NPCM8XX_GCR_FLOCKR2 = 0x020 / sizeof(uint32_t),
+ NPCM8XX_GCR_FLOCKR3,
+ NPCM8XX_GCR_A35_MODE = 0x034 / sizeof(uint32_t),
+ NPCM8XX_GCR_SPSWC,
+ NPCM8XX_GCR_INTCR,
+ NPCM8XX_GCR_INTSR,
+ NPCM8XX_GCR_HIFCR = 0x050 / sizeof(uint32_t),
+ NPCM8XX_GCR_INTCR2 = 0x060 / sizeof(uint32_t),
+ NPCM8XX_GCR_SRCNT = 0x068 / sizeof(uint32_t),
+ NPCM8XX_GCR_RESSR,
+ NPCM8XX_GCR_RLOCKR1,
+ NPCM8XX_GCR_FLOCKR1,
+ NPCM8XX_GCR_DSCNT,
+ NPCM8XX_GCR_MDLR,
+ NPCM8XX_GCR_SCRPAD_C = 0x080 / sizeof(uint32_t),
+ NPCM8XX_GCR_SCRPAD_B,
+ NPCM8XX_GCR_DAVCLVLR = 0x098 / sizeof(uint32_t),
+ NPCM8XX_GCR_INTCR3,
+ NPCM8XX_GCR_PCIRCTL = 0x0a0 / sizeof(uint32_t),
+ NPCM8XX_GCR_VSINTR,
+ NPCM8XX_GCR_SD2SUR1 = 0x0b4 / sizeof(uint32_t),
+ NPCM8XX_GCR_SD2SUR2,
+ NPCM8XX_GCR_INTCR4 = 0x0c0 / sizeof(uint32_t),
+ NPCM8XX_GCR_CPCTL = 0x0d0 / sizeof(uint32_t),
+ NPCM8XX_GCR_CP2BST,
+ NPCM8XX_GCR_B2CPNT,
+ NPCM8XX_GCR_CPPCTL,
+ NPCM8XX_GCR_I2CSEGSEL = 0x0e0 / sizeof(uint32_t),
+ NPCM8XX_GCR_I2CSEGCTL,
+ NPCM8XX_GCR_VSRCR,
+ NPCM8XX_GCR_MLOCKR,
+ NPCM8XX_GCR_SCRPAD = 0x13c / sizeof(uint32_t),
+ NPCM8XX_GCR_USB1PHYCTL,
+ NPCM8XX_GCR_USB2PHYCTL,
+ NPCM8XX_GCR_USB3PHYCTL,
+ NPCM8XX_GCR_MFSEL1 = 0x260 / sizeof(uint32_t),
+ NPCM8XX_GCR_MFSEL2,
+ NPCM8XX_GCR_MFSEL3,
+ NPCM8XX_GCR_MFSEL4,
+ NPCM8XX_GCR_MFSEL5,
+ NPCM8XX_GCR_MFSEL6,
+ NPCM8XX_GCR_MFSEL7,
+ NPCM8XX_GCR_MFSEL_LK1 = 0x280 / sizeof(uint32_t),
+ NPCM8XX_GCR_MFSEL_LK2,
+ NPCM8XX_GCR_MFSEL_LK3,
+ NPCM8XX_GCR_MFSEL_LK4,
+ NPCM8XX_GCR_MFSEL_LK5,
+ NPCM8XX_GCR_MFSEL_LK6,
+ NPCM8XX_GCR_MFSEL_LK7,
+ NPCM8XX_GCR_MFSEL_SET1 = 0x2a0 / sizeof(uint32_t),
+ NPCM8XX_GCR_MFSEL_SET2,
+ NPCM8XX_GCR_MFSEL_SET3,
+ NPCM8XX_GCR_MFSEL_SET4,
+ NPCM8XX_GCR_MFSEL_SET5,
+ NPCM8XX_GCR_MFSEL_SET6,
+ NPCM8XX_GCR_MFSEL_SET7,
+ NPCM8XX_GCR_MFSEL_CLR1 = 0x2c0 / sizeof(uint32_t),
+ NPCM8XX_GCR_MFSEL_CLR2,
+ NPCM8XX_GCR_MFSEL_CLR3,
+ NPCM8XX_GCR_MFSEL_CLR4,
+ NPCM8XX_GCR_MFSEL_CLR5,
+ NPCM8XX_GCR_MFSEL_CLR6,
+ NPCM8XX_GCR_MFSEL_CLR7,
+ NPCM8XX_GCR_WD0RCRLK = 0x400 / sizeof(uint32_t),
+ NPCM8XX_GCR_WD1RCRLK,
+ NPCM8XX_GCR_WD2RCRLK,
+ NPCM8XX_GCR_SWRSTC1LK,
+ NPCM8XX_GCR_SWRSTC2LK,
+ NPCM8XX_GCR_SWRSTC3LK,
+ NPCM8XX_GCR_TIPRSTCLK,
+ NPCM8XX_GCR_CORSTCLK,
+ NPCM8XX_GCR_WD0RCRBLK,
+ NPCM8XX_GCR_WD1RCRBLK,
+ NPCM8XX_GCR_WD2RCRBLK,
+ NPCM8XX_GCR_SWRSTC1BLK,
+ NPCM8XX_GCR_SWRSTC2BLK,
+ NPCM8XX_GCR_SWRSTC3BLK,
+ NPCM8XX_GCR_TIPRSTCBLK,
+ NPCM8XX_GCR_CORSTCBLK,
+ /* 64 scratch pad registers start here. 0xe00 ~ 0xefc */
+ NPCM8XX_GCR_SCRPAD_00 = 0xe00 / sizeof(uint32_t),
+ /* 32 semaphore registers start here. 0xf00 ~ 0xf7c */
+ NPCM8XX_GCR_GP_SEMFR_00 = 0xf00 / sizeof(uint32_t),
+ NPCM8XX_GCR_REGS_END = 0xf80 / sizeof(uint32_t),
+};
+
+static const uint32_t npcm8xx_cold_reset_values[NPCM8XX_GCR_NR_REGS] = {
+ [NPCM8XX_GCR_PDID] = 0x04a35850, /* Arbel A1 */
+ [NPCM8XX_GCR_MISCPE] = 0x0000ffff,
+ [NPCM8XX_GCR_A35_MODE] = 0xfff4ff30,
+ [NPCM8XX_GCR_SPSWC] = 0x00000003,
+ [NPCM8XX_GCR_INTCR] = 0x0010035e,
+ [NPCM8XX_GCR_HIFCR] = 0x0000004e,
+ [NPCM8XX_GCR_SD2SUR1] = 0xfdc80000,
+ [NPCM8XX_GCR_SD2SUR2] = 0x5200b130,
+ [NPCM8XX_GCR_INTCR2] = (1U << 19), /* DDR initialized */
+ [NPCM8XX_GCR_RESSR] = 0x80000000,
+ [NPCM8XX_GCR_DAVCLVLR] = 0x5a00f3cf,
+ [NPCM8XX_GCR_INTCR3] = 0x5e001002,
+ [NPCM8XX_GCR_VSRCR] = 0x00004800,
+ [NPCM8XX_GCR_SCRPAD] = 0x00000008,
+ [NPCM8XX_GCR_USB1PHYCTL] = 0x034730e4,
+ [NPCM8XX_GCR_USB2PHYCTL] = 0x034730e4,
+ [NPCM8XX_GCR_USB3PHYCTL] = 0x034730e4,
+ /* All 32 semaphores should be initialized to 1. */
+ [NPCM8XX_GCR_GP_SEMFR_00...NPCM8XX_GCR_REGS_END - 1] = 0x00000001,
+};
+
static uint64_t npcm_gcr_read(void *opaque, hwaddr offset, unsigned size)
{
uint32_t reg = offset / sizeof(uint32_t);
@@ -261,6 +373,18 @@ static void npcm7xx_gcr_class_init(ObjectClass *klass, void *data)
c->cold_reset_values = npcm7xx_cold_reset_values;
}
+static void npcm8xx_gcr_class_init(ObjectClass *klass, void *data)
+{
+ NPCMGCRClass *c = NPCM_GCR_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ QEMU_BUILD_BUG_ON(NPCM8XX_GCR_REGS_END > NPCM_GCR_MAX_NR_REGS);
+ QEMU_BUILD_BUG_ON(NPCM8XX_GCR_REGS_END != NPCM8XX_GCR_NR_REGS);
+ dc->desc = "NPCM8xx System Global Control Registers";
+ c->nr_regs = NPCM8XX_GCR_NR_REGS;
+ c->cold_reset_values = npcm8xx_cold_reset_values;
+}
+
static const TypeInfo npcm_gcr_info[] = {
{
.name = TYPE_NPCM_GCR,
@@ -276,5 +400,10 @@ static const TypeInfo npcm_gcr_info[] = {
.parent = TYPE_NPCM_GCR,
.class_init = npcm7xx_gcr_class_init,
},
+ {
+ .name = TYPE_NPCM8XX_GCR,
+ .parent = TYPE_NPCM_GCR,
+ .class_init = npcm8xx_gcr_class_init,
+ },
};
DEFINE_TYPES(npcm_gcr_info)
diff --git a/include/hw/misc/npcm_gcr.h b/include/hw/misc/npcm_gcr.h
index 9af24e5cdc..9ac76ca9ab 100644
--- a/include/hw/misc/npcm_gcr.h
+++ b/include/hw/misc/npcm_gcr.h
@@ -1,5 +1,5 @@
/*
- * Nuvoton NPCM7xx System Global Control Registers.
+ * Nuvoton NPCM7xx/8xx System Global Control Registers.
*
* Copyright 2020 Google LLC
*
@@ -54,8 +54,9 @@
* Number of registers in our device state structure. Don't change this without
* incrementing the version_id in the vmstate.
*/
-#define NPCM_GCR_MAX_NR_REGS NPCM7XX_GCR_NR_REGS
+#define NPCM_GCR_MAX_NR_REGS NPCM8XX_GCR_NR_REGS
#define NPCM7XX_GCR_NR_REGS (0x148 / sizeof(uint32_t))
+#define NPCM8XX_GCR_NR_REGS (0xf80 / sizeof(uint32_t))
typedef struct NPCMGCRState {
SysBusDevice parent;
@@ -78,6 +79,7 @@ typedef struct NPCMGCRClass {
#define TYPE_NPCM_GCR "npcm-gcr"
#define TYPE_NPCM7XX_GCR "npcm7xx-gcr"
+#define TYPE_NPCM8XX_GCR "npcm8xx-gcr"
OBJECT_DECLARE_TYPE(NPCMGCRState, NPCMGCRClass, NPCM_GCR)
#endif /* NPCM_GCR_H */
--
2.47.1.613.gc27f4b7a9f-goog
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 08/17] hw/misc: Add support for NPCM8XX GCR
2024-12-26 8:27 ` [PATCH v2 08/17] hw/misc: Add support for NPCM8XX GCR Hao Wu
@ 2025-02-04 15:49 ` Peter Maydell
0 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2025-02-04 15:49 UTC (permalink / raw)
To: Hao Wu
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair
On Thu, 26 Dec 2024 at 08:28, Hao Wu <wuhaotsh@google.com> wrote:
>
> Signed-off-by: Hao Wu <wuhaotsh@google.com>
> ---
> hw/misc/npcm_gcr.c | 131 ++++++++++++++++++++++++++++++++++++-
> include/hw/misc/npcm_gcr.h | 6 +-
> 2 files changed, 134 insertions(+), 3 deletions(-)
>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v2 09/17] hw/misc: Store DRAM size in NPCM8XX GCR Module
2024-12-26 8:27 [PATCH v2 00/17] hw/arm: Add NPCM8XX Support Hao Wu
` (7 preceding siblings ...)
2024-12-26 8:27 ` [PATCH v2 08/17] hw/misc: Add support for NPCM8XX GCR Hao Wu
@ 2024-12-26 8:27 ` Hao Wu
2025-02-04 15:51 ` Peter Maydell
2024-12-26 8:27 ` [PATCH v2 10/17] hw/misc: Support 8-bytes memop in NPCM GCR module Hao Wu
` (7 subsequent siblings)
16 siblings, 1 reply; 35+ messages in thread
From: Hao Wu @ 2024-12-26 8:27 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair, Hao Wu
NPCM8XX boot block stores the DRAM size in SCRPAD_B register in GCR
module. Since we don't simulate a detailed memory controller, we
need to store this information directly similar to the NPCM7XX's
INCTR3 register.
Signed-off-by: Hao Wu <wuhaotsh@google.com>
---
hw/misc/npcm_gcr.c | 24 ++++++++++++++++++++++++
include/hw/misc/npcm_gcr.h | 1 +
2 files changed, 25 insertions(+)
diff --git a/hw/misc/npcm_gcr.c b/hw/misc/npcm_gcr.c
index 52d0fa07ea..a4c9643119 100644
--- a/hw/misc/npcm_gcr.c
+++ b/hw/misc/npcm_gcr.c
@@ -279,6 +279,19 @@ static void npcm7xx_gcr_enter_reset(Object *obj, ResetType type)
s->regs[NPCM7XX_GCR_INTCR3] = s->reset_intcr3;
}
+static void npcm8xx_gcr_enter_reset(Object *obj, ResetType type)
+{
+ NPCMGCRState *s = NPCM_GCR(obj);
+ NPCMGCRClass *c = NPCM_GCR_GET_CLASS(obj);
+
+ memcpy(s->regs, c->cold_reset_values, c->nr_regs * sizeof(uint32_t));
+ /* These 3 registers are at the same location in both 7xx and 8xx. */
+ s->regs[NPCM8XX_GCR_PWRON] = s->reset_pwron;
+ s->regs[NPCM8XX_GCR_MDLR] = s->reset_mdlr;
+ s->regs[NPCM8XX_GCR_INTCR3] = s->reset_intcr3;
+ s->regs[NPCM8XX_GCR_SCRPAD_B] = s->reset_scrpad_b;
+}
+
static void npcm_gcr_realize(DeviceState *dev, Error **errp)
{
ERRP_GUARD();
@@ -322,6 +335,14 @@ static void npcm_gcr_realize(DeviceState *dev, Error **errp)
* https://github.com/Nuvoton-Israel/u-boot/blob/2aef993bd2aafeb5408dbaad0f3ce099ee40c4aa/board/nuvoton/poleg/poleg.c#L244
*/
s->reset_intcr3 |= ctz64(dram_size / NPCM7XX_GCR_MIN_DRAM_SIZE) << 8;
+
+ /*
+ * The boot block starting from 0.0.6 for NPCM8xx SoCs stores the DRAM size
+ * in the SCRPAD2 registers. We need to set this field correctly since
+ * the initialization is skipped as we mentioned above.
+ * https://github.com/Nuvoton-Israel/u-boot/blob/npcm8mnx-v2019.01_tmp/board/nuvoton/arbel/arbel.c#L737
+ */
+ s->reset_scrpad_b = dram_size;
}
static void npcm_gcr_init(Object *obj)
@@ -371,18 +392,21 @@ static void npcm7xx_gcr_class_init(ObjectClass *klass, void *data)
c->nr_regs = NPCM7XX_GCR_NR_REGS;
c->cold_reset_values = npcm7xx_cold_reset_values;
+ rc->phases.enter = npcm7xx_gcr_enter_reset;
}
static void npcm8xx_gcr_class_init(ObjectClass *klass, void *data)
{
NPCMGCRClass *c = NPCM_GCR_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
QEMU_BUILD_BUG_ON(NPCM8XX_GCR_REGS_END > NPCM_GCR_MAX_NR_REGS);
QEMU_BUILD_BUG_ON(NPCM8XX_GCR_REGS_END != NPCM8XX_GCR_NR_REGS);
dc->desc = "NPCM8xx System Global Control Registers";
c->nr_regs = NPCM8XX_GCR_NR_REGS;
c->cold_reset_values = npcm8xx_cold_reset_values;
+ rc->phases.enter = npcm8xx_gcr_enter_reset;
}
static const TypeInfo npcm_gcr_info[] = {
diff --git a/include/hw/misc/npcm_gcr.h b/include/hw/misc/npcm_gcr.h
index 9ac76ca9ab..d81bb9afb2 100644
--- a/include/hw/misc/npcm_gcr.h
+++ b/include/hw/misc/npcm_gcr.h
@@ -68,6 +68,7 @@ typedef struct NPCMGCRState {
uint32_t reset_pwron;
uint32_t reset_mdlr;
uint32_t reset_intcr3;
+ uint32_t reset_scrpad_b;
} NPCMGCRState;
typedef struct NPCMGCRClass {
--
2.47.1.613.gc27f4b7a9f-goog
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 09/17] hw/misc: Store DRAM size in NPCM8XX GCR Module
2024-12-26 8:27 ` [PATCH v2 09/17] hw/misc: Store DRAM size in NPCM8XX GCR Module Hao Wu
@ 2025-02-04 15:51 ` Peter Maydell
0 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2025-02-04 15:51 UTC (permalink / raw)
To: Hao Wu
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, hskinnemoen,
venture, pbonzini, jasowang, alistair
On Thu, 26 Dec 2024 at 08:28, Hao Wu <wuhaotsh@google.com> wrote:
>
> NPCM8XX boot block stores the DRAM size in SCRPAD_B register in GCR
> module. Since we don't simulate a detailed memory controller, we
> need to store this information directly similar to the NPCM7XX's
> INCTR3 register.
>
> Signed-off-by: Hao Wu <wuhaotsh@google.com>
> ---
> hw/misc/npcm_gcr.c | 24 ++++++++++++++++++++++++
> include/hw/misc/npcm_gcr.h | 1 +
> 2 files changed, 25 insertions(+)
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v2 10/17] hw/misc: Support 8-bytes memop in NPCM GCR module
2024-12-26 8:27 [PATCH v2 00/17] hw/arm: Add NPCM8XX Support Hao Wu
` (8 preceding siblings ...)
2024-12-26 8:27 ` [PATCH v2 09/17] hw/misc: Store DRAM size in NPCM8XX GCR Module Hao Wu
@ 2024-12-26 8:27 ` Hao Wu
2025-02-04 15:55 ` Peter Maydell
2024-12-26 8:27 ` [PATCH v2 11/17] hw/misc: Rename npcm7xx_clk to npcm_clk Hao Wu
` (6 subsequent siblings)
16 siblings, 1 reply; 35+ messages in thread
From: Hao Wu @ 2024-12-26 8:27 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair, Hao Wu
The NPCM8xx GCR device can be accessed with 64-bit memory operations.
This patch supports that.
Signed-off-by: Hao Wu <wuhaotsh@google.com>
---
hw/misc/npcm_gcr.c | 94 +++++++++++++++++++++++++++++++++-----------
hw/misc/trace-events | 4 +-
2 files changed, 74 insertions(+), 24 deletions(-)
diff --git a/hw/misc/npcm_gcr.c b/hw/misc/npcm_gcr.c
index a4c9643119..7dfdd3d74b 100644
--- a/hw/misc/npcm_gcr.c
+++ b/hw/misc/npcm_gcr.c
@@ -201,6 +201,7 @@ static uint64_t npcm_gcr_read(void *opaque, hwaddr offset, unsigned size)
uint32_t reg = offset / sizeof(uint32_t);
NPCMGCRState *s = opaque;
NPCMGCRClass *c = NPCM_GCR_GET_CLASS(s);
+ uint64_t value;
if (reg >= c->nr_regs) {
qemu_log_mask(LOG_GUEST_ERROR,
@@ -209,9 +210,21 @@ static uint64_t npcm_gcr_read(void *opaque, hwaddr offset, unsigned size)
return 0;
}
- trace_npcm_gcr_read(offset, s->regs[reg]);
+ switch (size) {
+ case 4:
+ value = s->regs[reg];
+ break;
+
+ case 8:
+ value = s->regs[reg] + (((uint64_t)s->regs[reg + 1]) << 32);
+ break;
+
+ default:
+ g_assert_not_reached();
+ }
- return s->regs[reg];
+ trace_npcm_gcr_read(offset, value);
+ return value;
}
static void npcm_gcr_write(void *opaque, hwaddr offset,
@@ -231,29 +244,65 @@ static void npcm_gcr_write(void *opaque, hwaddr offset,
return;
}
- switch (reg) {
- case NPCM7XX_GCR_PDID:
- case NPCM7XX_GCR_PWRON:
- case NPCM7XX_GCR_INTSR:
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: register @ 0x%04" HWADDR_PRIx " is read-only\n",
- __func__, offset);
- return;
-
- case NPCM7XX_GCR_RESSR:
- case NPCM7XX_GCR_CP2BST:
- /* Write 1 to clear */
- value = s->regs[reg] & ~value;
+ switch (size) {
+ case 4:
+ switch (reg) {
+ case NPCM7XX_GCR_PDID:
+ case NPCM7XX_GCR_PWRON:
+ case NPCM7XX_GCR_INTSR:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: register @ 0x%04" HWADDR_PRIx " is read-only\n",
+ __func__, offset);
+ return;
+
+ case NPCM7XX_GCR_RESSR:
+ case NPCM7XX_GCR_CP2BST:
+ /* Write 1 to clear */
+ value = s->regs[reg] & ~value;
+ break;
+
+ case NPCM7XX_GCR_RLOCKR1:
+ case NPCM7XX_GCR_MDLR:
+ /* Write 1 to set */
+ value |= s->regs[reg];
+ break;
+ };
+ s->regs[reg] = value;
break;
- case NPCM7XX_GCR_RLOCKR1:
- case NPCM7XX_GCR_MDLR:
- /* Write 1 to set */
- value |= s->regs[reg];
+ case 8:
+ s->regs[reg] = value;
+ s->regs[reg + 1] = v >> 32;
break;
- };
- s->regs[reg] = value;
+ default:
+ g_assert_not_reached();
+ }
+}
+
+static bool npcm_gcr_check_mem_op(void *opaque, hwaddr offset,
+ unsigned size, bool is_write,
+ MemTxAttrs attrs)
+{
+ NPCMGCRClass *c = NPCM_GCR_GET_CLASS(opaque);
+
+ if (offset >= c->nr_regs * sizeof(uint32_t)) {
+ return false;
+ }
+
+ switch (size) {
+ case 4:
+ return true;
+ case 8:
+ if (offset >= NPCM8XX_GCR_SCRPAD_00 * sizeof(uint32_t) &&
+ offset < (NPCM8XX_GCR_NR_REGS - 1) * sizeof(uint32_t)) {
+ return true;
+ } else {
+ return false;
+ }
+ default:
+ return false;
+ }
}
static const struct MemoryRegionOps npcm_gcr_ops = {
@@ -262,7 +311,8 @@ static const struct MemoryRegionOps npcm_gcr_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 4,
- .max_access_size = 4,
+ .max_access_size = 8,
+ .accepts = npcm_gcr_check_mem_op,
.unaligned = false,
},
};
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index f2d498e862..59c2d4ecc0 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -135,8 +135,8 @@ npcm7xx_clk_read(uint64_t offset, uint32_t value) " offset: 0x%04" PRIx64 " valu
npcm7xx_clk_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
# npcm_gcr.c
-npcm_gcr_read(uint64_t offset, uint32_t value) " offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
-npcm_gcr_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
+npcm_gcr_read(uint64_t offset, uint64_t value) " offset: 0x%04" PRIx64 " value: 0x%08" PRIx64
+npcm_gcr_write(uint64_t offset, uint64_t value) "offset: 0x%04" PRIx64 " value: 0x%08" PRIx64
# npcm7xx_mft.c
npcm7xx_mft_read(const char *name, uint64_t offset, uint16_t value) "%s: offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
--
2.47.1.613.gc27f4b7a9f-goog
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 10/17] hw/misc: Support 8-bytes memop in NPCM GCR module
2024-12-26 8:27 ` [PATCH v2 10/17] hw/misc: Support 8-bytes memop in NPCM GCR module Hao Wu
@ 2025-02-04 15:55 ` Peter Maydell
0 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2025-02-04 15:55 UTC (permalink / raw)
To: Hao Wu
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, hskinnemoen,
venture, pbonzini, jasowang, alistair
On Thu, 26 Dec 2024 at 08:28, Hao Wu <wuhaotsh@google.com> wrote:
>
> The NPCM8xx GCR device can be accessed with 64-bit memory operations.
> This patch supports that.
>
> Signed-off-by: Hao Wu <wuhaotsh@google.com>
> ---
> hw/misc/npcm_gcr.c | 94 +++++++++++++++++++++++++++++++++-----------
> hw/misc/trace-events | 4 +-
> 2 files changed, 74 insertions(+), 24 deletions(-)
>
> diff --git a/hw/misc/npcm_gcr.c b/hw/misc/npcm_gcr.c
> index a4c9643119..7dfdd3d74b 100644
> --- a/hw/misc/npcm_gcr.c
> +++ b/hw/misc/npcm_gcr.c
> @@ -201,6 +201,7 @@ static uint64_t npcm_gcr_read(void *opaque, hwaddr offset, unsigned size)
> uint32_t reg = offset / sizeof(uint32_t);
> NPCMGCRState *s = opaque;
> NPCMGCRClass *c = NPCM_GCR_GET_CLASS(s);
> + uint64_t value;
>
> if (reg >= c->nr_regs) {
> qemu_log_mask(LOG_GUEST_ERROR,
> @@ -209,9 +210,21 @@ static uint64_t npcm_gcr_read(void *opaque, hwaddr offset, unsigned size)
> return 0;
> }
>
> - trace_npcm_gcr_read(offset, s->regs[reg]);
> + switch (size) {
> + case 4:
> + value = s->regs[reg];
> + break;
> +
> + case 8:
> + value = s->regs[reg] + (((uint64_t)s->regs[reg + 1]) << 32);
Maybe
value = deposit64(s->regs[reg], 32, 32, s->regs[reg + 1]);
?
(Mostly it's just the cast that makes me suggest a rephrase.)
> + break;
> +
> + default:
> + g_assert_not_reached();
> + }
>
> - return s->regs[reg];
> + trace_npcm_gcr_read(offset, value);
> + return value;
> }
>
> static void npcm_gcr_write(void *opaque, hwaddr offset,
> @@ -231,29 +244,65 @@ static void npcm_gcr_write(void *opaque, hwaddr offset,
> return;
> }
>
> - switch (reg) {
> - case NPCM7XX_GCR_PDID:
> - case NPCM7XX_GCR_PWRON:
> - case NPCM7XX_GCR_INTSR:
> - qemu_log_mask(LOG_GUEST_ERROR,
> - "%s: register @ 0x%04" HWADDR_PRIx " is read-only\n",
> - __func__, offset);
> - return;
> -
> - case NPCM7XX_GCR_RESSR:
> - case NPCM7XX_GCR_CP2BST:
> - /* Write 1 to clear */
> - value = s->regs[reg] & ~value;
> + switch (size) {
> + case 4:
> + switch (reg) {
> + case NPCM7XX_GCR_PDID:
> + case NPCM7XX_GCR_PWRON:
> + case NPCM7XX_GCR_INTSR:
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "%s: register @ 0x%04" HWADDR_PRIx " is read-only\n",
> + __func__, offset);
> + return;
> +
> + case NPCM7XX_GCR_RESSR:
> + case NPCM7XX_GCR_CP2BST:
> + /* Write 1 to clear */
> + value = s->regs[reg] & ~value;
> + break;
> +
> + case NPCM7XX_GCR_RLOCKR1:
> + case NPCM7XX_GCR_MDLR:
> + /* Write 1 to set */
> + value |= s->regs[reg];
> + break;
> + };
> + s->regs[reg] = value;
> break;
>
> - case NPCM7XX_GCR_RLOCKR1:
> - case NPCM7XX_GCR_MDLR:
> - /* Write 1 to set */
> - value |= s->regs[reg];
> + case 8:
> + s->regs[reg] = value;
> + s->regs[reg + 1] = v >> 32;
s->regs[reg + 1] = extract64(v, 32, 32);
> break;
> - };
>
> - s->regs[reg] = value;
> + default:
> + g_assert_not_reached();
> + }
> +}
Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v2 11/17] hw/misc: Rename npcm7xx_clk to npcm_clk
2024-12-26 8:27 [PATCH v2 00/17] hw/arm: Add NPCM8XX Support Hao Wu
` (9 preceding siblings ...)
2024-12-26 8:27 ` [PATCH v2 10/17] hw/misc: Support 8-bytes memop in NPCM GCR module Hao Wu
@ 2024-12-26 8:27 ` Hao Wu
2025-02-04 15:56 ` Peter Maydell
2024-12-26 8:27 ` [PATCH v2 12/17] hw/misc: Move NPCM7XX CLK to NPCM CLK Hao Wu
` (5 subsequent siblings)
16 siblings, 1 reply; 35+ messages in thread
From: Hao Wu @ 2024-12-26 8:27 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair, Hao Wu
NPCM7XX and NPCM8XX have a different set of CLK registers. This
commit changes the name of the clk files to be used by both
NPCM7XX and NPCM8XX CLK modules.
Signed-off-by: Hao Wu <wuhaotsh@google.com>
---
hw/misc/meson.build | 2 +-
hw/misc/{npcm7xx_clk.c => npcm_clk.c} | 2 +-
include/hw/arm/npcm7xx.h | 2 +-
include/hw/misc/{npcm7xx_clk.h => npcm_clk.h} | 6 +++---
4 files changed, 6 insertions(+), 6 deletions(-)
rename hw/misc/{npcm7xx_clk.c => npcm_clk.c} (99%)
rename include/hw/misc/{npcm7xx_clk.h => npcm_clk.h} (98%)
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 9bab048849..743066eb96 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -67,7 +67,7 @@ system_ss.add(when: 'CONFIG_IMX', if_true: files(
'imx_rngc.c',
))
system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files(
- 'npcm7xx_clk.c',
+ 'npcm_clk.c',
'npcm_gcr.c',
'npcm7xx_mft.c',
'npcm7xx_pwm.c',
diff --git a/hw/misc/npcm7xx_clk.c b/hw/misc/npcm_clk.c
similarity index 99%
rename from hw/misc/npcm7xx_clk.c
rename to hw/misc/npcm_clk.c
index 46f907b61c..2bcb731099 100644
--- a/hw/misc/npcm7xx_clk.c
+++ b/hw/misc/npcm_clk.c
@@ -16,7 +16,7 @@
#include "qemu/osdep.h"
-#include "hw/misc/npcm7xx_clk.h"
+#include "hw/misc/npcm_clk.h"
#include "hw/timer/npcm7xx_timer.h"
#include "hw/qdev-clock.h"
#include "migration/vmstate.h"
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index 2e708471ec..e80fd91f20 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -23,7 +23,7 @@
#include "hw/gpio/npcm7xx_gpio.h"
#include "hw/i2c/npcm7xx_smbus.h"
#include "hw/mem/npcm7xx_mc.h"
-#include "hw/misc/npcm7xx_clk.h"
+#include "hw/misc/npcm_clk.h"
#include "hw/misc/npcm_gcr.h"
#include "hw/misc/npcm7xx_mft.h"
#include "hw/misc/npcm7xx_pwm.h"
diff --git a/include/hw/misc/npcm7xx_clk.h b/include/hw/misc/npcm_clk.h
similarity index 98%
rename from include/hw/misc/npcm7xx_clk.h
rename to include/hw/misc/npcm_clk.h
index 5ed4a4672b..0aef81e10c 100644
--- a/include/hw/misc/npcm7xx_clk.h
+++ b/include/hw/misc/npcm_clk.h
@@ -13,8 +13,8 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
-#ifndef NPCM7XX_CLK_H
-#define NPCM7XX_CLK_H
+#ifndef NPCM_CLK_H
+#define NPCM_CLK_H
#include "exec/memory.h"
#include "hw/clock.h"
@@ -177,4 +177,4 @@ struct NPCM7xxCLKState {
#define TYPE_NPCM7XX_CLK "npcm7xx-clk"
OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxCLKState, NPCM7XX_CLK)
-#endif /* NPCM7XX_CLK_H */
+#endif /* NPCM_CLK_H */
--
2.47.1.613.gc27f4b7a9f-goog
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 11/17] hw/misc: Rename npcm7xx_clk to npcm_clk
2024-12-26 8:27 ` [PATCH v2 11/17] hw/misc: Rename npcm7xx_clk to npcm_clk Hao Wu
@ 2025-02-04 15:56 ` Peter Maydell
0 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2025-02-04 15:56 UTC (permalink / raw)
To: Hao Wu
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, hskinnemoen,
venture, pbonzini, jasowang, alistair
On Thu, 26 Dec 2024 at 08:28, Hao Wu <wuhaotsh@google.com> wrote:
>
> NPCM7XX and NPCM8XX have a different set of CLK registers. This
> commit changes the name of the clk files to be used by both
> NPCM7XX and NPCM8XX CLK modules.
>
> Signed-off-by: Hao Wu <wuhaotsh@google.com>
> ---
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v2 12/17] hw/misc: Move NPCM7XX CLK to NPCM CLK
2024-12-26 8:27 [PATCH v2 00/17] hw/arm: Add NPCM8XX Support Hao Wu
` (10 preceding siblings ...)
2024-12-26 8:27 ` [PATCH v2 11/17] hw/misc: Rename npcm7xx_clk to npcm_clk Hao Wu
@ 2024-12-26 8:27 ` Hao Wu
2025-02-04 16:03 ` Peter Maydell
2024-12-26 8:27 ` [PATCH v2 13/17] hw/misc: Add nr_regs and cold_reset_values " Hao Wu
` (4 subsequent siblings)
16 siblings, 1 reply; 35+ messages in thread
From: Hao Wu @ 2024-12-26 8:27 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair, Hao Wu
A lot of NPCM7XX and NPCM8XX CLK modules share the same code,
this commit moves the NPCM7XX CLK to NPCM CLK for these
properties.
Signed-off-by: Hao Wu <wuhaotsh@google.com>
---
hw/misc/npcm_clk.c | 106 +++++++++++++++++++++----------------
hw/misc/trace-events | 6 +--
include/hw/arm/npcm7xx.h | 2 +-
include/hw/misc/npcm_clk.h | 22 ++++----
4 files changed, 76 insertions(+), 60 deletions(-)
diff --git a/hw/misc/npcm_clk.c b/hw/misc/npcm_clk.c
index 2bcb731099..0ecf0df3bb 100644
--- a/hw/misc/npcm_clk.c
+++ b/hw/misc/npcm_clk.c
@@ -198,7 +198,7 @@ static NPCM7xxClockPLL find_pll_by_reg(enum NPCM7xxCLKRegisters reg)
}
}
-static void npcm7xx_clk_update_all_plls(NPCM7xxCLKState *clk)
+static void npcm7xx_clk_update_all_plls(NPCMCLKState *clk)
{
int i;
@@ -207,7 +207,7 @@ static void npcm7xx_clk_update_all_plls(NPCM7xxCLKState *clk)
}
}
-static void npcm7xx_clk_update_all_sels(NPCM7xxCLKState *clk)
+static void npcm7xx_clk_update_all_sels(NPCMCLKState *clk)
{
int i;
@@ -216,7 +216,7 @@ static void npcm7xx_clk_update_all_sels(NPCM7xxCLKState *clk)
}
}
-static void npcm7xx_clk_update_all_dividers(NPCM7xxCLKState *clk)
+static void npcm7xx_clk_update_all_dividers(NPCMCLKState *clk)
{
int i;
@@ -225,7 +225,7 @@ static void npcm7xx_clk_update_all_dividers(NPCM7xxCLKState *clk)
}
}
-static void npcm7xx_clk_update_all_clocks(NPCM7xxCLKState *clk)
+static void npcm7xx_clk_update_all_clocks(NPCMCLKState *clk)
{
clock_update_hz(clk->clkref, NPCM7XX_CLOCK_REF_HZ);
npcm7xx_clk_update_all_plls(clk);
@@ -635,7 +635,7 @@ static void npcm7xx_clk_divider_init(Object *obj)
}
static void npcm7xx_init_clock_pll(NPCM7xxClockPLLState *pll,
- NPCM7xxCLKState *clk, const PLLInitInfo *init_info)
+ NPCMCLKState *clk, const PLLInitInfo *init_info)
{
pll->name = init_info->name;
pll->clk = clk;
@@ -647,7 +647,7 @@ static void npcm7xx_init_clock_pll(NPCM7xxClockPLLState *pll,
}
static void npcm7xx_init_clock_sel(NPCM7xxClockSELState *sel,
- NPCM7xxCLKState *clk, const SELInitInfo *init_info)
+ NPCMCLKState *clk, const SELInitInfo *init_info)
{
int input_size = init_info->input_size;
@@ -664,7 +664,7 @@ static void npcm7xx_init_clock_sel(NPCM7xxClockSELState *sel,
}
static void npcm7xx_init_clock_divider(NPCM7xxClockDividerState *div,
- NPCM7xxCLKState *clk, const DividerInitInfo *init_info)
+ NPCMCLKState *clk, const DividerInitInfo *init_info)
{
div->name = init_info->name;
div->clk = clk;
@@ -683,7 +683,7 @@ static void npcm7xx_init_clock_divider(NPCM7xxClockDividerState *div,
}
}
-static Clock *npcm7xx_get_clock(NPCM7xxCLKState *clk, ClockSrcType type,
+static Clock *npcm7xx_get_clock(NPCMCLKState *clk, ClockSrcType type,
int index)
{
switch (type) {
@@ -700,7 +700,7 @@ static Clock *npcm7xx_get_clock(NPCM7xxCLKState *clk, ClockSrcType type,
}
}
-static void npcm7xx_connect_clocks(NPCM7xxCLKState *clk)
+static void npcm7xx_connect_clocks(NPCMCLKState *clk)
{
int i, j;
Clock *src;
@@ -724,10 +724,10 @@ static void npcm7xx_connect_clocks(NPCM7xxCLKState *clk)
}
}
-static uint64_t npcm7xx_clk_read(void *opaque, hwaddr offset, unsigned size)
+static uint64_t npcm_clk_read(void *opaque, hwaddr offset, unsigned size)
{
uint32_t reg = offset / sizeof(uint32_t);
- NPCM7xxCLKState *s = opaque;
+ NPCMCLKState *s = opaque;
int64_t now_ns;
uint32_t value = 0;
@@ -766,19 +766,19 @@ static uint64_t npcm7xx_clk_read(void *opaque, hwaddr offset, unsigned size)
break;
};
- trace_npcm7xx_clk_read(offset, value);
+ trace_npcm_clk_read(offset, value);
return value;
}
-static void npcm7xx_clk_write(void *opaque, hwaddr offset,
+static void npcm_clk_write(void *opaque, hwaddr offset,
uint64_t v, unsigned size)
{
uint32_t reg = offset / sizeof(uint32_t);
- NPCM7xxCLKState *s = opaque;
+ NPCMCLKState *s = opaque;
uint32_t value = v;
- trace_npcm7xx_clk_write(offset, value);
+ trace_npcm_clk_write(offset, value);
if (reg >= NPCM7XX_CLK_NR_REGS) {
qemu_log_mask(LOG_GUEST_ERROR,
@@ -842,7 +842,7 @@ static void npcm7xx_clk_write(void *opaque, hwaddr offset,
static void npcm7xx_clk_perform_watchdog_reset(void *opaque, int n,
int level)
{
- NPCM7xxCLKState *clk = NPCM7XX_CLK(opaque);
+ NPCMCLKState *clk = NPCM_CLK(opaque);
uint32_t rcr;
g_assert(n >= 0 && n <= NPCM7XX_NR_WATCHDOGS);
@@ -856,9 +856,9 @@ static void npcm7xx_clk_perform_watchdog_reset(void *opaque, int n,
}
}
-static const struct MemoryRegionOps npcm7xx_clk_ops = {
- .read = npcm7xx_clk_read,
- .write = npcm7xx_clk_write,
+static const struct MemoryRegionOps npcm_clk_ops = {
+ .read = npcm_clk_read,
+ .write = npcm_clk_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 4,
@@ -867,9 +867,9 @@ static const struct MemoryRegionOps npcm7xx_clk_ops = {
},
};
-static void npcm7xx_clk_enter_reset(Object *obj, ResetType type)
+static void npcm_clk_enter_reset(Object *obj, ResetType type)
{
- NPCM7xxCLKState *s = NPCM7XX_CLK(obj);
+ NPCMCLKState *s = NPCM_CLK(obj);
QEMU_BUILD_BUG_ON(sizeof(s->regs) != sizeof(cold_reset_values));
@@ -882,7 +882,7 @@ static void npcm7xx_clk_enter_reset(Object *obj, ResetType type)
*/
}
-static void npcm7xx_clk_init_clock_hierarchy(NPCM7xxCLKState *s)
+static void npcm7xx_clk_init_clock_hierarchy(NPCMCLKState *s)
{
int i;
@@ -918,19 +918,19 @@ static void npcm7xx_clk_init_clock_hierarchy(NPCM7xxCLKState *s)
clock_update_hz(s->clkref, NPCM7XX_CLOCK_REF_HZ);
}
-static void npcm7xx_clk_init(Object *obj)
+static void npcm_clk_init(Object *obj)
{
- NPCM7xxCLKState *s = NPCM7XX_CLK(obj);
+ NPCMCLKState *s = NPCM_CLK(obj);
- memory_region_init_io(&s->iomem, obj, &npcm7xx_clk_ops, s,
- TYPE_NPCM7XX_CLK, 4 * KiB);
+ memory_region_init_io(&s->iomem, obj, &npcm_clk_ops, s,
+ TYPE_NPCM_CLK, 4 * KiB);
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
}
-static int npcm7xx_clk_post_load(void *opaque, int version_id)
+static int npcm_clk_post_load(void *opaque, int version_id)
{
if (version_id >= 1) {
- NPCM7xxCLKState *clk = opaque;
+ NPCMCLKState *clk = opaque;
npcm7xx_clk_update_all_clocks(clk);
}
@@ -938,10 +938,10 @@ static int npcm7xx_clk_post_load(void *opaque, int version_id)
return 0;
}
-static void npcm7xx_clk_realize(DeviceState *dev, Error **errp)
+static void npcm_clk_realize(DeviceState *dev, Error **errp)
{
int i;
- NPCM7xxCLKState *s = NPCM7XX_CLK(dev);
+ NPCMCLKState *s = NPCM_CLK(dev);
qdev_init_gpio_in_named(DEVICE(s), npcm7xx_clk_perform_watchdog_reset,
NPCM7XX_WATCHDOG_RESET_GPIO_IN, NPCM7XX_NR_WATCHDOGS);
@@ -996,15 +996,15 @@ static const VMStateDescription vmstate_npcm7xx_clk_divider = {
},
};
-static const VMStateDescription vmstate_npcm7xx_clk = {
- .name = "npcm7xx-clk",
- .version_id = 1,
- .minimum_version_id = 1,
- .post_load = npcm7xx_clk_post_load,
+static const VMStateDescription vmstate_npcm_clk = {
+ .name = "npcm-clk",
+ .version_id = 2,
+ .minimum_version_id = 2,
+ .post_load = npcm_clk_post_load,
.fields = (const VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, NPCM7xxCLKState, NPCM7XX_CLK_NR_REGS),
- VMSTATE_INT64(ref_ns, NPCM7xxCLKState),
- VMSTATE_CLOCK(clkref, NPCM7xxCLKState),
+ VMSTATE_UINT32_ARRAY(regs, NPCMCLKState, NPCM_CLK_MAX_NR_REGS),
+ VMSTATE_INT64(ref_ns, NPCMCLKState),
+ VMSTATE_CLOCK(clkref, NPCMCLKState),
VMSTATE_END_OF_LIST(),
},
};
@@ -1033,17 +1033,23 @@ static void npcm7xx_clk_divider_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_npcm7xx_clk_divider;
}
-static void npcm7xx_clk_class_init(ObjectClass *klass, void *data)
+static void npcm_clk_class_init(ObjectClass *klass, void *data)
{
ResettableClass *rc = RESETTABLE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- QEMU_BUILD_BUG_ON(NPCM7XX_CLK_REGS_END > NPCM7XX_CLK_NR_REGS);
+ dc->vmsd = &vmstate_npcm_clk;
+ dc->realize = npcm_clk_realize;
+ rc->phases.enter = npcm_clk_enter_reset;
+}
+
+static void npcm7xx_clk_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ QEMU_BUILD_BUG_ON(NPCM7XX_CLK_REGS_END > NPCM_CLK_MAX_NR_REGS);
+ QEMU_BUILD_BUG_ON(NPCM7XX_CLK_REGS_END != NPCM7XX_CLK_NR_REGS);
dc->desc = "NPCM7xx Clock Control Registers";
- dc->vmsd = &vmstate_npcm7xx_clk;
- dc->realize = npcm7xx_clk_realize;
- rc->phases.enter = npcm7xx_clk_enter_reset;
}
static const TypeInfo npcm7xx_clk_pll_info = {
@@ -1070,11 +1076,18 @@ static const TypeInfo npcm7xx_clk_divider_info = {
.class_init = npcm7xx_clk_divider_class_init,
};
+static const TypeInfo npcm_clk_info = {
+ .name = TYPE_NPCM_CLK,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(NPCMCLKState),
+ .instance_init = npcm_clk_init,
+ .class_init = npcm_clk_class_init,
+ .abstract = true,
+};
+
static const TypeInfo npcm7xx_clk_info = {
.name = TYPE_NPCM7XX_CLK,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(NPCM7xxCLKState),
- .instance_init = npcm7xx_clk_init,
+ .parent = TYPE_NPCM_CLK,
.class_init = npcm7xx_clk_class_init,
};
@@ -1083,6 +1096,7 @@ static void npcm7xx_clk_register_type(void)
type_register_static(&npcm7xx_clk_pll_info);
type_register_static(&npcm7xx_clk_sel_info);
type_register_static(&npcm7xx_clk_divider_info);
+ type_register_static(&npcm_clk_info);
type_register_static(&npcm7xx_clk_info);
}
type_init(npcm7xx_clk_register_type);
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index 59c2d4ecc0..6b313e4f88 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -130,9 +130,9 @@ mos6522_set_sr_int(void) "set sr_int"
mos6522_write(uint64_t addr, const char *name, uint64_t val) "reg=0x%"PRIx64 " [%s] val=0x%"PRIx64
mos6522_read(uint64_t addr, const char *name, unsigned val) "reg=0x%"PRIx64 " [%s] val=0x%x"
-# npcm7xx_clk.c
-npcm7xx_clk_read(uint64_t offset, uint32_t value) " offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
-npcm7xx_clk_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
+# npcm_clk.c
+npcm_clk_read(uint64_t offset, uint32_t value) " offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
+npcm_clk_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
# npcm_gcr.c
npcm_gcr_read(uint64_t offset, uint64_t value) " offset: 0x%04" PRIx64 " value: 0x%08" PRIx64
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index e80fd91f20..56536565b7 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -90,7 +90,7 @@ struct NPCM7xxState {
MemoryRegion *dram;
NPCMGCRState gcr;
- NPCM7xxCLKState clk;
+ NPCMCLKState clk;
NPCM7xxTimerCtrlState tim[3];
NPCM7xxADCState adc;
NPCM7xxPWMState pwm[NPCM7XX_NR_PWM_MODULES];
diff --git a/include/hw/misc/npcm_clk.h b/include/hw/misc/npcm_clk.h
index 0aef81e10c..db03b46a52 100644
--- a/include/hw/misc/npcm_clk.h
+++ b/include/hw/misc/npcm_clk.h
@@ -20,11 +20,12 @@
#include "hw/clock.h"
#include "hw/sysbus.h"
+#define NPCM7XX_CLK_NR_REGS (0x70 / sizeof(uint32_t))
/*
- * Number of registers in our device state structure. Don't change this without
- * incrementing the version_id in the vmstate.
+ * Number of maximum registers in NPCM device state structure. Don't change
+ * this without incrementing the version_id in the vmstate.
*/
-#define NPCM7XX_CLK_NR_REGS (0x70 / sizeof(uint32_t))
+#define NPCM_CLK_MAX_NR_REGS NPCM7XX_CLK_NR_REGS
#define NPCM7XX_WATCHDOG_RESET_GPIO_IN "npcm7xx-clk-watchdog-reset-gpio-in"
@@ -80,7 +81,7 @@ typedef enum NPCM7xxClockDivider {
NPCM7XX_CLOCK_NR_DIVIDERS,
} NPCM7xxClockConverter;
-typedef struct NPCM7xxCLKState NPCM7xxCLKState;
+typedef struct NPCMCLKState NPCMCLKState;
/**
* struct NPCM7xxClockPLLState - A PLL module in CLK module.
@@ -94,7 +95,7 @@ typedef struct NPCM7xxClockPLLState {
DeviceState parent;
const char *name;
- NPCM7xxCLKState *clk;
+ NPCMCLKState *clk;
Clock *clock_in;
Clock *clock_out;
@@ -115,7 +116,7 @@ typedef struct NPCM7xxClockSELState {
DeviceState parent;
const char *name;
- NPCM7xxCLKState *clk;
+ NPCMCLKState *clk;
uint8_t input_size;
Clock *clock_in[NPCM7XX_CLK_SEL_MAX_INPUT];
Clock *clock_out;
@@ -140,7 +141,7 @@ typedef struct NPCM7xxClockDividerState {
DeviceState parent;
const char *name;
- NPCM7xxCLKState *clk;
+ NPCMCLKState *clk;
Clock *clock_in;
Clock *clock_out;
@@ -155,7 +156,7 @@ typedef struct NPCM7xxClockDividerState {
};
} NPCM7xxClockDividerState;
-struct NPCM7xxCLKState {
+struct NPCMCLKState {
SysBusDevice parent;
MemoryRegion iomem;
@@ -165,7 +166,7 @@ struct NPCM7xxCLKState {
NPCM7xxClockSELState sels[NPCM7XX_CLOCK_NR_SELS];
NPCM7xxClockDividerState dividers[NPCM7XX_CLOCK_NR_DIVIDERS];
- uint32_t regs[NPCM7XX_CLK_NR_REGS];
+ uint32_t regs[NPCM_CLK_MAX_NR_REGS];
/* Time reference for SECCNT and CNTR25M, initialized by power on reset */
int64_t ref_ns;
@@ -174,7 +175,8 @@ struct NPCM7xxCLKState {
Clock *clkref;
};
+#define TYPE_NPCM_CLK "npcm-clk"
+OBJECT_DECLARE_SIMPLE_TYPE(NPCMCLKState, NPCM_CLK)
#define TYPE_NPCM7XX_CLK "npcm7xx-clk"
-OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxCLKState, NPCM7XX_CLK)
#endif /* NPCM_CLK_H */
--
2.47.1.613.gc27f4b7a9f-goog
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 12/17] hw/misc: Move NPCM7XX CLK to NPCM CLK
2024-12-26 8:27 ` [PATCH v2 12/17] hw/misc: Move NPCM7XX CLK to NPCM CLK Hao Wu
@ 2025-02-04 16:03 ` Peter Maydell
0 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2025-02-04 16:03 UTC (permalink / raw)
To: Hao Wu
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, hskinnemoen,
venture, pbonzini, jasowang, alistair
On Thu, 26 Dec 2024 at 08:28, Hao Wu <wuhaotsh@google.com> wrote:
>
> A lot of NPCM7XX and NPCM8XX CLK modules share the same code,
> this commit moves the NPCM7XX CLK to NPCM CLK for these
> properties.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v2 13/17] hw/misc: Add nr_regs and cold_reset_values to NPCM CLK
2024-12-26 8:27 [PATCH v2 00/17] hw/arm: Add NPCM8XX Support Hao Wu
` (11 preceding siblings ...)
2024-12-26 8:27 ` [PATCH v2 12/17] hw/misc: Move NPCM7XX CLK to NPCM CLK Hao Wu
@ 2024-12-26 8:27 ` Hao Wu
2025-02-04 16:04 ` Peter Maydell
2024-12-26 8:27 ` [PATCH v2 14/17] hw/misc: Support NPCM8XX CLK Module Registers Hao Wu
` (3 subsequent siblings)
16 siblings, 1 reply; 35+ messages in thread
From: Hao Wu @ 2024-12-26 8:27 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair, Hao Wu
These 2 values are different between NPCM7XX and NPCM8XX
CLKs. So we add them to the class and assign different values
to them.
Signed-off-by: Hao Wu <wuhaotsh@google.com>
---
hw/misc/npcm_clk.c | 17 +++++++++++------
include/hw/misc/npcm_clk.h | 9 ++++++++-
2 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/hw/misc/npcm_clk.c b/hw/misc/npcm_clk.c
index 0ecf0df3bb..eee754d31f 100644
--- a/hw/misc/npcm_clk.c
+++ b/hw/misc/npcm_clk.c
@@ -81,7 +81,7 @@ enum NPCM7xxCLKRegisters {
* All are loaded on power-up reset. CLKENx and SWRSTR should also be loaded on
* core domain reset, but this reset type is not yet supported by QEMU.
*/
-static const uint32_t cold_reset_values[NPCM7XX_CLK_NR_REGS] = {
+static const uint32_t npcm7xx_cold_reset_values[NPCM7XX_CLK_NR_REGS] = {
[NPCM7XX_CLK_CLKEN1] = 0xffffffff,
[NPCM7XX_CLK_CLKSEL] = 0x004aaaaa,
[NPCM7XX_CLK_CLKDIV1] = 0x5413f855,
@@ -728,10 +728,11 @@ static uint64_t npcm_clk_read(void *opaque, hwaddr offset, unsigned size)
{
uint32_t reg = offset / sizeof(uint32_t);
NPCMCLKState *s = opaque;
+ NPCMCLKClass *c = NPCM_CLK_GET_CLASS(s);
int64_t now_ns;
uint32_t value = 0;
- if (reg >= NPCM7XX_CLK_NR_REGS) {
+ if (reg >= c->nr_regs) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: offset 0x%04" HWADDR_PRIx " out of range\n",
__func__, offset);
@@ -776,11 +777,12 @@ static void npcm_clk_write(void *opaque, hwaddr offset,
{
uint32_t reg = offset / sizeof(uint32_t);
NPCMCLKState *s = opaque;
+ NPCMCLKClass *c = NPCM_CLK_GET_CLASS(s);
uint32_t value = v;
trace_npcm_clk_write(offset, value);
- if (reg >= NPCM7XX_CLK_NR_REGS) {
+ if (reg >= c->nr_regs) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: offset 0x%04" HWADDR_PRIx " out of range\n",
__func__, offset);
@@ -870,10 +872,9 @@ static const struct MemoryRegionOps npcm_clk_ops = {
static void npcm_clk_enter_reset(Object *obj, ResetType type)
{
NPCMCLKState *s = NPCM_CLK(obj);
+ NPCMCLKClass *c = NPCM_CLK_GET_CLASS(s);
- QEMU_BUILD_BUG_ON(sizeof(s->regs) != sizeof(cold_reset_values));
-
- memcpy(s->regs, cold_reset_values, sizeof(cold_reset_values));
+ memcpy(s->regs, c->cold_reset_values, sizeof(s->regs));
s->ref_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
npcm7xx_clk_update_all_clocks(s);
/*
@@ -1045,11 +1046,14 @@ static void npcm_clk_class_init(ObjectClass *klass, void *data)
static void npcm7xx_clk_class_init(ObjectClass *klass, void *data)
{
+ NPCMCLKClass *c = NPCM_CLK_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
QEMU_BUILD_BUG_ON(NPCM7XX_CLK_REGS_END > NPCM_CLK_MAX_NR_REGS);
QEMU_BUILD_BUG_ON(NPCM7XX_CLK_REGS_END != NPCM7XX_CLK_NR_REGS);
dc->desc = "NPCM7xx Clock Control Registers";
+ c->nr_regs = NPCM7XX_CLK_NR_REGS;
+ c->cold_reset_values = npcm7xx_cold_reset_values;
}
static const TypeInfo npcm7xx_clk_pll_info = {
@@ -1081,6 +1085,7 @@ static const TypeInfo npcm_clk_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(NPCMCLKState),
.instance_init = npcm_clk_init,
+ .class_size = sizeof(NPCMCLKClass),
.class_init = npcm_clk_class_init,
.abstract = true,
};
diff --git a/include/hw/misc/npcm_clk.h b/include/hw/misc/npcm_clk.h
index db03b46a52..f47614ac8d 100644
--- a/include/hw/misc/npcm_clk.h
+++ b/include/hw/misc/npcm_clk.h
@@ -175,8 +175,15 @@ struct NPCMCLKState {
Clock *clkref;
};
+typedef struct NPCMCLKClass {
+ SysBusDeviceClass parent;
+
+ size_t nr_regs;
+ const uint32_t *cold_reset_values;
+} NPCMCLKClass;
+
#define TYPE_NPCM_CLK "npcm-clk"
-OBJECT_DECLARE_SIMPLE_TYPE(NPCMCLKState, NPCM_CLK)
+OBJECT_DECLARE_TYPE(NPCMCLKState, NPCMCLKClass, NPCM_CLK)
#define TYPE_NPCM7XX_CLK "npcm7xx-clk"
#endif /* NPCM_CLK_H */
--
2.47.1.613.gc27f4b7a9f-goog
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 13/17] hw/misc: Add nr_regs and cold_reset_values to NPCM CLK
2024-12-26 8:27 ` [PATCH v2 13/17] hw/misc: Add nr_regs and cold_reset_values " Hao Wu
@ 2025-02-04 16:04 ` Peter Maydell
0 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2025-02-04 16:04 UTC (permalink / raw)
To: Hao Wu
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair
On Thu, 26 Dec 2024 at 08:28, Hao Wu <wuhaotsh@google.com> wrote:
>
> These 2 values are different between NPCM7XX and NPCM8XX
> CLKs. So we add them to the class and assign different values
> to them.
>
> Signed-off-by: Hao Wu <wuhaotsh@google.com>
> ---
> hw/misc/npcm_clk.c | 17 +++++++++++------
> include/hw/misc/npcm_clk.h | 9 ++++++++-
> 2 files changed, 19 insertions(+), 7 deletions(-)
>
> @@ -870,10 +872,9 @@ static const struct MemoryRegionOps npcm_clk_ops = {
> static void npcm_clk_enter_reset(Object *obj, ResetType type)
> {
> NPCMCLKState *s = NPCM_CLK(obj);
> + NPCMCLKClass *c = NPCM_CLK_GET_CLASS(s);
>
> - QEMU_BUILD_BUG_ON(sizeof(s->regs) != sizeof(cold_reset_values));
> -
> - memcpy(s->regs, cold_reset_values, sizeof(cold_reset_values));
> + memcpy(s->regs, c->cold_reset_values, sizeof(s->regs));
Same remark about an assert as in the other patch.
Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v2 14/17] hw/misc: Support NPCM8XX CLK Module Registers
2024-12-26 8:27 [PATCH v2 00/17] hw/arm: Add NPCM8XX Support Hao Wu
` (12 preceding siblings ...)
2024-12-26 8:27 ` [PATCH v2 13/17] hw/misc: Add nr_regs and cold_reset_values " Hao Wu
@ 2024-12-26 8:27 ` Hao Wu
2025-02-04 16:05 ` Peter Maydell
2024-12-26 8:27 ` [PATCH v2 15/17] hw/net: Add NPCM8XX PCS Module Hao Wu
` (2 subsequent siblings)
16 siblings, 1 reply; 35+ messages in thread
From: Hao Wu @ 2024-12-26 8:27 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair, Hao Wu
NPCM8XX adds a few new registers and have a different set of reset
values to the CLK modules. This patch supports them.
This patch doesn't support the new clock values generated by these
registers. Currently no modules use these new clock values so they
are not necessary at this point.
Implementation of these clocks might be required when implementing
these modules.
Signed-off-by: Hao Wu <wuhaotsh@google.com>
Reviewed-by: Titus Rwantare<titusr@google.com>
---
hw/misc/npcm_clk.c | 113 ++++++++++++++++++++++++++++++++++++-
include/hw/misc/npcm_clk.h | 10 +++-
2 files changed, 120 insertions(+), 3 deletions(-)
diff --git a/hw/misc/npcm_clk.c b/hw/misc/npcm_clk.c
index eee754d31f..af127991da 100644
--- a/hw/misc/npcm_clk.c
+++ b/hw/misc/npcm_clk.c
@@ -1,5 +1,5 @@
/*
- * Nuvoton NPCM7xx Clock Control Registers.
+ * Nuvoton NPCM7xx/8xx Clock Control Registers.
*
* Copyright 2020 Google LLC
*
@@ -75,6 +75,58 @@ enum NPCM7xxCLKRegisters {
NPCM7XX_CLK_REGS_END,
};
+enum NPCM8xxCLKRegisters {
+ NPCM8XX_CLK_CLKEN1,
+ NPCM8XX_CLK_CLKSEL,
+ NPCM8XX_CLK_CLKDIV1,
+ NPCM8XX_CLK_PLLCON0,
+ NPCM8XX_CLK_PLLCON1,
+ NPCM8XX_CLK_SWRSTR,
+ NPCM8XX_CLK_IPSRST1 = 0x20 / sizeof(uint32_t),
+ NPCM8XX_CLK_IPSRST2,
+ NPCM8XX_CLK_CLKEN2,
+ NPCM8XX_CLK_CLKDIV2,
+ NPCM8XX_CLK_CLKEN3,
+ NPCM8XX_CLK_IPSRST3,
+ NPCM8XX_CLK_WD0RCR,
+ NPCM8XX_CLK_WD1RCR,
+ NPCM8XX_CLK_WD2RCR,
+ NPCM8XX_CLK_SWRSTC1,
+ NPCM8XX_CLK_SWRSTC2,
+ NPCM8XX_CLK_SWRSTC3,
+ NPCM8XX_CLK_TIPRSTC,
+ NPCM8XX_CLK_PLLCON2,
+ NPCM8XX_CLK_CLKDIV3,
+ NPCM8XX_CLK_CORSTC,
+ NPCM8XX_CLK_PLLCONG,
+ NPCM8XX_CLK_AHBCKFI,
+ NPCM8XX_CLK_SECCNT,
+ NPCM8XX_CLK_CNTR25M,
+ /* Registers unique to NPCM8XX SoC */
+ NPCM8XX_CLK_CLKEN4,
+ NPCM8XX_CLK_IPSRST4,
+ NPCM8XX_CLK_BUSTO,
+ NPCM8XX_CLK_CLKDIV4,
+ NPCM8XX_CLK_WD0RCRB,
+ NPCM8XX_CLK_WD1RCRB,
+ NPCM8XX_CLK_WD2RCRB,
+ NPCM8XX_CLK_SWRSTC1B,
+ NPCM8XX_CLK_SWRSTC2B,
+ NPCM8XX_CLK_SWRSTC3B,
+ NPCM8XX_CLK_TIPRSTCB,
+ NPCM8XX_CLK_CORSTCB,
+ NPCM8XX_CLK_IPSRSTDIS1,
+ NPCM8XX_CLK_IPSRSTDIS2,
+ NPCM8XX_CLK_IPSRSTDIS3,
+ NPCM8XX_CLK_IPSRSTDIS4,
+ NPCM8XX_CLK_CLKENDIS1,
+ NPCM8XX_CLK_CLKENDIS2,
+ NPCM8XX_CLK_CLKENDIS3,
+ NPCM8XX_CLK_CLKENDIS4,
+ NPCM8XX_CLK_THRTL_CNT,
+ NPCM8XX_CLK_REGS_END,
+};
+
/*
* These reset values were taken from version 0.91 of the NPCM750R data sheet.
*
@@ -103,6 +155,46 @@ static const uint32_t npcm7xx_cold_reset_values[NPCM7XX_CLK_NR_REGS] = {
[NPCM7XX_CLK_AHBCKFI] = 0x000000c8,
};
+/*
+ * These reset values were taken from version 0.92 of the NPCM8xx data sheet.
+ */
+static const uint32_t npcm8xx_cold_reset_values[NPCM8XX_CLK_NR_REGS] = {
+ [NPCM8XX_CLK_CLKEN1] = 0xffffffff,
+ [NPCM8XX_CLK_CLKSEL] = 0x154aaaaa,
+ [NPCM8XX_CLK_CLKDIV1] = 0x5413f855,
+ [NPCM8XX_CLK_PLLCON0] = 0x00222101 | PLLCON_LOKI,
+ [NPCM8XX_CLK_PLLCON1] = 0x00202101 | PLLCON_LOKI,
+ [NPCM8XX_CLK_IPSRST1] = 0x00001000,
+ [NPCM8XX_CLK_IPSRST2] = 0x80000000,
+ [NPCM8XX_CLK_CLKEN2] = 0xffffffff,
+ [NPCM8XX_CLK_CLKDIV2] = 0xaa4f8f9f,
+ [NPCM8XX_CLK_CLKEN3] = 0xffffffff,
+ [NPCM8XX_CLK_IPSRST3] = 0x03000000,
+ [NPCM8XX_CLK_WD0RCR] = 0xffffffff,
+ [NPCM8XX_CLK_WD1RCR] = 0xffffffff,
+ [NPCM8XX_CLK_WD2RCR] = 0xffffffff,
+ [NPCM8XX_CLK_SWRSTC1] = 0x00000003,
+ [NPCM8XX_CLK_SWRSTC2] = 0x00000001,
+ [NPCM8XX_CLK_SWRSTC3] = 0x00000001,
+ [NPCM8XX_CLK_TIPRSTC] = 0x00000001,
+ [NPCM8XX_CLK_PLLCON2] = 0x00c02105 | PLLCON_LOKI,
+ [NPCM8XX_CLK_CLKDIV3] = 0x00009100,
+ [NPCM8XX_CLK_CORSTC] = 0x04000003,
+ [NPCM8XX_CLK_PLLCONG] = 0x01228606 | PLLCON_LOKI,
+ [NPCM8XX_CLK_AHBCKFI] = 0x000000c8,
+ [NPCM8XX_CLK_CLKEN4] = 0xffffffff,
+ [NPCM8XX_CLK_CLKDIV4] = 0x70009000,
+ [NPCM8XX_CLK_IPSRST4] = 0x02000000,
+ [NPCM8XX_CLK_WD0RCRB] = 0xfffffe71,
+ [NPCM8XX_CLK_WD1RCRB] = 0xfffffe71,
+ [NPCM8XX_CLK_WD2RCRB] = 0xfffffe71,
+ [NPCM8XX_CLK_SWRSTC1B] = 0xfffffe71,
+ [NPCM8XX_CLK_SWRSTC2B] = 0xfffffe71,
+ [NPCM8XX_CLK_SWRSTC3B] = 0xfffffe71,
+ [NPCM8XX_CLK_TIPRSTCB] = 0xfffffe71,
+ [NPCM8XX_CLK_CORSTCB] = 0xfffffe71,
+};
+
/* The number of watchdogs that can trigger a reset. */
#define NPCM7XX_NR_WATCHDOGS (3)
@@ -1056,6 +1148,18 @@ static void npcm7xx_clk_class_init(ObjectClass *klass, void *data)
c->cold_reset_values = npcm7xx_cold_reset_values;
}
+static void npcm8xx_clk_class_init(ObjectClass *klass, void *data)
+{
+ NPCMCLKClass *c = NPCM_CLK_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ QEMU_BUILD_BUG_ON(NPCM8XX_CLK_REGS_END > NPCM_CLK_MAX_NR_REGS);
+ QEMU_BUILD_BUG_ON(NPCM8XX_CLK_REGS_END != NPCM8XX_CLK_NR_REGS);
+ dc->desc = "NPCM8xx Clock Control Registers";
+ c->nr_regs = NPCM8XX_CLK_NR_REGS;
+ c->cold_reset_values = npcm8xx_cold_reset_values;
+}
+
static const TypeInfo npcm7xx_clk_pll_info = {
.name = TYPE_NPCM7XX_CLOCK_PLL,
.parent = TYPE_DEVICE,
@@ -1096,6 +1200,12 @@ static const TypeInfo npcm7xx_clk_info = {
.class_init = npcm7xx_clk_class_init,
};
+static const TypeInfo npcm8xx_clk_info = {
+ .name = TYPE_NPCM8XX_CLK,
+ .parent = TYPE_NPCM_CLK,
+ .class_init = npcm8xx_clk_class_init,
+};
+
static void npcm7xx_clk_register_type(void)
{
type_register_static(&npcm7xx_clk_pll_info);
@@ -1103,5 +1213,6 @@ static void npcm7xx_clk_register_type(void)
type_register_static(&npcm7xx_clk_divider_info);
type_register_static(&npcm_clk_info);
type_register_static(&npcm7xx_clk_info);
+ type_register_static(&npcm8xx_clk_info);
}
type_init(npcm7xx_clk_register_type);
diff --git a/include/hw/misc/npcm_clk.h b/include/hw/misc/npcm_clk.h
index f47614ac8d..8fa1e14bdd 100644
--- a/include/hw/misc/npcm_clk.h
+++ b/include/hw/misc/npcm_clk.h
@@ -1,5 +1,5 @@
/*
- * Nuvoton NPCM7xx Clock Control Registers.
+ * Nuvoton NPCM7xx/8xx Clock Control Registers.
*
* Copyright 2020 Google LLC
*
@@ -21,11 +21,12 @@
#include "hw/sysbus.h"
#define NPCM7XX_CLK_NR_REGS (0x70 / sizeof(uint32_t))
+#define NPCM8XX_CLK_NR_REGS (0xc4 / sizeof(uint32_t))
/*
* Number of maximum registers in NPCM device state structure. Don't change
* this without incrementing the version_id in the vmstate.
*/
-#define NPCM_CLK_MAX_NR_REGS NPCM7XX_CLK_NR_REGS
+#define NPCM_CLK_MAX_NR_REGS NPCM8XX_CLK_NR_REGS
#define NPCM7XX_WATCHDOG_RESET_GPIO_IN "npcm7xx-clk-watchdog-reset-gpio-in"
@@ -162,6 +163,10 @@ struct NPCMCLKState {
MemoryRegion iomem;
/* Clock converters */
+ /*
+ * TODO: Implement unique clock converters for NPCM8xx.
+ * NPCM8xx adds a few more clock outputs.
+ */
NPCM7xxClockPLLState plls[NPCM7XX_CLOCK_NR_PLLS];
NPCM7xxClockSELState sels[NPCM7XX_CLOCK_NR_SELS];
NPCM7xxClockDividerState dividers[NPCM7XX_CLOCK_NR_DIVIDERS];
@@ -185,5 +190,6 @@ typedef struct NPCMCLKClass {
#define TYPE_NPCM_CLK "npcm-clk"
OBJECT_DECLARE_TYPE(NPCMCLKState, NPCMCLKClass, NPCM_CLK)
#define TYPE_NPCM7XX_CLK "npcm7xx-clk"
+#define TYPE_NPCM8XX_CLK "npcm8xx-clk"
#endif /* NPCM_CLK_H */
--
2.47.1.613.gc27f4b7a9f-goog
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 14/17] hw/misc: Support NPCM8XX CLK Module Registers
2024-12-26 8:27 ` [PATCH v2 14/17] hw/misc: Support NPCM8XX CLK Module Registers Hao Wu
@ 2025-02-04 16:05 ` Peter Maydell
0 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2025-02-04 16:05 UTC (permalink / raw)
To: Hao Wu
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, hskinnemoen,
venture, pbonzini, jasowang, alistair
On Thu, 26 Dec 2024 at 08:28, Hao Wu <wuhaotsh@google.com> wrote:
>
> NPCM8XX adds a few new registers and have a different set of reset
> values to the CLK modules. This patch supports them.
>
> This patch doesn't support the new clock values generated by these
> registers. Currently no modules use these new clock values so they
> are not necessary at this point.
> Implementation of these clocks might be required when implementing
> these modules.
>
> Signed-off-by: Hao Wu <wuhaotsh@google.com>
> Reviewed-by: Titus Rwantare<titusr@google.com>
> ---
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v2 15/17] hw/net: Add NPCM8XX PCS Module
2024-12-26 8:27 [PATCH v2 00/17] hw/arm: Add NPCM8XX Support Hao Wu
` (13 preceding siblings ...)
2024-12-26 8:27 ` [PATCH v2 14/17] hw/misc: Support NPCM8XX CLK Module Registers Hao Wu
@ 2024-12-26 8:27 ` Hao Wu
2025-02-04 16:19 ` Peter Maydell
2024-12-26 8:27 ` [PATCH v2 16/17] hw/arm: Add NPCM8XX SoC Hao Wu
2024-12-26 8:28 ` [PATCH v2 17/17] hw/arm: Add NPCM845 Evaluation board Hao Wu
16 siblings, 1 reply; 35+ messages in thread
From: Hao Wu @ 2024-12-26 8:27 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair, Hao Wu
The PCS exists in NPCM8XX's GMAC1 and is used to control the SGMII
PHY. This implementation contains all the default registers and
the soft reset feature that are required to load the Linux kernel
driver. Further features have not been implemented yet.
Signed-off-by: Hao Wu <wuhaotsh@google.com>
---
hw/net/meson.build | 1 +
hw/net/npcm_pcs.c | 410 ++++++++++++++++++++++++++++++++++++++
hw/net/trace-events | 4 +-
include/hw/net/npcm_pcs.h | 42 ++++
4 files changed, 455 insertions(+), 2 deletions(-)
create mode 100644 hw/net/npcm_pcs.c
create mode 100644 include/hw/net/npcm_pcs.h
diff --git a/hw/net/meson.build b/hw/net/meson.build
index 3bb5d749a8..e6759e26ca 100644
--- a/hw/net/meson.build
+++ b/hw/net/meson.build
@@ -40,6 +40,7 @@ system_ss.add(when: 'CONFIG_SUNHME', if_true: files('sunhme.c'))
system_ss.add(when: 'CONFIG_FTGMAC100', if_true: files('ftgmac100.c'))
system_ss.add(when: 'CONFIG_SUNGEM', if_true: files('sungem.c'))
system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_emc.c', 'npcm_gmac.c'))
+system_ss.add(when: 'CONFIG_NPCM8XX', if_true: files('npcm_pcs.c'))
system_ss.add(when: 'CONFIG_COLDFIRE', if_true: files('mcf_fec.c'))
specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_llan.c'))
diff --git a/hw/net/npcm_pcs.c b/hw/net/npcm_pcs.c
new file mode 100644
index 0000000000..ce5034e234
--- /dev/null
+++ b/hw/net/npcm_pcs.c
@@ -0,0 +1,410 @@
+/*
+ * Nuvoton NPCM8xx PCS Module
+ *
+ * Copyright 2022 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/*
+ * Disclaimer:
+ * Currently we only implemented the default values of the registers and
+ * the soft reset feature. These are required to boot up the GMAC module
+ * in Linux kernel for NPCM845 boards. Other functionalities are not modeled.
+ */
+
+#include "qemu/osdep.h"
+
+#include "exec/hwaddr.h"
+#include "hw/registerfields.h"
+#include "hw/net/npcm_pcs.h"
+#include "migration/vmstate.h"
+#include "qemu/log.h"
+#include "qemu/units.h"
+#include "trace.h"
+
+#define NPCM_PCS_IND_AC_BA 0x1fe
+#define NPCM_PCS_IND_SR_CTL 0x1e00
+#define NPCM_PCS_IND_SR_MII 0x1f00
+#define NPCM_PCS_IND_SR_TIM 0x1f07
+#define NPCM_PCS_IND_VR_MII 0x1f80
+
+REG16(NPCM_PCS_SR_CTL_ID1, 0x08)
+REG16(NPCM_PCS_SR_CTL_ID2, 0x0a)
+REG16(NPCM_PCS_SR_CTL_STS, 0x10)
+
+REG16(NPCM_PCS_SR_MII_CTRL, 0x00)
+REG16(NPCM_PCS_SR_MII_STS, 0x02)
+REG16(NPCM_PCS_SR_MII_DEV_ID1, 0x04)
+REG16(NPCM_PCS_SR_MII_DEV_ID2, 0x06)
+REG16(NPCM_PCS_SR_MII_AN_ADV, 0x08)
+REG16(NPCM_PCS_SR_MII_LP_BABL, 0x0a)
+REG16(NPCM_PCS_SR_MII_AN_EXPN, 0x0c)
+REG16(NPCM_PCS_SR_MII_EXT_STS, 0x1e)
+
+REG16(NPCM_PCS_SR_TIM_SYNC_ABL, 0x10)
+REG16(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_LWR, 0x12)
+REG16(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_UPR, 0x14)
+REG16(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_LWR, 0x16)
+REG16(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_UPR, 0x18)
+REG16(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_LWR, 0x1a)
+REG16(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_UPR, 0x1c)
+REG16(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_LWR, 0x1e)
+REG16(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_UPR, 0x20)
+
+REG16(NPCM_PCS_VR_MII_MMD_DIG_CTRL1, 0x000)
+REG16(NPCM_PCS_VR_MII_AN_CTRL, 0x002)
+REG16(NPCM_PCS_VR_MII_AN_INTR_STS, 0x004)
+REG16(NPCM_PCS_VR_MII_TC, 0x006)
+REG16(NPCM_PCS_VR_MII_DBG_CTRL, 0x00a)
+REG16(NPCM_PCS_VR_MII_EEE_MCTRL0, 0x00c)
+REG16(NPCM_PCS_VR_MII_EEE_TXTIMER, 0x010)
+REG16(NPCM_PCS_VR_MII_EEE_RXTIMER, 0x012)
+REG16(NPCM_PCS_VR_MII_LINK_TIMER_CTRL, 0x014)
+REG16(NPCM_PCS_VR_MII_EEE_MCTRL1, 0x016)
+REG16(NPCM_PCS_VR_MII_DIG_STS, 0x020)
+REG16(NPCM_PCS_VR_MII_ICG_ERRCNT1, 0x022)
+REG16(NPCM_PCS_VR_MII_MISC_STS, 0x030)
+REG16(NPCM_PCS_VR_MII_RX_LSTS, 0x040)
+REG16(NPCM_PCS_VR_MII_MP_TX_BSTCTRL0, 0x070)
+REG16(NPCM_PCS_VR_MII_MP_TX_LVLCTRL0, 0x074)
+REG16(NPCM_PCS_VR_MII_MP_TX_GENCTRL0, 0x07a)
+REG16(NPCM_PCS_VR_MII_MP_TX_GENCTRL1, 0x07c)
+REG16(NPCM_PCS_VR_MII_MP_TX_STS, 0x090)
+REG16(NPCM_PCS_VR_MII_MP_RX_GENCTRL0, 0x0b0)
+REG16(NPCM_PCS_VR_MII_MP_RX_GENCTRL1, 0x0b2)
+REG16(NPCM_PCS_VR_MII_MP_RX_LOS_CTRL0, 0x0ba)
+REG16(NPCM_PCS_VR_MII_MP_MPLL_CTRL0, 0x0f0)
+REG16(NPCM_PCS_VR_MII_MP_MPLL_CTRL1, 0x0f2)
+REG16(NPCM_PCS_VR_MII_MP_MPLL_STS, 0x110)
+REG16(NPCM_PCS_VR_MII_MP_MISC_CTRL2, 0x126)
+REG16(NPCM_PCS_VR_MII_MP_LVL_CTRL, 0x130)
+REG16(NPCM_PCS_VR_MII_MP_MISC_CTRL0, 0x132)
+REG16(NPCM_PCS_VR_MII_MP_MISC_CTRL1, 0x134)
+REG16(NPCM_PCS_VR_MII_DIG_CTRL2, 0x1c2)
+REG16(NPCM_PCS_VR_MII_DIG_ERRCNT_SEL, 0x1c4)
+
+/* Register Fields */
+#define NPCM_PCS_SR_MII_CTRL_RST BIT(15)
+
+static const uint16_t npcm_pcs_sr_ctl_cold_reset_values[NPCM_PCS_NR_SR_CTLS] = {
+ [R_NPCM_PCS_SR_CTL_ID1] = 0x699e,
+ [R_NPCM_PCS_SR_CTL_STS] = 0x8000,
+};
+
+static const uint16_t npcm_pcs_sr_mii_cold_reset_values[NPCM_PCS_NR_SR_MIIS] = {
+ [R_NPCM_PCS_SR_MII_CTRL] = 0x1140,
+ [R_NPCM_PCS_SR_MII_STS] = 0x0109,
+ [R_NPCM_PCS_SR_MII_DEV_ID1] = 0x699e,
+ [R_NPCM_PCS_SR_MII_DEV_ID2] = 0xced0,
+ [R_NPCM_PCS_SR_MII_AN_ADV] = 0x0020,
+ [R_NPCM_PCS_SR_MII_EXT_STS] = 0xc000,
+};
+
+static const uint16_t npcm_pcs_sr_tim_cold_reset_values[NPCM_PCS_NR_SR_TIMS] = {
+ [R_NPCM_PCS_SR_TIM_SYNC_ABL] = 0x0003,
+ [R_NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_LWR] = 0x0038,
+ [R_NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_LWR] = 0x0038,
+ [R_NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_LWR] = 0x0058,
+ [R_NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_LWR] = 0x0048,
+};
+
+static const uint16_t npcm_pcs_vr_mii_cold_reset_values[NPCM_PCS_NR_VR_MIIS] = {
+ [R_NPCM_PCS_VR_MII_MMD_DIG_CTRL1] = 0x2400,
+ [R_NPCM_PCS_VR_MII_AN_INTR_STS] = 0x000a,
+ [R_NPCM_PCS_VR_MII_EEE_MCTRL0] = 0x899c,
+ [R_NPCM_PCS_VR_MII_DIG_STS] = 0x0010,
+ [R_NPCM_PCS_VR_MII_MP_TX_BSTCTRL0] = 0x000a,
+ [R_NPCM_PCS_VR_MII_MP_TX_LVLCTRL0] = 0x007f,
+ [R_NPCM_PCS_VR_MII_MP_TX_GENCTRL0] = 0x0001,
+ [R_NPCM_PCS_VR_MII_MP_RX_GENCTRL0] = 0x0100,
+ [R_NPCM_PCS_VR_MII_MP_RX_GENCTRL1] = 0x1100,
+ [R_NPCM_PCS_VR_MII_MP_RX_LOS_CTRL0] = 0x000e,
+ [R_NPCM_PCS_VR_MII_MP_MPLL_CTRL0] = 0x0100,
+ [R_NPCM_PCS_VR_MII_MP_MPLL_CTRL1] = 0x0032,
+ [R_NPCM_PCS_VR_MII_MP_MPLL_STS] = 0x0001,
+ [R_NPCM_PCS_VR_MII_MP_LVL_CTRL] = 0x0019,
+};
+
+static void npcm_pcs_soft_reset(NPCMPCSState *s)
+{
+ memcpy(s->sr_ctl, npcm_pcs_sr_ctl_cold_reset_values,
+ NPCM_PCS_NR_SR_CTLS * sizeof(uint16_t));
+ memcpy(s->sr_mii, npcm_pcs_sr_mii_cold_reset_values,
+ NPCM_PCS_NR_SR_MIIS * sizeof(uint16_t));
+ memcpy(s->sr_tim, npcm_pcs_sr_tim_cold_reset_values,
+ NPCM_PCS_NR_SR_TIMS * sizeof(uint16_t));
+ memcpy(s->vr_mii, npcm_pcs_vr_mii_cold_reset_values,
+ NPCM_PCS_NR_VR_MIIS * sizeof(uint16_t));
+}
+
+static uint16_t npcm_pcs_read_sr_ctl(NPCMPCSState *s, hwaddr offset)
+{
+ hwaddr regno = offset / sizeof(uint16_t);
+
+ if (regno >= NPCM_PCS_NR_SR_CTLS) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: SR_CTL read offset 0x%04" HWADDR_PRIx
+ " is out of range.\n",
+ DEVICE(s)->canonical_path, offset);
+ return 0;
+ }
+
+ return s->sr_ctl[regno];
+}
+
+static uint16_t npcm_pcs_read_sr_mii(NPCMPCSState *s, hwaddr offset)
+{
+ hwaddr regno = offset / sizeof(uint16_t);
+
+ if (regno >= NPCM_PCS_NR_SR_MIIS) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: SR_MII read offset 0x%04" HWADDR_PRIx
+ " is out of range.\n",
+ DEVICE(s)->canonical_path, offset);
+ return 0;
+ }
+
+ return s->sr_mii[regno];
+}
+
+static uint16_t npcm_pcs_read_sr_tim(NPCMPCSState *s, hwaddr offset)
+{
+ hwaddr regno = offset / sizeof(uint16_t);
+
+ if (regno >= NPCM_PCS_NR_SR_TIMS) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: SR_TIM read offset 0x%04" HWADDR_PRIx
+ " is out of range.\n",
+ DEVICE(s)->canonical_path, offset);
+ return 0;
+ }
+
+ return s->sr_tim[regno];
+}
+
+static uint16_t npcm_pcs_read_vr_mii(NPCMPCSState *s, hwaddr offset)
+{
+ hwaddr regno = offset / sizeof(uint16_t);
+
+ if (regno >= NPCM_PCS_NR_VR_MIIS) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: VR_MII read offset 0x%04" HWADDR_PRIx
+ " is out of range.\n",
+ DEVICE(s)->canonical_path, offset);
+ return 0;
+ }
+
+ return s->vr_mii[regno];
+}
+
+static void npcm_pcs_write_sr_ctl(NPCMPCSState *s, hwaddr offset, uint16_t v)
+{
+ hwaddr regno = offset / sizeof(uint16_t);
+
+ if (regno >= NPCM_PCS_NR_SR_CTLS) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: SR_CTL write offset 0x%04" HWADDR_PRIx
+ " is out of range.\n",
+ DEVICE(s)->canonical_path, offset);
+ return;
+ }
+
+ s->sr_ctl[regno] = v;
+}
+
+static void npcm_pcs_write_sr_mii(NPCMPCSState *s, hwaddr offset, uint16_t v)
+{
+ hwaddr regno = offset / sizeof(uint16_t);
+
+ if (regno >= NPCM_PCS_NR_SR_MIIS) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: SR_MII write offset 0x%04" HWADDR_PRIx
+ " is out of range.\n",
+ DEVICE(s)->canonical_path, offset);
+ return;
+ }
+
+ s->sr_mii[regno] = v;
+
+ if ((offset == A_NPCM_PCS_SR_MII_CTRL) && (v & NPCM_PCS_SR_MII_CTRL_RST)) {
+ /* Trigger a soft reset */
+ npcm_pcs_soft_reset(s);
+ }
+}
+
+static void npcm_pcs_write_sr_tim(NPCMPCSState *s, hwaddr offset, uint16_t v)
+{
+ hwaddr regno = offset / sizeof(uint16_t);
+
+ if (regno >= NPCM_PCS_NR_SR_TIMS) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: SR_TIM write offset 0x%04" HWADDR_PRIx
+ " is out of range.\n",
+ DEVICE(s)->canonical_path, offset);
+ return;
+ }
+
+ s->sr_tim[regno] = v;
+}
+
+static void npcm_pcs_write_vr_mii(NPCMPCSState *s, hwaddr offset, uint16_t v)
+{
+ hwaddr regno = offset / sizeof(uint16_t);
+
+ if (regno >= NPCM_PCS_NR_VR_MIIS) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: VR_MII write offset 0x%04" HWADDR_PRIx
+ " is out of range.\n",
+ DEVICE(s)->canonical_path, offset);
+ return;
+ }
+
+ s->vr_mii[regno] = v;
+}
+
+static uint64_t npcm_pcs_read(void *opaque, hwaddr offset, unsigned size)
+{
+ NPCMPCSState *s = opaque;
+ uint16_t v = 0;
+
+ if (offset == NPCM_PCS_IND_AC_BA) {
+ v = s->indirect_access_base;
+ } else {
+ switch (s->indirect_access_base) {
+ case NPCM_PCS_IND_SR_CTL:
+ v = npcm_pcs_read_sr_ctl(s, offset);
+ break;
+
+ case NPCM_PCS_IND_SR_MII:
+ v = npcm_pcs_read_sr_mii(s, offset);
+ break;
+
+ case NPCM_PCS_IND_SR_TIM:
+ v = npcm_pcs_read_sr_tim(s, offset);
+ break;
+
+ case NPCM_PCS_IND_VR_MII:
+ v = npcm_pcs_read_vr_mii(s, offset);
+ break;
+
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Read with invalid indirect address base: 0x%"
+ PRIx16 "\n", DEVICE(s)->canonical_path,
+ s->indirect_access_base);
+ }
+ }
+
+ trace_npcm_pcs_reg_read(DEVICE(s)->canonical_path, s->indirect_access_base,
+ offset, v);
+ return v;
+}
+
+static void npcm_pcs_write(void *opaque, hwaddr offset,
+ uint64_t v, unsigned size)
+{
+ NPCMPCSState *s = opaque;
+
+ trace_npcm_pcs_reg_write(DEVICE(s)->canonical_path, s->indirect_access_base,
+ offset, v);
+ if (offset == NPCM_PCS_IND_AC_BA) {
+ s->indirect_access_base = v;
+ } else {
+ switch (s->indirect_access_base) {
+ case NPCM_PCS_IND_SR_CTL:
+ npcm_pcs_write_sr_ctl(s, offset, v);
+ break;
+
+ case NPCM_PCS_IND_SR_MII:
+ npcm_pcs_write_sr_mii(s, offset, v);
+ break;
+
+ case NPCM_PCS_IND_SR_TIM:
+ npcm_pcs_write_sr_tim(s, offset, v);
+ break;
+
+ case NPCM_PCS_IND_VR_MII:
+ npcm_pcs_write_vr_mii(s, offset, v);
+ break;
+
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Write with invalid indirect address base: 0x%02"
+ PRIx16 "\n", DEVICE(s)->canonical_path,
+ s->indirect_access_base);
+ }
+ }
+}
+
+static void npcm_pcs_enter_reset(Object *obj, ResetType type)
+{
+ NPCMPCSState *s = NPCM_PCS(obj);
+
+ npcm_pcs_soft_reset(s);
+}
+
+static const struct MemoryRegionOps npcm_pcs_ops = {
+ .read = npcm_pcs_read,
+ .write = npcm_pcs_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 2,
+ .max_access_size = 2,
+ .unaligned = false,
+ },
+};
+
+static void npcm_pcs_realize(DeviceState *dev, Error **errp)
+{
+ NPCMPCSState *pcs = NPCM_PCS(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+ memory_region_init_io(&pcs->iomem, OBJECT(pcs), &npcm_pcs_ops, pcs,
+ TYPE_NPCM_PCS, 8 * KiB);
+ sysbus_init_mmio(sbd, &pcs->iomem);
+}
+
+static const VMStateDescription vmstate_npcm_pcs = {
+ .name = TYPE_NPCM_PCS,
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT16(indirect_access_base, NPCMPCSState),
+ VMSTATE_UINT16_ARRAY(sr_ctl, NPCMPCSState, NPCM_PCS_NR_SR_CTLS),
+ VMSTATE_UINT16_ARRAY(sr_mii, NPCMPCSState, NPCM_PCS_NR_SR_MIIS),
+ VMSTATE_UINT16_ARRAY(sr_tim, NPCMPCSState, NPCM_PCS_NR_SR_TIMS),
+ VMSTATE_UINT16_ARRAY(vr_mii, NPCMPCSState, NPCM_PCS_NR_VR_MIIS),
+ VMSTATE_END_OF_LIST(),
+ },
+};
+
+static void npcm_pcs_class_init(ObjectClass *klass, void *data)
+{
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+ dc->desc = "NPCM PCS Controller";
+ dc->realize = npcm_pcs_realize;
+ dc->vmsd = &vmstate_npcm_pcs;
+ rc->phases.enter = npcm_pcs_enter_reset;
+}
+
+static const TypeInfo npcm_pcs_types[] = {
+ {
+ .name = TYPE_NPCM_PCS,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(NPCMPCSState),
+ .class_init = npcm_pcs_class_init,
+ },
+};
+DEFINE_TYPES(npcm_pcs_types)
diff --git a/hw/net/trace-events b/hw/net/trace-events
index 6100ec324a..daaf95beec 100644
--- a/hw/net/trace-events
+++ b/hw/net/trace-events
@@ -483,8 +483,8 @@ npcm_gmac_packet_tx_desc_data(const char* name, uint32_t tdes0, uint32_t tdes1)
npcm_gmac_tx_desc_owner(const char* name, uint32_t desc_addr) "%s: TX Descriptor @0x%04" PRIX32 " is owned by software"
# npcm_pcs.c
-npcm_pcs_reg_read(const char *name, uint16_t indirect_access_baes, uint64_t offset, uint16_t value) "%s: IND: 0x%02" PRIx16 " offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
-npcm_pcs_reg_write(const char *name, uint16_t indirect_access_baes, uint64_t offset, uint16_t value) "%s: IND: 0x%02" PRIx16 " offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
+npcm_pcs_reg_read(const char *name, uint16_t indirect_access_base, uint64_t offset, uint16_t value) "%s: IND: 0x%02" PRIx16 " offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
+npcm_pcs_reg_write(const char *name, uint16_t indirect_access_base, uint64_t offset, uint16_t value) "%s: IND: 0x%02" PRIx16 " offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
# dp8398x.c
dp8393x_raise_irq(int isr) "raise irq, isr is 0x%04x"
diff --git a/include/hw/net/npcm_pcs.h b/include/hw/net/npcm_pcs.h
new file mode 100644
index 0000000000..dd947d2a9f
--- /dev/null
+++ b/include/hw/net/npcm_pcs.h
@@ -0,0 +1,42 @@
+/*
+ * Nuvoton NPCM8xx PCS Module
+ *
+ * Copyright 2022 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef NPCM_PCS_H
+#define NPCM_PCS_H
+
+#include "hw/sysbus.h"
+
+#define NPCM_PCS_NR_SR_CTLS (0x12 / sizeof(uint16_t))
+#define NPCM_PCS_NR_SR_MIIS (0x20 / sizeof(uint16_t))
+#define NPCM_PCS_NR_SR_TIMS (0x22 / sizeof(uint16_t))
+#define NPCM_PCS_NR_VR_MIIS (0x1c6 / sizeof(uint16_t))
+
+struct NPCMPCSState {
+ SysBusDevice parent;
+
+ MemoryRegion iomem;
+
+ uint16_t indirect_access_base;
+ uint16_t sr_ctl[NPCM_PCS_NR_SR_CTLS];
+ uint16_t sr_mii[NPCM_PCS_NR_SR_MIIS];
+ uint16_t sr_tim[NPCM_PCS_NR_SR_TIMS];
+ uint16_t vr_mii[NPCM_PCS_NR_VR_MIIS];
+} NPCMPCSState;
+
+#define TYPE_NPCM_PCS "npcm-pcs"
+OBJECT_DECLARE_SIMPLE_TYPE(NPCMPCSState, NPCM_PCS)
+
+#endif /* NPCM_PCS_H */
--
2.47.1.613.gc27f4b7a9f-goog
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 15/17] hw/net: Add NPCM8XX PCS Module
2024-12-26 8:27 ` [PATCH v2 15/17] hw/net: Add NPCM8XX PCS Module Hao Wu
@ 2025-02-04 16:19 ` Peter Maydell
0 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2025-02-04 16:19 UTC (permalink / raw)
To: Hao Wu
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, hskinnemoen,
venture, pbonzini, jasowang, alistair
On Thu, 26 Dec 2024 at 08:28, Hao Wu <wuhaotsh@google.com> wrote:
>
> The PCS exists in NPCM8XX's GMAC1 and is used to control the SGMII
> PHY. This implementation contains all the default registers and
> the soft reset feature that are required to load the Linux kernel
> driver. Further features have not been implemented yet.
>
> Signed-off-by: Hao Wu <wuhaotsh@google.com>
> ---
> hw/net/meson.build | 1 +
> hw/net/npcm_pcs.c | 410 ++++++++++++++++++++++++++++++++++++++
> hw/net/trace-events | 4 +-
> include/hw/net/npcm_pcs.h | 42 ++++
> 4 files changed, 455 insertions(+), 2 deletions(-)
> create mode 100644 hw/net/npcm_pcs.c
> create mode 100644 include/hw/net/npcm_pcs.h
>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
for basic structure, but it would be good if somebody
who knows the hardware reviewed it for whether it's
actually implementing the right thing.
thanks
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v2 16/17] hw/arm: Add NPCM8XX SoC
2024-12-26 8:27 [PATCH v2 00/17] hw/arm: Add NPCM8XX Support Hao Wu
` (14 preceding siblings ...)
2024-12-26 8:27 ` [PATCH v2 15/17] hw/net: Add NPCM8XX PCS Module Hao Wu
@ 2024-12-26 8:27 ` Hao Wu
2025-02-04 16:28 ` Peter Maydell
2024-12-26 8:28 ` [PATCH v2 17/17] hw/arm: Add NPCM845 Evaluation board Hao Wu
16 siblings, 1 reply; 35+ messages in thread
From: Hao Wu @ 2024-12-26 8:27 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair, Hao Wu
Signed-off-by: Hao Wu <wuhaotsh@google.com>
---
configs/devices/aarch64-softmmu/default.mak | 1 +
hw/arm/Kconfig | 11 +
hw/arm/meson.build | 1 +
hw/arm/npcm8xx.c | 810 ++++++++++++++++++++
include/hw/arm/npcm8xx.h | 107 +++
5 files changed, 930 insertions(+)
create mode 100644 hw/arm/npcm8xx.c
create mode 100644 include/hw/arm/npcm8xx.h
diff --git a/configs/devices/aarch64-softmmu/default.mak b/configs/devices/aarch64-softmmu/default.mak
index f82a04c27d..5ea1cc2dd1 100644
--- a/configs/devices/aarch64-softmmu/default.mak
+++ b/configs/devices/aarch64-softmmu/default.mak
@@ -8,3 +8,4 @@ include ../arm-softmmu/default.mak
# CONFIG_XLNX_ZYNQMP_ARM=n
# CONFIG_XLNX_VERSAL=n
# CONFIG_SBSA_REF=n
+CONFIG_NPCM8XX=y
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index e779b5af95..4fd5a41739 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -481,6 +481,17 @@ config NPCM7XX
select PCA954X
select USB_OHCI_SYSBUS
+config NPCM8XX
+ bool
+ select ARM_GIC
+ select SMBUS
+ select PL310 # cache controller
+ select NPCM7XX
+ select SERIAL
+ select SSI
+ select UNIMP
+
+
config FSL_IMX25
bool
default y
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index 490234b3b8..d7813c089c 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -12,6 +12,7 @@ arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: files('musicpal.c'))
arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.c'))
arm_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex-stm32-h405.c'))
arm_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx.c', 'npcm7xx_boards.c'))
+arm_ss.add(when: 'CONFIG_NPCM8XX', if_true: files('npcm8xx.c'))
arm_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview.c'))
arm_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa-ref.c'))
arm_ss.add(when: 'CONFIG_STELLARIS', if_true: files('stellaris.c'))
diff --git a/hw/arm/npcm8xx.c b/hw/arm/npcm8xx.c
new file mode 100644
index 0000000000..ed4185f37d
--- /dev/null
+++ b/hw/arm/npcm8xx.c
@@ -0,0 +1,810 @@
+/*
+ * Nuvoton NPCM8xx SoC family.
+ *
+ * Copyright 2022 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/arm/boot.h"
+#include "hw/arm/npcm8xx.h"
+#include "hw/char/serial-mm.h"
+#include "hw/intc/arm_gic.h"
+#include "hw/loader.h"
+#include "hw/misc/unimp.h"
+#include "hw/qdev-clock.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "qemu/units.h"
+#include "system/system.h"
+
+#define ARM_PHYS_TIMER_PPI 30
+#define ARM_VIRT_TIMER_PPI 27
+#define ARM_HYP_TIMER_PPI 26
+#define ARM_SEC_TIMER_PPI 29
+
+/*
+ * This covers the whole MMIO space. We'll use this to catch any MMIO accesses
+ * that aren't handled by a device.
+ */
+#define NPCM8XX_MMIO_BA (0x80000000)
+#define NPCM8XX_MMIO_SZ (0x7ffd0000)
+
+/* OTP fuse array */
+#define NPCM8XX_OTP_BA (0xf0189000)
+
+/* GIC Distributor */
+#define NPCM8XX_GICD_BA (0xdfff9000)
+#define NPCM8XX_GICC_BA (0xdfffa000)
+
+/* Core system modules. */
+#define NPCM8XX_CPUP_BA (0xf03fe000)
+#define NPCM8XX_GCR_BA (0xf0800000)
+#define NPCM8XX_CLK_BA (0xf0801000)
+#define NPCM8XX_MC_BA (0xf0824000)
+#define NPCM8XX_RNG_BA (0xf000b000)
+
+/* ADC Module */
+#define NPCM8XX_ADC_BA (0xf000c000)
+
+/* Internal AHB SRAM */
+#define NPCM8XX_RAM3_BA (0xc0008000)
+#define NPCM8XX_RAM3_SZ (4 * KiB)
+
+/* Memory blocks at the end of the address space */
+#define NPCM8XX_RAM2_BA (0xfffb0000)
+#define NPCM8XX_RAM2_SZ (256 * KiB)
+#define NPCM8XX_ROM_BA (0xffff0100)
+#define NPCM8XX_ROM_SZ (64 * KiB)
+
+/* SDHCI Modules */
+#define NPCM8XX_MMC_BA (0xf0842000)
+
+/* Run PLL1 at 1600 MHz */
+#define NPCM8XX_PLLCON1_FIXUP_VAL (0x00402101)
+/* Run the CPU from PLL1 and UART from PLL2 */
+#define NPCM8XX_CLKSEL_FIXUP_VAL (0x004aaba9)
+
+/* Clock configuration values to be fixed up when bypassing bootloader */
+
+/*
+ * Interrupt lines going into the GIC. This does not include internal Cortex-A9
+ * interrupts.
+ */
+enum NPCM8xxInterrupt {
+ NPCM8XX_ADC_IRQ = 0,
+ NPCM8XX_PECI_IRQ = 6,
+ NPCM8XX_KCS_HIB_IRQ = 9,
+ NPCM8XX_MMC_IRQ = 26,
+ NPCM8XX_TIMER0_IRQ = 32, /* Timer Module 0 */
+ NPCM8XX_TIMER1_IRQ,
+ NPCM8XX_TIMER2_IRQ,
+ NPCM8XX_TIMER3_IRQ,
+ NPCM8XX_TIMER4_IRQ,
+ NPCM8XX_TIMER5_IRQ, /* Timer Module 1 */
+ NPCM8XX_TIMER6_IRQ,
+ NPCM8XX_TIMER7_IRQ,
+ NPCM8XX_TIMER8_IRQ,
+ NPCM8XX_TIMER9_IRQ,
+ NPCM8XX_TIMER10_IRQ, /* Timer Module 2 */
+ NPCM8XX_TIMER11_IRQ,
+ NPCM8XX_TIMER12_IRQ,
+ NPCM8XX_TIMER13_IRQ,
+ NPCM8XX_TIMER14_IRQ,
+ NPCM8XX_WDG0_IRQ = 47, /* Timer Module 0 Watchdog */
+ NPCM8XX_WDG1_IRQ, /* Timer Module 1 Watchdog */
+ NPCM8XX_WDG2_IRQ, /* Timer Module 2 Watchdog */
+ NPCM8XX_EHCI1_IRQ = 61,
+ NPCM8XX_OHCI1_IRQ,
+ NPCM8XX_EHCI2_IRQ,
+ NPCM8XX_OHCI2_IRQ,
+ NPCM8XX_PWM0_IRQ = 93, /* PWM module 0 */
+ NPCM8XX_PWM1_IRQ, /* PWM module 1 */
+ NPCM8XX_MFT0_IRQ = 96, /* MFT module 0 */
+ NPCM8XX_MFT1_IRQ, /* MFT module 1 */
+ NPCM8XX_MFT2_IRQ, /* MFT module 2 */
+ NPCM8XX_MFT3_IRQ, /* MFT module 3 */
+ NPCM8XX_MFT4_IRQ, /* MFT module 4 */
+ NPCM8XX_MFT5_IRQ, /* MFT module 5 */
+ NPCM8XX_MFT6_IRQ, /* MFT module 6 */
+ NPCM8XX_MFT7_IRQ, /* MFT module 7 */
+ NPCM8XX_PCI_MBOX1_IRQ = 105,
+ NPCM8XX_PCI_MBOX2_IRQ,
+ NPCM8XX_GPIO0_IRQ = 116,
+ NPCM8XX_GPIO1_IRQ,
+ NPCM8XX_GPIO2_IRQ,
+ NPCM8XX_GPIO3_IRQ,
+ NPCM8XX_GPIO4_IRQ,
+ NPCM8XX_GPIO5_IRQ,
+ NPCM8XX_GPIO6_IRQ,
+ NPCM8XX_GPIO7_IRQ,
+ NPCM8XX_SMBUS0_IRQ = 128,
+ NPCM8XX_SMBUS1_IRQ,
+ NPCM8XX_SMBUS2_IRQ,
+ NPCM8XX_SMBUS3_IRQ,
+ NPCM8XX_SMBUS4_IRQ,
+ NPCM8XX_SMBUS5_IRQ,
+ NPCM8XX_SMBUS6_IRQ,
+ NPCM8XX_SMBUS7_IRQ,
+ NPCM8XX_SMBUS8_IRQ,
+ NPCM8XX_SMBUS9_IRQ,
+ NPCM8XX_SMBUS10_IRQ,
+ NPCM8XX_SMBUS11_IRQ,
+ NPCM8XX_SMBUS12_IRQ,
+ NPCM8XX_SMBUS13_IRQ,
+ NPCM8XX_SMBUS14_IRQ,
+ NPCM8XX_SMBUS15_IRQ,
+ NPCM8XX_SMBUS16_IRQ,
+ NPCM8XX_SMBUS17_IRQ,
+ NPCM8XX_SMBUS18_IRQ,
+ NPCM8XX_SMBUS19_IRQ,
+ NPCM8XX_SMBUS20_IRQ,
+ NPCM8XX_SMBUS21_IRQ,
+ NPCM8XX_SMBUS22_IRQ,
+ NPCM8XX_SMBUS23_IRQ,
+ NPCM8XX_SMBUS24_IRQ,
+ NPCM8XX_SMBUS25_IRQ,
+ NPCM8XX_SMBUS26_IRQ,
+ NPCM8XX_UART0_IRQ = 192,
+ NPCM8XX_UART1_IRQ,
+ NPCM8XX_UART2_IRQ,
+ NPCM8XX_UART3_IRQ,
+ NPCM8XX_UART4_IRQ,
+ NPCM8XX_UART5_IRQ,
+ NPCM8XX_UART6_IRQ,
+};
+
+/* Total number of GIC interrupts, including internal Cortex-A35 interrupts. */
+#define NPCM8XX_NUM_IRQ (288)
+#define NPCM8XX_PPI_BASE(cpu) ((NPCM8XX_NUM_IRQ - 32) + (cpu) * 32)
+
+/* Register base address for each Timer Module */
+static const hwaddr npcm8xx_tim_addr[] = {
+ 0xf0008000,
+ 0xf0009000,
+ 0xf000a000,
+};
+
+/* Register base address for each 16550 UART */
+static const hwaddr npcm8xx_uart_addr[] = {
+ 0xf0000000,
+ 0xf0001000,
+ 0xf0002000,
+ 0xf0003000,
+ 0xf0004000,
+ 0xf0005000,
+ 0xf0006000,
+};
+
+/* Direct memory-mapped access to SPI0 CS0-1. */
+static const hwaddr npcm8xx_fiu0_flash_addr[] = {
+ 0x80000000, /* CS0 */
+ 0x88000000, /* CS1 */
+};
+
+/* Direct memory-mapped access to SPI1 CS0-3. */
+static const hwaddr npcm8xx_fiu1_flash_addr[] = {
+ 0x90000000, /* CS0 */
+ 0x91000000, /* CS1 */
+ 0x92000000, /* CS2 */
+ 0x93000000, /* CS3 */
+};
+
+/* Direct memory-mapped access to SPI3 CS0-3. */
+static const hwaddr npcm8xx_fiu3_flash_addr[] = {
+ 0xa0000000, /* CS0 */
+ 0xa8000000, /* CS1 */
+ 0xb0000000, /* CS2 */
+ 0xb8000000, /* CS3 */
+};
+
+/* Register base address for each PWM Module */
+static const hwaddr npcm8xx_pwm_addr[] = {
+ 0xf0103000,
+ 0xf0104000,
+ 0xf0105000,
+};
+
+/* Register base address for each MFT Module */
+static const hwaddr npcm8xx_mft_addr[] = {
+ 0xf0180000,
+ 0xf0181000,
+ 0xf0182000,
+ 0xf0183000,
+ 0xf0184000,
+ 0xf0185000,
+ 0xf0186000,
+ 0xf0187000,
+};
+
+/* Direct memory-mapped access to each SMBus Module. */
+static const hwaddr npcm8xx_smbus_addr[] = {
+ 0xf0080000,
+ 0xf0081000,
+ 0xf0082000,
+ 0xf0083000,
+ 0xf0084000,
+ 0xf0085000,
+ 0xf0086000,
+ 0xf0087000,
+ 0xf0088000,
+ 0xf0089000,
+ 0xf008a000,
+ 0xf008b000,
+ 0xf008c000,
+ 0xf008d000,
+ 0xf008e000,
+ 0xf008f000,
+ 0xfff00000,
+ 0xfff01000,
+ 0xfff02000,
+ 0xfff03000,
+ 0xfff04000,
+ 0xfff05000,
+ 0xfff06000,
+ 0xfff07000,
+ 0xfff08000,
+ 0xfff09000,
+ 0xfff0a000,
+};
+
+/* Register base address for each USB host EHCI registers */
+static const hwaddr npcm8xx_ehci_addr[] = {
+ 0xf0828100,
+ 0xf082a100,
+};
+
+/* Register base address for each USB host OHCI registers */
+static const hwaddr npcm8xx_ohci_addr[] = {
+ 0xf0829000,
+ 0xf082b000,
+};
+
+static const struct {
+ hwaddr regs_addr;
+ uint32_t reset_pu;
+ uint32_t reset_pd;
+ uint32_t reset_osrc;
+ uint32_t reset_odsc;
+} npcm8xx_gpio[] = {
+ {
+ .regs_addr = 0xf0010000,
+ .reset_pu = 0x00000300,
+ .reset_pd = 0x000f0000,
+ }, {
+ .regs_addr = 0xf0011000,
+ .reset_pu = 0xe0fefe01,
+ .reset_pd = 0x07000000,
+ }, {
+ .regs_addr = 0xf0012000,
+ .reset_pu = 0xc00fffff,
+ .reset_pd = 0x3ff00000,
+ }, {
+ .regs_addr = 0xf0013000,
+ .reset_pd = 0x00003000,
+ }, {
+ .regs_addr = 0xf0014000,
+ .reset_pu = 0xffff0000,
+ }, {
+ .regs_addr = 0xf0015000,
+ .reset_pu = 0xff8387fe,
+ .reset_pd = 0x007c0001,
+ .reset_osrc = 0x08000000,
+ }, {
+ .regs_addr = 0xf0016000,
+ .reset_pu = 0x00000801,
+ .reset_pd = 0x00000302,
+ }, {
+ .regs_addr = 0xf0017000,
+ .reset_pu = 0x000002ff,
+ .reset_pd = 0x00000c00,
+ },
+};
+
+static const struct {
+ const char *name;
+ hwaddr regs_addr;
+ int cs_count;
+ const hwaddr *flash_addr;
+ size_t flash_size;
+} npcm8xx_fiu[] = {
+ {
+ .name = "fiu0",
+ .regs_addr = 0xfb000000,
+ .cs_count = ARRAY_SIZE(npcm8xx_fiu0_flash_addr),
+ .flash_addr = npcm8xx_fiu0_flash_addr,
+ .flash_size = 128 * MiB,
+ },
+ {
+ .name = "fiu1",
+ .regs_addr = 0xfb002000,
+ .cs_count = ARRAY_SIZE(npcm8xx_fiu1_flash_addr),
+ .flash_addr = npcm8xx_fiu1_flash_addr,
+ .flash_size = 16 * MiB,
+ }, {
+ .name = "fiu3",
+ .regs_addr = 0xc0000000,
+ .cs_count = ARRAY_SIZE(npcm8xx_fiu3_flash_addr),
+ .flash_addr = npcm8xx_fiu3_flash_addr,
+ .flash_size = 128 * MiB,
+ },
+};
+
+static struct arm_boot_info npcm8xx_binfo = {
+ .loader_start = NPCM8XX_LOADER_START,
+ .smp_loader_start = NPCM8XX_SMP_LOADER_START,
+ .smp_bootreg_addr = NPCM8XX_SMP_BOOTREG_ADDR,
+ .gic_cpu_if_addr = NPCM8XX_GICC_BA,
+ .secure_boot = false,
+ .board_id = -1,
+ .board_setup_addr = NPCM8XX_BOARD_SETUP_ADDR,
+};
+
+void npcm8xx_load_kernel(MachineState *machine, NPCM8xxState *soc)
+{
+ npcm8xx_binfo.ram_size = machine->ram_size;
+
+ arm_load_kernel(&soc->cpu[0], machine, &npcm8xx_binfo);
+}
+
+static void npcm8xx_init_fuses(NPCM8xxState *s)
+{
+ NPCM8xxClass *nc = NPCM8XX_GET_CLASS(s);
+ uint32_t value;
+
+ /*
+ * The initial mask of disabled modules indicates the chip derivative (e.g.
+ * NPCM750 or NPCM730).
+ */
+ value = tswap32(nc->disabled_modules);
+ npcm7xx_otp_array_write(&s->fuse_array, &value, NPCM7XX_FUSE_DERIVATIVE,
+ sizeof(value));
+}
+
+static void npcm8xx_write_adc_calibration(NPCM8xxState *s)
+{
+ /* Both ADC and the fuse array must have realized. */
+ QEMU_BUILD_BUG_ON(sizeof(s->adc.calibration_r_values) != 4);
+ npcm7xx_otp_array_write(&s->fuse_array, s->adc.calibration_r_values,
+ NPCM7XX_FUSE_ADC_CALIB, sizeof(s->adc.calibration_r_values));
+}
+
+static qemu_irq npcm8xx_irq(NPCM8xxState *s, int n)
+{
+ return qdev_get_gpio_in(DEVICE(&s->gic), n);
+}
+
+static void npcm8xx_init(Object *obj)
+{
+ NPCM8xxState *s = NPCM8XX(obj);
+ int i;
+
+ object_initialize_child(obj, "cpu-cluster", &s->cpu_cluster,
+ TYPE_CPU_CLUSTER);
+ for (i = 0; i < NPCM8XX_MAX_NUM_CPUS; i++) {
+ object_initialize_child(OBJECT(&s->cpu_cluster), "cpu[*]", &s->cpu[i],
+ ARM_CPU_TYPE_NAME("cortex-a53"));
+ }
+ object_initialize_child(obj, "gic", &s->gic, TYPE_ARM_GIC);
+ object_initialize_child(obj, "gcr", &s->gcr, TYPE_NPCM8XX_GCR);
+ object_property_add_alias(obj, "power-on-straps", OBJECT(&s->gcr),
+ "power-on-straps");
+ object_initialize_child(obj, "clk", &s->clk, TYPE_NPCM8XX_CLK);
+ object_initialize_child(obj, "otp", &s->fuse_array,
+ TYPE_NPCM7XX_FUSE_ARRAY);
+ object_initialize_child(obj, "mc", &s->mc, TYPE_NPCM7XX_MC);
+ object_initialize_child(obj, "rng", &s->rng, TYPE_NPCM7XX_RNG);
+ object_initialize_child(obj, "adc", &s->adc, TYPE_NPCM7XX_ADC);
+
+ for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
+ object_initialize_child(obj, "tim[*]", &s->tim[i], TYPE_NPCM7XX_TIMER);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(s->gpio); i++) {
+ object_initialize_child(obj, "gpio[*]", &s->gpio[i], TYPE_NPCM7XX_GPIO);
+ }
+
+
+ for (i = 0; i < ARRAY_SIZE(s->smbus); i++) {
+ object_initialize_child(obj, "smbus[*]", &s->smbus[i],
+ TYPE_NPCM7XX_SMBUS);
+ DEVICE(&s->smbus[i])->id = g_strdup_printf("smbus[%d]", i);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(s->ehci); i++) {
+ object_initialize_child(obj, "ehci[*]", &s->ehci[i], TYPE_NPCM7XX_EHCI);
+ }
+ for (i = 0; i < ARRAY_SIZE(s->ohci); i++) {
+ object_initialize_child(obj, "ohci[*]", &s->ohci[i], TYPE_SYSBUS_OHCI);
+ }
+
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm8xx_fiu) != ARRAY_SIZE(s->fiu));
+ for (i = 0; i < ARRAY_SIZE(s->fiu); i++) {
+ object_initialize_child(obj, npcm8xx_fiu[i].name, &s->fiu[i],
+ TYPE_NPCM7XX_FIU);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
+ object_initialize_child(obj, "pwm[*]", &s->pwm[i], TYPE_NPCM7XX_PWM);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(s->mft); i++) {
+ object_initialize_child(obj, "mft[*]", &s->mft[i], TYPE_NPCM7XX_MFT);
+ }
+
+ object_initialize_child(obj, "mmc", &s->mmc, TYPE_NPCM7XX_SDHCI);
+}
+
+static void npcm8xx_realize(DeviceState *dev, Error **errp)
+{
+ NPCM8xxState *s = NPCM8XX(dev);
+ NPCM8xxClass *nc = NPCM8XX_GET_CLASS(s);
+ int i;
+
+ if (memory_region_size(s->dram) > NPCM8XX_DRAM_SZ) {
+ error_setg(errp, "%s: NPCM8xx cannot address more than %" PRIu64
+ " MiB of DRAM", __func__, NPCM8XX_DRAM_SZ / MiB);
+ return;
+ }
+
+ /* CPUs */
+ for (i = 0; i < nc->num_cpus; i++) {
+ object_property_set_int(OBJECT(&s->cpu[i]), "mp-affinity",
+ arm_build_mp_affinity(i, NPCM8XX_MAX_NUM_CPUS),
+ &error_abort);
+ object_property_set_bool(OBJECT(&s->cpu[i]), "reset-hivecs", true,
+ &error_abort);
+ object_property_set_int(OBJECT(&s->cpu[i]), "core-count",
+ nc->num_cpus, &error_abort);
+
+ /* Disable security extensions. */
+ object_property_set_bool(OBJECT(&s->cpu[i]), "has_el3", false,
+ &error_abort);
+
+ if (!qdev_realize(DEVICE(&s->cpu[i]), NULL, errp)) {
+ return;
+ }
+ }
+
+ /* ARM GIC for Cortex A35. Can only fail if we pass bad parameters here. */
+ object_property_set_uint(OBJECT(&s->gic), "num-cpu", nc->num_cpus, errp);
+ object_property_set_uint(OBJECT(&s->gic), "num-irq", NPCM8XX_NUM_IRQ, errp);
+ object_property_set_uint(OBJECT(&s->gic), "revision", 2, errp);
+ object_property_set_bool(OBJECT(&s->gic), "has-security-extensions", true,
+ errp);
+ object_property_set_bool(OBJECT(&s->gic), "irq-reset-nonsecure", true,
+ errp);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->gic), errp)) {
+ return;
+ }
+ for (i = 0; i < nc->num_cpus; i++) {
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i,
+ qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_IRQ));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i + nc->num_cpus,
+ qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_FIQ));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i + nc->num_cpus * 2,
+ qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_VIRQ));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i + nc->num_cpus * 3,
+ qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_VFIQ));
+
+ qdev_connect_gpio_out(DEVICE(&s->cpu[i]), GTIMER_PHYS,
+ qdev_get_gpio_in(DEVICE(&s->gic),
+ NPCM8XX_PPI_BASE(i) + ARM_PHYS_TIMER_PPI));
+ qdev_connect_gpio_out(DEVICE(&s->cpu[i]), GTIMER_VIRT,
+ qdev_get_gpio_in(DEVICE(&s->gic),
+ NPCM8XX_PPI_BASE(i) + ARM_VIRT_TIMER_PPI));
+ qdev_connect_gpio_out(DEVICE(&s->cpu[i]), GTIMER_HYP,
+ qdev_get_gpio_in(DEVICE(&s->gic),
+ NPCM8XX_PPI_BASE(i) + ARM_HYP_TIMER_PPI));
+ qdev_connect_gpio_out(DEVICE(&s->cpu[i]), GTIMER_SEC,
+ qdev_get_gpio_in(DEVICE(&s->gic),
+ NPCM8XX_PPI_BASE(i) + ARM_SEC_TIMER_PPI));
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 0, NPCM8XX_GICD_BA);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 1, NPCM8XX_GICC_BA);
+
+ /* CPU cluster */
+ qdev_prop_set_uint32(DEVICE(&s->cpu_cluster), "cluster-id", 0);
+ qdev_realize(DEVICE(&s->cpu_cluster), NULL, &error_fatal);
+
+ /* System Global Control Registers (GCR). Can fail due to user input. */
+ object_property_set_int(OBJECT(&s->gcr), "disabled-modules",
+ nc->disabled_modules, &error_abort);
+ object_property_add_const_link(OBJECT(&s->gcr), "dram-mr", OBJECT(s->dram));
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->gcr), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gcr), 0, NPCM8XX_GCR_BA);
+
+ /* Clock Control Registers (CLK). Cannot fail. */
+ sysbus_realize(SYS_BUS_DEVICE(&s->clk), &error_abort);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->clk), 0, NPCM8XX_CLK_BA);
+
+ /* OTP fuse strap array. Cannot fail. */
+ sysbus_realize(SYS_BUS_DEVICE(&s->fuse_array), &error_abort);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->fuse_array), 0, NPCM8XX_OTP_BA);
+ npcm8xx_init_fuses(s);
+
+ /* Fake Memory Controller (MC). Cannot fail. */
+ sysbus_realize(SYS_BUS_DEVICE(&s->mc), &error_abort);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->mc), 0, NPCM8XX_MC_BA);
+
+ /* ADC Modules. Cannot fail. */
+ qdev_connect_clock_in(DEVICE(&s->adc), "clock", qdev_get_clock_out(
+ DEVICE(&s->clk), "adc-clock"));
+ sysbus_realize(SYS_BUS_DEVICE(&s->adc), &error_abort);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->adc), 0, NPCM8XX_ADC_BA);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->adc), 0,
+ npcm8xx_irq(s, NPCM8XX_ADC_IRQ));
+ npcm8xx_write_adc_calibration(s);
+
+ /* Timer Modules (TIM). Cannot fail. */
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm8xx_tim_addr) != ARRAY_SIZE(s->tim));
+ for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->tim[i]);
+ int first_irq;
+ int j;
+
+ /* Connect the timer clock. */
+ qdev_connect_clock_in(DEVICE(&s->tim[i]), "clock", qdev_get_clock_out(
+ DEVICE(&s->clk), "timer-clock"));
+
+ sysbus_realize(sbd, &error_abort);
+ sysbus_mmio_map(sbd, 0, npcm8xx_tim_addr[i]);
+
+ first_irq = NPCM8XX_TIMER0_IRQ + i * NPCM7XX_TIMERS_PER_CTRL;
+ for (j = 0; j < NPCM7XX_TIMERS_PER_CTRL; j++) {
+ qemu_irq irq = npcm8xx_irq(s, first_irq + j);
+ sysbus_connect_irq(sbd, j, irq);
+ }
+
+ /* IRQ for watchdogs */
+ sysbus_connect_irq(sbd, NPCM7XX_TIMERS_PER_CTRL,
+ npcm8xx_irq(s, NPCM8XX_WDG0_IRQ + i));
+ /* GPIO that connects clk module with watchdog */
+ /* TODO: Check this.*/
+ qdev_connect_gpio_out_named(DEVICE(&s->tim[i]),
+ NPCM7XX_WATCHDOG_RESET_GPIO_OUT, 0,
+ qdev_get_gpio_in_named(DEVICE(&s->clk),
+ NPCM7XX_WATCHDOG_RESET_GPIO_IN, i));
+ }
+
+ /* UART0..6 (16550 compatible) */
+ for (i = 0; i < ARRAY_SIZE(npcm8xx_uart_addr); i++) {
+ serial_mm_init(get_system_memory(), npcm8xx_uart_addr[i], 2,
+ npcm8xx_irq(s, NPCM8XX_UART0_IRQ + i), 115200,
+ serial_hd(i), DEVICE_LITTLE_ENDIAN);
+ }
+
+ /* Random Number Generator. Cannot fail. */
+ sysbus_realize(SYS_BUS_DEVICE(&s->rng), &error_abort);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->rng), 0, NPCM8XX_RNG_BA);
+
+ /* GPIO modules. Cannot fail. */
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm8xx_gpio) != ARRAY_SIZE(s->gpio));
+ for (i = 0; i < ARRAY_SIZE(s->gpio); i++) {
+ Object *obj = OBJECT(&s->gpio[i]);
+
+ object_property_set_uint(obj, "reset-pullup",
+ npcm8xx_gpio[i].reset_pu, &error_abort);
+ object_property_set_uint(obj, "reset-pulldown",
+ npcm8xx_gpio[i].reset_pd, &error_abort);
+ object_property_set_uint(obj, "reset-osrc",
+ npcm8xx_gpio[i].reset_osrc, &error_abort);
+ object_property_set_uint(obj, "reset-odsc",
+ npcm8xx_gpio[i].reset_odsc, &error_abort);
+ sysbus_realize(SYS_BUS_DEVICE(obj), &error_abort);
+ sysbus_mmio_map(SYS_BUS_DEVICE(obj), 0, npcm8xx_gpio[i].regs_addr);
+ sysbus_connect_irq(SYS_BUS_DEVICE(obj), 0,
+ npcm8xx_irq(s, NPCM8XX_GPIO0_IRQ + i));
+ }
+
+ /* SMBus modules. Cannot fail. */
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm8xx_smbus_addr) != ARRAY_SIZE(s->smbus));
+ for (i = 0; i < ARRAY_SIZE(s->smbus); i++) {
+ Object *obj = OBJECT(&s->smbus[i]);
+
+ sysbus_realize(SYS_BUS_DEVICE(obj), &error_abort);
+ sysbus_mmio_map(SYS_BUS_DEVICE(obj), 0, npcm8xx_smbus_addr[i]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(obj), 0,
+ npcm8xx_irq(s, NPCM8XX_SMBUS0_IRQ + i));
+ }
+
+ /* USB Host */
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(s->ohci) != ARRAY_SIZE(s->ehci));
+ for (i = 0; i < ARRAY_SIZE(s->ehci); i++) {
+ object_property_set_bool(OBJECT(&s->ehci[i]), "companion-enable", true,
+ &error_abort);
+ sysbus_realize(SYS_BUS_DEVICE(&s->ehci[i]), &error_abort);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0, npcm8xx_ehci_addr[i]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0,
+ npcm8xx_irq(s, NPCM8XX_EHCI1_IRQ + 2 * i));
+ }
+ for (i = 0; i < ARRAY_SIZE(s->ohci); i++) {
+ object_property_set_str(OBJECT(&s->ohci[i]), "masterbus", "usb-bus.0",
+ &error_abort);
+ object_property_set_uint(OBJECT(&s->ohci[i]), "num-ports", 1,
+ &error_abort);
+ object_property_set_uint(OBJECT(&s->ohci[i]), "firstport", i,
+ &error_abort);
+ sysbus_realize(SYS_BUS_DEVICE(&s->ohci[i]), &error_abort);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ohci[i]), 0, npcm8xx_ohci_addr[i]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ohci[i]), 0,
+ npcm8xx_irq(s, NPCM8XX_OHCI1_IRQ + 2 * i));
+ }
+
+ /* PWM Modules. Cannot fail. */
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm8xx_pwm_addr) != ARRAY_SIZE(s->pwm));
+ for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->pwm[i]);
+
+ qdev_connect_clock_in(DEVICE(&s->pwm[i]), "clock", qdev_get_clock_out(
+ DEVICE(&s->clk), "apb3-clock"));
+ sysbus_realize(sbd, &error_abort);
+ sysbus_mmio_map(sbd, 0, npcm8xx_pwm_addr[i]);
+ sysbus_connect_irq(sbd, i, npcm8xx_irq(s, NPCM8XX_PWM0_IRQ + i));
+ }
+
+ /* MFT Modules. Cannot fail. */
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm8xx_mft_addr) != ARRAY_SIZE(s->mft));
+ for (i = 0; i < ARRAY_SIZE(s->mft); i++) {
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->mft[i]);
+
+ qdev_connect_clock_in(DEVICE(&s->mft[i]), "clock-in",
+ qdev_get_clock_out(DEVICE(&s->clk),
+ "apb4-clock"));
+ sysbus_realize(sbd, &error_abort);
+ sysbus_mmio_map(sbd, 0, npcm8xx_mft_addr[i]);
+ sysbus_connect_irq(sbd, 0, npcm8xx_irq(s, NPCM8XX_MFT0_IRQ + i));
+ }
+
+ /*
+ * Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
+ * specified, but this is a programming error.
+ */
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm8xx_fiu) != ARRAY_SIZE(s->fiu));
+ for (i = 0; i < ARRAY_SIZE(s->fiu); i++) {
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->fiu[i]);
+ int j;
+
+ object_property_set_int(OBJECT(sbd), "cs-count",
+ npcm8xx_fiu[i].cs_count, &error_abort);
+ object_property_set_int(OBJECT(sbd), "flash-size",
+ npcm8xx_fiu[i].flash_size, &error_abort);
+ sysbus_realize(sbd, &error_abort);
+
+ sysbus_mmio_map(sbd, 0, npcm8xx_fiu[i].regs_addr);
+ for (j = 0; j < npcm8xx_fiu[i].cs_count; j++) {
+ sysbus_mmio_map(sbd, j + 1, npcm8xx_fiu[i].flash_addr[j]);
+ }
+ }
+
+ /* RAM2 (SRAM) */
+ memory_region_init_ram(&s->sram, OBJECT(dev), "ram2",
+ NPCM8XX_RAM2_SZ, &error_abort);
+ memory_region_add_subregion(get_system_memory(), NPCM8XX_RAM2_BA, &s->sram);
+
+ /* RAM3 (SRAM) */
+ memory_region_init_ram(&s->ram3, OBJECT(dev), "ram3",
+ NPCM8XX_RAM3_SZ, &error_abort);
+ memory_region_add_subregion(get_system_memory(), NPCM8XX_RAM3_BA, &s->ram3);
+
+ /* Internal ROM */
+ memory_region_init_rom(&s->irom, OBJECT(dev), "irom", NPCM8XX_ROM_SZ,
+ &error_abort);
+ memory_region_add_subregion(get_system_memory(), NPCM8XX_ROM_BA, &s->irom);
+
+ /* SDHCI */
+ sysbus_realize(SYS_BUS_DEVICE(&s->mmc), &error_abort);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->mmc), 0, NPCM8XX_MMC_BA);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->mmc), 0,
+ npcm8xx_irq(s, NPCM8XX_MMC_IRQ));
+
+
+ create_unimplemented_device("npcm8xx.shm", 0xc0001000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.gicextra", 0xdfffa000, 24 * KiB);
+ create_unimplemented_device("npcm8xx.vdmx", 0xe0800000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.pcierc", 0xe1000000, 64 * KiB);
+ create_unimplemented_device("npcm8xx.rootc", 0xe8000000, 128 * MiB);
+ create_unimplemented_device("npcm8xx.kcs", 0xf0007000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.gfxi", 0xf000e000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.fsw", 0xf000f000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.bt", 0xf0030000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.espi", 0xf009f000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.peci", 0xf0100000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.siox[1]", 0xf0101000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.siox[2]", 0xf0102000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.tmps", 0xf0188000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.pspi", 0xf0201000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.viru1", 0xf0204000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.viru2", 0xf0205000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.jtm1", 0xf0208000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.jtm2", 0xf0209000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.flm0", 0xf0210000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.flm1", 0xf0211000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.flm2", 0xf0212000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.flm3", 0xf0213000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.ahbpci", 0xf0400000, 1 * MiB);
+ create_unimplemented_device("npcm8xx.dap", 0xf0500000, 960 * KiB);
+ create_unimplemented_device("npcm8xx.mcphy", 0xf05f0000, 64 * KiB);
+ create_unimplemented_device("npcm8xx.pcs", 0xf0780000, 256 * KiB);
+ create_unimplemented_device("npcm8xx.tsgen", 0xf07fc000, 8 * KiB);
+ create_unimplemented_device("npcm8xx.gmac1", 0xf0802000, 8 * KiB);
+ create_unimplemented_device("npcm8xx.gmac2", 0xf0804000, 8 * KiB);
+ create_unimplemented_device("npcm8xx.gmac3", 0xf0806000, 8 * KiB);
+ create_unimplemented_device("npcm8xx.gmac4", 0xf0808000, 8 * KiB);
+ create_unimplemented_device("npcm8xx.copctl", 0xf080c000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.tipctl", 0xf080d000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.rst", 0xf080e000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.vcd", 0xf0810000, 64 * KiB);
+ create_unimplemented_device("npcm8xx.ece", 0xf0820000, 8 * KiB);
+ create_unimplemented_device("npcm8xx.vdma", 0xf0822000, 8 * KiB);
+ create_unimplemented_device("npcm8xx.usbd[0]", 0xf0830000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.usbd[1]", 0xf0831000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.usbd[2]", 0xf0832000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.usbd[3]", 0xf0833000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.usbd[4]", 0xf0834000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.usbd[5]", 0xf0835000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.usbd[6]", 0xf0836000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.usbd[7]", 0xf0837000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.usbd[8]", 0xf0838000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.usbd[9]", 0xf0839000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.pci_mbox1", 0xf0848000, 64 * KiB);
+ create_unimplemented_device("npcm8xx.gdma0", 0xf0850000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.gdma1", 0xf0851000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.gdma2", 0xf0852000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.aes", 0xf0858000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.des", 0xf0859000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.sha", 0xf085a000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.pci_mbox2", 0xf0868000, 64 * KiB);
+ create_unimplemented_device("npcm8xx.i3c0", 0xfff10000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.i3c1", 0xfff11000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.i3c2", 0xfff12000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.i3c3", 0xfff13000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.i3c4", 0xfff14000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.i3c5", 0xfff15000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.spixcs0", 0xf8000000, 16 * MiB);
+ create_unimplemented_device("npcm8xx.spixcs1", 0xf9000000, 16 * MiB);
+ create_unimplemented_device("npcm8xx.spix", 0xfb001000, 4 * KiB);
+ create_unimplemented_device("npcm8xx.vect", 0xffff0000, 256);
+}
+
+static const Property npcm8xx_properties[] = {
+ DEFINE_PROP_LINK("dram-mr", NPCM8xxState, dram, TYPE_MEMORY_REGION,
+ MemoryRegion *),
+};
+
+static void npcm8xx_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ NPCM8xxClass *nc = NPCM8XX_CLASS(oc);
+
+ dc->realize = npcm8xx_realize;
+ dc->user_creatable = false;
+ nc->disabled_modules = 0x00000000;
+ nc->num_cpus = NPCM8XX_MAX_NUM_CPUS;
+ device_class_set_props(dc, npcm8xx_properties);
+}
+
+static const TypeInfo npcm8xx_soc_types[] = {
+ {
+ .name = TYPE_NPCM8XX,
+ .parent = TYPE_DEVICE,
+ .instance_size = sizeof(NPCM8xxState),
+ .instance_init = npcm8xx_init,
+ .class_size = sizeof(NPCM8xxClass),
+ .class_init = npcm8xx_class_init,
+ },
+};
+
+DEFINE_TYPES(npcm8xx_soc_types);
diff --git a/include/hw/arm/npcm8xx.h b/include/hw/arm/npcm8xx.h
new file mode 100644
index 0000000000..1f7e3d8116
--- /dev/null
+++ b/include/hw/arm/npcm8xx.h
@@ -0,0 +1,107 @@
+/*
+ * Nuvoton NPCM8xx SoC family.
+ *
+ * Copyright 2022 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#ifndef NPCM8XX_H
+#define NPCM8XX_H
+
+#include "hw/boards.h"
+#include "hw/adc/npcm7xx_adc.h"
+#include "hw/core/split-irq.h"
+#include "hw/cpu/cluster.h"
+#include "hw/gpio/npcm7xx_gpio.h"
+#include "hw/i2c/npcm7xx_smbus.h"
+#include "hw/intc/arm_gic_common.h"
+#include "hw/mem/npcm7xx_mc.h"
+#include "hw/misc/npcm_clk.h"
+#include "hw/misc/npcm_gcr.h"
+#include "hw/misc/npcm7xx_mft.h"
+#include "hw/misc/npcm7xx_pwm.h"
+#include "hw/misc/npcm7xx_rng.h"
+#include "hw/net/npcm7xx_emc.h"
+#include "hw/nvram/npcm7xx_otp.h"
+#include "hw/sd/npcm7xx_sdhci.h"
+#include "hw/timer/npcm7xx_timer.h"
+#include "hw/ssi/npcm7xx_fiu.h"
+#include "hw/usb/hcd-ehci.h"
+#include "hw/usb/hcd-ohci.h"
+#include "target/arm/cpu.h"
+
+#define NPCM8XX_MAX_NUM_CPUS (4)
+
+/* The first half of the address space is reserved for DDR4 DRAM. */
+#define NPCM8XX_DRAM_BA (0x00000000)
+#define NPCM8XX_DRAM_SZ (2 * GiB)
+
+/* Magic addresses for setting up direct kernel booting and SMP boot stubs. */
+#define NPCM8XX_LOADER_START (0x00000000) /* Start of SDRAM */
+#define NPCM8XX_SMP_LOADER_START (0xffff0000) /* Boot ROM */
+#define NPCM8XX_SMP_BOOTREG_ADDR (0xf080013c) /* GCR.SCRPAD */
+#define NPCM8XX_BOARD_SETUP_ADDR (0xffff1000) /* Boot ROM */
+
+#define NPCM8XX_NR_PWM_MODULES 3
+
+typedef struct NPCM8xxState {
+ DeviceState parent;
+
+ ARMCPU cpu[NPCM8XX_MAX_NUM_CPUS];
+ CPUClusterState cpu_cluster;
+ GICState gic;
+
+ MemoryRegion sram;
+ MemoryRegion irom;
+ MemoryRegion ram3;
+ MemoryRegion *dram;
+
+ NPCMGCRState gcr;
+ NPCMCLKState clk;
+ NPCM7xxTimerCtrlState tim[3];
+ NPCM7xxADCState adc;
+ NPCM7xxPWMState pwm[NPCM8XX_NR_PWM_MODULES];
+ NPCM7xxMFTState mft[8];
+ NPCM7xxOTPState fuse_array;
+ NPCM7xxMCState mc;
+ NPCM7xxRNGState rng;
+ NPCM7xxGPIOState gpio[8];
+ NPCM7xxSMBusState smbus[27];
+ EHCISysBusState ehci[2];
+ OHCISysBusState ohci[2];
+ NPCM7xxFIUState fiu[3];
+ NPCM7xxSDHCIState mmc;
+} NPCM8xxState;
+
+typedef struct NPCM8xxClass {
+ DeviceClass parent;
+
+ /* Bitmask of modules that are permanently disabled on this chip. */
+ uint32_t disabled_modules;
+ /* Number of CPU cores enabled in this SoC class. */
+ uint32_t num_cpus;
+} NPCM8xxClass;
+
+#define TYPE_NPCM8XX "npcm8xx"
+OBJECT_DECLARE_TYPE(NPCM8xxState, NPCM8xxClass, NPCM8XX)
+
+/**
+ * npcm8xx_load_kernel - Loads memory with everything needed to boot
+ * @machine - The machine containing the SoC to be booted.
+ * @soc - The SoC containing the CPU to be booted.
+ *
+ * This will set up the ARM boot info structure for the specific NPCM8xx
+ * derivative and call arm_load_kernel() to set up loading of the kernel, etc.
+ * into memory, if requested by the user.
+ */
+void npcm8xx_load_kernel(MachineState *machine, NPCM8xxState *soc);
+
+#endif /* NPCM8XX_H */
--
2.47.1.613.gc27f4b7a9f-goog
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 16/17] hw/arm: Add NPCM8XX SoC
2024-12-26 8:27 ` [PATCH v2 16/17] hw/arm: Add NPCM8XX SoC Hao Wu
@ 2025-02-04 16:28 ` Peter Maydell
0 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2025-02-04 16:28 UTC (permalink / raw)
To: Hao Wu
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, hskinnemoen,
venture, pbonzini, jasowang, alistair
On Thu, 26 Dec 2024 at 08:29, Hao Wu <wuhaotsh@google.com> wrote:
>
> Signed-off-by: Hao Wu <wuhaotsh@google.com>
> ---
> configs/devices/aarch64-softmmu/default.mak | 1 +
> hw/arm/Kconfig | 11 +
> hw/arm/meson.build | 1 +
> hw/arm/npcm8xx.c | 810 ++++++++++++++++++++
> include/hw/arm/npcm8xx.h | 107 +++
> 5 files changed, 930 insertions(+)
> create mode 100644 hw/arm/npcm8xx.c
> create mode 100644 include/hw/arm/npcm8xx.h
>
> diff --git a/configs/devices/aarch64-softmmu/default.mak b/configs/devices/aarch64-softmmu/default.mak
> index f82a04c27d..5ea1cc2dd1 100644
> --- a/configs/devices/aarch64-softmmu/default.mak
> +++ b/configs/devices/aarch64-softmmu/default.mak
> @@ -8,3 +8,4 @@ include ../arm-softmmu/default.mak
> # CONFIG_XLNX_ZYNQMP_ARM=n
> # CONFIG_XLNX_VERSAL=n
> # CONFIG_SBSA_REF=n
> +CONFIG_NPCM8XX=y
This should be a commented-out "n" (the way we arrange
this has flipped around since you originally wrote
the board support).
> diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> index e779b5af95..4fd5a41739 100644
> --- a/hw/arm/Kconfig
> +++ b/hw/arm/Kconfig
> @@ -481,6 +481,17 @@ config NPCM7XX
> select PCA954X
> select USB_OHCI_SYSBUS
>
> +config NPCM8XX
> + bool
> + select ARM_GIC
> + select SMBUS
> + select PL310 # cache controller
> + select NPCM7XX
> + select SERIAL
> + select SSI
> + select UNIMP
You want a "depends on TCG && ARM" clause: compare the
other stanzas in the file.
(This is the other half of the flipping-around noted above).
> config FSL_IMX25
> bool
> default y
> diff --git a/hw/arm/meson.build b/hw/arm/meson.build
> index 490234b3b8..d7813c089c 100644
> --- a/hw/arm/meson.build
> +++ b/hw/arm/meson.build
> @@ -12,6 +12,7 @@ arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: files('musicpal.c'))
> arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.c'))
> arm_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex-stm32-h405.c'))
> arm_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx.c', 'npcm7xx_boards.c'))
> +arm_ss.add(when: 'CONFIG_NPCM8XX', if_true: files('npcm8xx.c'))
> arm_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview.c'))
> arm_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa-ref.c'))
> arm_ss.add(when: 'CONFIG_STELLARIS', if_true: files('stellaris.c'))
> diff --git a/hw/arm/npcm8xx.c b/hw/arm/npcm8xx.c
> new file mode 100644
> index 0000000000..ed4185f37d
> --- /dev/null
> +++ b/hw/arm/npcm8xx.c
> @@ -0,0 +1,810 @@
> +/*
> + * Nuvoton NPCM8xx SoC family.
> + *
> + * Copyright 2022 Google LLC
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
> + * for more details.
> + */
> +
> +#include "qemu/osdep.h"
> +
> +#include "hw/arm/boot.h"
> +#include "hw/arm/npcm8xx.h"
> +#include "hw/char/serial-mm.h"
> +#include "hw/intc/arm_gic.h"
> +#include "hw/loader.h"
> +#include "hw/misc/unimp.h"
> +#include "hw/qdev-clock.h"
> +#include "hw/qdev-properties.h"
> +#include "qapi/error.h"
> +#include "qemu/units.h"
> +#include "system/system.h"
> +
> +#define ARM_PHYS_TIMER_PPI 30
> +#define ARM_VIRT_TIMER_PPI 27
> +#define ARM_HYP_TIMER_PPI 26
> +#define ARM_SEC_TIMER_PPI 29
We have defines for these basically-standardized IRQ
numbers in include/hw/arm/bsa.h now.
> +
> +/*
> + * This covers the whole MMIO space. We'll use this to catch any MMIO accesses
> + * that aren't handled by a device.
> + */
> +#define NPCM8XX_MMIO_BA (0x80000000)
> +#define NPCM8XX_MMIO_SZ (0x7ffd0000)
You don't need brackets around simple constants in a #define.
> +/* Total number of GIC interrupts, including internal Cortex-A35 interrupts. */
> +#define NPCM8XX_NUM_IRQ (288)
> +#define NPCM8XX_PPI_BASE(cpu) ((NPCM8XX_NUM_IRQ - 32) + (cpu) * 32)
These "32"s should probably be "GIC_INTERNAL"s.
> + /* IRQ for watchdogs */
> + sysbus_connect_irq(sbd, NPCM7XX_TIMERS_PER_CTRL,
> + npcm8xx_irq(s, NPCM8XX_WDG0_IRQ + i));
> + /* GPIO that connects clk module with watchdog */
> + /* TODO: Check this.*/
Good idea :-)
> + qdev_connect_gpio_out_named(DEVICE(&s->tim[i]),
> + NPCM7XX_WATCHDOG_RESET_GPIO_OUT, 0,
> + qdev_get_gpio_in_named(DEVICE(&s->clk),
> + NPCM7XX_WATCHDOG_RESET_GPIO_IN, i));
> + }
Otherwise looks OK, but again, review by somebody who
knows the hardware would be nice.
thanks
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v2 17/17] hw/arm: Add NPCM845 Evaluation board
2024-12-26 8:27 [PATCH v2 00/17] hw/arm: Add NPCM8XX Support Hao Wu
` (15 preceding siblings ...)
2024-12-26 8:27 ` [PATCH v2 16/17] hw/arm: Add NPCM8XX SoC Hao Wu
@ 2024-12-26 8:28 ` Hao Wu
2025-02-04 16:08 ` Peter Maydell
16 siblings, 1 reply; 35+ messages in thread
From: Hao Wu @ 2024-12-26 8:28 UTC (permalink / raw)
To: peter.maydell
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, mimik-dev,
hskinnemoen, venture, pbonzini, jasowang, alistair, Hao Wu
Signed-off-by: Hao Wu <wuhaotsh@google.com>
---
hw/arm/meson.build | 2 +-
hw/arm/npcm8xx_boards.c | 256 +++++++++++++++++++++++++++++++++++++++
include/hw/arm/npcm8xx.h | 20 +++
3 files changed, 277 insertions(+), 1 deletion(-)
create mode 100644 hw/arm/npcm8xx_boards.c
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index d7813c089c..465c757f97 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -12,7 +12,7 @@ arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: files('musicpal.c'))
arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.c'))
arm_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex-stm32-h405.c'))
arm_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx.c', 'npcm7xx_boards.c'))
-arm_ss.add(when: 'CONFIG_NPCM8XX', if_true: files('npcm8xx.c'))
+arm_ss.add(when: 'CONFIG_NPCM8XX', if_true: files('npcm8xx.c', 'npcm8xx_boards.c'))
arm_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview.c'))
arm_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa-ref.c'))
arm_ss.add(when: 'CONFIG_STELLARIS', if_true: files('stellaris.c'))
diff --git a/hw/arm/npcm8xx_boards.c b/hw/arm/npcm8xx_boards.c
new file mode 100644
index 0000000000..079df695d3
--- /dev/null
+++ b/hw/arm/npcm8xx_boards.c
@@ -0,0 +1,256 @@
+/*
+ * Machine definitions for boards featuring an NPCM8xx SoC.
+ *
+ * Copyright 2021 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "chardev/char.h"
+#include "hw/arm/npcm8xx.h"
+#include "hw/core/cpu.h"
+#include "hw/loader.h"
+#include "hw/qdev-core.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu/datadir.h"
+#include "qemu/units.h"
+
+#define NPCM845_EVB_POWER_ON_STRAPS 0x000017ff
+
+static const char npcm8xx_default_bootrom[] = "npcm8xx_bootrom.bin";
+
+static void npcm8xx_load_bootrom(MachineState *machine, NPCM8xxState *soc)
+{
+ const char *bios_name = machine->firmware ?: npcm8xx_default_bootrom;
+ g_autofree char *filename = NULL;
+ int ret;
+
+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+ if (!filename) {
+ error_report("Could not find ROM image '%s'", bios_name);
+ if (!machine->kernel_filename) {
+ /* We can't boot without a bootrom or a kernel image. */
+ exit(1);
+ }
+ return;
+ }
+ ret = load_image_mr(filename, machine->ram);
+ if (ret < 0) {
+ error_report("Failed to load ROM image '%s'", filename);
+ exit(1);
+ }
+}
+
+static void npcm8xx_connect_flash(NPCM7xxFIUState *fiu, int cs_no,
+ const char *flash_type, DriveInfo *dinfo)
+{
+ DeviceState *flash;
+ qemu_irq flash_cs;
+
+ flash = qdev_new(flash_type);
+ if (dinfo) {
+ qdev_prop_set_drive(flash, "drive", blk_by_legacy_dinfo(dinfo));
+ }
+ qdev_realize_and_unref(flash, BUS(fiu->spi), &error_fatal);
+
+ flash_cs = qdev_get_gpio_in_named(flash, SSI_GPIO_CS, 0);
+ qdev_connect_gpio_out_named(DEVICE(fiu), "cs", cs_no, flash_cs);
+}
+
+static void npcm8xx_connect_dram(NPCM8xxState *soc, MemoryRegion *dram)
+{
+ memory_region_add_subregion(get_system_memory(), NPCM8XX_DRAM_BA, dram);
+
+ object_property_set_link(OBJECT(soc), "dram-mr", OBJECT(dram),
+ &error_abort);
+}
+
+static NPCM8xxState *npcm8xx_create_soc(MachineState *machine,
+ uint32_t hw_straps)
+{
+ NPCM8xxMachineClass *nmc = NPCM8XX_MACHINE_GET_CLASS(machine);
+ MachineClass *mc = MACHINE_CLASS(nmc);
+ Object *obj;
+
+ if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
+ error_report("This board can only be used with %s",
+ mc->default_cpu_type);
+ exit(1);
+ }
+
+ obj = object_new_with_props(nmc->soc_type, OBJECT(machine), "soc",
+ &error_abort, NULL);
+ object_property_set_uint(obj, "power-on-straps", hw_straps, &error_abort);
+
+ return NPCM8XX(obj);
+}
+
+static I2CBus *npcm8xx_i2c_get_bus(NPCM8xxState *soc, uint32_t num)
+{
+ g_assert(num < ARRAY_SIZE(soc->smbus));
+ return I2C_BUS(qdev_get_child_bus(DEVICE(&soc->smbus[num]), "i2c-bus"));
+}
+
+static void npcm8xx_init_pwm_splitter(NPCM8xxMachine *machine,
+ NPCM8xxState *soc, const int *fan_counts)
+{
+ SplitIRQ *splitters = machine->fan_splitter;
+
+ /*
+ * PWM 0~3 belong to module 0 output 0~3.
+ * PWM 4~7 belong to module 1 output 0~3.
+ */
+ for (int i = 0; i < NPCM8XX_NR_PWM_MODULES; ++i) {
+ for (int j = 0; j < NPCM7XX_PWM_PER_MODULE; ++j) {
+ int splitter_no = i * NPCM7XX_PWM_PER_MODULE + j;
+ DeviceState *splitter;
+
+ if (fan_counts[splitter_no] < 1) {
+ continue;
+ }
+ object_initialize_child(OBJECT(machine), "fan-splitter[*]",
+ &splitters[splitter_no], TYPE_SPLIT_IRQ);
+ splitter = DEVICE(&splitters[splitter_no]);
+ qdev_prop_set_uint16(splitter, "num-lines",
+ fan_counts[splitter_no]);
+ qdev_realize(splitter, NULL, &error_abort);
+ qdev_connect_gpio_out_named(DEVICE(&soc->pwm[i]), "duty-gpio-out",
+ j, qdev_get_gpio_in(splitter, 0));
+ }
+ }
+}
+
+static void npcm8xx_connect_pwm_fan(NPCM8xxState *soc, SplitIRQ *splitter,
+ int fan_no, int output_no)
+{
+ DeviceState *fan;
+ int fan_input;
+ qemu_irq fan_duty_gpio;
+
+ g_assert(fan_no >= 0 && fan_no <= NPCM7XX_MFT_MAX_FAN_INPUT);
+ /*
+ * Fan 0~1 belong to module 0 input 0~1.
+ * Fan 2~3 belong to module 1 input 0~1.
+ * ...
+ * Fan 14~15 belong to module 7 input 0~1.
+ * Fan 16~17 belong to module 0 input 2~3.
+ * Fan 18~19 belong to module 1 input 2~3.
+ */
+ if (fan_no < 16) {
+ fan = DEVICE(&soc->mft[fan_no / 2]);
+ fan_input = fan_no % 2;
+ } else {
+ fan = DEVICE(&soc->mft[(fan_no - 16) / 2]);
+ fan_input = fan_no % 2 + 2;
+ }
+
+ /* Connect the Fan to PWM module */
+ fan_duty_gpio = qdev_get_gpio_in_named(fan, "duty", fan_input);
+ qdev_connect_gpio_out(DEVICE(splitter), output_no, fan_duty_gpio);
+}
+
+static void npcm845_evb_i2c_init(NPCM8xxState *soc)
+{
+ /* tmp100 temperature sensor on SVB, tmp105 is compatible */
+ i2c_slave_create_simple(npcm8xx_i2c_get_bus(soc, 6), "tmp105", 0x48);
+}
+
+static void npcm845_evb_fan_init(NPCM8xxMachine *machine, NPCM8xxState *soc)
+{
+ SplitIRQ *splitter = machine->fan_splitter;
+ static const int fan_counts[] = {2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0};
+
+ npcm8xx_init_pwm_splitter(machine, soc, fan_counts);
+ npcm8xx_connect_pwm_fan(soc, &splitter[0], 0x00, 0);
+ npcm8xx_connect_pwm_fan(soc, &splitter[0], 0x01, 1);
+ npcm8xx_connect_pwm_fan(soc, &splitter[1], 0x02, 0);
+ npcm8xx_connect_pwm_fan(soc, &splitter[1], 0x03, 1);
+ npcm8xx_connect_pwm_fan(soc, &splitter[2], 0x04, 0);
+ npcm8xx_connect_pwm_fan(soc, &splitter[2], 0x05, 1);
+ npcm8xx_connect_pwm_fan(soc, &splitter[3], 0x06, 0);
+ npcm8xx_connect_pwm_fan(soc, &splitter[3], 0x07, 1);
+ npcm8xx_connect_pwm_fan(soc, &splitter[4], 0x08, 0);
+ npcm8xx_connect_pwm_fan(soc, &splitter[4], 0x09, 1);
+ npcm8xx_connect_pwm_fan(soc, &splitter[5], 0x0a, 0);
+ npcm8xx_connect_pwm_fan(soc, &splitter[5], 0x0b, 1);
+ npcm8xx_connect_pwm_fan(soc, &splitter[6], 0x0c, 0);
+ npcm8xx_connect_pwm_fan(soc, &splitter[6], 0x0d, 1);
+ npcm8xx_connect_pwm_fan(soc, &splitter[7], 0x0e, 0);
+ npcm8xx_connect_pwm_fan(soc, &splitter[7], 0x0f, 1);
+}
+
+static void npcm845_evb_init(MachineState *machine)
+{
+ NPCM8xxState *soc;
+
+ soc = npcm8xx_create_soc(machine, NPCM845_EVB_POWER_ON_STRAPS);
+ npcm8xx_connect_dram(soc, machine->ram);
+ qdev_realize(DEVICE(soc), NULL, &error_fatal);
+
+ npcm8xx_load_bootrom(machine, soc);
+ npcm8xx_connect_flash(&soc->fiu[0], 0, "w25q256", drive_get(IF_MTD, 0, 0));
+ npcm845_evb_i2c_init(soc);
+ npcm845_evb_fan_init(NPCM8XX_MACHINE(machine), soc);
+ npcm8xx_load_kernel(machine, soc);
+}
+
+static void npcm8xx_set_soc_type(NPCM8xxMachineClass *nmc, const char *type)
+{
+ NPCM8xxClass *sc = NPCM8XX_CLASS(object_class_by_name(type));
+ MachineClass *mc = MACHINE_CLASS(nmc);
+
+ nmc->soc_type = type;
+ mc->default_cpus = mc->min_cpus = mc->max_cpus = sc->num_cpus;
+}
+
+static void npcm8xx_machine_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
+ mc->no_floppy = 1;
+ mc->no_cdrom = 1;
+ mc->no_parallel = 1;
+ mc->default_ram_id = "ram";
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a53");
+}
+
+static void npcm845_evb_machine_class_init(ObjectClass *oc, void *data)
+{
+ NPCM8xxMachineClass *nmc = NPCM8XX_MACHINE_CLASS(oc);
+ MachineClass *mc = MACHINE_CLASS(oc);
+
+ npcm8xx_set_soc_type(nmc, TYPE_NPCM8XX);
+
+ mc->desc = "Nuvoton NPCM845 Evaluation Board (Cortex-A35)";
+ mc->init = npcm845_evb_init;
+ mc->default_ram_size = 1 * GiB;
+};
+
+static const TypeInfo npcm8xx_machine_types[] = {
+ {
+ .name = TYPE_NPCM8XX_MACHINE,
+ .parent = TYPE_MACHINE,
+ .instance_size = sizeof(NPCM8xxMachine),
+ .class_size = sizeof(NPCM8xxMachineClass),
+ .class_init = npcm8xx_machine_class_init,
+ .abstract = true,
+ }, {
+ .name = MACHINE_TYPE_NAME("npcm845-evb"),
+ .parent = TYPE_NPCM8XX_MACHINE,
+ .class_init = npcm845_evb_machine_class_init,
+ },
+};
+
+DEFINE_TYPES(npcm8xx_machine_types)
diff --git a/include/hw/arm/npcm8xx.h b/include/hw/arm/npcm8xx.h
index 1f7e3d8116..f465d1eeb5 100644
--- a/include/hw/arm/npcm8xx.h
+++ b/include/hw/arm/npcm8xx.h
@@ -52,6 +52,26 @@
#define NPCM8XX_NR_PWM_MODULES 3
+typedef struct NPCM8xxMachine {
+ MachineState parent;
+ /*
+ * PWM fan splitter. each splitter connects to one PWM output and
+ * multiple MFT inputs.
+ */
+ SplitIRQ fan_splitter[NPCM8XX_NR_PWM_MODULES *
+ NPCM7XX_PWM_PER_MODULE];
+} NPCM8xxMachine;
+
+
+typedef struct NPCM8xxMachineClass {
+ MachineClass parent;
+
+ const char *soc_type;
+} NPCM8xxMachineClass;
+
+#define TYPE_NPCM8XX_MACHINE MACHINE_TYPE_NAME("npcm8xx")
+OBJECT_DECLARE_TYPE(NPCM8xxMachine, NPCM8xxMachineClass, NPCM8XX_MACHINE)
+
typedef struct NPCM8xxState {
DeviceState parent;
--
2.47.1.613.gc27f4b7a9f-goog
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [PATCH v2 17/17] hw/arm: Add NPCM845 Evaluation board
2024-12-26 8:28 ` [PATCH v2 17/17] hw/arm: Add NPCM845 Evaluation board Hao Wu
@ 2025-02-04 16:08 ` Peter Maydell
0 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2025-02-04 16:08 UTC (permalink / raw)
To: Hao Wu
Cc: qemu-arm, qemu-devel, Avi.Fishman, kfting, titusr, hskinnemoen,
venture, pbonzini, jasowang, alistair
On Thu, 26 Dec 2024 at 08:29, Hao Wu <wuhaotsh@google.com> wrote:
>
> Signed-off-by: Hao Wu <wuhaotsh@google.com>
> ---
> hw/arm/meson.build | 2 +-
> hw/arm/npcm8xx_boards.c | 256 +++++++++++++++++++++++++++++++++++++++
> include/hw/arm/npcm8xx.h | 20 +++
> 3 files changed, 277 insertions(+), 1 deletion(-)
> create mode 100644 hw/arm/npcm8xx_boards.c
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread