Re: [PATCH v3 11/11] tests/qtest: Adding PCS Module test to GMAC Qtest

2023-10-17 Thread Hao Wu
On Tue, Oct 17, 2023 at 4:04 PM Nabih Estefan 
wrote:

> From: Nabih Estefan Diaz 
>
>  - Add PCS Register check to npcm_gmac-test
>
> Signed-off-by: Nabih Estefan Diaz 
>
Reviewed-by: Hao Wu 

> ---
>  tests/qtest/npcm_gmac-test.c | 134 ++-
>  1 file changed, 133 insertions(+), 1 deletion(-)
>
> diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
> index 84511fd915..1f0ad664f4 100644
> --- a/tests/qtest/npcm_gmac-test.c
> +++ b/tests/qtest/npcm_gmac-test.c
> @@ -20,6 +20,10 @@
>  /* Name of the GMAC Device */
>  #define TYPE_NPCM_GMAC "npcm-gmac"
>
> +/* Address of the PCS Module */
> +#define PCS_BASE_ADDRESS 0xf078
> +#define NPCM_PCS_IND_AC_BA 0x1fe
> +
>  typedef struct GMACModule {
>  int irq;
>  uint64_t base_addr;
> @@ -111,6 +115,62 @@ typedef enum NPCMRegister {
>  NPCM_GMAC_PTP_STNSUR = 0x714,
>  NPCM_GMAC_PTP_TAR = 0x718,
>  NPCM_GMAC_PTP_TTSR = 0x71c,
> +
> +/* PCS Registers */
> +NPCM_PCS_SR_CTL_ID1 = 0x3c0008,
> +NPCM_PCS_SR_CTL_ID2 = 0x3c000a,
> +NPCM_PCS_SR_CTL_STS = 0x3c0010,
> +
> +NPCM_PCS_SR_MII_CTRL = 0x3e,
> +NPCM_PCS_SR_MII_STS = 0x3e0002,
> +NPCM_PCS_SR_MII_DEV_ID1 = 0x3e0004,
> +NPCM_PCS_SR_MII_DEV_ID2 = 0x3e0006,
> +NPCM_PCS_SR_MII_AN_ADV = 0x3e0008,
> +NPCM_PCS_SR_MII_LP_BABL = 0x3e000a,
> +NPCM_PCS_SR_MII_AN_EXPN = 0x3e000c,
> +NPCM_PCS_SR_MII_EXT_STS = 0x3e001e,
> +
> +NPCM_PCS_SR_TIM_SYNC_ABL = 0x3e0e10,
> +NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_LWR = 0x3e0e12,
> +NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_UPR = 0x3e0e14,
> +NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_LWR = 0x3e0e16,
> +NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_UPR = 0x3e0e18,
> +NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_LWR = 0x3e0e1a,
> +NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_UPR = 0x3e0e1c,
> +NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_LWR = 0x3e0e1e,
> +NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_UPR = 0x3e0e20,
> +
> +NPCM_PCS_VR_MII_MMD_DIG_CTRL1 = 0x3f,
> +NPCM_PCS_VR_MII_AN_CTRL = 0x3f0002,
> +NPCM_PCS_VR_MII_AN_INTR_STS = 0x3f0004,
> +NPCM_PCS_VR_MII_TC = 0x3f0006,
> +NPCM_PCS_VR_MII_DBG_CTRL = 0x3f000a,
> +NPCM_PCS_VR_MII_EEE_MCTRL0 = 0x3f000c,
> +NPCM_PCS_VR_MII_EEE_TXTIMER = 0x3f0010,
> +NPCM_PCS_VR_MII_EEE_RXTIMER = 0x3f0012,
> +NPCM_PCS_VR_MII_LINK_TIMER_CTRL = 0x3f0014,
> +NPCM_PCS_VR_MII_EEE_MCTRL1 = 0x3f0016,
> +NPCM_PCS_VR_MII_DIG_STS = 0x3f0020,
> +NPCM_PCS_VR_MII_ICG_ERRCNT1 = 0x3f0022,
> +NPCM_PCS_VR_MII_MISC_STS = 0x3f0030,
> +NPCM_PCS_VR_MII_RX_LSTS = 0x3f0040,
> +NPCM_PCS_VR_MII_MP_TX_BSTCTRL0 = 0x3f0070,
> +NPCM_PCS_VR_MII_MP_TX_LVLCTRL0 = 0x3f0074,
> +NPCM_PCS_VR_MII_MP_TX_GENCTRL0 = 0x3f007a,
> +NPCM_PCS_VR_MII_MP_TX_GENCTRL1 = 0x3f007c,
> +NPCM_PCS_VR_MII_MP_TX_STS = 0x3f0090,
> +NPCM_PCS_VR_MII_MP_RX_GENCTRL0 = 0x3f00b0,
> +NPCM_PCS_VR_MII_MP_RX_GENCTRL1 = 0x3f00b2,
> +NPCM_PCS_VR_MII_MP_RX_LOS_CTRL0 = 0x3f00ba,
> +NPCM_PCS_VR_MII_MP_MPLL_CTRL0 = 0x3f00f0,
> +NPCM_PCS_VR_MII_MP_MPLL_CTRL1 = 0x3f00f2,
> +NPCM_PCS_VR_MII_MP_MPLL_STS = 0x3f0110,
> +NPCM_PCS_VR_MII_MP_MISC_CTRL2 = 0x3f0126,
> +NPCM_PCS_VR_MII_MP_LVL_CTRL = 0x3f0130,
> +NPCM_PCS_VR_MII_MP_MISC_CTRL0 = 0x3f0132,
> +NPCM_PCS_VR_MII_MP_MISC_CTRL1 = 0x3f0134,
> +NPCM_PCS_VR_MII_DIG_CTRL2 = 0x3f01c2,
> +NPCM_PCS_VR_MII_DIG_ERRCNT_SEL = 0x3f01c4,
>  } NPCMRegister;
>
>  static uint32_t gmac_read(QTestState *qts, const GMACModule *mod,
> @@ -119,6 +179,15 @@ static uint32_t gmac_read(QTestState *qts, const
> GMACModule *mod,
>  return qtest_readl(qts, mod->base_addr + regno);
>  }
>
> +static uint16_t pcs_read(QTestState *qts, const GMACModule *mod,
> +  NPCMRegister regno)
> +{
> +uint32_t write_value = (regno & 0x3ffe00) >> 9;
> +qtest_writel(qts, PCS_BASE_ADDRESS + NPCM_PCS_IND_AC_BA, write_value);
> +uint32_t read_offset = regno & 0x1ff;
> +return qtest_readl(qts, PCS_BASE_ADDRESS + read_offset);
> +}
> +
>  /* Check that GMAC registers are reset to default value */
>  static void test_init(gconstpointer test_data)
>  {
> @@ -129,7 +198,12 @@ static void test_init(gconstpointer test_data)
>  #define CHECK_REG32(regno, value) \
>  do { \
>  g_assert_cmphex(gmac_read(qts, mod, (regno)), ==, (value)); \
> -} while (0)
> +} while (0) ;
> +
> +#define CHECK_REG_PCS(regno, value) \
> +do { \
> +g_assert_cmphex(pcs_read(qts, mod, (regno)), ==, (value)); \
> +} while (0) ;
>
>  CHECK_REG32(NPCM_DMA_BUS_MODE, 0x00020100);
>  CHECK_REG32(NPCM_DMA_

Re: [PATCH v3 09/11] hw/net: GMAC Rx Implementation

2023-10-17 Thread Hao Wu
Please consolidate the commit message in this patch. I think we only need
to describe the functionality you implemented here (i.e. the receive (RX)
for the GMAC model) and how you did it. There's no need to keep the verbose
comment on each corner cases we had.



On Tue, Oct 17, 2023 at 4:04 PM Nabih Estefan 
wrote:

> From: Nabih Estefan Diaz 
>
> - Implementation of Receive function for packets
> - Implementation for reading and writing from and to descriptors in
>   memory for Rx
>
> NOTE: At this point in development we believe this function is working
> as intended, and the kernel supports these findings, but we need the
> Transmit function to work before we upload
>
> Signed-off-by: Nabih Estefan Diaz 
>
> hw/net: npcm_gmac Flush queued packets when starting RX
>
> When RX starts, we need to flush the queued packets so that they
> can be received by the GMAC device. Without this it won't work
> with TAP NIC device.
>
> Signed-off-by: Hao Wu 
>
> hw/net: Handle RX desc full in NPCM GMAC
>
> When RX descriptor list is full, it returns a DMA_STATUS for software to
> handle it. But there's no way to indicate the software ha handled all RX
> descriptors and the whole pipeline stalls.
>
> We do something similar to NPCM7XX EMC to handle this case.
>
> 1. Return packet size when RX descriptor is full, effectively dropping
> these packets in such a case.
> 2. When software clears RX descriptor full bit, continue receiving further
> packets by flushing QEMU packet queue.
>
> Signed-off-by: Hao Wu 
>
> hw/net: Receive and drop packets when descriptors are full in GMAC
>
> Effectively this allows QEMU to receive and drop incoming packets when
> RX descriptors are full. Similar to EMC, this lets GMAC to drop packets
> faster, especially during bootup sequence.
>
> Signed-off-by: Hao Wu 
>
> hw/net: Update frame_ptr during gmac_receive
>
> There was a bug that frame_ptr wasn't updated after receiving
> the first batch of data, causing the received data to be wrong
> when the frame is too large.
>
> Signed-off-by: Hao Wu 
>
> hw/net: Fix GMAC not detecting owned by software properly in RX
>
> RX should stop receiving when a descriptor is owned by software
> but currently implementation made it reversed (owned by DMA) instead.
>
> Signed-off-by: Hao Wu 
>
> hw/net: Fix GMAC receive problem
>
> Fix the following 2 problems in GMAC receive function:
>
> 1. When kernel driver disables GMAC RX interrupt and all descriptors
> are full, it will not send further interrupt to the kernel
> driver as the driver doesn't listen to NPCM_DMA_STATUS_RU.
> Since descriptors full indicates that there are packets received
> we should also set NPCM_DMA_STATUS_RI for firing the interrupt.
> 2. Kernel driver does not clear rdes0 from used descriptor so we need
> to clear it such that old flags are removed before setting new
> flags.
>
> Signed-off-by: Hao Wu 
> ---
>  hw/net/npcm_gmac.c | 356 ++---
>  include/hw/net/npcm_gmac.h |  28 +--
>  2 files changed, 342 insertions(+), 42 deletions(-)
>
> diff --git a/hw/net/npcm_gmac.c b/hw/net/npcm_gmac.c
> index 6f8109e0ee..a7c8b67223 100644
> --- a/hw/net/npcm_gmac.c
> +++ b/hw/net/npcm_gmac.c
> @@ -23,7 +23,11 @@
>  #include "hw/registerfields.h"
>  #include "hw/net/mii.h"
>  #include "hw/net/npcm_gmac.h"
> +#include "linux/if_ether.h"
>  #include "migration/vmstate.h"
> +#include "net/checksum.h"
> +#include "net/net.h"
> +#include "qemu/cutils.h"
>  #include "qemu/log.h"
>  #include "qemu/units.h"
>  #include "sysemu/dma.h"
> @@ -91,7 +95,6 @@ REG32(NPCM_GMAC_PTP_TTSR, 0x71c)
>  #define NPCM_DMA_BUS_MODE_SWR   BIT(0)
>
>  static const uint32_t npcm_gmac_cold_reset_values[NPCM_GMAC_NR_REGS] = {
> -/* Reduce version to 3.2 so that the kernel can enable interrupt. */
>
Why is this line removed?

>  [R_NPCM_GMAC_VERSION] = 0x1032,
>  [R_NPCM_GMAC_TIMER_CTRL]  = 0x03e8,
>  [R_NPCM_GMAC_MAC0_ADDR_HI]= 0x8000,
> @@ -146,6 +149,17 @@ static void gmac_phy_set_link(NPCMGMACState *s, bool
> active)
>
>  static bool gmac_can_receive(NetClientState *nc)
>  {
> +NPCMGMACState *gmac = NPCM_GMAC(qemu_get_nic_opaque(nc));
> +
> +/* If GMAC receive is disabled. */
> +if (!(gmac->regs[R_NPCM_GMAC_MAC_CONFIG] &
> NPCM_GMAC_MAC_CONFIG_RX_EN)) {
> +return false;
> +}
> +
> +/* If GMAC DMA RX is stopped. */
> +if (!(gmac->regs[R_NPCM_DMA_CONTROL] &
> NPCM_DMA_CONTROL_START_S

Re: [PATCH v3 08/11] hw/net: General GMAC Implementation

2023-10-17 Thread Hao Wu
On Tue, Oct 17, 2023 at 4:04 PM Nabih Estefan 
wrote:

> From: Nabih Estefan Diaz 
>
> - General GMAC Register handling
> - GMAC IRQ Handling
> - Added traces in some methods for debugging
> - Lots of declarations for accessing information on GMAC Descriptors
> (npcm_gmac.h file)
>
> NOTE: With code on this state, the GMAC can boot-up properly and will show
> up in the ifconfig command on the BMC
>
> Google-Rebase-Count: 1
> Signed-off-by: Nabih Estefan Diaz 
> Google-Bug-Id: 237557100
> Change-Id: I3a4332ee5bab31b919782031a77c5b943f45ca2f
>
Please remove the Google-specific hashes. (Only signed-off-by is needed.)

> ---
>  include/hw/net/npcm_gmac.h | 198 ++---
>  1 file changed, 184 insertions(+), 14 deletions(-)
>
> diff --git a/include/hw/net/npcm_gmac.h b/include/hw/net/npcm_gmac.h
> index e5729e83ea..c97eb6fe6e 100644
> --- a/include/hw/net/npcm_gmac.h
> +++ b/include/hw/net/npcm_gmac.h
> @@ -34,13 +34,15 @@ struct NPCMGMACRxDesc {
>  };
>
>  /* NPCMGMACRxDesc.flags values */
> -/* RDES2 and RDES3 are buffer address pointers */
> -/* Owner: 0 = software, 1 = gmac */
> -#define RX_DESC_RDES0_OWNER_MASK BIT(31)
> +/* RDES2 and RDES3 are buffer addresses */
> +/* Owner: 0 = software, 1 = dma */
> +#define RX_DESC_RDES0_OWN BIT(31)
>  /* Destination Address Filter Fail */
> -#define RX_DESC_RDES0_DEST_ADDR_FILT_FAIL_MASK BIT(30)
> -/* Frame length*/
> -#define RX_DESC_RDES0_FRAME_LEN_MASK(word) extract32(word, 16, 29)
> +#define RX_DESC_RDES0_DEST_ADDR_FILT_FAIL BIT(30)
> +/* Frame length */
> +#define RX_DESC_RDES0_FRAME_LEN_MASK(word) extract32(word, 16, 14)
> +/* Frame length Shift*/
> +#define RX_DESC_RDES0_FRAME_LEN_SHIFT 16
>  /* Error Summary */
>  #define RX_DESC_RDES0_ERR_SUMM_MASK BIT(15)
>  /* Descriptor Error */
> @@ -83,9 +85,9 @@ struct NPCMGMACRxDesc {
>  /* Receive Buffer 2 Size */
>  #define RX_DESC_RDES1_BFFR2_SZ_SHIFT 11
>  #define RX_DESC_RDES1_BFFR2_SZ_MASK(word) extract32(word, \
> -RX_DESC_RDES1_BFFR2_SZ_SHIFT, 10 + RX_DESC_RDES1_BFFR2_SZ_SHIFT)
> +RX_DESC_RDES1_BFFR2_SZ_SHIFT, 11)
>  /* Receive Buffer 1 Size */
> -#define RX_DESC_RDES1_BFFR1_SZ_MASK(word) extract32(word, 0, 10)
> +#define RX_DESC_RDES1_BFFR1_SZ_MASK(word) extract32(word, 0, 11)
>
>
>  struct NPCMGMACTxDesc {
> @@ -96,9 +98,9 @@ struct NPCMGMACTxDesc {
>  };
>
>  /* NPCMGMACTxDesc.flags values */
> -/* TDES2 and TDES3 are buffer address pointers */
> +/* TDES2 and TDES3 are buffer addresses */
>  /* Owner: 0 = software, 1 = gmac */
> -#define TX_DESC_TDES0_OWNER_MASK BIT(31)
> +#define TX_DESC_TDES0_OWN BIT(31)
>  /* Tx Time Stamp Status */
>  #define TX_DESC_TDES0_TTSS_MASK BIT(17)
>  /* IP Header Error */
> @@ -122,7 +124,7 @@ struct NPCMGMACTxDesc {
>  /* VLAN Frame */
>  #define TX_DESC_TDES0_VLAN_FRM_MASK BIT(7)
>  /* Collision Count */
> -#define TX_DESC_TDES0_COLL_CNT_MASK(word) extract32(word, 3, 6)
> +#define TX_DESC_TDES0_COLL_CNT_MASK(word) extract32(word, 3, 4)
>  /* Excessive Deferral */
>  #define TX_DESC_TDES0_EXCS_DEF_MASK BIT(2)
>  /* Underflow Error */
> @@ -137,7 +139,7 @@ struct NPCMGMACTxDesc {
>  /* Last Segment */
>  #define TX_DESC_TDES1_FIRST_SEG_MASK BIT(29)
>  /* Checksum Insertion Control */
> -#define TX_DESC_TDES1_CHKSM_INS_CTRL_MASK(word) extract32(word, 27, 28)
> +#define TX_DESC_TDES1_CHKSM_INS_CTRL_MASK(word) extract32(word, 27, 2)
>  /* Disable Cyclic Redundancy Check */
>  #define TX_DESC_TDES1_DIS_CDC_MASK BIT(26)
>  /* Transmit End of Ring */
> @@ -145,9 +147,9 @@ struct NPCMGMACTxDesc {
>  /* Secondary Address Chained */
>  #define TX_DESC_TDES1_SEC_ADDR_CHND_MASK BIT(24)
>  /* Transmit Buffer 2 Size */
> -#define TX_DESC_TDES1_BFFR2_SZ_MASK(word) extract32(word, 11, 21)
> +#define TX_DESC_TDES1_BFFR2_SZ_MASK(word) extract32(word, 11, 11)
>  /* Transmit Buffer 1 Size */
> -#define TX_DESC_TDES1_BFFR1_SZ_MASK(word) extract32(word, 0, 10)
> +#define TX_DESC_TDES1_BFFR1_SZ_MASK(word) extract32(word, 0, 11)
>
>  typedef struct NPCMGMACState {
>  SysBusDevice parent;
> @@ -165,4 +167,172 @@ typedef struct NPCMGMACState {
>  #define TYPE_NPCM_GMAC "npcm-gmac"
>  OBJECT_DECLARE_SIMPLE_TYPE(NPCMGMACState, NPCM_GMAC)
>
> +/* Mask for RO bits in Status */
> +#define NPCM_DMA_STATUS_RO_MASK(word) (word & 0xfffe)
> +/* Mask for RO bits in Status */
> +#define NPCM_DMA_STATUS_W1C_MASK(word) (word & 0x1e7ff)
> +
> +/* Transmit Process State */
> +#define NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT 20
> +/* Transmit States */
> +#define NPCM_DMA_STATUS_TX_STOPPED_STATE \
> +(0b000 << NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT)
> +#define NPCM_DMA_STATUS_TX_RUNNING_FETCHING_STATE \
> +(0b001 << NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT)
> +#define NPCM_DMA_STATUS_TX_RUNNING_WAITING_STATE \
> +(0b010 << NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT)
> +#define NPCM_DMA_STATUS_TX_RUNNING_READ_STATE \
> +(0b011 << NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT)
> +#define NPCM_DMA_STATUS_TX_SUSPENDED_STATE \
> +(0b110 << 

Re: [PATCH v3 07/11] include/hw/net: Implemented Classes and Masks for GMAC Descriptors

2023-10-17 Thread Hao Wu
On Tue, Oct 17, 2023 at 4:04 PM Nabih Estefan 
wrote:

> From: Nabih Estefan Diaz 
>
>  - Implemeted classes for GMAC Receive and Transmit Descriptors
>  - Implemented Masks for said descriptors
>
> Signed-off-by: Nabih Estefan Diaz 
>
Reviewed-by: Hao Wu 

> ---
>  hw/net/npcm_gmac.c   | 183 +++
>  hw/net/trace-events  |   9 ++
>  include/hw/net/npcm_gmac.h   |   2 -
>  tests/qtest/npcm_gmac-test.c |   2 +-
>  4 files changed, 150 insertions(+), 46 deletions(-)
>
> diff --git a/hw/net/npcm_gmac.c b/hw/net/npcm_gmac.c
> index 5ce632858d..6f8109e0ee 100644
> --- a/hw/net/npcm_gmac.c
> +++ b/hw/net/npcm_gmac.c
> @@ -32,7 +32,7 @@
>  REG32(NPCM_DMA_BUS_MODE, 0x1000)
>  REG32(NPCM_DMA_XMT_POLL_DEMAND, 0x1004)
>  REG32(NPCM_DMA_RCV_POLL_DEMAND, 0x1008)
> -REG32(NPCM_DMA_RCV_BASE_ADDR, 0x100c)
> +REG32(NPCM_DMA_RX_BASE_ADDR, 0x100c)
>  REG32(NPCM_DMA_TX_BASE_ADDR, 0x1010)
>  REG32(NPCM_DMA_STATUS, 0x1014)
>  REG32(NPCM_DMA_CONTROL, 0x1018)
> @@ -91,7 +91,8 @@ REG32(NPCM_GMAC_PTP_TTSR, 0x71c)
>  #define NPCM_DMA_BUS_MODE_SWR   BIT(0)
>
>  static const uint32_t npcm_gmac_cold_reset_values[NPCM_GMAC_NR_REGS] = {
> -[R_NPCM_GMAC_VERSION] = 0x1037,
> +/* Reduce version to 3.2 so that the kernel can enable interrupt. */
> +[R_NPCM_GMAC_VERSION] = 0x1032,
>  [R_NPCM_GMAC_TIMER_CTRL]  = 0x03e8,
>  [R_NPCM_GMAC_MAC0_ADDR_HI]= 0x8000,
>  [R_NPCM_GMAC_MAC0_ADDR_LO]= 0x,
> @@ -125,12 +126,12 @@ static const uint16_t phy_reg_init[] = {
>  [MII_EXTSTAT]   = 0x3000, /* 1000BASTE_T full-duplex capable */
>  };
>
> -static void npcm_gmac_soft_reset(NPCMGMACState *s)
> +static void npcm_gmac_soft_reset(NPCMGMACState *gmac)
>  {
> -memcpy(s->regs, npcm_gmac_cold_reset_values,
> +memcpy(gmac->regs, npcm_gmac_cold_reset_values,
> NPCM_GMAC_NR_REGS * sizeof(uint32_t));
>  /* Clear reset bits */
> -s->regs[R_NPCM_DMA_BUS_MODE] &= ~NPCM_DMA_BUS_MODE_SWR;
> +gmac->regs[R_NPCM_DMA_BUS_MODE] &= ~NPCM_DMA_BUS_MODE_SWR;
>  }
>
>  static void gmac_phy_set_link(NPCMGMACState *s, bool active)
> @@ -148,11 +149,53 @@ static bool gmac_can_receive(NetClientState *nc)
>  return true;
>  }
>
> -static ssize_t gmac_receive(NetClientState *nc, const uint8_t *buf,
> size_t len1)
> +/*
> + * Function that updates the GMAC IRQ
> + * It find the logical OR of the enabled bits for NIS (if enabled)
> + * It find the logical OR of the enabled bits for AIS (if enabled)
> + */
> +static void gmac_update_irq(NPCMGMACState *gmac)
>  {
> -return 0;
> +/*
> + * Check if the normal interrupts summery is enabled
> + * if so, add the bits for the summary that are enabled
> + */
> +if (gmac->regs[R_NPCM_DMA_INTR_ENA] & gmac->regs[R_NPCM_DMA_STATUS] &
> +(NPCM_DMA_INTR_ENAB_NIE_BITS))
> +{
> +gmac->regs[R_NPCM_DMA_STATUS] |=  NPCM_DMA_STATUS_NIS;
> +}
> +/*
> + * Check if the abnormal interrupts summery is enabled
> + * if so, add the bits for the summary that are enabled
> + */
> +if (gmac->regs[R_NPCM_DMA_INTR_ENA] & gmac->regs[R_NPCM_DMA_STATUS] &
> +(NPCM_DMA_INTR_ENAB_AIE_BITS))
> +{
> +gmac->regs[R_NPCM_DMA_STATUS] |=  NPCM_DMA_STATUS_AIS;
> +}
> +
> +/* Get the logical OR of both normal and abnormal interrupts */
> +int level = !!((gmac->regs[R_NPCM_DMA_STATUS] &
> +gmac->regs[R_NPCM_DMA_INTR_ENA] &
> +NPCM_DMA_STATUS_NIS) |
> +   (gmac->regs[R_NPCM_DMA_STATUS] &
> +   gmac->regs[R_NPCM_DMA_INTR_ENA] &
> +   NPCM_DMA_STATUS_AIS));
> +
> +/* Set the IRQ */
> +trace_npcm_gmac_update_irq(DEVICE(gmac)->canonical_path,
> +   gmac->regs[R_NPCM_DMA_STATUS],
> +   gmac->regs[R_NPCM_DMA_INTR_ENA],
> +   level);
> +qemu_set_irq(gmac->irq, level);
>  }
>
> +static ssize_t gmac_receive(NetClientState *nc, const uint8_t *buf,
> size_t len)
> +{
> +/* Placeholder */
> +return 0;
> +}
>  static void gmac_cleanup(NetClientState *nc)
>  {
>  /* Nothing to do yet. */
> @@ -166,7 +209,7 @@ static void gmac_set_link(NetClientState *nc)
>  gmac_phy_set_link(s, !nc->link_down);
>  }
>
> -static void npcm_gmac_mdio_access(NPCMGMACState *s, uint16_t v)
> +static void npcm_gmac_mdio_access(NPCMGMACState *gmac, uint16_t v)
>  {
>  bool busy = v &

Re: [PATCH v3 06/11] \tests/qtest: Creating qtest for GMAC Module

2023-10-17 Thread Hao Wu
You have an extra "\" in the title.

On Tue, Oct 17, 2023 at 4:04 PM Nabih Estefan 
wrote:

> From: Nabih Estefan Diaz 
>
>  - Created qtest to check initialization of registers in GMAC Module.
>  - Implemented test into Build File.
>
> Signed-off-by: Nabih Estefan Diaz 
> ---
>  tests/qtest/meson.build  |  11 +-
>  tests/qtest/npcm_gmac-test.c | 209 +++
>  2 files changed, 215 insertions(+), 5 deletions(-)
>  create mode 100644 tests/qtest/npcm_gmac-test.c
>
> diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
> index 05d26e9292..3ff9f5d364 100644
> --- a/tests/qtest/meson.build
> +++ b/tests/qtest/meson.build
> @@ -191,6 +191,8 @@ qtests_npcm7xx = \
> 'npcm7xx_timer-test',
> 'npcm7xx_watchdog_timer-test'] + \
> (slirp.found() ? ['npcm7xx_emc-test'] : [])
> +qtests_npcm8xx = \
> +  ['npcm_gmac-test']
>
I haven't sent 8xx code yet (which I should do, sorry!). Maybe we should
remove 8xx related config for now?

>  qtests_aspeed = \
>['aspeed_hace-test',
> 'aspeed_smc-test',
> @@ -205,9 +207,7 @@ qtests_arm = \
>(config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed : [])
> + \
>(config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
>(config_all_devices.has_key('CONFIG_GENERIC_LOADER') ?
> ['hexloader-test'] : []) + \
> -  (config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ?
> ['tpm-tis-i2c-test'] : []) + \
> -  (config_all_devices.has_key('CONFIG_VEXPRESS') ? ['test-arm-mptimer'] :
> []) + \
> -  (config_all_devices.has_key('CONFIG_MICROBIT') ? ['microbit-test'] :
> []) + \
> +  (config_all_devices.has_key('CONFIG_NPCM8XX') ? qtests_npcm8xx : []) + \
>
ditto.

>['arm-cpu-features',
> 'boot-serial-test']
>
> @@ -219,8 +219,9 @@ qtests_aarch64 = \
>(config_all_devices.has_key('CONFIG_XLNX_ZYNQMP_ARM') ?
> ['xlnx-can-test', 'fuzz-xlnx-dp-test'] : []) + \
>(config_all_devices.has_key('CONFIG_XLNX_VERSAL') ? ['xlnx-canfd-test']
> : []) + \
>(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] :
> []) +  \
> -  (config_all.has_key('CONFIG_TCG') and
>   \
> -   config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ?
> ['tpm-tis-i2c-test'] : []) + \
> +  (config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed : [])
> + \
> +  (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
> +  (config_all_devices.has_key('CONFIG_NPCM8XX') ? qtests_npcm8xx : []) + \
>
ditto

>['arm-cpu-features',
> 'numa-test',
> 'boot-serial-test',
> diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
> new file mode 100644
> index 00..30d27e8dcc
> --- /dev/null
> +++ b/tests/qtest/npcm_gmac-test.c
> @@ -0,0 +1,209 @@
> +/*
> + * QTests for Nuvoton NPCM7xx/8xx GMAC Modules.
> + *
> + * Copyright 2022 Google LLC
>
nit: could be 2023 right now?

> + *
> + * 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 "libqos/libqos.h"
> +
> +/* Name of the GMAC Device */
> +#define TYPE_NPCM_GMAC "npcm-gmac"
> +
> +typedef struct GMACModule {
> +int irq;
> +uint64_t base_addr;
> +} GMACModule;
> +
> +typedef struct TestData {
> +const GMACModule *module;
> +} TestData;
> +
> +/* Values extracted from hw/arm/npcm8xx.c */
>
I think 7xx and 8xx has the same config for GMAC. Maybe use 7xx for now?

> +static const GMACModule gmac_module_list[] = {
> +{
> +.irq= 14,
> +.base_addr  = 0xf0802000
> +},
> +{
> +.irq= 15,
> +.base_addr  = 0xf0804000
> +},
> +{
> +.irq= 16,
> +.base_addr  = 0xf0806000
> +},
> +{
> +.irq= 17,
> +.base_addr  = 0xf0808000
> +}
> +};
> +
> +/* Returns the index of the GMAC module. */
> +static int gmac_module_index(const GMACModule *mod)
> +{
> +ptrdiff_t diff = mod - gmac_module_list;
> +
> +g_assert_true(diff >= 0 && diff < ARRAY_SIZE(gmac_module_list));
> +
> +return diff;
> +}
> +
> +/* 32-bit register indices. Taken from npcm_gmac.c */
> +typedef enum NPCMRegister {
> +/* DMA Registers */
> +NPCM_DMA_BUS_MODE = 0x1000,
> +NPCM_DMA_XMT_POLL_DEMAND = 0x1004,
> +NPCM_DMA_RCV_POLL_DEMAND = 0x1008,
> +NPCM_DMA_RCV_BASE_ADDR = 0x100c,
> +NPCM_DMA_TX_BASE_ADDR = 0x1010,
> +NPCM_DMA_STATUS = 0x1014,
> +NPCM_DMA_CONTROL = 0x1018,
> +NPCM_DMA_INTR_ENA = 0x101c,
> +NPCM_DMA_MISSED_FRAME_CTR = 0x1020,
> +NPCM_DMA_HOST_TX_DESC = 

Re: [PATCH] hw/timer/npcm7xx_timer: Prevent timer from counting down past zero

2023-09-22 Thread Hao Wu
Is this related to this error?

https://lists.gnu.org/archive/html/qemu-devel/2023-09/msg04903.html

On Fri, Sep 22, 2023 at 11:14 AM Chris Rauer  wrote:

> The counter register is only 24-bits and counts down.  If the timer is
> running but the qtimer to reset it hasn't fired off yet, there is a chance
> the regster read can return an invalid result.
>
> Signed-off-by: Chris Rauer 
> ---
>  hw/timer/npcm7xx_timer.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/hw/timer/npcm7xx_timer.c b/hw/timer/npcm7xx_timer.c
> index 32f5e021f8..a8bd93aeb2 100644
> --- a/hw/timer/npcm7xx_timer.c
> +++ b/hw/timer/npcm7xx_timer.c
> @@ -138,6 +138,9 @@ static int64_t npcm7xx_timer_count_to_ns(NPCM7xxTimer
> *t, uint32_t count)
>  /* Convert a time interval in nanoseconds to a timer cycle count. */
>  static uint32_t npcm7xx_timer_ns_to_count(NPCM7xxTimer *t, int64_t ns)
>  {
> +if (ns < 0) {
> +return 0;
> +}
>  return clock_ns_to_ticks(t->ctrl->clock, ns) /
>  npcm7xx_tcsr_prescaler(t->tcsr);
>  }
> --
> 2.42.0.515.g380fc7ccd1-goog
>
>


Re: npcm7xx_timer-test.c is unreliable

2023-09-19 Thread Hao Wu
>
> Let me take a look at that. I suspect the timer is off by 1 tick due to
> some rounding errors.


Re: [PATCH v2 2/7] docs/specs: IPMI device emulation: main processor

2023-03-27 Thread Hao Wu
Thank you. I'll include the change in the next patch set when I refactor
patch v4 (which might take a while.)

On Sat, Mar 25, 2023 at 4:56 PM Corey Minyard  wrote:

> On Fri, Mar 24, 2023 at 04:08:59PM -0700, Hao Wu wrote:
> > From: Havard Skinnemoen 
> >
> > This document is an attempt to briefly document the existing IPMI
> > emulation support on the main processor. It provides the necessary
> > background for the BMC-side IPMI emulation proposed by the next patch.
> >
> > Signed-off-by: Havard Skinnemoen 
> > Signed-off-by: Hao Wu 
> > ---
> > +* An external BMC simulator or emulator, connected over a chardev
> > +  (``ipmi-bmc-extern``). `ipmi_sim
> > +  <
> https://sourceforge.net/p/openipmi/code/ci//master/tree/lanserv/README.ipmi_sim
> >`_
>
> Nit, you have a double slash above.
>
> Other than that, this does a good job of explaining things.  I'm good
> with these docs.
>
> -corey
>


Re: [PATCH v2 4/7] hw/ipmi: Refactor IPMI interface

2023-03-27 Thread Hao Wu
Hi, Cedric

The naming scheme is suggested by Corey in a previous review:

https://lists.gnu.org/archive/html/qemu-devel/2021-09/msg02691.html

I originally kept "IpmIBmc" for the host side code talking to BMC but it
might also cause confusion as well. I'm not sure which name is the best
here. Maybe Corey can shed some light on this one? Thank you!

Best Regards,

On Mon, Mar 27, 2023 at 5:34 AM Cédric Le Goater  wrote:

> Hello Hao,
>
> On 3/25/23 00:09, Hao Wu wrote:
> > This patch refactors the IPMI interface so that it can be used by both
> > the BMC side and core-side simulation.
> >
> > Detail changes:
> > (1) Split IPMIInterface into IPMIInterfaceHost (for host side
> >  simulation) and IPMIInterfaceClient (for BMC side simulation).
> > (2) rename handle_rsp -> handle_msg so the name fits both BMC side and
> >  Core side.
> > (3) Add a new class IPMICore. This class represents a simulator/external
> >  connection for both BMC and Core side emulation.
> > (4) Change the original IPMIBmc to IPMIBmcHost, representing host side
> >  simulation.
> > (5) Add a new type IPMIBmcClient representing BMC side simulation.
> > (6) Appy the changes to  the entire IPMI library.
>
> 'IPMIBmcHost' is a BMC object model (internal or external) and
> 'IPMIBmcClient' is a host object model ?
>
> [ ... ]
>
> > @@ -267,15 +267,15 @@ void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor)
> >* Instantiate the machine BMC. PowerNV uses the QEMU internal
> >* simulator but it could also be external.
> >*/
> > -IPMIBmc *pnv_bmc_create(PnvPnor *pnor)
> > +IPMIBmcHost *pnv_bmc_create(PnvPnor *pnor)
> >   {
> >   Object *obj;
> >
> >   obj = object_new(TYPE_IPMI_BMC_SIMULATOR);
> >   qdev_realize(DEVICE(obj), NULL, _fatal);
> > -pnv_bmc_set_pnor(IPMI_BMC(obj), pnor);
> > +pnv_bmc_set_pnor(IPMI_BMC_HOST(obj), pnor);
> >
> > -return IPMI_BMC(obj);
> > +return IPMI_BMC_HOST(obj);
>
> QEMU PowerNV machines model the host side of OpenPOWER systems which
> have an Aspeed SoC based BMC for management. The routine above creates
> an Aspeed *BMC* object model for the PowerNV *host* machine. I find
> 'IPMIBmcHost' confusing. It shouldn't have a 'Host' suffix I think.
>
> 'IPMIBmcClient' sounds ok, or 'IPMIBmcPeer' maybe.
>
> Thanks,
>
> C.
>
>


[PATCH v2 7/7] hw/ipmi: Add a KCS Module for NPCM7XX

2023-03-24 Thread Hao Wu
Add a KCS module for NPCM7xx SoC. This module implements the IPMI
responder interface and is responsible to communicate with an external
host via the KCS channels in an NPCM7xx SoC.

Note that we cannot directly use ipmi_kcs.c since the communication
direction is the opposite. For example, in READ_STATE, ipmi_kcs.c (core
side emulation) reads a message from BMC while npcm7xx_kcs.c
(BMC-side emulation) sends a message to the core.

Signed-off-by: Hao Wu 
Reviewed-by: Tyrone Ting 
---
 docs/system/arm/nuvoton.rst   |   1 -
 hw/arm/npcm7xx.c  |  10 +-
 hw/ipmi/meson.build   |   1 +
 hw/ipmi/npcm7xx_kcs.c | 590 ++
 hw/ipmi/trace-events  |   8 +
 hw/ipmi/trace.h   |   1 +
 include/hw/arm/npcm7xx.h  |   2 +
 include/hw/ipmi/npcm7xx_kcs.h | 103 ++
 meson.build   |   1 +
 9 files changed, 715 insertions(+), 2 deletions(-)
 create mode 100644 hw/ipmi/npcm7xx_kcs.c
 create mode 100644 hw/ipmi/trace-events
 create mode 100644 hw/ipmi/trace.h
 create mode 100644 include/hw/ipmi/npcm7xx_kcs.h

diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
index 0424cae4b0..5ed0afa06e 100644
--- a/docs/system/arm/nuvoton.rst
+++ b/docs/system/arm/nuvoton.rst
@@ -57,7 +57,6 @@ Missing devices
  * LPC/eSPI host-to-BMC interface, including
 
* Keyboard and mouse controller interface (KBCI)
-   * Keyboard Controller Style (KCS) channels
* BIOS POST code FIFO
* System Wake-up Control (SWC)
* Shared memory (SHM)
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 15ff21d047..1937a0e9b1 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -45,6 +45,7 @@
 #define NPCM7XX_CLK_BA  (0xf0801000)
 #define NPCM7XX_MC_BA   (0xf0824000)
 #define NPCM7XX_RNG_BA  (0xf000b000)
+#define NPCM7XX_KCS_BA  (0xf0007000)
 
 /* USB Host modules */
 #define NPCM7XX_EHCI_BA (0xf0806000)
@@ -83,6 +84,7 @@ enum NPCM7xxInterrupt {
 NPCM7XX_UART1_IRQ,
 NPCM7XX_UART2_IRQ,
 NPCM7XX_UART3_IRQ,
+NPCM7XX_KCS_HIB_IRQ = 9,
 NPCM7XX_EMC1RX_IRQ  = 15,
 NPCM7XX_EMC1TX_IRQ,
 NPCM7XX_MMC_IRQ = 26,
@@ -431,6 +433,7 @@ static void npcm7xx_init(Object *obj)
 TYPE_NPCM7XX_SMBUS);
 }
 
+object_initialize_child(obj, "kcs", >kcs, TYPE_NPCM7XX_KCS);
 object_initialize_child(obj, "ehci", >ehci, TYPE_NPCM7XX_EHCI);
 object_initialize_child(obj, "ohci", >ohci, TYPE_SYSBUS_OHCI);
 
@@ -612,6 +615,12 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
npcm7xx_irq(s, NPCM7XX_SMBUS0_IRQ + i));
 }
 
+/* KCS modules*/
+sysbus_realize(SYS_BUS_DEVICE(>kcs), _abort);
+sysbus_mmio_map(SYS_BUS_DEVICE(>kcs), 0, NPCM7XX_KCS_BA);
+sysbus_connect_irq(SYS_BUS_DEVICE(>kcs), 0,
+   npcm7xx_irq(s, NPCM7XX_KCS_HIB_IRQ));
+
 /* USB Host */
 object_property_set_bool(OBJECT(>ehci), "companion-enable", true,
  _abort);
@@ -741,7 +750,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 create_unimplemented_device("npcm7xx.shm",  0xc0001000,   4 * KiB);
 create_unimplemented_device("npcm7xx.vdmx", 0xe080,   4 * KiB);
 create_unimplemented_device("npcm7xx.pcierc",   0xe100,  64 * KiB);
-create_unimplemented_device("npcm7xx.kcs",  0xf0007000,   4 * KiB);
 create_unimplemented_device("npcm7xx.gfxi", 0xf000e000,   4 * KiB);
 create_unimplemented_device("npcm7xx.espi", 0xf009f000,   4 * KiB);
 create_unimplemented_device("npcm7xx.peci", 0xf010,   4 * KiB);
diff --git a/hw/ipmi/meson.build b/hw/ipmi/meson.build
index b1dd4710dc..3d8b030ba5 100644
--- a/hw/ipmi/meson.build
+++ b/hw/ipmi/meson.build
@@ -8,5 +8,6 @@ ipmi_ss.add(when: 'CONFIG_ISA_IPMI_BT', if_true: 
files('isa_ipmi_bt.c'))
 ipmi_ss.add(when: 'CONFIG_PCI_IPMI_BT', if_true: files('pci_ipmi_bt.c'))
 ipmi_ss.add(when: 'CONFIG_IPMI_SSIF', if_true: files('smbus_ipmi.c'))
 ipmi_ss.add(when: 'CONFIG_IPMI_HOST', if_true: files('ipmi_host_extern.c'))
+ipmi_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_kcs.c'))
 
 softmmu_ss.add_all(when: 'CONFIG_IPMI', if_true: ipmi_ss)
diff --git a/hw/ipmi/npcm7xx_kcs.c b/hw/ipmi/npcm7xx_kcs.c
new file mode 100644
index 00..d46f053b2c
--- /dev/null
+++ b/hw/ipmi/npcm7xx_kcs.c
@@ -0,0 +1,590 @@
+/*
+ * Nuvoton NPCM7xx KCS Module
+ *
+ * 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 usef

[PATCH v2 5/7] hw/ipmi: Take out common from ipmi_bmc_extern.c

2023-03-24 Thread Hao Wu
This patch refactors ipmi_bmc_extern.c and takes out the parts that can
be used both ipmi_bmc_extern.c and bmc_host_extern.c to a common file
ipmi_extern.c.

Now we have a connection called IPMIExtern which handles the connection,
and IPMIBmcExtern that handles core-side emulation specific stuff.

Basically most of the message transaction are moved. The stuff remained
are basically hardware operations like handle_reset and handle_hw_op.
These stuff have different behaviors in core-side and BMC-side
emulation.

Signed-off-by: Hao Wu 
---
 hw/ipmi/ipmi_bmc_extern.c | 420 --
 hw/ipmi/ipmi_extern.c | 418 +
 hw/ipmi/ipmi_extern.h |  90 
 hw/ipmi/meson.build   |   2 +-
 4 files changed, 545 insertions(+), 385 deletions(-)
 create mode 100644 hw/ipmi/ipmi_extern.c
 create mode 100644 hw/ipmi/ipmi_extern.h

diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c
index 67f6a5d829..2f44094ff7 100644
--- a/hw/ipmi/ipmi_bmc_extern.c
+++ b/hw/ipmi/ipmi_bmc_extern.c
@@ -34,210 +34,43 @@
 #include "qemu/timer.h"
 #include "chardev/char-fe.h"
 #include "hw/ipmi/ipmi.h"
+#include "hw/ipmi/ipmi_extern.h"
 #include "hw/qdev-properties.h"
 #include "hw/qdev-properties-system.h"
 #include "migration/vmstate.h"
 #include "qom/object.h"
 
-#define VM_MSG_CHAR0xA0 /* Marks end of message */
-#define VM_CMD_CHAR0xA1 /* Marks end of a command */
-#define VM_ESCAPE_CHAR 0xAA /* Set bit 4 from the next byte to 0 */
-
-#define VM_PROTOCOL_VERSION1
-#define VM_CMD_VERSION 0xff /* A version number byte follows */
-#define VM_CMD_NOATTN  0x00
-#define VM_CMD_ATTN0x01
-#define VM_CMD_ATTN_IRQ0x02
-#define VM_CMD_POWEROFF0x03
-#define VM_CMD_RESET   0x04
-#define VM_CMD_ENABLE_IRQ  0x05 /* Enable/disable the messaging irq */
-#define VM_CMD_DISABLE_IRQ 0x06
-#define VM_CMD_SEND_NMI0x07
-#define VM_CMD_CAPABILITIES0x08
-#define   VM_CAPABILITIES_POWER0x01
-#define   VM_CAPABILITIES_RESET0x02
-#define   VM_CAPABILITIES_IRQ  0x04
-#define   VM_CAPABILITIES_NMI  0x08
-#define   VM_CAPABILITIES_ATTN 0x10
-#define   VM_CAPABILITIES_GRACEFUL_SHUTDOWN 0x20
-#define VM_CMD_GRACEFUL_SHUTDOWN   0x09
-
 #define TYPE_IPMI_BMC_EXTERN "ipmi-bmc-extern"
 OBJECT_DECLARE_SIMPLE_TYPE(IPMIBmcExtern, IPMI_BMC_EXTERN)
+
 struct IPMIBmcExtern {
 IPMIBmcHost parent;
 
-CharBackend chr;
-
-bool connected;
-
-unsigned char inbuf[MAX_IPMI_MSG_SIZE + 2];
-unsigned int inpos;
-bool in_escape;
-bool in_too_many;
-bool waiting_rsp;
-bool sending_cmd;
-
-unsigned char outbuf[(MAX_IPMI_MSG_SIZE + 2) * 2 + 1];
-unsigned int outpos;
-unsigned int outlen;
-
-struct QEMUTimer *extern_timer;
+IPMIExtern conn;
 
 /* A reset event is pending to be sent upstream. */
 bool send_reset;
 };
 
-static unsigned char
-ipmb_checksum(const unsigned char *data, int size, unsigned char start)
+static void continue_send_bmc(IPMIBmcExtern *ibe)
 {
-unsigned char csum = start;
-
-for (; size > 0; size--, data++) {
-csum += *data;
-}
-return csum;
-}
-
-static void continue_send(IPMIBmcExtern *ibe)
-{
-int ret;
-if (ibe->outlen == 0) {
-goto check_reset;
-}
- send:
-ret = qemu_chr_fe_write(>chr, ibe->outbuf + ibe->outpos,
-ibe->outlen - ibe->outpos);
-if (ret > 0) {
-ibe->outpos += ret;
-}
-if (ibe->outpos < ibe->outlen) {
-/* Not fully transmitted, try again in a 10ms */
-timer_mod_ns(ibe->extern_timer,
- qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 1000);
-} else {
-/* Sent */
-ibe->outlen = 0;
-ibe->outpos = 0;
-if (!ibe->sending_cmd) {
-ibe->waiting_rsp = true;
-} else {
-ibe->sending_cmd = false;
-}
-check_reset:
-if (ibe->connected && ibe->send_reset) {
+if (continue_send(>conn)) {
+if (ibe->conn.connected && ibe->send_reset) {
 /* Send the reset */
-ibe->outbuf[0] = VM_CMD_RESET;
-ibe->outbuf[1] = VM_CMD_CHAR;
-ibe->outlen = 2;
-ibe->outpos = 0;
+ibe->conn.outbuf[0] = VM_CMD_RESET;
+ibe->conn.outbuf[1] = VM_CMD_CHAR;
+ibe->conn.outlen = 2;
+ibe->conn.outpos = 0;
 ibe->send_reset = false;
-ibe->sending_cmd = true;
-goto send;
-}
-
-if (ibe->waiting_rsp) {
-/* Make sure we get a response within 4 seconds. */
-timer_mod_ns(i

[PATCH v2 4/7] hw/ipmi: Refactor IPMI interface

2023-03-24 Thread Hao Wu
This patch refactors the IPMI interface so that it can be used by both
the BMC side and core-side simulation.

Detail changes:
(1) Split IPMIInterface into IPMIInterfaceHost (for host side
simulation) and IPMIInterfaceClient (for BMC side simulation).
(2) rename handle_rsp -> handle_msg so the name fits both BMC side and
Core side.
(3) Add a new class IPMICore. This class represents a simulator/external
connection for both BMC and Core side emulation.
(4) Change the original IPMIBmc to IPMIBmcHost, representing host side
simulation.
(5) Add a new type IPMIBmcClient representing BMC side simulation.
(6) Appy the changes to  the entire IPMI library.

Signed-off-by: Hao Wu 
---
 hw/acpi/ipmi.c |   4 +-
 hw/ipmi/ipmi.c |  60 +
 hw/ipmi/ipmi_bmc_extern.c  |  67 ++
 hw/ipmi/ipmi_bmc_sim.c |  78 -
 hw/ipmi/ipmi_bt.c  |  33 +
 hw/ipmi/ipmi_kcs.c |  31 +
 hw/ipmi/isa_ipmi_bt.c  |  18 ++---
 hw/ipmi/isa_ipmi_kcs.c |  13 ++--
 hw/ipmi/pci_ipmi_bt.c  |   8 +--
 hw/ipmi/pci_ipmi_kcs.c |   8 +--
 hw/ipmi/smbus_ipmi.c   |  26 +++
 hw/ppc/pnv.c   |   4 +-
 hw/ppc/pnv_bmc.c   |  22 +++---
 hw/smbios/smbios_type_38.c |  11 +--
 include/hw/ipmi/ipmi.h | 135 ++---
 include/hw/ipmi/ipmi_bt.h  |   2 +-
 include/hw/ipmi/ipmi_kcs.h |   2 +-
 include/hw/ppc/pnv.h   |  12 ++--
 18 files changed, 332 insertions(+), 202 deletions(-)

diff --git a/hw/acpi/ipmi.c b/hw/acpi/ipmi.c
index a20e57d465..e6d2cd790b 100644
--- a/hw/acpi/ipmi.c
+++ b/hw/acpi/ipmi.c
@@ -66,8 +66,8 @@ void build_ipmi_dev_aml(AcpiDevAmlIf *adev, Aml *scope)
 {
 Aml *dev;
 IPMIFwInfo info = {};
-IPMIInterface *ii = IPMI_INTERFACE(adev);
-IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii);
+IPMIInterfaceHost *ii = IPMI_INTERFACE_HOST(adev);
+IPMIInterfaceHostClass *iic = IPMI_INTERFACE_HOST_GET_CLASS(ii);
 uint16_t version;
 
 iic->get_fwinfo(ii, );
diff --git a/hw/ipmi/ipmi.c b/hw/ipmi/ipmi.c
index bbb07b151e..1be923ffb8 100644
--- a/hw/ipmi/ipmi.c
+++ b/hw/ipmi/ipmi.c
@@ -38,7 +38,7 @@ uint32_t ipmi_next_uuid(void)
 return ipmi_current_uuid++;
 }
 
-static int ipmi_do_hw_op(IPMIInterface *s, enum ipmi_op op, int checkonly)
+static int ipmi_do_hw_op(IPMIInterfaceHost *s, enum ipmi_op op, int checkonly)
 {
 switch (op) {
 case IPMI_RESET_CHASSIS:
@@ -78,9 +78,9 @@ static int ipmi_do_hw_op(IPMIInterface *s, enum ipmi_op op, 
int checkonly)
 }
 }
 
-static void ipmi_interface_class_init(ObjectClass *class, void *data)
+static void ipmi_interface_host_class_init(ObjectClass *class, void *data)
 {
-IPMIInterfaceClass *ik = IPMI_INTERFACE_CLASS(class);
+IPMIInterfaceHostClass *ik = IPMI_INTERFACE_HOST_CLASS(class);
 
 ik->do_hw_op = ipmi_do_hw_op;
 }
@@ -89,27 +89,48 @@ static const TypeInfo ipmi_interface_type_info = {
 .name = TYPE_IPMI_INTERFACE,
 .parent = TYPE_INTERFACE,
 .class_size = sizeof(IPMIInterfaceClass),
-.class_init = ipmi_interface_class_init,
+};
+
+static const TypeInfo ipmi_interface_host_type_info = {
+.name = TYPE_IPMI_INTERFACE_HOST,
+.parent = TYPE_IPMI_INTERFACE,
+.class_size = sizeof(IPMIInterfaceHostClass),
+.class_init = ipmi_interface_host_class_init,
+};
+
+static const TypeInfo ipmi_interface_client_type_info = {
+.name = TYPE_IPMI_INTERFACE_CLIENT,
+.parent = TYPE_IPMI_INTERFACE,
+.class_size = sizeof(IPMIInterfaceClientClass),
+};
+
+static const TypeInfo ipmi_core_type_info = {
+.name = TYPE_IPMI_CORE,
+.parent = TYPE_DEVICE,
+.instance_size = sizeof(IPMICore),
+.class_size = sizeof(IPMICoreClass),
+.abstract = true,
 };
 
 static void isa_ipmi_bmc_check(const Object *obj, const char *name,
Object *val, Error **errp)
 {
-IPMIBmc *bmc = IPMI_BMC(val);
+IPMICore *ic = IPMI_CORE(val);
 
-if (bmc->intf)
+if (ic->intf) {
 error_setg(errp, "BMC object is already in use");
+}
 }
 
 void ipmi_bmc_find_and_link(Object *obj, Object **bmc)
 {
-object_property_add_link(obj, "bmc", TYPE_IPMI_BMC, bmc,
+object_property_add_link(obj, "bmc", TYPE_IPMI_BMC_HOST, bmc,
  isa_ipmi_bmc_check,
  OBJ_PROP_LINK_STRONG);
 }
 
 static Property ipmi_bmc_properties[] = {
-DEFINE_PROP_UINT8("slave_addr",  IPMIBmc, slave_addr, 0x20),
+DEFINE_PROP_UINT8("slave_addr",  IPMIBmcHost, slave_addr, 0x20),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -120,19 +141,30 @@ static void bmc_class_init(ObjectClass *oc, void *data)
 device_class_set_props(dc, ipmi_bmc_properties);
 }
 
-static const TypeInfo ipmi_bmc_type_info = {
-.name = TYPE_IPMI_BMC,
-.parent = TYPE_DEVICE,
-.instance_size = sizeof(IPMIBmc),
+static const TypeInfo ipmi_bmc

[PATCH v2 6/7] hw/ipmi: Add an IPMI external host device

2023-03-24 Thread Hao Wu
The IPMI external host device works for Baseband Management Controller
(BMC) emulations. It works as a representation of a host class that
connects to a given BMC.  It can connect to a real host hardware or a
emulated or simulated host device. In particular it can connect to a
host QEMU instance with device ipmi-bmc-extern.

For more details of IPMI host device in BMC emulation, see
docs/specs/ipmi.rst.

Signed-off-by: Hao Wu 
---
 configs/devices/arm-softmmu/default.mak |   2 +
 hw/ipmi/Kconfig |   4 +
 hw/ipmi/ipmi_extern.c   |  18 ++-
 hw/ipmi/ipmi_host_extern.c  | 170 
 hw/ipmi/meson.build |   1 +
 include/hw/ipmi/ipmi.h  |   4 +
 6 files changed, 197 insertions(+), 2 deletions(-)
 create mode 100644 hw/ipmi/ipmi_host_extern.c

diff --git a/configs/devices/arm-softmmu/default.mak 
b/configs/devices/arm-softmmu/default.mak
index 1b49a7830c..76e902bc4b 100644
--- a/configs/devices/arm-softmmu/default.mak
+++ b/configs/devices/arm-softmmu/default.mak
@@ -25,6 +25,8 @@ CONFIG_GUMSTIX=y
 CONFIG_SPITZ=y
 CONFIG_TOSA=y
 CONFIG_Z2=y
+CONFIG_IPMI=y
+CONFIG_IPMI_HOST=y
 CONFIG_NPCM7XX=y
 CONFIG_COLLIE=y
 CONFIG_ASPEED_SOC=y
diff --git a/hw/ipmi/Kconfig b/hw/ipmi/Kconfig
index 9befd4f422..d767948b79 100644
--- a/hw/ipmi/Kconfig
+++ b/hw/ipmi/Kconfig
@@ -11,6 +11,10 @@ config IPMI_EXTERN
 default y
 depends on IPMI
 
+config IPMI_HOST
+bool
+depends on IPMI
+
 config ISA_IPMI_KCS
 bool
 depends on ISA_BUS
diff --git a/hw/ipmi/ipmi_extern.c b/hw/ipmi/ipmi_extern.c
index 185d20c337..b9466a4d58 100644
--- a/hw/ipmi/ipmi_extern.c
+++ b/hw/ipmi/ipmi_extern.c
@@ -145,11 +145,25 @@ void ipmi_extern_handle_command(IPMIExtern *ibe,
 if (err) {
 IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
 unsigned char rsp[3];
+
 rsp[0] = cmd[0] | 0x04;
 rsp[1] = cmd[1];
 rsp[2] = err;
-ibe->waiting_rsp = false;
-k->handle_msg(s, msg_id, rsp, 3);
+
+if (ibe->bmc_side) {
+/* For BMC Side, send out an error message. */
+addchar(ibe, msg_id);
+for (i = 0; i < 3; ++i) {
+addchar(ibe, rsp[i]);
+}
+csum = ipmb_checksum(_id, 1, 0);
+addchar(ibe, -ipmb_checksum(rsp, 3, csum));
+continue_send(ibe);
+} else {
+/* For Core side, handle an error message. */
+ibe->waiting_rsp = false;
+k->handle_msg(s, msg_id, rsp, 3);
+}
 goto out;
 }
 
diff --git a/hw/ipmi/ipmi_host_extern.c b/hw/ipmi/ipmi_host_extern.c
new file mode 100644
index 00..c70f968eef
--- /dev/null
+++ b/hw/ipmi/ipmi_host_extern.c
@@ -0,0 +1,170 @@
+/*
+ * IPMI Host external connection
+ *
+ * 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.
+ */
+
+/*
+ * This is designed to connect to a host QEMU VM that runs ipmi_bmc_extern.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "qemu/module.h"
+#include "qapi/error.h"
+#include "chardev/char-fe.h"
+#include "hw/ipmi/ipmi.h"
+#include "hw/ipmi/ipmi_extern.h"
+#include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
+#include "migration/vmstate.h"
+#include "qom/object.h"
+
+#define TYPE_IPMI_HOST_EXTERN "ipmi-host-extern"
+OBJECT_DECLARE_SIMPLE_TYPE(IPMIHostExtern, IPMI_HOST_EXTERN)
+
+typedef struct IPMIHostExtern {
+IPMICore parent;
+
+IPMIExtern conn;
+
+IPMIInterface *responder;
+
+uint8_t capability;
+} IPMIHostExtern;
+
+/*
+ * Handle a command (typically IPMI response) from IPMI interface
+ * and send it out to the external host.
+ */
+static void ipmi_host_extern_handle_command(IPMICore *h, uint8_t *cmd,
+unsigned cmd_len, unsigned max_cmd_len, uint8_t msg_id)
+{
+IPMIHostExtern *ihe = IPMI_HOST_EXTERN(h);
+
+ipmi_extern_handle_command(>conn, cmd, cmd_len, max_cmd_len, msg_id);
+}
+
+/* This function handles a control command from the host. */
+static void ipmi_host_extern_handle_hw_op(IPMICore *ic, uint8_t cmd,
+  uint8_t operand)
+{
+IPMIHostExtern *ihe = IPMI_HOST_EXTERN(ic);
+
+switch (cmd) {
+case VM_CMD_VERSION:
+/* The host informs us the protocol version. */
+if (unlikely(operand != V

[PATCH v2 3/7] docs/specs: IPMI device emulation: BMC

2023-03-24 Thread Hao Wu
From: Havard Skinnemoen 

The IPMI document is expanded with a proposal to emulate BMC-side IPMI
devices. This allows a QEMU instance running server software to interact
with a different QEMU instance running BMC firmware, which should
closely model how a real server system works.

Signed-off-by: Havard Skinnemoen 
Signed-off-by: Hao Wu 
---
 docs/specs/ipmi.rst | 70 +
 1 file changed, 70 insertions(+)

diff --git a/docs/specs/ipmi.rst b/docs/specs/ipmi.rst
index e0badc7f15..b06ad74728 100644
--- a/docs/specs/ipmi.rst
+++ b/docs/specs/ipmi.rst
@@ -91,6 +91,76 @@ further delegated to an external emulator, or a real BMC. The
 ``ipmi-bmc-extern`` device has a required ``chardev`` property which specifies
 the communications channel to the external BMC.
 
+Baseband Management Controller (BMC) emulation
+==
+
+This section is about emulation of IPMI-related devices in a System-on-Chip
+(SoC) used as a Baseband Management Controller. This is not to be confused with
+emulating the BMC device as seen by the main processor.
+
+SoCs that are designed to be used as a BMC often have dedicated hardware that
+allows them to be connected to one or more of the IPMI System Interfaces. The
+BMC-side hardware interface is not standardized, so each type of SoC may need
+its own device implementation in QEMU, for example:
+
+* ``aspeed-ibt`` for emulating the Aspeed iBT peripheral.
+* ``npcm7xx-kcs`` for emulating the Nuvoton NPCM7xx Host-to-BMC Keyboard
+  Controller Style (KCS) channels.
+
+.. blockdiag::
+
+blockdiag bmc_ipmi {
+orientation = portrait
+default_group_color = "none";
+class interface [color = lightblue];
+class host [color = salmon];
+
+host [color="aquamarine", label="External Host"]
+
+group {
+orientation = portrait
+
+group {
+orientation = portrait
+
+bmc-interface [class = "interface"]
+npcm7xx-ipmi-kcs [class = "interface", stacked]
+
+bmc-interface <- npcm7xx-ipmi-kcs [hstyle = generalization];
+}
+
+group {
+orientation = portrait
+
+bmc-host [class = "host"];
+bmc-host-sim [class = "host"];
+bmc-host-extern [class = "host"];
+
+bmc-host <- bmc-host-sim [hstyle = generalization];
+bmc-host <- bmc-host-extern [hstyle = generalization];
+}
+
+bmc-interface <-> bmc-host
+}
+
+bmc-host-extern <-> host [label="chardev"];
+}
+
+IPMI Host
+-
+
+Mirroring the main processor emulation, the interface devices delegate
+emulation of host behavior to a Host device that is a subclass of
+``ipmi-core``. This type of device is called a Host because that's what it
+looks like to the BMC guest software.
+
+The host behavior may be further delegated to an external emulator (e.g.
+another QEMU VM) through the ``ipmi-bmc-client`` host implementation. This
+device has a required ``chardev`` property which specifies the communications
+channel to the external host and a required ``interface-client`` property which
+specifies the underlying IPMI interface. The wire format is the same as for
+``ipmi-bmc-extern``.
+
 Wire protocol
 =
 
-- 
2.40.0.348.gf938b09366-goog




[PATCH v2 0/7] Handling IPMI for emulated BMC

2023-03-24 Thread Hao Wu
This patch set is follow-up to our BMC side IPMI
code that was sent our 18 months ago. It addresses
Corey's comments.

Baseboard Management Controllers (BMCs) are special
processors that monitors state of a computer, often
used in data center servers. They often communicate
via IPMI. As a result, it is important to emulate
the IPMI interface so that they can connect to host
machines.

This patch set aims to refactor the existing hw/ipmi
and make it handles both Core side and BMC side
emulations. We also added the implementation of the
KCS module for NPCM7XX BMC boards that work as a backend.
We have tested this patch on various NPCM7xx based
systems and they can communicate with a host that runs
pmi-bmc-extern

The structure is as follows:
Patch 1-3 contains some documentation written by
Havard Skinnomoen that how the emulation of existing
host-side IPMI and the new BMC-side IPMI works.
Patch 4-5 refactors the current IPMI code so that
they work for both host-side and BMC-side.
Patch 6 adds a new ipmi-host-extern which represents
BMC-side emulation that is similar to the current
ipmi-bmc-extern.
Patch 7 implements the KCS device in NPCM7XX boards. It
works as a backend to the ipmi-host-extern device. Since
the direction is different we can't directly use ipmi-kcs.c
for BMC emulation.

-- Changes since v1 --

1. Use the terms Corey suggested in patch v7 throughout
   the patch set.
2. Squash the original patch 6 into patch 4 so that
   the structure is clearer.
3. Addressed other comments from Corey in the original
   patch set.

Hao Wu (4):
  hw/ipmi: Refactor IPMI interface
  hw/ipmi: Take out common from ipmi_bmc_extern.c
  hw/ipmi: Add an IPMI external host device
  hw/ipmi: Add a KCS Module for NPCM7XX

Havard Skinnemoen (3):
  docs: enable sphinx blockdiag extension
  docs/specs: IPMI device emulation: main processor
  docs/specs: IPMI device emulation: BMC

 configs/devices/arm-softmmu/default.mak |   2 +
 docs/conf.py|   6 +-
 docs/specs/index.rst|   1 +
 docs/specs/ipmi.rst | 170 +++
 docs/system/arm/nuvoton.rst |   1 -
 hw/acpi/ipmi.c  |   4 +-
 hw/arm/npcm7xx.c|  10 +-
 hw/ipmi/Kconfig |   4 +
 hw/ipmi/ipmi.c  |  60 ++-
 hw/ipmi/ipmi_bmc_extern.c   | 439 ++
 hw/ipmi/ipmi_bmc_sim.c  |  78 ++--
 hw/ipmi/ipmi_bt.c   |  33 +-
 hw/ipmi/ipmi_extern.c   | 432 +
 hw/ipmi/ipmi_extern.h   |  90 
 hw/ipmi/ipmi_host_extern.c  | 170 +++
 hw/ipmi/ipmi_kcs.c  |  31 +-
 hw/ipmi/isa_ipmi_bt.c   |  18 +-
 hw/ipmi/isa_ipmi_kcs.c  |  13 +-
 hw/ipmi/meson.build |   4 +-
 hw/ipmi/npcm7xx_kcs.c   | 590 
 hw/ipmi/pci_ipmi_bt.c   |   8 +-
 hw/ipmi/pci_ipmi_kcs.c  |   8 +-
 hw/ipmi/smbus_ipmi.c|  26 +-
 hw/ipmi/trace-events|   8 +
 hw/ipmi/trace.h |   1 +
 hw/ppc/pnv.c|   4 +-
 hw/ppc/pnv_bmc.c|  22 +-
 hw/smbios/smbios_type_38.c  |  11 +-
 include/hw/arm/npcm7xx.h|   2 +
 include/hw/ipmi/ipmi.h  | 139 --
 include/hw/ipmi/ipmi_bt.h   |   2 +-
 include/hw/ipmi/ipmi_kcs.h  |   2 +-
 include/hw/ipmi/npcm7xx_kcs.h   | 103 +
 include/hw/ppc/pnv.h|  12 +-
 meson.build |   1 +
 35 files changed, 1939 insertions(+), 566 deletions(-)
 create mode 100644 docs/specs/ipmi.rst
 create mode 100644 hw/ipmi/ipmi_extern.c
 create mode 100644 hw/ipmi/ipmi_extern.h
 create mode 100644 hw/ipmi/ipmi_host_extern.c
 create mode 100644 hw/ipmi/npcm7xx_kcs.c
 create mode 100644 hw/ipmi/trace-events
 create mode 100644 hw/ipmi/trace.h
 create mode 100644 include/hw/ipmi/npcm7xx_kcs.h

-- 
2.40.0.348.gf938b09366-goog




[PATCH v2 2/7] docs/specs: IPMI device emulation: main processor

2023-03-24 Thread Hao Wu
From: Havard Skinnemoen 

This document is an attempt to briefly document the existing IPMI
emulation support on the main processor. It provides the necessary
background for the BMC-side IPMI emulation proposed by the next patch.

Signed-off-by: Havard Skinnemoen 
Signed-off-by: Hao Wu 
---
 docs/specs/index.rst |   1 +
 docs/specs/ipmi.rst  | 100 +++
 2 files changed, 101 insertions(+)
 create mode 100644 docs/specs/ipmi.rst

diff --git a/docs/specs/index.rst b/docs/specs/index.rst
index a58d9311cb..0b0ff4cbc4 100644
--- a/docs/specs/index.rst
+++ b/docs/specs/index.rst
@@ -12,6 +12,7 @@ guest hardware that is specific to QEMU.
ppc-spapr-xive
ppc-spapr-numa
acpi_hw_reduced_hotplug
+   ipmi
tpm
acpi_hest_ghes
acpi_cpu_hotplug
diff --git a/docs/specs/ipmi.rst b/docs/specs/ipmi.rst
new file mode 100644
index 00..e0badc7f15
--- /dev/null
+++ b/docs/specs/ipmi.rst
@@ -0,0 +1,100 @@
+=
+IPMI device emulation
+=
+
+QEMU supports emulating many types of machines. This includes machines that may
+serve as the main processor in an IPMI system, e.g. x86 or POWER server
+processors, as well as machines emulating ARM-based Baseband Management
+Controllers (BMCs), e.g. AST2xxx or NPCM7xxx systems-on-chip.
+
+Main processor emulation
+
+
+A server platform may include one of the following system interfaces for
+communicating with a BMC:
+
+* A Keyboard Controller Style (KCS) Interface, accessible via ISA
+  (``isa-ipmi-kcs``) or PCI (``pci-ipmi-kcs``).
+* A Block Transfer (BT) Interface, accessible via ISA (``isa-ipmi-bt``) or PCI
+  (``pci-ipmi-bt``).
+* An SMBus System Interface (SSIF; ``smbus-ipmi``).
+
+These interfaces can all be emulated by QEMU. To emulate the behavior of the
+BMC, the messaging interface emulators use one of the following backends:
+
+* A BMC simulator running within the QEMU process (``ipmi-bmc-sim``).
+* An external BMC simulator or emulator, connected over a chardev
+  (``ipmi-bmc-extern``). `ipmi_sim
+  
<https://sourceforge.net/p/openipmi/code/ci//master/tree/lanserv/README.ipmi_sim>`_
+  from OpenIPMI is an example external BMC emulator.
+
+The following diagram shows how these entities relate to each other.
+
+.. blockdiag::
+
+blockdiag main_processor_ipmi {
+orientation = portrait
+default_group_color = "none";
+class msgif [color = lightblue];
+class bmc [color = salmon];
+
+ipmi_sim [color="aquamarine", label="External BMC"]
+ipmi-bmc-extern <-> ipmi_sim [label="chardev"];
+
+group {
+orientation = portrait
+
+ipmi-interface <-> ipmi-bmc;
+
+group {
+orientation = portrait
+
+ipmi-interface [class = "msgif"];
+isa-ipmi-kcs [class="msgif", stacked];
+
+ipmi-interface <- isa-ipmi-kcs [hstyle = generalization];
+}
+
+
+group {
+orientation = portrait
+
+ipmi-bmc [class = "bmc"];
+ipmi-bmc-sim [class="bmc"];
+ipmi-bmc-extern [class="bmc"];
+
+ipmi-bmc <- ipmi-bmc-sim [hstyle = generalization];
+ipmi-bmc <- ipmi-bmc-extern [hstyle = generalization];
+}
+
+}
+}
+
+IPMI System Interfaces
+--
+
+The system software running on the main processor may use a *system interface*
+to communicate with the BMC. These are hardware devices attached to an ISA, PCI
+or i2c bus, and in QEMU, they all need to implement ``ipmi-interface-host``.
+This allows a BMC implementation to interact with the system interface in a
+standard way.
+
+IPMI BMC
+
+
+The system interface devices delegate emulation of BMC behavior to a BMC
+device, that is a subclass of ``ipmi-bmc-host``. This type of device is called
+a BMC because that's what it looks like to the main processor guest software.
+
+The BMC behavior may be simulated within the qemu process (``ipmi-bmc-sim``) or
+further delegated to an external emulator, or a real BMC. The
+``ipmi-bmc-extern`` device has a required ``chardev`` property which specifies
+the communications channel to the external BMC.
+
+Wire protocol
+=
+
+The wire protocol used between ``ipmi-bmc-extern`` and the external BMC
+emulator is defined by `README.vm
+<https://sourceforge.net/p/openipmi/code/ci/master/tree/lanserv/README.vm>`_
+from the OpenIPMI project.
-- 
2.40.0.348.gf938b09366-goog




[PATCH v2 1/7] docs: enable sphinx blockdiag extension

2023-03-24 Thread Hao Wu
From: Havard Skinnemoen 

This allows use to add block diagrams in documentations,
such as the block diagram in docs/specs/impi.rst.

Signed-off-by: Havard Skinnemoen 
Signed-off-by: Hao Wu 
---
 docs/conf.py | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/docs/conf.py b/docs/conf.py
index 00767b0e24..6974647408 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -71,7 +71,11 @@
 # Add any Sphinx extension module names here, as strings. They can be
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
 # ones.
-extensions = ['kerneldoc', 'qmp_lexer', 'hxtool', 'depfile', 'qapidoc']
+extensions = ['kerneldoc', 'qmp_lexer', 'hxtool', 'depfile', 'qapidoc',
+'sphinxcontrib.blockdiag']
+
+# Fontpath for blockdiag (truetype font)
+blockdiag_fontpath = 
'/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf'
 
 if sphinx.version_info[:3] > (4, 0, 0):
 tags.add('sphinx4')
-- 
2.40.0.348.gf938b09366-goog




[PATCH v3 2/3] hw/ssi: Add Nuvoton PSPI Module

2023-02-08 Thread Hao Wu
Nuvoton's PSPI is a general purpose SPI module which enables
connections to SPI-based peripheral devices.

Signed-off-by: Hao Wu 
Reviewed-by: Chris Rauer 
Reviewed-by: Philippe Mathieu-Daude 
---
 MAINTAINERS|   6 +-
 hw/ssi/meson.build |   2 +-
 hw/ssi/npcm_pspi.c | 221 +
 hw/ssi/trace-events|   5 +
 include/hw/ssi/npcm_pspi.h |  53 +
 5 files changed, 283 insertions(+), 4 deletions(-)
 create mode 100644 hw/ssi/npcm_pspi.c
 create mode 100644 include/hw/ssi/npcm_pspi.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 347936e41c..1e2a711373 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -803,9 +803,9 @@ M: Tyrone Ting 
 M: Hao Wu 
 L: qemu-...@nongnu.org
 S: Supported
-F: hw/*/npcm7xx*
-F: include/hw/*/npcm7xx*
-F: tests/qtest/npcm7xx*
+F: hw/*/npcm*
+F: include/hw/*/npcm*
+F: tests/qtest/npcm*
 F: pc-bios/npcm7xx_bootrom.bin
 F: roms/vbootrom
 F: docs/system/arm/nuvoton.rst
diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
index 702aa5e4df..904a47161a 100644
--- a/hw/ssi/meson.build
+++ b/hw/ssi/meson.build
@@ -1,6 +1,6 @@
 softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_smc.c'))
 softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('mss-spi.c'))
-softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_fiu.c'))
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_fiu.c', 
'npcm_pspi.c'))
 softmmu_ss.add(when: 'CONFIG_PL022', if_true: files('pl022.c'))
 softmmu_ss.add(when: 'CONFIG_SIFIVE_SPI', if_true: files('sifive_spi.c'))
 softmmu_ss.add(when: 'CONFIG_SSI', if_true: files('ssi.c'))
diff --git a/hw/ssi/npcm_pspi.c b/hw/ssi/npcm_pspi.c
new file mode 100644
index 00..3fb935043a
--- /dev/null
+++ b/hw/ssi/npcm_pspi.c
@@ -0,0 +1,221 @@
+/*
+ * Nuvoton NPCM Peripheral SPI Module (PSPI)
+ *
+ * Copyright 2023 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/irq.h"
+#include "hw/registerfields.h"
+#include "hw/ssi/npcm_pspi.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+
+#include "trace.h"
+
+REG16(PSPI_DATA, 0x0)
+REG16(PSPI_CTL1, 0x2)
+FIELD(PSPI_CTL1, SPIEN, 0,  1)
+FIELD(PSPI_CTL1, MOD,   2,  1)
+FIELD(PSPI_CTL1, EIR,   5,  1)
+FIELD(PSPI_CTL1, EIW,   6,  1)
+FIELD(PSPI_CTL1, SCM,   7,  1)
+FIELD(PSPI_CTL1, SCIDL, 8,  1)
+FIELD(PSPI_CTL1, SCDV,  9,  7)
+REG16(PSPI_STAT, 0x4)
+FIELD(PSPI_STAT, BSY,  0,  1)
+FIELD(PSPI_STAT, RBF,  1,  1)
+
+static void npcm_pspi_update_irq(NPCMPSPIState *s)
+{
+int level = 0;
+
+/* Only fire IRQ when the module is enabled. */
+if (FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, SPIEN)) {
+/* Update interrupt as BSY is cleared. */
+if ((!FIELD_EX16(s->regs[R_PSPI_STAT], PSPI_STAT, BSY)) &&
+FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, EIW)) {
+level = 1;
+}
+
+/* Update interrupt as RBF is set. */
+if (FIELD_EX16(s->regs[R_PSPI_STAT], PSPI_STAT, RBF) &&
+FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, EIR)) {
+level = 1;
+}
+}
+qemu_set_irq(s->irq, level);
+}
+
+static uint16_t npcm_pspi_read_data(NPCMPSPIState *s)
+{
+uint16_t value = s->regs[R_PSPI_DATA];
+
+/* Clear stat bits as the value are read out. */
+s->regs[R_PSPI_STAT] = 0;
+
+return value;
+}
+
+static void npcm_pspi_write_data(NPCMPSPIState *s, uint16_t data)
+{
+uint16_t value = 0;
+
+if (FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, MOD)) {
+value = ssi_transfer(s->spi, extract16(data, 8, 8)) << 8;
+}
+value |= ssi_transfer(s->spi, extract16(data, 0, 8));
+s->regs[R_PSPI_DATA] = value;
+
+/* Mark data as available */
+s->regs[R_PSPI_STAT] = R_PSPI_STAT_BSY_MASK | R_PSPI_STAT_RBF_MASK;
+}
+
+/* Control register read handler. */
+static uint64_t npcm_pspi_ctrl_read(void *opaque, hwaddr addr,
+unsigned int size)
+{
+NPCMPSPIState *s = opaque;
+uint16_t value;
+
+switch (addr) {
+case A_PSPI_DATA:
+value = npcm_pspi_read_data(s);
+break;
+
+case A_PSPI_CTL1:
+value = s->regs[R_PSPI_CTL1];
+break;
+
+case A_PS

[PATCH v3 3/3] hw/arm: Attach PSPI module to NPCM7XX SoC

2023-02-08 Thread Hao Wu
Signed-off-by: Hao Wu 
Reviewed-by: Titus Rwantare 
Reviewed-by: Philippe Mathieu-Daude 
---
 docs/system/arm/nuvoton.rst |  2 +-
 hw/arm/npcm7xx.c| 25 +++--
 include/hw/arm/npcm7xx.h|  2 ++
 3 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
index c38df32bde..0424cae4b0 100644
--- a/docs/system/arm/nuvoton.rst
+++ b/docs/system/arm/nuvoton.rst
@@ -49,6 +49,7 @@ Supported devices
  * SMBus controller (SMBF)
  * Ethernet controller (EMC)
  * Tachometer
+ * Peripheral SPI controller (PSPI)
 
 Missing devices
 ---
@@ -64,7 +65,6 @@ Missing devices
 
  * Ethernet controller (GMAC)
  * USB device (USBD)
- * Peripheral SPI controller (PSPI)
  * SD/MMC host
  * PECI interface
  * PCI and PCIe root complex and bridges
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index d85cc02765..15ff21d047 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -86,6 +86,8 @@ enum NPCM7xxInterrupt {
 NPCM7XX_EMC1RX_IRQ  = 15,
 NPCM7XX_EMC1TX_IRQ,
 NPCM7XX_MMC_IRQ = 26,
+NPCM7XX_PSPI2_IRQ   = 28,
+NPCM7XX_PSPI1_IRQ   = 31,
 NPCM7XX_TIMER0_IRQ  = 32,   /* Timer Module 0 */
 NPCM7XX_TIMER1_IRQ,
 NPCM7XX_TIMER2_IRQ,
@@ -220,6 +222,12 @@ static const hwaddr npcm7xx_emc_addr[] = {
 0xf0826000,
 };
 
+/* Register base address for each PSPI Module */
+static const hwaddr npcm7xx_pspi_addr[] = {
+0xf020,
+0xf0201000,
+};
+
 static const struct {
 hwaddr regs_addr;
 uint32_t unconnected_pins;
@@ -444,6 +452,10 @@ static void npcm7xx_init(Object *obj)
 object_initialize_child(obj, "emc[*]", >emc[i], TYPE_NPCM7XX_EMC);
 }
 
+for (i = 0; i < ARRAY_SIZE(s->pspi); i++) {
+object_initialize_child(obj, "pspi[*]", >pspi[i], TYPE_NPCM_PSPI);
+}
+
 object_initialize_child(obj, "mmc", >mmc, TYPE_NPCM7XX_SDHCI);
 }
 
@@ -715,6 +727,17 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 sysbus_connect_irq(SYS_BUS_DEVICE(>mmc), 0,
 npcm7xx_irq(s, NPCM7XX_MMC_IRQ));
 
+/* PSPI */
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_pspi_addr) != ARRAY_SIZE(s->pspi));
+for (i = 0; i < ARRAY_SIZE(s->pspi); i++) {
+SysBusDevice *sbd = SYS_BUS_DEVICE(>pspi[i]);
+int irq = (i == 0) ? NPCM7XX_PSPI1_IRQ : NPCM7XX_PSPI2_IRQ;
+
+sysbus_realize(sbd, _abort);
+sysbus_mmio_map(sbd, 0, npcm7xx_pspi_addr[i]);
+sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, irq));
+}
+
 create_unimplemented_device("npcm7xx.shm",  0xc0001000,   4 * KiB);
 create_unimplemented_device("npcm7xx.vdmx", 0xe080,   4 * KiB);
 create_unimplemented_device("npcm7xx.pcierc",   0xe100,  64 * KiB);
@@ -724,8 +747,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 create_unimplemented_device("npcm7xx.peci", 0xf010,   4 * KiB);
 create_unimplemented_device("npcm7xx.siox[1]",  0xf0101000,   4 * KiB);
 create_unimplemented_device("npcm7xx.siox[2]",  0xf0102000,   4 * KiB);
-create_unimplemented_device("npcm7xx.pspi1",0xf020,   4 * KiB);
-create_unimplemented_device("npcm7xx.pspi2",0xf0201000,   4 * KiB);
 create_unimplemented_device("npcm7xx.ahbpci",   0xf040,   1 * MiB);
 create_unimplemented_device("npcm7xx.mcphy",0xf05f,  64 * KiB);
 create_unimplemented_device("npcm7xx.gmac1",0xf0802000,   8 * KiB);
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index f1b7e4a48d..72c7722096 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -32,6 +32,7 @@
 #include "hw/nvram/npcm7xx_otp.h"
 #include "hw/timer/npcm7xx_timer.h"
 #include "hw/ssi/npcm7xx_fiu.h"
+#include "hw/ssi/npcm_pspi.h"
 #include "hw/usb/hcd-ehci.h"
 #include "hw/usb/hcd-ohci.h"
 #include "target/arm/cpu.h"
@@ -104,6 +105,7 @@ struct NPCM7xxState {
 NPCM7xxFIUState fiu[2];
 NPCM7xxEMCState emc[2];
 NPCM7xxSDHCIState   mmc;
+NPCMPSPIState   pspi[2];
 };
 
 #define TYPE_NPCM7XX"npcm7xx"
-- 
2.39.1.519.gcb327c4b5f-goog




[PATCH v3 1/3] MAINTAINERS: Add myself to maintainers and remove Havard

2023-02-08 Thread Hao Wu
Havard is no longer working on the Nuvoton systems for a while
and won't be able to do any work on it in the future. So I'll
take over maintaining the Nuvoton system from him.

Signed-off-by: Hao Wu 
Acked-by: Havard Skinnemoen 
Reviewed-by: Philippe Mathieu-Daude 
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index fa10ecaeb9..347936e41c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -799,8 +799,8 @@ F: include/hw/net/mv88w8618_eth.h
 F: docs/system/arm/musicpal.rst
 
 Nuvoton NPCM7xx
-M: Havard Skinnemoen 
 M: Tyrone Ting 
+M: Hao Wu 
 L: qemu-...@nongnu.org
 S: Supported
 F: hw/*/npcm7xx*
-- 
2.39.1.519.gcb327c4b5f-goog




[PATCH v3 0/3] Nuvoton Peripheral SPI (PSPI) Module

2023-02-08 Thread Hao Wu
This patch set adds peripheral SPI (PSPI) modules
to NPCM7XX SoCs. These modules can be used to
connect any SPI peripheral devices to the SoC.

This module will also be used in the next generation
NPCM8XX SoCs which haven't been merged yet.

-- Changes from v2 --
Change max_access_size to 2 to match the datasheet.

-- Changes from v1 --
A few minor updates for npcm-pspi.c according to
Phillipe Mathieu-Daude's review.

Thanks!

Hao Wu (3):
  MAINTAINERS: Add myself to maintainers and remove Havard
  hw/ssi: Add Nuvoton PSPI Module
  hw/arm: Attach PSPI module to NPCM7XX SoC

 MAINTAINERS |   8 +-
 docs/system/arm/nuvoton.rst |   2 +-
 hw/arm/npcm7xx.c|  25 +++-
 hw/ssi/meson.build  |   2 +-
 hw/ssi/npcm_pspi.c  | 221 
 hw/ssi/trace-events |   5 +
 include/hw/arm/npcm7xx.h|   2 +
 include/hw/ssi/npcm_pspi.h  |  53 +
 8 files changed, 310 insertions(+), 8 deletions(-)
 create mode 100644 hw/ssi/npcm_pspi.c
 create mode 100644 include/hw/ssi/npcm_pspi.h

-- 
2.39.1.519.gcb327c4b5f-goog




Re: [PATCH v2 2/3] hw/ssi: Add Nuvoton PSPI Module

2023-02-08 Thread Hao Wu
Thanks for pointing that out. I'll send another version to fix that.

On Tue, Feb 7, 2023 at 11:48 PM Philippe Mathieu-Daudé 
wrote:

> On 7/2/23 20:45, Hao Wu wrote:
> > Nuvoton's PSPI is a general purpose SPI module which enables
> > connections to SPI-based peripheral devices.
> >
> > Signed-off-by: Hao Wu 
> > Reviewed-by: Chris Rauer 
> > Reviewed-by: Philippe Mathieu-Daude 
> > ---
> >   MAINTAINERS|   6 +-
> >   hw/ssi/meson.build |   2 +-
> >   hw/ssi/npcm_pspi.c | 221 +
> >   hw/ssi/trace-events|   5 +
> >   include/hw/ssi/npcm_pspi.h |  53 +
> >   5 files changed, 283 insertions(+), 4 deletions(-)
> >   create mode 100644 hw/ssi/npcm_pspi.c
> >   create mode 100644 include/hw/ssi/npcm_pspi.h
>
>
> > +static const MemoryRegionOps npcm_pspi_ctrl_ops = {
> > +.read = npcm_pspi_ctrl_read,
> > +.write = npcm_pspi_ctrl_write,
> > +.endianness = DEVICE_LITTLE_ENDIAN,
> > +.valid = {
> > +.min_access_size = 1,
> > +.max_access_size = 4,
>
> You said in v1 "The datasheet suggests it's either 8-bit or
> 16-bit accesses.", so we want max_access_size = 2 here, right?
>
> > +.unaligned = false,
> > +},
> > +.impl = {
> > +.min_access_size = 2,
> > +.max_access_size = 2,
> > +.unaligned = false,
> > +},
> > +};
>
>
>


[PATCH v2 1/3] MAINTAINERS: Add myself to maintainers and remove Havard

2023-02-07 Thread Hao Wu
Havard is no longer working on the Nuvoton systems for a while
and won't be able to do any work on it in the future. So I'll
take over maintaining the Nuvoton system from him.

Signed-off-by: Hao Wu 
Acked-by: Havard Skinnemoen 
Reviewed-by: Philippe Mathieu-Daude 
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index fa10ecaeb9..347936e41c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -799,8 +799,8 @@ F: include/hw/net/mv88w8618_eth.h
 F: docs/system/arm/musicpal.rst
 
 Nuvoton NPCM7xx
-M: Havard Skinnemoen 
 M: Tyrone Ting 
+M: Hao Wu 
 L: qemu-...@nongnu.org
 S: Supported
 F: hw/*/npcm7xx*
-- 
2.39.1.519.gcb327c4b5f-goog




[PATCH v2 3/3] hw/arm: Attach PSPI module to NPCM7XX SoC

2023-02-07 Thread Hao Wu
Signed-off-by: Hao Wu 
Reviewed-by: Titus Rwantare 
Reviewed-by: Philippe Mathieu-Daude 
---
 docs/system/arm/nuvoton.rst |  2 +-
 hw/arm/npcm7xx.c| 25 +++--
 include/hw/arm/npcm7xx.h|  2 ++
 3 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
index c38df32bde..0424cae4b0 100644
--- a/docs/system/arm/nuvoton.rst
+++ b/docs/system/arm/nuvoton.rst
@@ -49,6 +49,7 @@ Supported devices
  * SMBus controller (SMBF)
  * Ethernet controller (EMC)
  * Tachometer
+ * Peripheral SPI controller (PSPI)
 
 Missing devices
 ---
@@ -64,7 +65,6 @@ Missing devices
 
  * Ethernet controller (GMAC)
  * USB device (USBD)
- * Peripheral SPI controller (PSPI)
  * SD/MMC host
  * PECI interface
  * PCI and PCIe root complex and bridges
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index d85cc02765..15ff21d047 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -86,6 +86,8 @@ enum NPCM7xxInterrupt {
 NPCM7XX_EMC1RX_IRQ  = 15,
 NPCM7XX_EMC1TX_IRQ,
 NPCM7XX_MMC_IRQ = 26,
+NPCM7XX_PSPI2_IRQ   = 28,
+NPCM7XX_PSPI1_IRQ   = 31,
 NPCM7XX_TIMER0_IRQ  = 32,   /* Timer Module 0 */
 NPCM7XX_TIMER1_IRQ,
 NPCM7XX_TIMER2_IRQ,
@@ -220,6 +222,12 @@ static const hwaddr npcm7xx_emc_addr[] = {
 0xf0826000,
 };
 
+/* Register base address for each PSPI Module */
+static const hwaddr npcm7xx_pspi_addr[] = {
+0xf020,
+0xf0201000,
+};
+
 static const struct {
 hwaddr regs_addr;
 uint32_t unconnected_pins;
@@ -444,6 +452,10 @@ static void npcm7xx_init(Object *obj)
 object_initialize_child(obj, "emc[*]", >emc[i], TYPE_NPCM7XX_EMC);
 }
 
+for (i = 0; i < ARRAY_SIZE(s->pspi); i++) {
+object_initialize_child(obj, "pspi[*]", >pspi[i], TYPE_NPCM_PSPI);
+}
+
 object_initialize_child(obj, "mmc", >mmc, TYPE_NPCM7XX_SDHCI);
 }
 
@@ -715,6 +727,17 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 sysbus_connect_irq(SYS_BUS_DEVICE(>mmc), 0,
 npcm7xx_irq(s, NPCM7XX_MMC_IRQ));
 
+/* PSPI */
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_pspi_addr) != ARRAY_SIZE(s->pspi));
+for (i = 0; i < ARRAY_SIZE(s->pspi); i++) {
+SysBusDevice *sbd = SYS_BUS_DEVICE(>pspi[i]);
+int irq = (i == 0) ? NPCM7XX_PSPI1_IRQ : NPCM7XX_PSPI2_IRQ;
+
+sysbus_realize(sbd, _abort);
+sysbus_mmio_map(sbd, 0, npcm7xx_pspi_addr[i]);
+sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, irq));
+}
+
 create_unimplemented_device("npcm7xx.shm",  0xc0001000,   4 * KiB);
 create_unimplemented_device("npcm7xx.vdmx", 0xe080,   4 * KiB);
 create_unimplemented_device("npcm7xx.pcierc",   0xe100,  64 * KiB);
@@ -724,8 +747,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 create_unimplemented_device("npcm7xx.peci", 0xf010,   4 * KiB);
 create_unimplemented_device("npcm7xx.siox[1]",  0xf0101000,   4 * KiB);
 create_unimplemented_device("npcm7xx.siox[2]",  0xf0102000,   4 * KiB);
-create_unimplemented_device("npcm7xx.pspi1",0xf020,   4 * KiB);
-create_unimplemented_device("npcm7xx.pspi2",0xf0201000,   4 * KiB);
 create_unimplemented_device("npcm7xx.ahbpci",   0xf040,   1 * MiB);
 create_unimplemented_device("npcm7xx.mcphy",0xf05f,  64 * KiB);
 create_unimplemented_device("npcm7xx.gmac1",0xf0802000,   8 * KiB);
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index f1b7e4a48d..72c7722096 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -32,6 +32,7 @@
 #include "hw/nvram/npcm7xx_otp.h"
 #include "hw/timer/npcm7xx_timer.h"
 #include "hw/ssi/npcm7xx_fiu.h"
+#include "hw/ssi/npcm_pspi.h"
 #include "hw/usb/hcd-ehci.h"
 #include "hw/usb/hcd-ohci.h"
 #include "target/arm/cpu.h"
@@ -104,6 +105,7 @@ struct NPCM7xxState {
 NPCM7xxFIUState fiu[2];
 NPCM7xxEMCState emc[2];
 NPCM7xxSDHCIState   mmc;
+NPCMPSPIState   pspi[2];
 };
 
 #define TYPE_NPCM7XX"npcm7xx"
-- 
2.39.1.519.gcb327c4b5f-goog




[PATCH v2 0/3] Nuvoton Peripheral SPI (PSPI) Module

2023-02-07 Thread Hao Wu
This patch set adds peripheral SPI (PSPI) modules
to NPCM7XX SoCs. These modules can be used to
connect any SPI peripheral devices to the SoC.

This module will also be used in the next generation
NPCM8XX SoCs which haven't been merged yet.

-- Changes from v1 --
A few minor updates for npcm-pspi.c according to
Phillipe Mathieu-Daude's review.

Thanks!

Hao Wu (3):
  MAINTAINERS: Add myself to maintainers and remove Havard
  hw/ssi: Add Nuvoton PSPI Module
  hw/arm: Attach PSPI module to NPCM7XX SoC

 MAINTAINERS |   8 +-
 docs/system/arm/nuvoton.rst |   2 +-
 hw/arm/npcm7xx.c|  25 +++-
 hw/ssi/meson.build  |   2 +-
 hw/ssi/npcm_pspi.c  | 221 
 hw/ssi/trace-events |   5 +
 include/hw/arm/npcm7xx.h|   2 +
 include/hw/ssi/npcm_pspi.h  |  53 +
 8 files changed, 310 insertions(+), 8 deletions(-)
 create mode 100644 hw/ssi/npcm_pspi.c
 create mode 100644 include/hw/ssi/npcm_pspi.h

-- 
2.39.1.519.gcb327c4b5f-goog




[PATCH v2 2/3] hw/ssi: Add Nuvoton PSPI Module

2023-02-07 Thread Hao Wu
Nuvoton's PSPI is a general purpose SPI module which enables
connections to SPI-based peripheral devices.

Signed-off-by: Hao Wu 
Reviewed-by: Chris Rauer 
Reviewed-by: Philippe Mathieu-Daude 
---
 MAINTAINERS|   6 +-
 hw/ssi/meson.build |   2 +-
 hw/ssi/npcm_pspi.c | 221 +
 hw/ssi/trace-events|   5 +
 include/hw/ssi/npcm_pspi.h |  53 +
 5 files changed, 283 insertions(+), 4 deletions(-)
 create mode 100644 hw/ssi/npcm_pspi.c
 create mode 100644 include/hw/ssi/npcm_pspi.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 347936e41c..1e2a711373 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -803,9 +803,9 @@ M: Tyrone Ting 
 M: Hao Wu 
 L: qemu-...@nongnu.org
 S: Supported
-F: hw/*/npcm7xx*
-F: include/hw/*/npcm7xx*
-F: tests/qtest/npcm7xx*
+F: hw/*/npcm*
+F: include/hw/*/npcm*
+F: tests/qtest/npcm*
 F: pc-bios/npcm7xx_bootrom.bin
 F: roms/vbootrom
 F: docs/system/arm/nuvoton.rst
diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
index 702aa5e4df..904a47161a 100644
--- a/hw/ssi/meson.build
+++ b/hw/ssi/meson.build
@@ -1,6 +1,6 @@
 softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_smc.c'))
 softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('mss-spi.c'))
-softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_fiu.c'))
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_fiu.c', 
'npcm_pspi.c'))
 softmmu_ss.add(when: 'CONFIG_PL022', if_true: files('pl022.c'))
 softmmu_ss.add(when: 'CONFIG_SIFIVE_SPI', if_true: files('sifive_spi.c'))
 softmmu_ss.add(when: 'CONFIG_SSI', if_true: files('ssi.c'))
diff --git a/hw/ssi/npcm_pspi.c b/hw/ssi/npcm_pspi.c
new file mode 100644
index 00..1fd865d04e
--- /dev/null
+++ b/hw/ssi/npcm_pspi.c
@@ -0,0 +1,221 @@
+/*
+ * Nuvoton NPCM Peripheral SPI Module (PSPI)
+ *
+ * Copyright 2023 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/irq.h"
+#include "hw/registerfields.h"
+#include "hw/ssi/npcm_pspi.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+
+#include "trace.h"
+
+REG16(PSPI_DATA, 0x0)
+REG16(PSPI_CTL1, 0x2)
+FIELD(PSPI_CTL1, SPIEN, 0,  1)
+FIELD(PSPI_CTL1, MOD,   2,  1)
+FIELD(PSPI_CTL1, EIR,   5,  1)
+FIELD(PSPI_CTL1, EIW,   6,  1)
+FIELD(PSPI_CTL1, SCM,   7,  1)
+FIELD(PSPI_CTL1, SCIDL, 8,  1)
+FIELD(PSPI_CTL1, SCDV,  9,  7)
+REG16(PSPI_STAT, 0x4)
+FIELD(PSPI_STAT, BSY,  0,  1)
+FIELD(PSPI_STAT, RBF,  1,  1)
+
+static void npcm_pspi_update_irq(NPCMPSPIState *s)
+{
+int level = 0;
+
+/* Only fire IRQ when the module is enabled. */
+if (FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, SPIEN)) {
+/* Update interrupt as BSY is cleared. */
+if ((!FIELD_EX16(s->regs[R_PSPI_STAT], PSPI_STAT, BSY)) &&
+FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, EIW)) {
+level = 1;
+}
+
+/* Update interrupt as RBF is set. */
+if (FIELD_EX16(s->regs[R_PSPI_STAT], PSPI_STAT, RBF) &&
+FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, EIR)) {
+level = 1;
+}
+}
+qemu_set_irq(s->irq, level);
+}
+
+static uint16_t npcm_pspi_read_data(NPCMPSPIState *s)
+{
+uint16_t value = s->regs[R_PSPI_DATA];
+
+/* Clear stat bits as the value are read out. */
+s->regs[R_PSPI_STAT] = 0;
+
+return value;
+}
+
+static void npcm_pspi_write_data(NPCMPSPIState *s, uint16_t data)
+{
+uint16_t value = 0;
+
+if (FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, MOD)) {
+value = ssi_transfer(s->spi, extract16(data, 8, 8)) << 8;
+}
+value |= ssi_transfer(s->spi, extract16(data, 0, 8));
+s->regs[R_PSPI_DATA] = value;
+
+/* Mark data as available */
+s->regs[R_PSPI_STAT] = R_PSPI_STAT_BSY_MASK | R_PSPI_STAT_RBF_MASK;
+}
+
+/* Control register read handler. */
+static uint64_t npcm_pspi_ctrl_read(void *opaque, hwaddr addr,
+unsigned int size)
+{
+NPCMPSPIState *s = opaque;
+uint16_t value;
+
+switch (addr) {
+case A_PSPI_DATA:
+value = npcm_pspi_read_data(s);
+break;
+
+case A_PSPI_CTL1:
+value = s->regs[R_PSPI_CTL1];
+break;
+
+case A_PS

Re: [PATCH 2/3] hw/ssi: Add Nuvoton PSPI Module

2023-02-07 Thread Hao Wu
On Tue, Feb 7, 2023 at 10:46 AM Hao Wu  wrote:

> Thanks for your review!
>
> On Mon, Feb 6, 2023 at 11:13 PM Philippe Mathieu-Daudé 
> wrote:
>
>> On 7/2/23 00:34, Hao Wu wrote:
>> > Nuvoton's PSPI is a general purpose SPI module which enables
>> > connections to SPI-based peripheral devices.
>> >
>> > Signed-off-by: Hao Wu 
>> > Reviewed-by: Chris Rauer 
>> > ---
>> >   MAINTAINERS|   6 +-
>> >   hw/ssi/meson.build |   2 +-
>> >   hw/ssi/npcm_pspi.c | 216 +
>> >   hw/ssi/trace-events|   5 +
>> >   include/hw/ssi/npcm_pspi.h |  53 +
>> >   5 files changed, 278 insertions(+), 4 deletions(-)
>> >   create mode 100644 hw/ssi/npcm_pspi.c
>> >   create mode 100644 include/hw/ssi/npcm_pspi.h
>>
>>
>> > +static const MemoryRegionOps npcm_pspi_ctrl_ops = {
>> > +.read = npcm_pspi_ctrl_read,
>> > +.write = npcm_pspi_ctrl_write,
>> > +.endianness = DEVICE_LITTLE_ENDIAN,
>> > +.valid = {
>> > +.min_access_size = 1,
>> > +.max_access_size = 2,
>>
>> I'm not sure about ".max_access_size = 2". The datasheet does
>> not seem public. Does that mean the CPU bus can not do a 32-bit
>> access to read two consecutive 16-bit registers? (these fields
>> restrict the guest accesses to the device).
>>
>> > +.unaligned = false,
>> > +},
>>
>> You might want instead (which is how you implemented the r/w
>> handlers):
>>
>>  .impl.min_access_size = 2,
>>  .impl.max_access_size = 2,
>>
> Thanks for the reminder. The datasheet suggests it's either 8-bit or
> 16-bit accesses. But I think using your suggestion makes sense
> and will be more widely adapted.
>
>>
>> > +};
>>
>>
>> > +static void npcm_pspi_realize(DeviceState *dev, Error **errp)
>> > +{
>> > +NPCMPSPIState *s = NPCM_PSPI(dev);
>> > +SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
>> > +Object *obj = OBJECT(dev);
>> > +
>> > +s->spi = ssi_create_bus(dev, "pspi");
>>
>> FYI there is an ongoing discussion about how to model QOM tree. If
>> this bus isn't shared with another controller, the "embed QOM child
>> in parent" style could be preferred. If so, the bus would be created
>> as:
>>
>>object_initialize_child(obj, "pspi", >spi, TYPE_SSI_BUS);
>>
> I was just following some existing code here. I think I can use the new
> style.
>
I've tried to use this and got the following error:
**
ERROR:../qom/object.c:511:object_initialize_with_type: assertion failed:
(size >= type->instance_size)
Bail out! ERROR:../qom/object.c:511:object_initialize_with_type: assertion
failed: (size >= type->instance_size)

I think the problem is that we define s->spi as SSIBus* instead of SSIBus.
But if we define it as SSIBus, we'll
get an incomplete type error. Fixing it will require refactoring
hw/ssi/ssi.c which I'm not sure if we want to do
it right now. This code is consistent with other code in hw/ssi so I guess
we can leave it here for now and wait
for a future refactor.

>
>> > +memory_region_init_io(>mmio, obj, _pspi_ctrl_ops, s,
>> > +  "mmio", 4 * KiB);
>> > +sysbus_init_mmio(sbd, >mmio);
>> > +sysbus_init_irq(sbd, >irq);
>> > +}
>>
>>
>> > diff --git a/hw/ssi/trace-events b/hw/ssi/trace-events
>> > index c707d4aaba..16ea9954c4 100644
>> > --- a/hw/ssi/trace-events
>> > +++ b/hw/ssi/trace-events
>>
>> > +# npcm_pspi.c
>> > +npcm_pspi_enter_reset(const char *id, int reset_type) "%s reset type:
>> %d"
>> > +npcm_pspi_ctrl_read(const char *id, uint64_t addr, uint16_t data) "%s
>> offset: 0x%04" PRIx64 " value: 0x%08" PRIx16
>> > +npcm_pspi_ctrl_write(const char *id, uint64_t addr, uint16_t data) "%s
>> offset: 0x%04" PRIx64 " value: 0x%08" PRIx16
>>
>> Since the region is 4KiB and the implementation is 16-bit, the formats
>> could be simplified as offset 0x%03 and value 0x%04. The traces will
>> then be more digestible to human eyes.
>>
> I'll do this.
>
>>
>> Modulo the impl.access_size change:
>> Reviewed-by: Philippe Mathieu-Daudé 
>>
>>


Re: [PATCH 2/3] hw/ssi: Add Nuvoton PSPI Module

2023-02-07 Thread Hao Wu
Thanks for your review!

On Mon, Feb 6, 2023 at 11:13 PM Philippe Mathieu-Daudé 
wrote:

> On 7/2/23 00:34, Hao Wu wrote:
> > Nuvoton's PSPI is a general purpose SPI module which enables
> > connections to SPI-based peripheral devices.
> >
> > Signed-off-by: Hao Wu 
> > Reviewed-by: Chris Rauer 
> > ---
> >   MAINTAINERS|   6 +-
> >   hw/ssi/meson.build |   2 +-
> >   hw/ssi/npcm_pspi.c | 216 +
> >   hw/ssi/trace-events|   5 +
> >   include/hw/ssi/npcm_pspi.h |  53 +
> >   5 files changed, 278 insertions(+), 4 deletions(-)
> >   create mode 100644 hw/ssi/npcm_pspi.c
> >   create mode 100644 include/hw/ssi/npcm_pspi.h
>
>
> > +static const MemoryRegionOps npcm_pspi_ctrl_ops = {
> > +.read = npcm_pspi_ctrl_read,
> > +.write = npcm_pspi_ctrl_write,
> > +.endianness = DEVICE_LITTLE_ENDIAN,
> > +.valid = {
> > +.min_access_size = 1,
> > +.max_access_size = 2,
>
> I'm not sure about ".max_access_size = 2". The datasheet does
> not seem public. Does that mean the CPU bus can not do a 32-bit
> access to read two consecutive 16-bit registers? (these fields
> restrict the guest accesses to the device).
>
> > +.unaligned = false,
> > +},
>
> You might want instead (which is how you implemented the r/w
> handlers):
>
>  .impl.min_access_size = 2,
>  .impl.max_access_size = 2,
>
Thanks for the reminder. The datasheet suggests it's either 8-bit or
16-bit accesses. But I think using your suggestion makes sense
and will be more widely adapted.

>
> > +};
>
>
> > +static void npcm_pspi_realize(DeviceState *dev, Error **errp)
> > +{
> > +NPCMPSPIState *s = NPCM_PSPI(dev);
> > +SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
> > +Object *obj = OBJECT(dev);
> > +
> > +s->spi = ssi_create_bus(dev, "pspi");
>
> FYI there is an ongoing discussion about how to model QOM tree. If
> this bus isn't shared with another controller, the "embed QOM child
> in parent" style could be preferred. If so, the bus would be created
> as:
>
>object_initialize_child(obj, "pspi", >spi, TYPE_SSI_BUS);
>
I was just following some existing code here. I think I can use the new
style.

>
> > +memory_region_init_io(>mmio, obj, _pspi_ctrl_ops, s,
> > +  "mmio", 4 * KiB);
> > +sysbus_init_mmio(sbd, >mmio);
> > +sysbus_init_irq(sbd, >irq);
> > +}
>
>
> > diff --git a/hw/ssi/trace-events b/hw/ssi/trace-events
> > index c707d4aaba..16ea9954c4 100644
> > --- a/hw/ssi/trace-events
> > +++ b/hw/ssi/trace-events
>
> > +# npcm_pspi.c
> > +npcm_pspi_enter_reset(const char *id, int reset_type) "%s reset type:
> %d"
> > +npcm_pspi_ctrl_read(const char *id, uint64_t addr, uint16_t data) "%s
> offset: 0x%04" PRIx64 " value: 0x%08" PRIx16
> > +npcm_pspi_ctrl_write(const char *id, uint64_t addr, uint16_t data) "%s
> offset: 0x%04" PRIx64 " value: 0x%08" PRIx16
>
> Since the region is 4KiB and the implementation is 16-bit, the formats
> could be simplified as offset 0x%03 and value 0x%04. The traces will
> then be more digestible to human eyes.
>
I'll do this.

>
> Modulo the impl.access_size change:
> Reviewed-by: Philippe Mathieu-Daudé 
>
>


[PATCH 0/3] Nuvoton Peripheral SPI (PSPI) Module

2023-02-06 Thread Hao Wu
This patch set adds peripheral SPI (PSPI) modules
to NPCM7XX SoCs. These modules can be used to
connect any SPI peripheral devices to the SoC.

This module will also be used in the next generation
NPCM8XX SoCs which haven't been merged yet.

Thanks!

Hao Wu (3):
  MAINTAINERS: Add myself to maintainers and remove Havard
  hw/ssi: Add Nuvoton PSPI Module
  hw/arm: Attach PSPI module to NPCM7XX SoC

 MAINTAINERS |   8 +-
 docs/system/arm/nuvoton.rst |   2 +-
 hw/arm/npcm7xx.c|  25 -
 hw/ssi/meson.build  |   2 +-
 hw/ssi/npcm_pspi.c  | 216 
 hw/ssi/trace-events |   5 +
 include/hw/arm/npcm7xx.h|   2 +
 include/hw/ssi/npcm_pspi.h  |  53 +
 8 files changed, 305 insertions(+), 8 deletions(-)
 create mode 100644 hw/ssi/npcm_pspi.c
 create mode 100644 include/hw/ssi/npcm_pspi.h

-- 
2.39.1.519.gcb327c4b5f-goog




[PATCH 3/3] hw/arm: Attach PSPI module to NPCM7XX SoC

2023-02-06 Thread Hao Wu
Signed-off-by: Hao Wu 
Reviewed-by: Titus Rwantare 
---
 docs/system/arm/nuvoton.rst |  2 +-
 hw/arm/npcm7xx.c| 25 +++--
 include/hw/arm/npcm7xx.h|  2 ++
 3 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
index c38df32bde..0424cae4b0 100644
--- a/docs/system/arm/nuvoton.rst
+++ b/docs/system/arm/nuvoton.rst
@@ -49,6 +49,7 @@ Supported devices
  * SMBus controller (SMBF)
  * Ethernet controller (EMC)
  * Tachometer
+ * Peripheral SPI controller (PSPI)
 
 Missing devices
 ---
@@ -64,7 +65,6 @@ Missing devices
 
  * Ethernet controller (GMAC)
  * USB device (USBD)
- * Peripheral SPI controller (PSPI)
  * SD/MMC host
  * PECI interface
  * PCI and PCIe root complex and bridges
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index d85cc02765..15ff21d047 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -86,6 +86,8 @@ enum NPCM7xxInterrupt {
 NPCM7XX_EMC1RX_IRQ  = 15,
 NPCM7XX_EMC1TX_IRQ,
 NPCM7XX_MMC_IRQ = 26,
+NPCM7XX_PSPI2_IRQ   = 28,
+NPCM7XX_PSPI1_IRQ   = 31,
 NPCM7XX_TIMER0_IRQ  = 32,   /* Timer Module 0 */
 NPCM7XX_TIMER1_IRQ,
 NPCM7XX_TIMER2_IRQ,
@@ -220,6 +222,12 @@ static const hwaddr npcm7xx_emc_addr[] = {
 0xf0826000,
 };
 
+/* Register base address for each PSPI Module */
+static const hwaddr npcm7xx_pspi_addr[] = {
+0xf020,
+0xf0201000,
+};
+
 static const struct {
 hwaddr regs_addr;
 uint32_t unconnected_pins;
@@ -444,6 +452,10 @@ static void npcm7xx_init(Object *obj)
 object_initialize_child(obj, "emc[*]", >emc[i], TYPE_NPCM7XX_EMC);
 }
 
+for (i = 0; i < ARRAY_SIZE(s->pspi); i++) {
+object_initialize_child(obj, "pspi[*]", >pspi[i], TYPE_NPCM_PSPI);
+}
+
 object_initialize_child(obj, "mmc", >mmc, TYPE_NPCM7XX_SDHCI);
 }
 
@@ -715,6 +727,17 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 sysbus_connect_irq(SYS_BUS_DEVICE(>mmc), 0,
 npcm7xx_irq(s, NPCM7XX_MMC_IRQ));
 
+/* PSPI */
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_pspi_addr) != ARRAY_SIZE(s->pspi));
+for (i = 0; i < ARRAY_SIZE(s->pspi); i++) {
+SysBusDevice *sbd = SYS_BUS_DEVICE(>pspi[i]);
+int irq = (i == 0) ? NPCM7XX_PSPI1_IRQ : NPCM7XX_PSPI2_IRQ;
+
+sysbus_realize(sbd, _abort);
+sysbus_mmio_map(sbd, 0, npcm7xx_pspi_addr[i]);
+sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, irq));
+}
+
 create_unimplemented_device("npcm7xx.shm",  0xc0001000,   4 * KiB);
 create_unimplemented_device("npcm7xx.vdmx", 0xe080,   4 * KiB);
 create_unimplemented_device("npcm7xx.pcierc",   0xe100,  64 * KiB);
@@ -724,8 +747,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 create_unimplemented_device("npcm7xx.peci", 0xf010,   4 * KiB);
 create_unimplemented_device("npcm7xx.siox[1]",  0xf0101000,   4 * KiB);
 create_unimplemented_device("npcm7xx.siox[2]",  0xf0102000,   4 * KiB);
-create_unimplemented_device("npcm7xx.pspi1",0xf020,   4 * KiB);
-create_unimplemented_device("npcm7xx.pspi2",0xf0201000,   4 * KiB);
 create_unimplemented_device("npcm7xx.ahbpci",   0xf040,   1 * MiB);
 create_unimplemented_device("npcm7xx.mcphy",0xf05f,  64 * KiB);
 create_unimplemented_device("npcm7xx.gmac1",0xf0802000,   8 * KiB);
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index f1b7e4a48d..72c7722096 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -32,6 +32,7 @@
 #include "hw/nvram/npcm7xx_otp.h"
 #include "hw/timer/npcm7xx_timer.h"
 #include "hw/ssi/npcm7xx_fiu.h"
+#include "hw/ssi/npcm_pspi.h"
 #include "hw/usb/hcd-ehci.h"
 #include "hw/usb/hcd-ohci.h"
 #include "target/arm/cpu.h"
@@ -104,6 +105,7 @@ struct NPCM7xxState {
 NPCM7xxFIUState fiu[2];
 NPCM7xxEMCState emc[2];
 NPCM7xxSDHCIState   mmc;
+NPCMPSPIState   pspi[2];
 };
 
 #define TYPE_NPCM7XX"npcm7xx"
-- 
2.39.1.519.gcb327c4b5f-goog




[PATCH 2/3] hw/ssi: Add Nuvoton PSPI Module

2023-02-06 Thread Hao Wu
Nuvoton's PSPI is a general purpose SPI module which enables
connections to SPI-based peripheral devices.

Signed-off-by: Hao Wu 
Reviewed-by: Chris Rauer 
---
 MAINTAINERS|   6 +-
 hw/ssi/meson.build |   2 +-
 hw/ssi/npcm_pspi.c | 216 +
 hw/ssi/trace-events|   5 +
 include/hw/ssi/npcm_pspi.h |  53 +
 5 files changed, 278 insertions(+), 4 deletions(-)
 create mode 100644 hw/ssi/npcm_pspi.c
 create mode 100644 include/hw/ssi/npcm_pspi.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 347936e41c..1e2a711373 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -803,9 +803,9 @@ M: Tyrone Ting 
 M: Hao Wu 
 L: qemu-...@nongnu.org
 S: Supported
-F: hw/*/npcm7xx*
-F: include/hw/*/npcm7xx*
-F: tests/qtest/npcm7xx*
+F: hw/*/npcm*
+F: include/hw/*/npcm*
+F: tests/qtest/npcm*
 F: pc-bios/npcm7xx_bootrom.bin
 F: roms/vbootrom
 F: docs/system/arm/nuvoton.rst
diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
index 702aa5e4df..904a47161a 100644
--- a/hw/ssi/meson.build
+++ b/hw/ssi/meson.build
@@ -1,6 +1,6 @@
 softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_smc.c'))
 softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('mss-spi.c'))
-softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_fiu.c'))
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_fiu.c', 
'npcm_pspi.c'))
 softmmu_ss.add(when: 'CONFIG_PL022', if_true: files('pl022.c'))
 softmmu_ss.add(when: 'CONFIG_SIFIVE_SPI', if_true: files('sifive_spi.c'))
 softmmu_ss.add(when: 'CONFIG_SSI', if_true: files('ssi.c'))
diff --git a/hw/ssi/npcm_pspi.c b/hw/ssi/npcm_pspi.c
new file mode 100644
index 00..565bba5282
--- /dev/null
+++ b/hw/ssi/npcm_pspi.c
@@ -0,0 +1,216 @@
+/*
+ * Nuvoton NPCM Peripheral SPI Module (PSPI)
+ *
+ * Copyright 2023 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/irq.h"
+#include "hw/registerfields.h"
+#include "hw/ssi/npcm_pspi.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+
+#include "trace.h"
+
+REG16(PSPI_DATA, 0x0)
+REG16(PSPI_CTL1, 0x2)
+FIELD(PSPI_CTL1, SPIEN, 0,  1)
+FIELD(PSPI_CTL1, MOD,   2,  1)
+FIELD(PSPI_CTL1, EIR,   5,  1)
+FIELD(PSPI_CTL1, EIW,   6,  1)
+FIELD(PSPI_CTL1, SCM,   7,  1)
+FIELD(PSPI_CTL1, SCIDL, 8,  1)
+FIELD(PSPI_CTL1, SCDV,  9,  7)
+REG16(PSPI_STAT, 0x4)
+FIELD(PSPI_STAT, BSY,  0,  1)
+FIELD(PSPI_STAT, RBF,  1,  1)
+
+static void npcm_pspi_update_irq(NPCMPSPIState *s)
+{
+int level = 0;
+
+/* Only fire IRQ when the module is enabled. */
+if (FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, SPIEN)) {
+/* Update interrupt as BSY is cleared. */
+if ((!FIELD_EX16(s->regs[R_PSPI_STAT], PSPI_STAT, BSY)) &&
+FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, EIW)) {
+level = 1;
+}
+
+/* Update interrupt as RBF is set. */
+if (FIELD_EX16(s->regs[R_PSPI_STAT], PSPI_STAT, RBF) &&
+FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, EIR)) {
+level = 1;
+}
+}
+qemu_set_irq(s->irq, level);
+}
+
+static uint16_t npcm_pspi_read_data(NPCMPSPIState *s)
+{
+uint16_t value = s->regs[R_PSPI_DATA];
+
+/* Clear stat bits as the value are read out. */
+s->regs[R_PSPI_STAT] = 0;
+
+return value;
+}
+
+static void npcm_pspi_write_data(NPCMPSPIState *s, uint16_t data)
+{
+uint16_t value = 0;
+
+if (FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, MOD)) {
+value = ssi_transfer(s->spi, extract16(data, 8, 8)) << 8;
+}
+value |= ssi_transfer(s->spi, extract16(data, 0, 8));
+s->regs[R_PSPI_DATA] = value;
+
+/* Mark data as available */
+s->regs[R_PSPI_STAT] = R_PSPI_STAT_BSY_MASK | R_PSPI_STAT_RBF_MASK;
+}
+
+/* Control register read handler. */
+static uint64_t npcm_pspi_ctrl_read(void *opaque, hwaddr addr,
+unsigned int size)
+{
+NPCMPSPIState *s = opaque;
+uint16_t value;
+
+switch (addr) {
+case A_PSPI_DATA:
+value = npcm_pspi_read_data(s);
+break;
+
+case A_PSPI_CTL1:
+value = s->regs[R_PSPI_CTL1];
+break;
+
+case A_PSPI_STAT:
+   

[PATCH 1/3] MAINTAINERS: Add myself to maintainers and remove Havard

2023-02-06 Thread Hao Wu
Havard is no longer working on the Nuvoton systems for a while
and won't be able to do any work on it in the future. So I'll
take over maintaining the Nuvoton system from him.

Signed-off-by: Hao Wu 
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index fa10ecaeb9..347936e41c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -799,8 +799,8 @@ F: include/hw/net/mv88w8618_eth.h
 F: docs/system/arm/musicpal.rst
 
 Nuvoton NPCM7xx
-M: Havard Skinnemoen 
 M: Tyrone Ting 
+M: Hao Wu 
 L: qemu-...@nongnu.org
 S: Supported
 F: hw/*/npcm7xx*
-- 
2.39.1.519.gcb327c4b5f-goog




Re: [PATCH v4 1/2] hw/sensor: Add SB-TSI Temperature Sensor Interface

2023-02-06 Thread Hao Wu
Hi,

It seems like this patch set is reviewed but never merged. Who should take
this patch set? What are our next steps for them?

Thanks!

On Mon, Jan 31, 2022 at 2:29 PM Patrick Venture  wrote:

> From: Hao Wu 
>
> SB Temperature Sensor Interface (SB-TSI) is an SMBus compatible
> interface that reports AMD SoC's Ttcl (normalized temperature),
> and resembles a typical 8-pin remote temperature sensor's I2C interface
> to BMC.
>
> This patch implements a basic AMD SB-TSI sensor that is
> compatible with the open-source data sheet from AMD and Linux
> kernel driver.
>
> Reference:
> Linux kernel driver:
> https://lkml.org/lkml/2020/12/11/968
> Register Map:
> https://developer.amd.com/wp-content/resources/56255_3_03.PDF
> (Chapter 6)
>
> Signed-off-by: Hao Wu 
> Signed-off-by: Patrick Venture 
> Reviewed-by: Doug Evans 
> Reviewed-by: Philippe Mathieu-Daudé 
> Acked-by: Corey Minyard 
> ---
>  meson.build   |   1 +
>  hw/sensor/trace.h |   1 +
>  include/hw/sensor/sbtsi.h |  45 +
>  hw/sensor/tmp_sbtsi.c | 369 ++
>  hw/sensor/Kconfig |   4 +
>  hw/sensor/meson.build |   1 +
>  hw/sensor/trace-events|   5 +
>  7 files changed, 426 insertions(+)
>  create mode 100644 hw/sensor/trace.h
>  create mode 100644 include/hw/sensor/sbtsi.h
>  create mode 100644 hw/sensor/tmp_sbtsi.c
>  create mode 100644 hw/sensor/trace-events
>
> diff --git a/meson.build b/meson.build
> index c1b1db1e28..3634214546 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -2494,6 +2494,7 @@ if have_system
>  'hw/rtc',
>  'hw/s390x',
>  'hw/scsi',
> +'hw/sensor',
>  'hw/sd',
>  'hw/sh4',
>  'hw/sparc',
> diff --git a/hw/sensor/trace.h b/hw/sensor/trace.h
> new file mode 100644
> index 00..e4721560b0
> --- /dev/null
> +++ b/hw/sensor/trace.h
> @@ -0,0 +1 @@
> +#include "trace/trace-hw_sensor.h"
> diff --git a/include/hw/sensor/sbtsi.h b/include/hw/sensor/sbtsi.h
> new file mode 100644
> index 00..9073f76ebb
> --- /dev/null
> +++ b/include/hw/sensor/sbtsi.h
> @@ -0,0 +1,45 @@
> +/*
> + * AMD SBI Temperature Sensor Interface (SB-TSI)
> + *
> + * 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.
> + */
> +#ifndef QEMU_TMP_SBTSI_H
> +#define QEMU_TMP_SBTSI_H
> +
> +/*
> + * SB-TSI registers only support SMBus byte data access. "_INT" registers
> are
> + * the integer part of a temperature value or limit, and "_DEC" registers
> are
> + * corresponding decimal parts.
> + */
> +#define SBTSI_REG_TEMP_INT  0x01 /* RO */
> +#define SBTSI_REG_STATUS0x02 /* RO */
> +#define SBTSI_REG_CONFIG0x03 /* RO */
> +#define SBTSI_REG_TEMP_HIGH_INT 0x07 /* RW */
> +#define SBTSI_REG_TEMP_LOW_INT  0x08 /* RW */
> +#define SBTSI_REG_CONFIG_WR 0x09 /* RW */
> +#define SBTSI_REG_TEMP_DEC  0x10 /* RO */
> +#define SBTSI_REG_TEMP_HIGH_DEC 0x13 /* RW */
> +#define SBTSI_REG_TEMP_LOW_DEC  0x14 /* RW */
> +#define SBTSI_REG_ALERT_CONFIG  0xBF /* RW */
> +#define SBTSI_REG_MAN   0xFE /* RO */
> +#define SBTSI_REG_REV   0xFF /* RO */
> +
> +#define SBTSI_STATUS_HIGH_ALERT BIT(4)
> +#define SBTSI_STATUS_LOW_ALERT  BIT(3)
> +#define SBTSI_CONFIG_ALERT_MASK BIT(7)
> +#define SBTSI_ALARM_EN  BIT(0)
> +
> +/* The temperature we stored are in units of 0.125 degrees. */
> +#define SBTSI_TEMP_UNIT_IN_MILLIDEGREE 125
> +
> +#endif
> diff --git a/hw/sensor/tmp_sbtsi.c b/hw/sensor/tmp_sbtsi.c
> new file mode 100644
> index 00..d5406844ef
> --- /dev/null
> +++ b/hw/sensor/tmp_sbtsi.c
> @@ -0,0 +1,369 @@
> +/*
> + * AMD SBI Temperature Sensor Interface (SB-TSI)
> + *
> + * 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 imp

Re: [PATCH] docs/nuvoton: Update URL for images

2022-10-04 Thread Hao Wu
On Mon, Oct 3, 2022 at 10:01 PM Joel Stanley  wrote:

> openpower.xyz was retired some time ago. The OpenBMC Jenkins is where
> images can be found these days.
>
> Signed-off-by: Joel Stanley 
>
Reviewed-by: Hao Wu 

> ---
>  docs/system/arm/nuvoton.rst | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
> index ef2792076aa8..c38df32bde07 100644
> --- a/docs/system/arm/nuvoton.rst
> +++ b/docs/system/arm/nuvoton.rst
> @@ -82,9 +82,9 @@ Boot options
>
>  The Nuvoton machines can boot from an OpenBMC firmware image, or directly
> into
>  a kernel using the ``-kernel`` option. OpenBMC images for ``quanta-gsj``
> and
> -possibly others can be downloaded from the OpenPOWER jenkins :
> +possibly others can be downloaded from the OpenBMC jenkins :
>
> -   https://openpower.xyz/
> +   https://jenkins.openbmc.org/
>
>  The firmware image should be attached as an MTD drive. Example :
>
> --
> 2.35.1
>
>
>


Re: [PATCH 43/51] tests/qtest: npcm7xx_emc-test: Skip running test_{tx, rx} on win32

2022-08-25 Thread Hao Wu
On Wed, Aug 24, 2022 at 3:35 AM Bin Meng  wrote:

> From: Bin Meng 
>
> The test cases 'test_{tx,rx}' call socketpair() which does not exist
> on win32. Exclude them.
>
> Signed-off-by: Bin Meng 
>
Reviewed-by: Hao Wu 

> ---
>
>  tests/qtest/npcm7xx_emc-test.c | 8 
>  1 file changed, 8 insertions(+)
>
> diff --git a/tests/qtest/npcm7xx_emc-test.c
> b/tests/qtest/npcm7xx_emc-test.c
> index a353fef0ca..c373d24e1e 100644
> --- a/tests/qtest/npcm7xx_emc-test.c
> +++ b/tests/qtest/npcm7xx_emc-test.c
> @@ -209,6 +209,7 @@ static int emc_module_index(const EMCModule *mod)
>  return diff;
>  }
>
> +#ifndef _WIN32
>  static void packet_test_clear(void *sockets)
>  {
>  int *test_sockets = sockets;
> @@ -243,6 +244,7 @@ static int *packet_test_init(int module_num, GString
> *cmd_line)
>  g_test_queue_destroy(packet_test_clear, test_sockets);
>  return test_sockets;
>  }
> +#endif /* _WIN32 */
>
>  static uint32_t emc_read(QTestState *qts, const EMCModule *mod,
>   NPCM7xxPWMRegister regno)
> @@ -250,6 +252,7 @@ static uint32_t emc_read(QTestState *qts, const
> EMCModule *mod,
>  return qtest_readl(qts, mod->base_addr + regno * sizeof(uint32_t));
>  }
>
> +#ifndef _WIN32
>  static void emc_write(QTestState *qts, const EMCModule *mod,
>NPCM7xxPWMRegister regno, uint32_t value)
>  {
> @@ -339,6 +342,7 @@ static bool emc_soft_reset(QTestState *qts, const
> EMCModule *mod)
>  g_message("%s: Timeout expired", __func__);
>  return false;
>  }
> +#endif /* _WIN32 */
>
>  /* Check emc registers are reset to default value. */
>  static void test_init(gconstpointer test_data)
> @@ -387,6 +391,7 @@ static void test_init(gconstpointer test_data)
>  qtest_quit(qts);
>  }
>
> +#ifndef _WIN32
>  static bool emc_wait_irq(QTestState *qts, const EMCModule *mod, int step,
>   bool is_tx)
>  {
> @@ -843,6 +848,7 @@ static void test_rx(gconstpointer test_data)
>
>  qtest_quit(qts);
>  }
> +#endif /* _WIN32 */
>
>  static void emc_add_test(const char *name, const TestData* td,
>   GTestDataFunc fn)
> @@ -865,8 +871,10 @@ int main(int argc, char **argv)
>  td->module = _module_list[i];
>
>  add_test(init, td);
> +#ifndef _WIN32
>  add_test(tx, td);
>  add_test(rx, td);
> +#endif
>  }
>
>  return g_test_run();
> --
> 2.34.1
>
>
>


[PATCH v2] target/arm: Add cortex-a35

2022-08-18 Thread Hao Wu
Add cortex A35 core and enable it for virt board.

Signed-off-by: Hao Wu 
Reviewed-by: Joe Komlodi 
---
 docs/system/arm/virt.rst |  1 +
 hw/arm/virt.c|  1 +
 target/arm/cpu64.c   | 80 
 3 files changed, 82 insertions(+)

diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
index 3b6ba69a9a..20442ea2c1 100644
--- a/docs/system/arm/virt.rst
+++ b/docs/system/arm/virt.rst
@@ -52,6 +52,7 @@ Supported guest CPU types:
 
 - ``cortex-a7`` (32-bit)
 - ``cortex-a15`` (32-bit; the default)
+- ``cortex-a35`` (64-bit)
 - ``cortex-a53`` (64-bit)
 - ``cortex-a57`` (64-bit)
 - ``cortex-a72`` (64-bit)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 9633f822f3..ee06003aed 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -199,6 +199,7 @@ static const int a15irqmap[] = {
 static const char *valid_cpus[] = {
 ARM_CPU_TYPE_NAME("cortex-a7"),
 ARM_CPU_TYPE_NAME("cortex-a15"),
+ARM_CPU_TYPE_NAME("cortex-a35"),
 ARM_CPU_TYPE_NAME("cortex-a53"),
 ARM_CPU_TYPE_NAME("cortex-a57"),
 ARM_CPU_TYPE_NAME("cortex-a72"),
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 78e27f778a..9d1ea32057 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -36,6 +36,85 @@
 #include "hw/qdev-properties.h"
 #include "internals.h"
 
+static void aarch64_a35_initfn(Object *obj)
+{
+ARMCPU *cpu = ARM_CPU(obj);
+
+cpu->dtb_compatible = "arm,cortex-a35";
+set_feature(>env, ARM_FEATURE_V8);
+set_feature(>env, ARM_FEATURE_NEON);
+set_feature(>env, ARM_FEATURE_GENERIC_TIMER);
+set_feature(>env, ARM_FEATURE_AARCH64);
+set_feature(>env, ARM_FEATURE_CBAR_RO);
+set_feature(>env, ARM_FEATURE_EL2);
+set_feature(>env, ARM_FEATURE_EL3);
+set_feature(>env, ARM_FEATURE_PMU);
+
+/* From B2.2 AArch64 identification registers. */
+cpu->midr = 0x411fd040;
+cpu->revidr = 0;
+cpu->ctr = 0x84448004;
+cpu->isar.id_pfr0 = 0x0131;
+cpu->isar.id_pfr1 = 0x00011011;
+cpu->isar.id_dfr0 = 0x03010066;
+cpu->id_afr0 = 0;
+cpu->isar.id_mmfr0 = 0x10201105;
+cpu->isar.id_mmfr1 = 0x4000;
+cpu->isar.id_mmfr2 = 0x0126;
+cpu->isar.id_mmfr3 = 0x02102211;
+cpu->isar.id_isar0 = 0x02101110;
+cpu->isar.id_isar1 = 0x13112111;
+cpu->isar.id_isar2 = 0x21232042;
+cpu->isar.id_isar3 = 0x01112131;
+cpu->isar.id_isar4 = 0x00011142;
+cpu->isar.id_isar5 = 0x00011121;
+cpu->isar.id_aa64pfr0 = 0x;
+cpu->isar.id_aa64pfr1 = 0;
+cpu->isar.id_aa64dfr0 = 0x10305106;
+cpu->isar.id_aa64dfr1 = 0;
+cpu->isar.id_aa64isar0 = 0x00011120;
+cpu->isar.id_aa64isar1 = 0;
+cpu->isar.id_aa64mmfr0 = 0x00101122;
+cpu->isar.id_aa64mmfr1 = 0;
+cpu->clidr = 0x0a200023;
+cpu->dcz_blocksize = 4;
+
+/* From B2.4 AArch64 Virtual Memory control registers */
+cpu->reset_sctlr = 0x00c50838;
+
+/* From B2.10 AArch64 performance monitor registers */
+cpu->isar.reset_pmcr_el0 = 0x410a3000;
+
+/* From B2.29 Cache ID registers */
+cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
+cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
+cpu->ccsidr[2] = 0x703fe03a; /* 512KB L2 cache */
+
+/* From B3.5 VGIC Type register */
+cpu->gic_num_lrs = 4;
+cpu->gic_vpribits = 5;
+cpu->gic_vprebits = 5;
+cpu->gic_pribits = 5;
+
+/* From C6.4 Debug ID Register */
+cpu->isar.dbgdidr = 0x3516d000;
+/* From C6.5 Debug Device ID Register */
+cpu->isar.dbgdevid = 0x00110f13;
+/* From C6.6 Debug Device ID Register 1 */
+cpu->isar.dbgdevid1 = 0x2;
+
+/* From Cortex-A35 SIMD and Floating-point Support r1p0 */
+/* From 3.2 AArch32 register summary */
+cpu->reset_fpsid = 0x41034043;
+
+/* From 2.2 AArch64 register summary */
+cpu->isar.mvfr0 = 0x10110222;
+cpu->isar.mvfr1 = 0x1211;
+cpu->isar.mvfr2 = 0x0043;
+
+/* These values are the same with A53/A57/A72. */
+define_cortex_a72_a57_a53_cp_reginfo(cpu);
+}
 
 static void aarch64_a57_initfn(Object *obj)
 {
@@ -1158,6 +1237,7 @@ static void aarch64_a64fx_initfn(Object *obj)
 }
 
 static const ARMCPUInfo aarch64_cpus[] = {
+{ .name = "cortex-a35", .initfn = aarch64_a35_initfn },
 { .name = "cortex-a57", .initfn = aarch64_a57_initfn },
 { .name = "cortex-a53", .initfn = aarch64_a53_initfn },
 { .name = "cortex-a72", .initfn = aarch64_a72_initfn },
-- 
2.37.1.595.g718a3a8f04-goog




Re: [PATCH] target/arm: Add cortex-a35

2022-08-18 Thread Hao Wu
Hi,

This is used by a new series of Nuvoton SoC (NPCM8XX) which contains 4
Cortex A-35 cores.

I'll update the missing fields in a follow-up patch set.

On Thu, Aug 18, 2022 at 7:59 AM Peter Maydell 
wrote:

> On Mon, 15 Aug 2022 at 22:35, Hao Wu  wrote:
> >
> > Add cortex A35 core and enable it for virt board.
> >
> > Signed-off-by: Hao Wu 
> > Reviewed-by: Joe Komlodi 
>
> > +static void aarch64_a35_initfn(Object *obj)
> > +{
> > +ARMCPU *cpu = ARM_CPU(obj);
> > +
> > +cpu->dtb_compatible = "arm,cortex-a35";
> > +set_feature(>env, ARM_FEATURE_V8);
> > +set_feature(>env, ARM_FEATURE_NEON);
> > +set_feature(>env, ARM_FEATURE_GENERIC_TIMER);
> > +set_feature(>env, ARM_FEATURE_AARCH64);
> > +set_feature(>env, ARM_FEATURE_CBAR_RO);
> > +set_feature(>env, ARM_FEATURE_EL2);
> > +set_feature(>env, ARM_FEATURE_EL3);
> > +set_feature(>env, ARM_FEATURE_PMU);
> > +
> > +/* From B2.2 AArch64 identification registers. */
> > +cpu->midr = 0x410fd042;
>
> The r1p0 TRM is out, so we might as well emulate that: 0x411FD040
>
> A few fields are missing:
>
>  cpu->isar.dbgdidr
>  cpu->isar.dbgdevid
>  cpu->isar.dbgdevid1
>  cpu->isar.reset_pmcr_el0
>  cpu->gic_pribits
>
> (these probably landed after you wrote these patch).
>
> Otherwise looks OK.
>
> Remind me, what did you want the Cortex-A35 in particular for ?
>
> thanks
> -- PMM
>


[PATCH] target/arm: Add cortex-a35

2022-08-15 Thread Hao Wu
Add cortex A35 core and enable it for virt board.

Signed-off-by: Hao Wu 
Reviewed-by: Joe Komlodi 
---
 docs/system/arm/virt.rst |  1 +
 hw/arm/virt.c|  1 +
 target/arm/cpu64.c   | 69 
 3 files changed, 71 insertions(+)

diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
index 3b6ba69a9a..20442ea2c1 100644
--- a/docs/system/arm/virt.rst
+++ b/docs/system/arm/virt.rst
@@ -52,6 +52,7 @@ Supported guest CPU types:
 
 - ``cortex-a7`` (32-bit)
 - ``cortex-a15`` (32-bit; the default)
+- ``cortex-a35`` (64-bit)
 - ``cortex-a53`` (64-bit)
 - ``cortex-a57`` (64-bit)
 - ``cortex-a72`` (64-bit)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 9633f822f3..ee06003aed 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -199,6 +199,7 @@ static const int a15irqmap[] = {
 static const char *valid_cpus[] = {
 ARM_CPU_TYPE_NAME("cortex-a7"),
 ARM_CPU_TYPE_NAME("cortex-a15"),
+ARM_CPU_TYPE_NAME("cortex-a35"),
 ARM_CPU_TYPE_NAME("cortex-a53"),
 ARM_CPU_TYPE_NAME("cortex-a57"),
 ARM_CPU_TYPE_NAME("cortex-a72"),
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 78e27f778a..4f96b80ffb 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -36,6 +36,74 @@
 #include "hw/qdev-properties.h"
 #include "internals.h"
 
+static void aarch64_a35_initfn(Object *obj)
+{
+ARMCPU *cpu = ARM_CPU(obj);
+
+cpu->dtb_compatible = "arm,cortex-a35";
+set_feature(>env, ARM_FEATURE_V8);
+set_feature(>env, ARM_FEATURE_NEON);
+set_feature(>env, ARM_FEATURE_GENERIC_TIMER);
+set_feature(>env, ARM_FEATURE_AARCH64);
+set_feature(>env, ARM_FEATURE_CBAR_RO);
+set_feature(>env, ARM_FEATURE_EL2);
+set_feature(>env, ARM_FEATURE_EL3);
+set_feature(>env, ARM_FEATURE_PMU);
+
+/* From B2.2 AArch64 identification registers. */
+cpu->midr = 0x410fd042;
+cpu->revidr = 0;
+cpu->ctr = 0x84448004;
+cpu->isar.id_pfr0 = 0x0131;
+cpu->isar.id_pfr1 = 0x00011011;
+cpu->isar.id_dfr0 = 0x03010066;
+cpu->id_afr0 = 0;
+cpu->isar.id_mmfr0 = 0x10201105;
+cpu->isar.id_mmfr1 = 0x4000;
+cpu->isar.id_mmfr2 = 0x0126;
+cpu->isar.id_mmfr3 = 0x02102211;
+cpu->isar.id_isar0 = 0x02101110;
+cpu->isar.id_isar1 = 0x13112111;
+cpu->isar.id_isar2 = 0x21232042;
+cpu->isar.id_isar3 = 0x01112131;
+cpu->isar.id_isar4 = 0x00011142;
+cpu->isar.id_isar5 = 0x00011121;
+cpu->isar.id_aa64pfr0 = 0x;
+cpu->isar.id_aa64pfr1 = 0;
+cpu->isar.id_aa64dfr0 = 0x10305106;
+cpu->isar.id_aa64dfr1 = 0;
+cpu->isar.id_aa64isar0 = 0x00011120;
+cpu->isar.id_aa64isar1 = 0;
+cpu->isar.id_aa64mmfr0 = 0x00101122;
+cpu->isar.id_aa64mmfr1 = 0;
+cpu->clidr = 0x0a200023;
+cpu->dcz_blocksize = 4;
+
+/* From B2.4 AArch64 Virtual Memory control registers */
+cpu->reset_sctlr = 0x00c50838;
+
+/* From B2.29 Cache ID registers */
+cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
+cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
+cpu->ccsidr[2] = 0x703fe03a; /* 512KB L2 cache */
+
+/* From B3.5 VGIC Type register */
+cpu->gic_num_lrs = 4;
+cpu->gic_vpribits = 5;
+cpu->gic_vprebits = 5;
+
+/* From Cortex-A35 SIMD and Floating-point Support r1p0 */
+/* From 3.2 AArch32 register summary */
+cpu->reset_fpsid = 0x41034043;
+
+/* From 2.2 AArch64 register summary */
+cpu->isar.mvfr0 = 0x10110222;
+cpu->isar.mvfr1 = 0x1211;
+cpu->isar.mvfr2 = 0x0043;
+
+/* These values are the same with A53/A57/A72. */
+define_cortex_a72_a57_a53_cp_reginfo(cpu);
+}
 
 static void aarch64_a57_initfn(Object *obj)
 {
@@ -1158,6 +1226,7 @@ static void aarch64_a64fx_initfn(Object *obj)
 }
 
 static const ARMCPUInfo aarch64_cpus[] = {
+{ .name = "cortex-a35", .initfn = aarch64_a35_initfn },
 { .name = "cortex-a57", .initfn = aarch64_a57_initfn },
 { .name = "cortex-a53", .initfn = aarch64_a53_initfn },
 { .name = "cortex-a72", .initfn = aarch64_a72_initfn },
-- 
2.37.1.595.g718a3a8f04-goog




[PATCH v5 7/8] hw/arm: Set drive property for at24c eeprom

2022-07-14 Thread Hao Wu
This patch allows the user to attach an external drive as a property
for an onboard at24c eeprom device. It uses an unit number to
distinguish different devices.

Signed-off-by: Hao Wu 
---
 hw/arm/npcm7xx_boards.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index b083b0c572..b8337871ba 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -141,11 +141,16 @@ static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, 
uint32_t num)
 }
 
 static void at24c_eeprom_init(I2CBus *i2c_bus, int bus, uint8_t addr,
-  uint32_t rsize)
+  uint32_t rsize, int unit)
 {
 I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
 DeviceState *dev = DEVICE(i2c_dev);
+DriveInfo *dinfo;
 
+dinfo = drive_get(IF_OTHER, bus, unit);
+if (dinfo) {
+qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo));
+}
 qdev_prop_set_uint32(dev, "rom-size", rsize);
 i2c_slave_realize_and_unref(i2c_dev, i2c_bus, _abort);
 }
@@ -252,8 +257,8 @@ static void quanta_gsj_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x5c);
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x5c);
 
-at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 9), 9, 0x55, 8192);
-at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 10), 10, 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 9), 9, 0x55, 8192, 0);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 10), 10, 0x55, 8192, 1);
 
 /*
  * i2c-11:
@@ -360,7 +365,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), TYPE_PCA9548, 0x77);
 
 /* mbfru */
-at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 4), 4, 0x50, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 4), 4, 0x50, 8192, 0);
 
 i2c_mux = i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 13),
   TYPE_PCA9548, 0x77);
@@ -372,7 +377,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 5), "tmp105", 0x49);
 
 /* bmcfru */
-at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 14), 14, 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 14), 14, 0x55, 8192, 1);
 
 /* TODO: Add remaining i2c devices. */
 }
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH v5 6/8] hw/arm: npcm8xx_boards: EEPROMs can take bus as parameter

2022-07-14 Thread Hao Wu
We allow at24c_eeprom_init to take a I2CBus* as parameter. This allows
us to attach an EEPROM device behind an I2C mux which is not
possible with the old method.

Signed-off-by: Hao Wu 
---
 hw/arm/npcm7xx_boards.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 6bc6f5d2fe..b083b0c572 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -140,10 +140,9 @@ static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, 
uint32_t num)
 return I2C_BUS(qdev_get_child_bus(DEVICE(>smbus[num]), "i2c-bus"));
 }
 
-static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr,
+static void at24c_eeprom_init(I2CBus *i2c_bus, int bus, uint8_t addr,
   uint32_t rsize)
 {
-I2CBus *i2c_bus = npcm7xx_i2c_get_bus(soc, bus);
 I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
 DeviceState *dev = DEVICE(i2c_dev);
 
@@ -253,8 +252,8 @@ static void quanta_gsj_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x5c);
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x5c);
 
-at24c_eeprom_init(soc, 9, 0x55, 8192);
-at24c_eeprom_init(soc, 10, 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 9), 9, 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 10), 10, 0x55, 8192);
 
 /*
  * i2c-11:
@@ -360,7 +359,8 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), TYPE_PCA9548, 0x77);
 
-at24c_eeprom_init(soc, 4, 0x50, 8192); /* mbfru */
+/* mbfru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 4), 4, 0x50, 8192);
 
 i2c_mux = i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 13),
   TYPE_PCA9548, 0x77);
@@ -371,7 +371,8 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 4), "tmp105", 0x48);
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 5), "tmp105", 0x49);
 
-at24c_eeprom_init(soc, 14, 0x55, 8192); /* bmcfru */
+/* bmcfru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 14), 14, 0x55, 8192);
 
 /* TODO: Add remaining i2c devices. */
 }
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH v5 4/8] hw/adc: Make adci[*] R/W in NPCM7XX ADC

2022-07-14 Thread Hao Wu
Our sensor test requires both reading and writing from a sensor's
QOM property. So we need to make the input of ADC module R/W instead
of write only for that to work.

Signed-off-by: Hao Wu 
Reviewed-by: Titus Rwantare 
Reviewed-by: Peter Maydell 
---
 hw/adc/npcm7xx_adc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/adc/npcm7xx_adc.c b/hw/adc/npcm7xx_adc.c
index 47fb9e5f74..bc6f3f55e6 100644
--- a/hw/adc/npcm7xx_adc.c
+++ b/hw/adc/npcm7xx_adc.c
@@ -242,7 +242,7 @@ static void npcm7xx_adc_init(Object *obj)
 
 for (i = 0; i < NPCM7XX_ADC_NUM_INPUTS; ++i) {
 object_property_add_uint32_ptr(obj, "adci[*]",
->adci[i], OBJ_PROP_FLAG_WRITE);
+>adci[i], OBJ_PROP_FLAG_READWRITE);
 }
 object_property_add_uint32_ptr(obj, "vref",
 >vref, OBJ_PROP_FLAG_WRITE);
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH v5 2/8] hw/i2c: Read FIFO during RXF_CTL change in NPCM7XX SMBus

2022-07-14 Thread Hao Wu
Originally we read in from SMBus when RXF_STS is cleared. However,
the driver clears RXF_STS before setting RXF_CTL, causing the SM bus
module to read incorrect amount of bytes in FIFO mode when the number
of bytes read changed. This patch fixes this issue.

Signed-off-by: Hao Wu 
Reviewed-by: Titus Rwantare 
Acked-by: Corey Minyard 
---
 hw/i2c/npcm7xx_smbus.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
index f18e311556..1435daea94 100644
--- a/hw/i2c/npcm7xx_smbus.c
+++ b/hw/i2c/npcm7xx_smbus.c
@@ -637,9 +637,6 @@ static void npcm7xx_smbus_write_rxf_sts(NPCM7xxSMBusState 
*s, uint8_t value)
 {
 if (value & NPCM7XX_SMBRXF_STS_RX_THST) {
 s->rxf_sts &= ~NPCM7XX_SMBRXF_STS_RX_THST;
-if (s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
-npcm7xx_smbus_recv_fifo(s);
-}
 }
 }
 
@@ -651,6 +648,9 @@ static void npcm7xx_smbus_write_rxf_ctl(NPCM7xxSMBusState 
*s, uint8_t value)
 new_ctl = KEEP_OLD_BIT(s->rxf_ctl, new_ctl, NPCM7XX_SMBRXF_CTL_LAST);
 }
 s->rxf_ctl = new_ctl;
+if (s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
+npcm7xx_smbus_recv_fifo(s);
+}
 }
 
 static uint64_t npcm7xx_smbus_read(void *opaque, hwaddr offset, unsigned size)
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH v5 3/8] hw/adc: Fix CONV bit in NPCM7XX ADC CON register

2022-07-14 Thread Hao Wu
The correct bit for the CONV bit in NPCM7XX ADC is bit 13. This patch
fixes that in the module, and also lower the IRQ when the guest
is done handling an interrupt event from the ADC module.

Signed-off-by: Hao Wu 
Reviewed-by: Patrick Venture
Reviewed-by: Peter Maydell 
---
 hw/adc/npcm7xx_adc.c   | 2 +-
 tests/qtest/npcm7xx_adc-test.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/adc/npcm7xx_adc.c b/hw/adc/npcm7xx_adc.c
index 0f0a9f63e2..47fb9e5f74 100644
--- a/hw/adc/npcm7xx_adc.c
+++ b/hw/adc/npcm7xx_adc.c
@@ -36,7 +36,7 @@ REG32(NPCM7XX_ADC_DATA, 0x4)
 #define NPCM7XX_ADC_CON_INT BIT(18)
 #define NPCM7XX_ADC_CON_EN  BIT(17)
 #define NPCM7XX_ADC_CON_RST BIT(16)
-#define NPCM7XX_ADC_CON_CONVBIT(14)
+#define NPCM7XX_ADC_CON_CONVBIT(13)
 #define NPCM7XX_ADC_CON_DIV(rv) extract32(rv, 1, 8)
 
 #define NPCM7XX_ADC_MAX_RESULT  1023
diff --git a/tests/qtest/npcm7xx_adc-test.c b/tests/qtest/npcm7xx_adc-test.c
index 3fa6d9ece0..8048044d28 100644
--- a/tests/qtest/npcm7xx_adc-test.c
+++ b/tests/qtest/npcm7xx_adc-test.c
@@ -50,7 +50,7 @@
 #define CON_INT BIT(18)
 #define CON_EN  BIT(17)
 #define CON_RST BIT(16)
-#define CON_CONVBIT(14)
+#define CON_CONVBIT(13)
 #define CON_DIV(rv) extract32(rv, 1, 8)
 
 #define FST_RDSTBIT(1)
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH v5 8/8] hw/arm: quanta-gbs-bmc add i2c devices

2022-07-14 Thread Hao Wu
From: Patrick Venture 

Adds supported i2c devices to the quanta-gbc-bmc board.

Signed-off-by: Patrick Venture 
Reviewed-by: Hao Wu 
---
 hw/arm/npcm7xx_boards.c | 82 -
 1 file changed, 49 insertions(+), 33 deletions(-)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index b8337871ba..4bae5589f0 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -290,10 +290,12 @@ static void quanta_gsj_fan_init(NPCM7xxMachine *machine, 
NPCM7xxState *soc)
 
 static void quanta_gbs_i2c_init(NPCM7xxState *soc)
 {
+I2CSlave *i2c_mux;
+
+/* i2c-0: */
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 0), TYPE_PCA9546, 0x71);
+
 /*
- * i2c-0:
- * pca9546@71
- *
  * i2c-1:
  * pca9535@24
  * pca9535@20
@@ -302,46 +304,60 @@ static void quanta_gbs_i2c_init(NPCM7xxState *soc)
  * pca9535@23
  * pca9535@25
  * pca9535@26
- *
- * i2c-2:
- * sbtsi@4c
- *
- * i2c-5:
- * atmel,24c64@50 mb_fru
- * pca9546@71
- * - channel 0: max31725@54
- * - channel 1: max31725@55
- * - channel 2: max31725@5d
- *  atmel,24c64@51 fan_fru
- * - channel 3: atmel,24c64@52 hsbp_fru
- *
+ */
+
+/* i2c-2: sbtsi@4c */
+
+/* i2c-5: */
+/* mb_fru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 5), 5, 0x50, 8192, 0);
+i2c_mux = i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 5),
+  TYPE_PCA9546, 0x71);
+/* max31725 is tmp105 compatible. */
+i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 0), "tmp105", 0x54);
+i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 1), "tmp105", 0x55);
+i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 2), "tmp105", 0x5d);
+/* fan_fru */
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 5, 0x51, 8192, 1);
+/* hsbp_fru */
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 5, 0x52, 8192, 2);
+
+/*
  * i2c-6:
  * pca9545@73
  *
  * i2c-7:
  * pca9545@72
- *
- * i2c-8:
- * adi,adm1272@10
- *
- * i2c-9:
- * pca9546@71
- * - channel 0: isil,isl68137@60
- * - channel 1: isil,isl68137@61
- * - channel 2: isil,isl68137@63
- * - channel 3: isil,isl68137@45
- *
+ */
+
+/* i2c-8: */
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 8), "adm1272", 0x10);
+
+/* i2c-9: */
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 9), TYPE_PCA9546, 0x71);
+/*
+ * - channel 0: isil,isl68137@60
+ * - channel 1: isil,isl68137@61
+ * - channel 2: isil,isl68137@63
+ * - channel 3: isil,isl68137@45
+ */
+
+/*
  * i2c-10:
  * pca9545@71
  *
  * i2c-11:
  * pca9545@76
- *
- * i2c-12:
- * maxim,max34451@4e
- * isil,isl68137@5d
- * isil,isl68137@5e
- *
+ */
+
+/* i2c-12: */
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 12), "max34451", 0x4e);
+/*
+ * isil,isl68137@5d
+ * isil,isl68137@5e
+ */
+
+/*
  * i2c-14:
  * pca9545@70
  */
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH v5 1/8] hw/i2c: Clear ACK bit in NPCM7xx SMBus module

2022-07-14 Thread Hao Wu
The ACK bit in NPCM7XX SMBus module should be cleared each time it
sends out a NACK signal. This patch fixes the bug that it fails to
do so.

Signed-off-by: Hao Wu 
Reviewed-by: Titus Rwantare 
Reviewed-by: Peter Maydell 
---
 hw/i2c/npcm7xx_smbus.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
index e7e0ba66fe..f18e311556 100644
--- a/hw/i2c/npcm7xx_smbus.c
+++ b/hw/i2c/npcm7xx_smbus.c
@@ -270,7 +270,7 @@ static void npcm7xx_smbus_recv_byte(NPCM7xxSMBusState *s)
 if (s->st & NPCM7XX_SMBCTL1_ACK) {
 trace_npcm7xx_smbus_nack(DEVICE(s)->canonical_path);
 i2c_nack(s->bus);
-s->st &= NPCM7XX_SMBCTL1_ACK;
+s->st &= ~NPCM7XX_SMBCTL1_ACK;
 }
 trace_npcm7xx_smbus_recv_byte((DEVICE(s)->canonical_path), s->sda);
 npcm7xx_smbus_update_irq(s);
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH v5 5/8] blockdev: Add a new IF type IF_OTHER

2022-07-14 Thread Hao Wu
This type is used to represent block devs that are not suitable to
be represented by other existing types.

A sample use is to represent an at24c eeprom device defined in
hw/nvram/eeprom_at24c.c. The block device can be used to contain the
content of the said eeprom device.

Signed-off-by: Hao Wu 
---
 blockdev.c| 4 +++-
 include/sysemu/blockdev.h | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/blockdev.c b/blockdev.c
index 9230888e34..befd69ac5f 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -82,6 +82,7 @@ static const char *const if_name[IF_COUNT] = {
 [IF_MTD] = "mtd",
 [IF_SD] = "sd",
 [IF_VIRTIO] = "virtio",
+[IF_OTHER] = "other",
 [IF_XEN] = "xen",
 };
 
@@ -726,7 +727,8 @@ QemuOptsList qemu_legacy_drive_opts = {
 },{
 .name = "if",
 .type = QEMU_OPT_STRING,
-.help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
+.help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio,"
+" other)",
 },{
 .name = "file",
 .type = QEMU_OPT_STRING,
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index 3211b16513..d9dd5af291 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -21,6 +21,7 @@ typedef enum {
  */
 IF_NONE = 0,
 IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO, IF_XEN,
+IF_OTHER,
 IF_COUNT
 } BlockInterfaceType;
 
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH v5 0/8] Misc NPCM7XX patches

2022-07-14 Thread Hao Wu
[NOTE: I'm reviving a bunch of patches that was in the process of
upstreaming a while ago but paused.]

This patch set contains a few bug fixes and I2C devices for some
NPCM7XX boards.

Patch 1~2 fix a problem that causes the SMBus module to behave
incorrectly when it's in FIFO mode and trying to receive more than
16 bytes at a time.

Patch 3 fixes a error in a register for ADC module.

Patch 4 makes the ADC input to be R/W instead of write only. It allows
a test system to read these via QMP and has no negative effect.

Patch 5 adds a new blockdev IF type IF_OTHER.

Patch 6 allows at24c_eeprom_init to take a bus as parameter so it can
be used by more use cases (e.g. behind an I2C mux.)

Patch 7 allows at24c_eeprom_init to take a drive as property, similar
to sdhci_attach_device().

Patch 8 uses the function defined in patch 5 to add the EEPROM and other
I2C devices for Quanta GBS board.

-- Changes since v4:
1. Add comments to patch 5.
2. Split patch 6 into 2 patches according to the feedback.  Each patch does it 
own task.

-- Changes since v3:
1. Add a new blockdev IF type IF_OTHER.
2. Use IF_OTHER instead of IF_NONE.

-- Changes since v2:
1. Dropped patch 7.
2. Drop an extra variable in patch 5.

-- Changes since v1:
1. Rewrote patch 5 to implement the function in NPCM7xx board file instead
   of the EEPROM device file.
2. Slightly modify patch 6 to adapt to the changes and QEMU comment style.
3. Squash patch 7 into patch 5 to make it compile.
4. Add a new patch 7.

Hao Wu (7):
  hw/i2c: Clear ACK bit in NPCM7xx SMBus module
  hw/i2c: Read FIFO during RXF_CTL change in NPCM7XX SMBus
  hw/adc: Fix CONV bit in NPCM7XX ADC CON register
  hw/adc: Make adci[*] R/W in NPCM7XX ADC
  blockdev: Add a new IF type IF_OTHER
  hw/arm: npcm8xx_boards: EEPROMs can take bus as parameter
  hw/arm: Set drive property for at24c eeprom

Patrick Venture (1):
  hw/arm: quanta-gbs-bmc add i2c devices

 blockdev.c |   4 +-
 hw/adc/npcm7xx_adc.c   |   4 +-
 hw/arm/npcm7xx_boards.c| 102 -
 hw/i2c/npcm7xx_smbus.c |   8 +--
 include/sysemu/blockdev.h  |   1 +
 tests/qtest/npcm7xx_adc-test.c |   2 +-
 6 files changed, 73 insertions(+), 48 deletions(-)

-- 
2.37.0.170.g444d1eabd0-goog




[PATCH 3/8] hw/adc: Fix CONV bit in NPCM7XX ADC CON register

2022-07-14 Thread Hao Wu
The correct bit for the CONV bit in NPCM7XX ADC is bit 13. This patch
fixes that in the module, and also lower the IRQ when the guest
is done handling an interrupt event from the ADC module.

Signed-off-by: Hao Wu 
Reviewed-by: Patrick Venture
Reviewed-by: Peter Maydell 
---
 hw/adc/npcm7xx_adc.c   | 2 +-
 tests/qtest/npcm7xx_adc-test.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/adc/npcm7xx_adc.c b/hw/adc/npcm7xx_adc.c
index 0f0a9f63e2..47fb9e5f74 100644
--- a/hw/adc/npcm7xx_adc.c
+++ b/hw/adc/npcm7xx_adc.c
@@ -36,7 +36,7 @@ REG32(NPCM7XX_ADC_DATA, 0x4)
 #define NPCM7XX_ADC_CON_INT BIT(18)
 #define NPCM7XX_ADC_CON_EN  BIT(17)
 #define NPCM7XX_ADC_CON_RST BIT(16)
-#define NPCM7XX_ADC_CON_CONVBIT(14)
+#define NPCM7XX_ADC_CON_CONVBIT(13)
 #define NPCM7XX_ADC_CON_DIV(rv) extract32(rv, 1, 8)
 
 #define NPCM7XX_ADC_MAX_RESULT  1023
diff --git a/tests/qtest/npcm7xx_adc-test.c b/tests/qtest/npcm7xx_adc-test.c
index 3fa6d9ece0..8048044d28 100644
--- a/tests/qtest/npcm7xx_adc-test.c
+++ b/tests/qtest/npcm7xx_adc-test.c
@@ -50,7 +50,7 @@
 #define CON_INT BIT(18)
 #define CON_EN  BIT(17)
 #define CON_RST BIT(16)
-#define CON_CONVBIT(14)
+#define CON_CONVBIT(13)
 #define CON_DIV(rv) extract32(rv, 1, 8)
 
 #define FST_RDSTBIT(1)
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH 1/8] hw/i2c: Clear ACK bit in NPCM7xx SMBus module

2022-07-14 Thread Hao Wu
The ACK bit in NPCM7XX SMBus module should be cleared each time it
sends out a NACK signal. This patch fixes the bug that it fails to
do so.

Signed-off-by: Hao Wu 
Reviewed-by: Titus Rwantare 
Reviewed-by: Peter Maydell 
---
 hw/i2c/npcm7xx_smbus.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
index e7e0ba66fe..f18e311556 100644
--- a/hw/i2c/npcm7xx_smbus.c
+++ b/hw/i2c/npcm7xx_smbus.c
@@ -270,7 +270,7 @@ static void npcm7xx_smbus_recv_byte(NPCM7xxSMBusState *s)
 if (s->st & NPCM7XX_SMBCTL1_ACK) {
 trace_npcm7xx_smbus_nack(DEVICE(s)->canonical_path);
 i2c_nack(s->bus);
-s->st &= NPCM7XX_SMBCTL1_ACK;
+s->st &= ~NPCM7XX_SMBCTL1_ACK;
 }
 trace_npcm7xx_smbus_recv_byte((DEVICE(s)->canonical_path), s->sda);
 npcm7xx_smbus_update_irq(s);
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH 5/8] blockdev: Add a new IF type IF_OTHER

2022-07-14 Thread Hao Wu
This type is used to represent block devs that are not suitable to
be represented by other existing types.

A sample use is to represent an at24c eeprom device defined in
hw/nvram/eeprom_at24c.c. The block device can be used to contain the
content of the said eeprom device.

Signed-off-by: Hao Wu 
---
 blockdev.c| 4 +++-
 include/sysemu/blockdev.h | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/blockdev.c b/blockdev.c
index 9230888e34..befd69ac5f 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -82,6 +82,7 @@ static const char *const if_name[IF_COUNT] = {
 [IF_MTD] = "mtd",
 [IF_SD] = "sd",
 [IF_VIRTIO] = "virtio",
+[IF_OTHER] = "other",
 [IF_XEN] = "xen",
 };
 
@@ -726,7 +727,8 @@ QemuOptsList qemu_legacy_drive_opts = {
 },{
 .name = "if",
 .type = QEMU_OPT_STRING,
-.help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
+.help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio,"
+" other)",
 },{
 .name = "file",
 .type = QEMU_OPT_STRING,
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index 3211b16513..d9dd5af291 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -21,6 +21,7 @@ typedef enum {
  */
 IF_NONE = 0,
 IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO, IF_XEN,
+IF_OTHER,
 IF_COUNT
 } BlockInterfaceType;
 
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH 4/8] hw/adc: Make adci[*] R/W in NPCM7XX ADC

2022-07-14 Thread Hao Wu
Our sensor test requires both reading and writing from a sensor's
QOM property. So we need to make the input of ADC module R/W instead
of write only for that to work.

Signed-off-by: Hao Wu 
Reviewed-by: Titus Rwantare 
Reviewed-by: Peter Maydell 
---
 hw/adc/npcm7xx_adc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/adc/npcm7xx_adc.c b/hw/adc/npcm7xx_adc.c
index 47fb9e5f74..bc6f3f55e6 100644
--- a/hw/adc/npcm7xx_adc.c
+++ b/hw/adc/npcm7xx_adc.c
@@ -242,7 +242,7 @@ static void npcm7xx_adc_init(Object *obj)
 
 for (i = 0; i < NPCM7XX_ADC_NUM_INPUTS; ++i) {
 object_property_add_uint32_ptr(obj, "adci[*]",
->adci[i], OBJ_PROP_FLAG_WRITE);
+>adci[i], OBJ_PROP_FLAG_READWRITE);
 }
 object_property_add_uint32_ptr(obj, "vref",
 >vref, OBJ_PROP_FLAG_WRITE);
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH 2/8] hw/i2c: Read FIFO during RXF_CTL change in NPCM7XX SMBus

2022-07-14 Thread Hao Wu
Originally we read in from SMBus when RXF_STS is cleared. However,
the driver clears RXF_STS before setting RXF_CTL, causing the SM bus
module to read incorrect amount of bytes in FIFO mode when the number
of bytes read changed. This patch fixes this issue.

Signed-off-by: Hao Wu 
Reviewed-by: Titus Rwantare 
Acked-by: Corey Minyard 
---
 hw/i2c/npcm7xx_smbus.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
index f18e311556..1435daea94 100644
--- a/hw/i2c/npcm7xx_smbus.c
+++ b/hw/i2c/npcm7xx_smbus.c
@@ -637,9 +637,6 @@ static void npcm7xx_smbus_write_rxf_sts(NPCM7xxSMBusState 
*s, uint8_t value)
 {
 if (value & NPCM7XX_SMBRXF_STS_RX_THST) {
 s->rxf_sts &= ~NPCM7XX_SMBRXF_STS_RX_THST;
-if (s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
-npcm7xx_smbus_recv_fifo(s);
-}
 }
 }
 
@@ -651,6 +648,9 @@ static void npcm7xx_smbus_write_rxf_ctl(NPCM7xxSMBusState 
*s, uint8_t value)
 new_ctl = KEEP_OLD_BIT(s->rxf_ctl, new_ctl, NPCM7XX_SMBRXF_CTL_LAST);
 }
 s->rxf_ctl = new_ctl;
+if (s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
+npcm7xx_smbus_recv_fifo(s);
+}
 }
 
 static uint64_t npcm7xx_smbus_read(void *opaque, hwaddr offset, unsigned size)
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH 0/8] Misc NPCM7XX patches

2022-07-14 Thread Hao Wu
[NOTE: I'm reviving a bunch of patches that was in the process of
upstreaming a while ago but paused.]

This patch set contains a few bug fixes and I2C devices for some
NPCM7XX boards.

Patch 1~2 fix a problem that causes the SMBus module to behave
incorrectly when it's in FIFO mode and trying to receive more than
16 bytes at a time.

Patch 3 fixes a error in a register for ADC module.

Patch 4 makes the ADC input to be R/W instead of write only. It allows
a test system to read these via QMP and has no negative effect.

Patch 5 adds a new blockdev IF type IF_OTHER.

Patch 6 allows at24c_eeprom_init to take a bus as parameter so it can
be used by more use cases (e.g. behind an I2C mux.)

Patch 7 allows at24c_eeprom_init to take a drive as property, similar
to sdhci_attach_device().

Patch 8 uses the function defined in patch 5 to add the EEPROM and other
I2C devices for Quanta GBS board.

-- Changes since v4:
1. Add comments to patch 5.
2. Split patch 6 into 2 patches according to the feedback.  Each patch does it 
own task.

-- Changes since v3:
1. Add a new blockdev IF type IF_OTHER.
2. Use IF_OTHER instead of IF_NONE.

-- Changes since v2:
1. Dropped patch 7.
2. Drop an extra variable in patch 5.

-- Changes since v1:
1. Rewrote patch 5 to implement the function in NPCM7xx board file instead
   of the EEPROM device file.
2. Slightly modify patch 6 to adapt to the changes and QEMU comment style.
3. Squash patch 7 into patch 5 to make it compile.
4. Add a new patch 7.

Hao Wu (7):
  hw/i2c: Clear ACK bit in NPCM7xx SMBus module
  hw/i2c: Read FIFO during RXF_CTL change in NPCM7XX SMBus
  hw/adc: Fix CONV bit in NPCM7XX ADC CON register
  hw/adc: Make adci[*] R/W in NPCM7XX ADC
  blockdev: Add a new IF type IF_OTHER
  hw/arm: npcm8xx_boards: EEPROMs can take bus as parameter
  hw/arm: Set drive property for at24c eeprom

Patrick Venture (1):
  hw/arm: quanta-gbs-bmc add i2c devices

 blockdev.c |   4 +-
 hw/adc/npcm7xx_adc.c   |   4 +-
 hw/arm/npcm7xx_boards.c| 102 -
 hw/i2c/npcm7xx_smbus.c |   8 +--
 include/sysemu/blockdev.h  |   1 +
 tests/qtest/npcm7xx_adc-test.c |   2 +-
 6 files changed, 73 insertions(+), 48 deletions(-)

-- 
2.37.0.170.g444d1eabd0-goog




[PATCH 8/8] hw/arm: quanta-gbs-bmc add i2c devices

2022-07-14 Thread Hao Wu
From: Patrick Venture 

Adds supported i2c devices to the quanta-gbc-bmc board.

Signed-off-by: Patrick Venture 
Reviewed-by: Hao Wu 
---
 hw/arm/npcm7xx_boards.c | 82 -
 1 file changed, 49 insertions(+), 33 deletions(-)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index b8337871ba..4bae5589f0 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -290,10 +290,12 @@ static void quanta_gsj_fan_init(NPCM7xxMachine *machine, 
NPCM7xxState *soc)
 
 static void quanta_gbs_i2c_init(NPCM7xxState *soc)
 {
+I2CSlave *i2c_mux;
+
+/* i2c-0: */
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 0), TYPE_PCA9546, 0x71);
+
 /*
- * i2c-0:
- * pca9546@71
- *
  * i2c-1:
  * pca9535@24
  * pca9535@20
@@ -302,46 +304,60 @@ static void quanta_gbs_i2c_init(NPCM7xxState *soc)
  * pca9535@23
  * pca9535@25
  * pca9535@26
- *
- * i2c-2:
- * sbtsi@4c
- *
- * i2c-5:
- * atmel,24c64@50 mb_fru
- * pca9546@71
- * - channel 0: max31725@54
- * - channel 1: max31725@55
- * - channel 2: max31725@5d
- *  atmel,24c64@51 fan_fru
- * - channel 3: atmel,24c64@52 hsbp_fru
- *
+ */
+
+/* i2c-2: sbtsi@4c */
+
+/* i2c-5: */
+/* mb_fru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 5), 5, 0x50, 8192, 0);
+i2c_mux = i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 5),
+  TYPE_PCA9546, 0x71);
+/* max31725 is tmp105 compatible. */
+i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 0), "tmp105", 0x54);
+i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 1), "tmp105", 0x55);
+i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 2), "tmp105", 0x5d);
+/* fan_fru */
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 5, 0x51, 8192, 1);
+/* hsbp_fru */
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 5, 0x52, 8192, 2);
+
+/*
  * i2c-6:
  * pca9545@73
  *
  * i2c-7:
  * pca9545@72
- *
- * i2c-8:
- * adi,adm1272@10
- *
- * i2c-9:
- * pca9546@71
- * - channel 0: isil,isl68137@60
- * - channel 1: isil,isl68137@61
- * - channel 2: isil,isl68137@63
- * - channel 3: isil,isl68137@45
- *
+ */
+
+/* i2c-8: */
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 8), "adm1272", 0x10);
+
+/* i2c-9: */
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 9), TYPE_PCA9546, 0x71);
+/*
+ * - channel 0: isil,isl68137@60
+ * - channel 1: isil,isl68137@61
+ * - channel 2: isil,isl68137@63
+ * - channel 3: isil,isl68137@45
+ */
+
+/*
  * i2c-10:
  * pca9545@71
  *
  * i2c-11:
  * pca9545@76
- *
- * i2c-12:
- * maxim,max34451@4e
- * isil,isl68137@5d
- * isil,isl68137@5e
- *
+ */
+
+/* i2c-12: */
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 12), "max34451", 0x4e);
+/*
+ * isil,isl68137@5d
+ * isil,isl68137@5e
+ */
+
+/*
  * i2c-14:
  * pca9545@70
  */
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH 3/8] hw/adc: Fix CONV bit in NPCM7XX ADC CON register

2022-07-14 Thread Hao Wu
The correct bit for the CONV bit in NPCM7XX ADC is bit 13. This patch
fixes that in the module, and also lower the IRQ when the guest
is done handling an interrupt event from the ADC module.

Signed-off-by: Hao Wu 
Reviewed-by: Patrick Venture
Reviewed-by: Peter Maydell 
---
 hw/adc/npcm7xx_adc.c   | 2 +-
 tests/qtest/npcm7xx_adc-test.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/adc/npcm7xx_adc.c b/hw/adc/npcm7xx_adc.c
index 0f0a9f63e2..47fb9e5f74 100644
--- a/hw/adc/npcm7xx_adc.c
+++ b/hw/adc/npcm7xx_adc.c
@@ -36,7 +36,7 @@ REG32(NPCM7XX_ADC_DATA, 0x4)
 #define NPCM7XX_ADC_CON_INT BIT(18)
 #define NPCM7XX_ADC_CON_EN  BIT(17)
 #define NPCM7XX_ADC_CON_RST BIT(16)
-#define NPCM7XX_ADC_CON_CONVBIT(14)
+#define NPCM7XX_ADC_CON_CONVBIT(13)
 #define NPCM7XX_ADC_CON_DIV(rv) extract32(rv, 1, 8)
 
 #define NPCM7XX_ADC_MAX_RESULT  1023
diff --git a/tests/qtest/npcm7xx_adc-test.c b/tests/qtest/npcm7xx_adc-test.c
index 3fa6d9ece0..8048044d28 100644
--- a/tests/qtest/npcm7xx_adc-test.c
+++ b/tests/qtest/npcm7xx_adc-test.c
@@ -50,7 +50,7 @@
 #define CON_INT BIT(18)
 #define CON_EN  BIT(17)
 #define CON_RST BIT(16)
-#define CON_CONVBIT(14)
+#define CON_CONVBIT(13)
 #define CON_DIV(rv) extract32(rv, 1, 8)
 
 #define FST_RDSTBIT(1)
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH 7/8] hw/arm: Set drive property for at24c eeprom

2022-07-14 Thread Hao Wu
This patch allows the user to attach an external drive as a property
for an onboard at24c eeprom device. It uses an unit number to
distinguish different devices.

Signed-off-by: Hao Wu 
---
 hw/arm/npcm7xx_boards.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index b083b0c572..b8337871ba 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -141,11 +141,16 @@ static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, 
uint32_t num)
 }
 
 static void at24c_eeprom_init(I2CBus *i2c_bus, int bus, uint8_t addr,
-  uint32_t rsize)
+  uint32_t rsize, int unit)
 {
 I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
 DeviceState *dev = DEVICE(i2c_dev);
+DriveInfo *dinfo;
 
+dinfo = drive_get(IF_OTHER, bus, unit);
+if (dinfo) {
+qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo));
+}
 qdev_prop_set_uint32(dev, "rom-size", rsize);
 i2c_slave_realize_and_unref(i2c_dev, i2c_bus, _abort);
 }
@@ -252,8 +257,8 @@ static void quanta_gsj_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x5c);
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x5c);
 
-at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 9), 9, 0x55, 8192);
-at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 10), 10, 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 9), 9, 0x55, 8192, 0);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 10), 10, 0x55, 8192, 1);
 
 /*
  * i2c-11:
@@ -360,7 +365,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), TYPE_PCA9548, 0x77);
 
 /* mbfru */
-at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 4), 4, 0x50, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 4), 4, 0x50, 8192, 0);
 
 i2c_mux = i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 13),
   TYPE_PCA9548, 0x77);
@@ -372,7 +377,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 5), "tmp105", 0x49);
 
 /* bmcfru */
-at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 14), 14, 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 14), 14, 0x55, 8192, 1);
 
 /* TODO: Add remaining i2c devices. */
 }
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH 1/8] hw/i2c: Clear ACK bit in NPCM7xx SMBus module

2022-07-14 Thread Hao Wu
The ACK bit in NPCM7XX SMBus module should be cleared each time it
sends out a NACK signal. This patch fixes the bug that it fails to
do so.

Signed-off-by: Hao Wu 
Reviewed-by: Titus Rwantare 
Reviewed-by: Peter Maydell 
---
 hw/i2c/npcm7xx_smbus.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
index e7e0ba66fe..f18e311556 100644
--- a/hw/i2c/npcm7xx_smbus.c
+++ b/hw/i2c/npcm7xx_smbus.c
@@ -270,7 +270,7 @@ static void npcm7xx_smbus_recv_byte(NPCM7xxSMBusState *s)
 if (s->st & NPCM7XX_SMBCTL1_ACK) {
 trace_npcm7xx_smbus_nack(DEVICE(s)->canonical_path);
 i2c_nack(s->bus);
-s->st &= NPCM7XX_SMBCTL1_ACK;
+s->st &= ~NPCM7XX_SMBCTL1_ACK;
 }
 trace_npcm7xx_smbus_recv_byte((DEVICE(s)->canonical_path), s->sda);
 npcm7xx_smbus_update_irq(s);
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH 4/8] hw/adc: Make adci[*] R/W in NPCM7XX ADC

2022-07-14 Thread Hao Wu
Our sensor test requires both reading and writing from a sensor's
QOM property. So we need to make the input of ADC module R/W instead
of write only for that to work.

Signed-off-by: Hao Wu 
Reviewed-by: Titus Rwantare 
Reviewed-by: Peter Maydell 
---
 hw/adc/npcm7xx_adc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/adc/npcm7xx_adc.c b/hw/adc/npcm7xx_adc.c
index 47fb9e5f74..bc6f3f55e6 100644
--- a/hw/adc/npcm7xx_adc.c
+++ b/hw/adc/npcm7xx_adc.c
@@ -242,7 +242,7 @@ static void npcm7xx_adc_init(Object *obj)
 
 for (i = 0; i < NPCM7XX_ADC_NUM_INPUTS; ++i) {
 object_property_add_uint32_ptr(obj, "adci[*]",
->adci[i], OBJ_PROP_FLAG_WRITE);
+>adci[i], OBJ_PROP_FLAG_READWRITE);
 }
 object_property_add_uint32_ptr(obj, "vref",
 >vref, OBJ_PROP_FLAG_WRITE);
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH 6/8] hw/arm: npcm8xx_boards: EEPROMs can take bus as parameter

2022-07-14 Thread Hao Wu
We allow at24c_eeprom_init to take a I2CBus* as parameter. This allows
us to attach an EEPROM device behind an I2C mux which is not
possible with the old method.

Signed-off-by: Hao Wu 
---
 hw/arm/npcm7xx_boards.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 6bc6f5d2fe..b083b0c572 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -140,10 +140,9 @@ static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, 
uint32_t num)
 return I2C_BUS(qdev_get_child_bus(DEVICE(>smbus[num]), "i2c-bus"));
 }
 
-static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr,
+static void at24c_eeprom_init(I2CBus *i2c_bus, int bus, uint8_t addr,
   uint32_t rsize)
 {
-I2CBus *i2c_bus = npcm7xx_i2c_get_bus(soc, bus);
 I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
 DeviceState *dev = DEVICE(i2c_dev);
 
@@ -253,8 +252,8 @@ static void quanta_gsj_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x5c);
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x5c);
 
-at24c_eeprom_init(soc, 9, 0x55, 8192);
-at24c_eeprom_init(soc, 10, 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 9), 9, 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 10), 10, 0x55, 8192);
 
 /*
  * i2c-11:
@@ -360,7 +359,8 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), TYPE_PCA9548, 0x77);
 
-at24c_eeprom_init(soc, 4, 0x50, 8192); /* mbfru */
+/* mbfru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 4), 4, 0x50, 8192);
 
 i2c_mux = i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 13),
   TYPE_PCA9548, 0x77);
@@ -371,7 +371,8 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 4), "tmp105", 0x48);
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 5), "tmp105", 0x49);
 
-at24c_eeprom_init(soc, 14, 0x55, 8192); /* bmcfru */
+/* bmcfru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 14), 14, 0x55, 8192);
 
 /* TODO: Add remaining i2c devices. */
 }
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH 2/8] hw/i2c: Read FIFO during RXF_CTL change in NPCM7XX SMBus

2022-07-14 Thread Hao Wu
Originally we read in from SMBus when RXF_STS is cleared. However,
the driver clears RXF_STS before setting RXF_CTL, causing the SM bus
module to read incorrect amount of bytes in FIFO mode when the number
of bytes read changed. This patch fixes this issue.

Signed-off-by: Hao Wu 
Reviewed-by: Titus Rwantare 
Acked-by: Corey Minyard 
---
 hw/i2c/npcm7xx_smbus.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
index f18e311556..1435daea94 100644
--- a/hw/i2c/npcm7xx_smbus.c
+++ b/hw/i2c/npcm7xx_smbus.c
@@ -637,9 +637,6 @@ static void npcm7xx_smbus_write_rxf_sts(NPCM7xxSMBusState 
*s, uint8_t value)
 {
 if (value & NPCM7XX_SMBRXF_STS_RX_THST) {
 s->rxf_sts &= ~NPCM7XX_SMBRXF_STS_RX_THST;
-if (s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
-npcm7xx_smbus_recv_fifo(s);
-}
 }
 }
 
@@ -651,6 +648,9 @@ static void npcm7xx_smbus_write_rxf_ctl(NPCM7xxSMBusState 
*s, uint8_t value)
 new_ctl = KEEP_OLD_BIT(s->rxf_ctl, new_ctl, NPCM7XX_SMBRXF_CTL_LAST);
 }
 s->rxf_ctl = new_ctl;
+if (s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
+npcm7xx_smbus_recv_fifo(s);
+}
 }
 
 static uint64_t npcm7xx_smbus_read(void *opaque, hwaddr offset, unsigned size)
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH 5/8] blockdev: Add a new IF type IF_OTHER

2022-07-14 Thread Hao Wu
This type is used to represent block devs that are not suitable to
be represented by other existing types.

A sample use is to represent an at24c eeprom device defined in
hw/nvram/eeprom_at24c.c. The block device can be used to contain the
content of the said eeprom device.

Signed-off-by: Hao Wu 
---
 blockdev.c| 4 +++-
 include/sysemu/blockdev.h | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/blockdev.c b/blockdev.c
index 9230888e34..befd69ac5f 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -82,6 +82,7 @@ static const char *const if_name[IF_COUNT] = {
 [IF_MTD] = "mtd",
 [IF_SD] = "sd",
 [IF_VIRTIO] = "virtio",
+[IF_OTHER] = "other",
 [IF_XEN] = "xen",
 };
 
@@ -726,7 +727,8 @@ QemuOptsList qemu_legacy_drive_opts = {
 },{
 .name = "if",
 .type = QEMU_OPT_STRING,
-.help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
+.help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio,"
+" other)",
 },{
 .name = "file",
 .type = QEMU_OPT_STRING,
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index 3211b16513..d9dd5af291 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -21,6 +21,7 @@ typedef enum {
  */
 IF_NONE = 0,
 IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO, IF_XEN,
+IF_OTHER,
 IF_COUNT
 } BlockInterfaceType;
 
-- 
2.37.0.170.g444d1eabd0-goog




[PATCH 0/8] Misc NPCM7XX patches

2022-07-14 Thread Hao Wu
[NOTE: I'm reviving a bunch of patches that was in the process of
upstreaming a while ago but paused.]

This patch set contains a few bug fixes and I2C devices for some
NPCM7XX boards.

Patch 1~2 fix a problem that causes the SMBus module to behave
incorrectly when it's in FIFO mode and trying to receive more than
16 bytes at a time.

Patch 3 fixes a error in a register for ADC module.

Patch 4 makes the ADC input to be R/W instead of write only. It allows
a test system to read these via QMP and has no negative effect.

Patch 5 adds a new blockdev IF type IF_OTHER.

Patch 6 allows at24c_eeprom_init to take a bus as parameter so it can
be used by more use cases (e.g. behind an I2C mux.)

Patch 7 allows at24c_eeprom_init to take a drive as property, similar
to sdhci_attach_device().

Patch 8 uses the function defined in patch 5 to add the EEPROM and other
I2C devices for Quanta GBS board.

-- Changes since v4:
1. Add comments to patch 5.
2. Split patch 6 into 2 patches according to the feedback.  Each patch does it 
own task.

-- Changes since v3:
1. Add a new blockdev IF type IF_OTHER.
2. Use IF_OTHER instead of IF_NONE.

-- Changes since v2:
1. Dropped patch 7.
2. Drop an extra variable in patch 5.

-- Changes since v1:
1. Rewrote patch 5 to implement the function in NPCM7xx board file instead
   of the EEPROM device file.
2. Slightly modify patch 6 to adapt to the changes and QEMU comment style.
3. Squash patch 7 into patch 5 to make it compile.
4. Add a new patch 7.

Hao Wu (7):
  hw/i2c: Clear ACK bit in NPCM7xx SMBus module
  hw/i2c: Read FIFO during RXF_CTL change in NPCM7XX SMBus
  hw/adc: Fix CONV bit in NPCM7XX ADC CON register
  hw/adc: Make adci[*] R/W in NPCM7XX ADC
  blockdev: Add a new IF type IF_OTHER
  hw/arm: npcm8xx_boards: EEPROMs can take bus as parameter
  hw/arm: Set drive property for at24c eeprom

Patrick Venture (1):
  hw/arm: quanta-gbs-bmc add i2c devices

 blockdev.c |   4 +-
 hw/adc/npcm7xx_adc.c   |   4 +-
 hw/arm/npcm7xx_boards.c| 102 -
 hw/i2c/npcm7xx_smbus.c |   8 +--
 include/sysemu/blockdev.h  |   1 +
 tests/qtest/npcm7xx_adc-test.c |   2 +-
 6 files changed, 73 insertions(+), 48 deletions(-)

-- 
2.37.0.170.g444d1eabd0-goog




[PATCH] tests/qtest: Reduce npcm7xx_sdhci test image size

2022-06-09 Thread Hao Wu
Creating 1GB image for a simple qtest is unnecessary
and could lead to failures. We reduce the image size
to 1MB to reduce the test overhead.

Signed-off-by: Hao Wu 
---
 tests/qtest/npcm7xx_sdhci-test.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/qtest/npcm7xx_sdhci-test.c b/tests/qtest/npcm7xx_sdhci-test.c
index aa35a77e8d..5d68540e52 100644
--- a/tests/qtest/npcm7xx_sdhci-test.c
+++ b/tests/qtest/npcm7xx_sdhci-test.c
@@ -24,7 +24,7 @@
 #define NPCM7XX_REG_SIZE 0x100
 #define NPCM7XX_MMC_BA 0xF0842000
 #define NPCM7XX_BLK_SIZE 512
-#define NPCM7XX_TEST_IMAGE_SIZE (1 << 30)
+#define NPCM7XX_TEST_IMAGE_SIZE (1 << 20)
 
 char *sd_path;
 
-- 
2.36.1.476.g0c4daa206d-goog




Re: [PATCH v5] tests/qtest: add qtests for npcm7xx sdhci

2022-06-09 Thread Hao Wu
Hi,

We did some experiments on this issue. It looks like the image size
restriction is in firmware. So in qtest we can make it
much smaller (e.g. 1MB) and the test still passes. We can send a patch with
this change if necessary.

On Thu, May 26, 2022 at 9:21 AM Patrick Venture  wrote:

>
>
> On Thu, May 26, 2022 at 8:54 AM Peter Maydell 
> wrote:
>
>> On Fri, 25 Feb 2022 at 17:45, Hao Wu  wrote:
>> >
>> > From: Shengtan Mao 
>> >
>> > Reviewed-by: Hao Wu 
>> > Reviewed-by: Chris Rauer 
>> > Signed-off-by: Shengtan Mao 
>> > Signed-off-by: Patrick Venture 
>>
>> Hi; John Snow tells me that this test fails in the tests/vm/netbsd
>> VM (you can test this with 'make vm-build-netbsd') because the
>> assert() on the ftruncate() call fails:
>>
>> > +ret = ftruncate(fd, NPCM7XX_TEST_IMAGE_SIZE);
>> > +g_assert_cmpint(ret, ==, 0);
>>
>> > +#define NPCM7XX_TEST_IMAGE_SIZE (1 << 30)
>>
>> I haven't investigated the exact cause, but this is a
>> gigabyte, right? That's a pretty massive file for a test case to
>> create -- can we make the test use a more sensible size of
>> sd card image ?
>>
>
> It looks like the nuvoton part had an issue with a smaller image size, but
> we can resurrect that thread and poke at it a bit and see what shakes out.
>
>
>>
>> thanks
>> -- PMM
>>
>


Re: [PATCH] qtest/npcm7xx_pwm-test: Fix memory leak in mft_qom_set

2022-05-31 Thread Hao Wu
On Tue, May 31, 2022 at 6:18 AM Miaoqian Lin  wrote:

> g_strdup_printf() allocated memory for path, we should free it with
> g_free() when no longer needed.
>
> Signed-off-by: Miaoqian Lin 
>
Reviewed-by: Hao Wu 

> ---
>  tests/qtest/npcm7xx_pwm-test.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/tests/qtest/npcm7xx_pwm-test.c
> b/tests/qtest/npcm7xx_pwm-test.c
> index c4a5fdcacd79..e320a625c4b6 100644
> --- a/tests/qtest/npcm7xx_pwm-test.c
> +++ b/tests/qtest/npcm7xx_pwm-test.c
> @@ -268,6 +268,9 @@ static void mft_qom_set(QTestState *qts, int index,
> const char *name,
>  path, name, value);
>  /* The qom set message returns successfully. */
>  g_assert_true(qdict_haskey(response, "return"));
> +
> +qobject_unref(response);
> +g_free(path);
>  }
>
>  static uint32_t get_pll(uint32_t con)
> --
> 2.25.1
>
>
>


Re: [PATCH for-7.1 00/11] hw/arm: Add NPCM8XX support

2022-04-21 Thread Hao Wu
Thanks!

I can add the new CPU type to virt in a separate patch set. It might take a
while before I send out
that patch set.

Since this patch set will be dependent on that I won't send out a v2 on
this patch set until that finishes.

On Thu, Apr 21, 2022 at 9:42 AM Peter Maydell 
wrote:

> On Thu, 21 Apr 2022 at 17:29, Hao Wu  wrote:
> >
> > Thanks for all the comments you gave! I'll go over and address them
> recently.
> >
> > For this question, The actual CPU should be cortex A35. However, I don't
> see
> > them supported in QEMU. If I inserted CPU with "cortex-a35" QEMU will
> complain:
> > qemu-system-aarch64: missing object type 'cortex-a35-arm-cpu'
> >
> > What should I do here?
>
> You need to implement the new CPU type first... This means adding
> something to target/arm/cpu64.c which will look similar to the
> existing CPU handling. You need to watch out for:
>  * getting all the ID register values right (check the TRM for the CPU)
>  * implementing whatever the right impdef system registers are
>  * checking whether QEMU is still missing support for any of the
>architectural features that the A35 implements (what QEMU
>supports is listed in docs/system/arm/emulation.rst)
>
> It's typically not much code but quite a lot of cross-checking
> against the TRM for the CPU that we're not missing pieces...
> Since you can add the A35 as a supported CPU type for the 'virt'
> board you can do A35 support as a separate patchset that doesn't
> depend on the npmc8xx work.
>
>
> https://patchew.org/QEMU/20220417174426.711829-1-richard.hender...@linaro.org/20220417174426.711829-60-richard.hender...@linaro.org/
> is an example of how to add a new CPU (in that case the A76), at
> the end of a large patchset from RTH that's still going through
> code review.
>
> -- PMM
>


Re: [PATCH for-7.1 00/11] hw/arm: Add NPCM8XX support

2022-04-21 Thread Hao Wu
Thanks for all the comments you gave! I'll go over and address them
recently.

For this question, The actual CPU should be cortex A35. However, I don't see
them supported in QEMU. If I inserted CPU with "cortex-a35" QEMU will
complain:
qemu-system-aarch64: missing object type 'cortex-a35-arm-cpu'

What should I do here?

On Thu, Apr 21, 2022 at 3:45 AM Peter Maydell 
wrote:

> On Tue, 5 Apr 2022 at 23:37, Hao Wu  wrote:
> >
> > NPCM8XX BMCs are the successors of the NPCM7XX BMCs. They feature
> > quad-core ARM Cortex A35 that supports both 32 bits and 64 bits
> > operations.
>
> Here and in the documentation patch you say "Cortex-A35", but the
> patch implementing the new SoC creates Cortex-A53 CPUs. Which
> is correct ?
>
> thanks
> -- PMM
>


[PATCH v2 1/2] hw/misc: Add PWRON STRAP bit fields in GCR module

2022-04-11 Thread Hao Wu
Similar to the Aspeed code in include/misc/aspeed_scu.h, we define
the PWRON STRAP fields in their corresponding module for NPCM7XX.

Signed-off-by: Hao Wu 
Reviewed-by: Patrick Venture 
---
 include/hw/misc/npcm7xx_gcr.h | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h
index 13109d9d32..9419e0a7d2 100644
--- a/include/hw/misc/npcm7xx_gcr.h
+++ b/include/hw/misc/npcm7xx_gcr.h
@@ -19,6 +19,36 @@
 #include "exec/memory.h"
 #include "hw/sysbus.h"
 
+/*
+ * NPCM7XX PWRON STRAP bit fields
+ * 12: SPI0 powered by VSBV3 at 1.8V
+ * 11: System flash attached to BMC
+ * 10: BSP alternative pins.
+ * 9:8: Flash UART command route enabled.
+ * 7: Security enabled.
+ * 6: HI-Z state control.
+ * 5: ECC disabled.
+ * 4: Reserved
+ * 3: JTAG2 enabled.
+ * 2:0: CPU and DRAM clock frequency.
+ */
+#define NPCM7XX_PWRON_STRAP_SPI0F18 BIT(12)
+#define NPCM7XX_PWRON_STRAP_SFABBIT(11)
+#define NPCM7XX_PWRON_STRAP_BSPABIT(10)
+#define NPCM7XX_PWRON_STRAP_FUP(x)  ((x) << 8)
+#define FUP_NORM_UART2  3
+#define FUP_PROG_UART3  2
+#define FUP_PROG_UART2  1
+#define FUP_NORM_UART3  0
+#define NPCM7XX_PWRON_STRAP_SECEN   BIT(7)
+#define NPCM7XX_PWRON_STRAP_HIZ BIT(6)
+#define NPCM7XX_PWRON_STRAP_ECC BIT(5)
+#define NPCM7XX_PWRON_STRAP_RESERVE1BIT(4)
+#define NPCM7XX_PWRON_STRAP_J2ENBIT(3)
+#define NPCM7XX_PWRON_STRAP_CKFRQ(x)(x)
+#define CKFRQ_SKIPINIT  0x000
+#define CKFRQ_DEFAULT   0x111
+
 /*
  * Number of registers in our device state structure. Don't change this without
  * incrementing the version_id in the vmstate.
-- 
2.35.1.1178.g4f1659d476-goog




[PATCH v2 2/2] hw/arm: Use bit fields for NPCM7XX PWRON STRAPs

2022-04-11 Thread Hao Wu
This patch uses the defined fields to describe PWRON STRAPs for
better readability.

Signed-off-by: Hao Wu 
Reviewed-by: Patrick Venture 
---
 hw/arm/npcm7xx_boards.c | 24 +++-
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 0678a56156..6bc6f5d2fe 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -30,11 +30,25 @@
 #include "sysemu/sysemu.h"
 #include "sysemu/block-backend.h"
 
-#define NPCM750_EVB_POWER_ON_STRAPS 0x1ff7
-#define QUANTA_GSJ_POWER_ON_STRAPS 0x1fff
-#define QUANTA_GBS_POWER_ON_STRAPS 0x17ff
-#define KUDO_BMC_POWER_ON_STRAPS 0x1fff
-#define MORI_BMC_POWER_ON_STRAPS 0x1fff
+#define NPCM7XX_POWER_ON_STRAPS_DEFAULT (   \
+NPCM7XX_PWRON_STRAP_SPI0F18 |   \
+NPCM7XX_PWRON_STRAP_SFAB |  \
+NPCM7XX_PWRON_STRAP_BSPA |  \
+NPCM7XX_PWRON_STRAP_FUP(FUP_NORM_UART2) |   \
+NPCM7XX_PWRON_STRAP_SECEN | \
+NPCM7XX_PWRON_STRAP_HIZ |   \
+NPCM7XX_PWRON_STRAP_ECC |   \
+NPCM7XX_PWRON_STRAP_RESERVE1 |  \
+NPCM7XX_PWRON_STRAP_J2EN |  \
+NPCM7XX_PWRON_STRAP_CKFRQ(CKFRQ_DEFAULT))
+
+#define NPCM750_EVB_POWER_ON_STRAPS ( \
+NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_J2EN)
+#define QUANTA_GSJ_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
+#define QUANTA_GBS_POWER_ON_STRAPS ( \
+NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_SFAB)
+#define KUDO_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
+#define MORI_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
 
 static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
 
-- 
2.35.1.1178.g4f1659d476-goog




[PATCH v2 0/2] Define NPCM7XX PWRON bit fields

2022-04-11 Thread Hao Wu
Currently, the PWRON STRAP values in NPCM7XX boards are magic
numbers. Similar to the aspeed ones in hw/arm/aspeed.c, we
define bit fields constants for them and use these fields instead
of the magic numbers in the current implementation. The code
should behave exactly the same as the existing one.

-- Changes since v1
* Fix errors and apply suggestions Peter made on v1.

Hao Wu (2):
  hw/misc: Add PWRON STRAP bit fields in GCR module
  hw/arm: Use bit fields for NPCM7XX PWRON STRAPs

 hw/arm/npcm7xx_boards.c   | 24 +++-
 include/hw/misc/npcm7xx_gcr.h | 30 ++
 2 files changed, 49 insertions(+), 5 deletions(-)

-- 
2.35.1.1178.g4f1659d476-goog




[PATCH 1/2] hw/misc: Add PWRON STRAP bit fields in GCR module

2022-04-06 Thread Hao Wu
Similar to the Aspeed code in include/misc/aspeed_scu.h, we define
the PWRON STRAP fields in their corresponding module for NPCM7XX.

Signed-off-by: Hao Wu 
Reviewed-by: Patrick Venture 
---
 include/hw/misc/npcm7xx_gcr.h | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h
index 13109d9d32..98da5d171f 100644
--- a/include/hw/misc/npcm7xx_gcr.h
+++ b/include/hw/misc/npcm7xx_gcr.h
@@ -19,6 +19,36 @@
 #include "exec/memory.h"
 #include "hw/sysbus.h"
 
+/*
+ * NPCM7XX PWRON STRAP bit fields
+ * 12: SPI0 powered by VSBV3 at 1.8V
+ * 11: System flash attached to BMC
+ * 10: BSP alternative pins.
+ * 9:8: Flash UART command route enabled.
+ * 7: Security enabled.
+ * 6: HI-Z state control.
+ * 5: ECC disabled.
+ * 4: Reserved
+ * 3: JTAG2 enabled.
+ * 2:0: CPU and DRAM clock frequency.
+ */
+#define NPCM7XX_PWRON_STRAP_SPI0F18 BIT(12)
+#define NPCM7XX_PWRON_STRAP_SFABBIT(11)
+#define NPCM7XX_PWRON_STRAP_BSPABIT(10)
+#define NPCM7XX_PWRON_STRAP_FUP(x)  ((x) << 8)
+#define FUP_NORM_UART2  3
+#define FUP_PROG_UART3  2
+#define FUP_PROG_UART2  1
+#define FUP_NORM_UART3  0
+#define NPCM7XX_PWRON_STRAP_SECEN   BIT(7)
+#define NPCM7XX_PWRON_STRAP_HIZ BIT(6)
+#define NPCM7XX_PWRON_STRAP_ECC BIT(5)
+#define NPCM7XX_PWRON_STRAP_RESERVE1BIT(4)
+#define NPCM7XX_PWRON_STRAP_J2ENBIT(3)
+#define NPCM7XX_PWRON_STRAP_CKFRQ(x)((x) << 8)
+#define CKFRQ_SKIPINIT  (0x000)
+#define CKFRQ_DEFAULT   (0x111)
+
 /*
  * Number of registers in our device state structure. Don't change this without
  * incrementing the version_id in the vmstate.
-- 
2.35.1.1094.g7c7d902a7c-goog




[PATCH 2/2] hw/arm: Use bit fields for NPCM7XX PWRON STRAPs

2022-04-06 Thread Hao Wu
This patch uses the defined fields to describe PWRON STRAPs for
better readability.

Signed-off-by: Hao Wu 
Reviewed-by: Patrick Venture 
---
 hw/arm/npcm7xx_boards.c | 24 +++-
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 0678a56156..62d4092657 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -30,11 +30,25 @@
 #include "sysemu/sysemu.h"
 #include "sysemu/block-backend.h"
 
-#define NPCM750_EVB_POWER_ON_STRAPS 0x1ff7
-#define QUANTA_GSJ_POWER_ON_STRAPS 0x1fff
-#define QUANTA_GBS_POWER_ON_STRAPS 0x17ff
-#define KUDO_BMC_POWER_ON_STRAPS 0x1fff
-#define MORI_BMC_POWER_ON_STRAPS 0x1fff
+#define NPCM7XX_POWER_ON_STRAPS_DEFAULT (   \
+NPCM7XX_PWRON_STRAP_SPI0F18 |   \
+NPCM7XX_PWRON_STRAP_SFAB |  \
+NPCM7XX_PWRON_STRAP_BSPA |  \
+NPCM7XX_PWRON_STRAP_FUP(FUP_NORM_UART2) |   \
+NPCM7XX_PWRON_STRAP_SECEN | \
+NPCM7XX_PWRON_STRAP_HIZ |   \
+NPCM7XX_PWRON_STRAP_ECC |   \
+NPCM7XX_PWRON_STRAP_RESERVE1 |  \
+NPCM7XX_PWRON_STRAP_J2EN |  \
+NPCM7XX_PWRON_STRAP_CKFRQ(CKFRQ_DEFAULT))   \
+
+#define NPCM750_EVB_POWER_ON_STRAPS ( \
+NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_RESERVE1)
+#define QUANTA_GSJ_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
+#define QUANTA_GBS_POWER_ON_STRAPS ( \
+NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_SFAB)
+#define KUDO_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
+#define MORI_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
 
 static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
 
-- 
2.35.1.1094.g7c7d902a7c-goog




[PATCH 0/2] Define NPCM7XX PWRON bit fields

2022-04-06 Thread Hao Wu
Currently, the PWRON STRAP values in NPCM7XX boards are magic
numbers. Similar to the aspeed ones in hw/arm/aspeed.c, we
define bit fields constants for them and use these fields instead
of the magic numbers in the current implementation. The code
should behave exactly the same as the existing one.

Hao Wu (2):
  hw/misc: Add PWRON STRAP bit fields in GCR module
  hw/arm: Use bit fields for NPCM7XX PWRON STRAPs

 hw/arm/npcm7xx_boards.c   | 24 +++-
 include/hw/misc/npcm7xx_gcr.h | 30 ++
 2 files changed, 49 insertions(+), 5 deletions(-)

-- 
2.35.1.1094.g7c7d902a7c-goog




[PATCH for-7.1 09/11] pc-bios: Add NPCM8xx Bootrom

2022-04-05 Thread Hao Wu
The bootrom is a minimal bootrom that can be used to bring up
an NPCM845 Linux kernel. Its source code can be found at
github.com/google/vbootrom/tree/master/npcm8xx

Signed-off-by: Hao Wu 
Reviwed-by: Titus Rwantare 
---
 pc-bios/npcm8xx_bootrom.bin | Bin 0 -> 608 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 pc-bios/npcm8xx_bootrom.bin

diff --git a/pc-bios/npcm8xx_bootrom.bin b/pc-bios/npcm8xx_bootrom.bin
new file mode 100644
index 
..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=Ru)PgZC)Y`f
zTqA9Am28qLHlr*^#;re-)dpxT0U42|O+cWOcx=B;{6xXH04vx?cjm
z+%U{oFx!aPpV3>ZKz0i$XA-yq{f}x4;|pbw;l#@9zGd|z-rs*H@V-o%PEV)D-)8n2%DyH5@w_^Y8
LH5R3RMV#gjxYTW}

literal 0
HcmV?d1

-- 
2.35.1.1094.g7c7d902a7c-goog




[PATCH for-7.1 11/11] hw/arm: Add NPCM845 Evaluation board

2022-04-05 Thread Hao Wu
Signed-off-by: Hao Wu 
Reviwed-by: Patrick Venture 
---
 hw/arm/meson.build   |   2 +-
 hw/arm/npcm8xx_boards.c  | 257 +++
 include/hw/arm/npcm8xx.h |  20 +++
 3 files changed, 278 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/npcm8xx_boards.c

diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index cf824241c5..e813cd72fa 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -14,7 +14,7 @@ arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: 
files('musicpal.c'))
 arm_ss.add(when: 'CONFIG_NETDUINO2', if_true: files('netduino2.c'))
 arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.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_NSERIES', if_true: files('nseries.c'))
 arm_ss.add(when: 'CONFIG_SX1', if_true: files('omap_sx1.c'))
 arm_ss.add(when: 'CONFIG_CHEETAH', if_true: files('palm.c'))
diff --git a/hw/arm/npcm8xx_boards.c b/hw/arm/npcm8xx_boards.c
new file mode 100644
index 00..2290473d12
--- /dev/null
+++ b/hw/arm/npcm8xx_boards.c
@@ -0,0 +1,257 @@
+/*
+ * Machine definitions for boards featuring an NPCM8xx SoC.
+ *
+ * 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 "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-common.h"
+#include "qemu/datadir.h"
+#include "qemu/units.h"
+#include "sysemu/block-backend.h"
+
+#define NPCM845_EVB_POWER_ON_STRAPS 0x17ff
+
+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), _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),
+ _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",
+_abort, NULL);
+object_property_set_uint(obj, "power-on-straps", hw_straps, _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(>smbus[num]), "i2c-bus"));
+}
+
+static void npcm8xx_

[PATCH for-7.1 05/11] hw/misc: Store DRAM size in NPCM8XX GCR Module

2022-04-05 Thread 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 
Reviwed-by: Titus Rwantare 
---
 hw/misc/npcm_gcr.c | 33 ++---
 include/hw/misc/npcm_gcr.h |  1 +
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/hw/misc/npcm_gcr.c b/hw/misc/npcm_gcr.c
index 2349949599..14c298602a 100644
--- a/hw/misc/npcm_gcr.c
+++ b/hw/misc/npcm_gcr.c
@@ -267,7 +267,7 @@ static const struct MemoryRegionOps npcm_gcr_ops = {
 },
 };
 
-static void npcm_gcr_enter_reset(Object *obj, ResetType type)
+static void npcm7xx_gcr_enter_reset(Object *obj, ResetType type)
 {
 NPCMGCRState *s = NPCM_GCR(obj);
 NPCMGCRClass *c = NPCM_GCR_GET_CLASS(obj);
@@ -283,6 +283,23 @@ static void npcm_gcr_enter_reset(Object *obj, ResetType 
type)
 }
 }
 
+static void npcm8xx_gcr_enter_reset(Object *obj, ResetType type)
+{
+NPCMGCRState *s = NPCM_GCR(obj);
+NPCMGCRClass *c = NPCM_GCR_GET_CLASS(obj);
+
+switch (type) {
+case RESET_TYPE_COLD:
+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;
+break;
+}
+}
+
 static void npcm_gcr_realize(DeviceState *dev, Error **errp)
 {
 ERRP_GUARD();
@@ -326,6 +343,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)
@@ -355,12 +380,10 @@ static Property npcm_gcr_properties[] = {
 
 static void npcm_gcr_class_init(ObjectClass *klass, void *data)
 {
-ResettableClass *rc = RESETTABLE_CLASS(klass);
 DeviceClass *dc = DEVICE_CLASS(klass);
 
 dc->realize = npcm_gcr_realize;
 dc->vmsd = _npcm_gcr;
-rc->phases.enter = npcm_gcr_enter_reset;
 
 device_class_set_props(dc, npcm_gcr_properties);
 }
@@ -369,24 +392,28 @@ 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";
 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 ac3d781c2e..bd69199d51 100644
--- a/include/hw/misc/npcm_gcr.h
+++ b/include/hw/misc/npcm_gcr.h
@@ -39,6 +39,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.35.1.1094.g7c7d902a7c-goog




[PATCH for-7.1 08/11] hw/net: Add NPCM8XX PCS Module

2022-04-05 Thread 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 
Reviewed-by: Titus Rwantare 
---
 hw/net/meson.build|   1 +
 hw/net/npcm_pcs.c | 409 ++
 hw/net/trace-events   |   4 +
 include/hw/net/npcm_pcs.h |  42 
 4 files changed, 456 insertions(+)
 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 685b75badb..4cba3e66db 100644
--- a/hw/net/meson.build
+++ b/hw/net/meson.build
@@ -37,6 +37,7 @@ softmmu_ss.add(when: 'CONFIG_SUNHME', if_true: 
files('sunhme.c'))
 softmmu_ss.add(when: 'CONFIG_FTGMAC100', if_true: files('ftgmac100.c'))
 softmmu_ss.add(when: 'CONFIG_SUNGEM', if_true: files('sungem.c'))
 softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_emc.c'))
+softmmu_ss.add(when: 'CONFIG_NPCM8XX', if_true: files('npcm_pcs.c'))
 
 softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_eth.c'))
 softmmu_ss.add(when: 'CONFIG_COLDFIRE', if_true: files('mcf_fec.c'))
diff --git a/hw/net/npcm_pcs.c b/hw/net/npcm_pcs.c
new file mode 100644
index 00..efe5f68d9c
--- /dev/null
+++ b/hw/net/npcm_pcs.c
@@ -0,0 +1,409 @@
+/*
+ * 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 

[PATCH for-7.1 07/11] hw/misc: Support 8-bytes memop in NPCM GCR module

2022-04-05 Thread Hao Wu
The NPCM8xx GCR device can be accessed with 64-bit memory operations.
This patch supports that.

Signed-off-by: Hao Wu 
Reviewed-by: Patrick Venture 
---
 hw/misc/npcm_gcr.c   | 98 +---
 hw/misc/trace-events |  4 +-
 2 files changed, 77 insertions(+), 25 deletions(-)

diff --git a/hw/misc/npcm_gcr.c b/hw/misc/npcm_gcr.c
index 14c298602a..aa81db23d7 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,23 @@ 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];
+if (s->regs[reg] != 0) {
+trace_npcm_gcr_read(offset, value);
+}
+return value;
 }
 
 static void npcm_gcr_write(void *opaque, hwaddr offset,
@@ -222,7 +237,7 @@ static void npcm_gcr_write(void *opaque, hwaddr offset,
 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 >= c->nr_regs) {
 qemu_log_mask(LOG_GUEST_ERROR,
@@ -231,29 +246,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 +313,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 02650acfff..2ffec963e7 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -103,8 +103,8 @@ npcm_clk_read(uint64_t offset, uint32_t value) " offset: 
0x%04" PRIx64 " value:
 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, uint32_t value) " offset: 0x%04" PRIx64 " 
value: 0x%08" PRIx32
-npcm_gcr_write(uint64_t offset, uint32_t va

[PATCH for-7.1 06/11] hw/intc: Add a property to allow GIC to reset into non secure mode

2022-04-05 Thread Hao Wu
This property allows certain boards like NPCM8xx to boot the kernel
directly into non-secure mode. This is necessary since we do not
support secure boot features for NPCM8xx now.

Signed-off-by: Hao Wu 
Reviewed-by: Patrick Venture 
---
 hw/intc/arm_gic_common.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c
index 7b44d5625b..7ddc5cfbd0 100644
--- a/hw/intc/arm_gic_common.c
+++ b/hw/intc/arm_gic_common.c
@@ -358,6 +358,8 @@ static Property arm_gic_common_properties[] = {
 /* True if the GIC should implement the virtualization extensions */
 DEFINE_PROP_BOOL("has-virtualization-extensions", GICState, virt_extn, 0),
 DEFINE_PROP_UINT32("num-priority-bits", GICState, n_prio_bits, 8),
+/* True if we want to directly booting a kernel into NonSecure */
+DEFINE_PROP_BOOL("irq-reset-nonsecure", GICState, irq_reset_nonsecure, 0),
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.35.1.1094.g7c7d902a7c-goog




[PATCH for-7.1 03/11] hw/misc: Support NPCM8XX GCR module

2022-04-05 Thread Hao Wu
NPCM8XX has a different set of global control registers than 7XX.
This patch supports that.

Signed-off-by: Hao Wu 
Reviwed-by: Titus Rwantare 
---
 MAINTAINERS   |   9 +-
 hw/misc/meson.build   |   2 +-
 hw/misc/npcm7xx_gcr.c | 269 
 hw/misc/npcm_gcr.c| 413 ++
 hw/misc/trace-events  |   6 +-
 include/hw/arm/npcm7xx.h  |   4 +-
 include/hw/misc/{npcm7xx_gcr.h => npcm_gcr.h} |  29 +-
 7 files changed, 445 insertions(+), 287 deletions(-)
 delete mode 100644 hw/misc/npcm7xx_gcr.c
 create mode 100644 hw/misc/npcm_gcr.c
 rename include/hw/misc/{npcm7xx_gcr.h => npcm_gcr.h} (56%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4ad2451e03..c31ed09527 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -791,14 +791,15 @@ F: hw/net/mv88w8618_eth.c
 F: include/hw/net/mv88w8618_eth.h
 F: docs/system/arm/musicpal.rst
 
-Nuvoton NPCM7xx
+Nuvoton NPCM
 M: Havard Skinnemoen 
 M: Tyrone Ting 
+M: Hao Wu 
 L: qemu-...@nongnu.org
 S: Supported
-F: hw/*/npcm7xx*
-F: include/hw/*/npcm7xx*
-F: tests/qtest/npcm7xx*
+F: hw/*/npcm*
+F: include/hw/*/npcm*
+F: tests/qtest/npcm*
 F: pc-bios/npcm7xx_bootrom.bin
 F: roms/vbootrom
 F: docs/system/arm/nuvoton.rst
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 6fb69612e0..13f8fee5b6 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -61,7 +61,7 @@ softmmu_ss.add(when: 'CONFIG_IMX', if_true: files(
 softmmu_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mst_fpga.c'))
 softmmu_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/npcm7xx_gcr.c
deleted file mode 100644
index eace9e1967..00
--- a/hw/misc/npcm7xx_gcr.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Nuvoton NPCM7xx System Global Control Registers.
- *
- * Copyright 2020 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/misc/npcm7xx_gcr.h"
-#include "hw/qdev-properties.h"
-#include "migration/vmstate.h"
-#include "qapi/error.h"
-#include "qemu/cutils.h"
-#include "qemu/log.h"
-#include "qemu/module.h"
-#include "qemu/units.h"
-
-#include "trace.h"
-
-#define NPCM7XX_GCR_MIN_DRAM_SIZE   (128 * MiB)
-#define NPCM7XX_GCR_MAX_DRAM_SIZE   (2 * GiB)
-
-enum NPCM7xxGCRRegisters {
-NPCM7XX_GCR_PDID,
-NPCM7XX_GCR_PWRON,
-NPCM7XX_GCR_MFSEL1  = 0x0c / sizeof(uint32_t),
-NPCM7XX_GCR_MFSEL2,
-NPCM7XX_GCR_MISCPE,
-NPCM7XX_GCR_SPSWC   = 0x038 / sizeof(uint32_t),
-NPCM7XX_GCR_INTCR,
-NPCM7XX_GCR_INTSR,
-NPCM7XX_GCR_HIFCR   = 0x050 / sizeof(uint32_t),
-NPCM7XX_GCR_INTCR2  = 0x060 / sizeof(uint32_t),
-NPCM7XX_GCR_MFSEL3,
-NPCM7XX_GCR_SRCNT,
-NPCM7XX_GCR_RESSR,
-NPCM7XX_GCR_RLOCKR1,
-NPCM7XX_GCR_FLOCKR1,
-NPCM7XX_GCR_DSCNT,
-NPCM7XX_GCR_MDLR,
-NPCM7XX_GCR_SCRPAD3,
-NPCM7XX_GCR_SCRPAD2,
-NPCM7XX_GCR_DAVCLVLR= 0x098 / sizeof(uint32_t),
-NPCM7XX_GCR_INTCR3,
-NPCM7XX_GCR_VSINTR  = 0x0ac / sizeof(uint32_t),
-NPCM7XX_GCR_MFSEL4,
-NPCM7XX_GCR_CPBPNTR = 0x0c4 / sizeof(uint32_t),
-NPCM7XX_GCR_CPCTL   = 0x0d0 / sizeof(uint32_t),
-NPCM7XX_GCR_CP2BST,
-NPCM7XX_GCR_B2CPNT,
-NPCM7XX_GCR_CPPCTL,
-NPCM7XX_GCR_I2CSEGSEL,
-NPCM7XX_GCR_I2CSEGCTL,
-NPCM7XX_GCR_VSRCR,
-NPCM7XX_GCR_MLOCKR,
-NPCM7XX_GCR_SCRPAD  = 0x013c / sizeof(uint32_t),
-NPCM7XX_GCR_USB1PHYCTL,
-NPCM7XX_GCR_USB2PHYCTL,
-NPCM7XX_GCR_REGS_END,
-};
-
-static const uint32_t cold_reset_values[NPCM7XX_GCR_NR_REGS] = {
-[NPCM7XX_GCR_PDID]  = 0x04a92750,   /* Poleg A1 */
-[NPCM7XX_GCR_MISCPE]= 0x,
-[NPCM7XX_GCR_SPSWC] = 0x0003,
-[NPCM7XX_GCR_INTCR] = 0x035e,
-[NPCM7XX_GCR_HIFCR] = 0x004e,
-[NPCM7XX_GCR_INTCR2]= (1U << 19),   /* DDR initialized */
-[NPCM7XX_GCR_RESSR] = 0x8000,
-[NPCM7XX_GCR_DSCNT] = 0x00c0,
-[NPCM7XX_GCR_DAVCLVLR]  = 0x5a00f3cf,
-[NPCM7XX_GCR_SCRPAD]= 0x0008,
-[NPCM7XX_GCR_USB1PHYCTL]= 0x034730e4,
-[NPCM7XX_GCR_USB2PHYCTL]= 0x034730e4,
-};
-
-sta

[PATCH for-7.1 01/11] docs/system/arm: Add Description for NPCM8XX SoC

2022-04-05 Thread 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 
Reviewed-by: Patrick Venture 
---
 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 ef2792076a..bead17fa7e 100644
--- a/docs/system/arm/nuvoton.rst
+++ b/docs/system/arm/nuvoton.rst
@@ -1,12 +1,13 @@
 Nuvoton iBMC boards (``*-bmc``, ``npcm750-evb``, ``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
 -
 
@@ -61,6 +64,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.35.1.1094.g7c7d902a7c-goog




[PATCH for-7.1 04/11] hw/misc: Support NPCM8XX CLK Module Registers

2022-04-05 Thread 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 
Reviewed-by: Titus Rwantare
---
 hw/misc/meson.build   |   2 +-
 hw/misc/{npcm7xx_clk.c => npcm_clk.c} | 238 ++
 hw/misc/trace-events  |   6 +-
 include/hw/arm/npcm7xx.h  |   4 +-
 include/hw/misc/{npcm7xx_clk.h => npcm_clk.h} |  43 ++--
 5 files changed, 219 insertions(+), 74 deletions(-)
 rename hw/misc/{npcm7xx_clk.c => npcm_clk.c} (81%)
 rename include/hw/misc/{npcm7xx_clk.h => npcm_clk.h} (83%)

diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 13f8fee5b6..b4e9d3f857 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -60,7 +60,7 @@ softmmu_ss.add(when: 'CONFIG_IMX', if_true: files(
 ))
 softmmu_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mst_fpga.c'))
 softmmu_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 81%
rename from hw/misc/npcm7xx_clk.c
rename to hw/misc/npcm_clk.c
index bc2b879feb..f4601a3e9a 100644
--- a/hw/misc/npcm7xx_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
  *
@@ -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"
@@ -75,13 +75,65 @@ 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.
  *
  * 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]= 0x,
 [NPCM7XX_CLK_CLKSEL]= 0x004a,
 [NPCM7XX_CLK_CLKDIV1]   = 0x5413f855,
@@ -103,6 +155,46 @@ static const uint32_t 
cold_reset_values[NPCM7XX_CLK_NR_REGS] = {
 [NPCM7XX_CLK_AHBCKFI]   = 0x00c8,
 };
 
+/*
+ * 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]= 0x,
+[NPCM8XX_CLK_CLKSEL]= 0x154a,
+[NPCM8XX_CLK_CLKDIV1]   = 0x5413f855,
+[NPCM8XX_CLK_PLLCON0]   = 0x00222101 | PLLCON_LOKI,
+[NPCM8XX_CLK_PLLCON1]   = 0x00202101 | PLLCON_LOKI,
+[NPCM8XX_CLK_IPSRST1]   = 0x1000,
+[NPCM8XX_CLK_IPSRST2]   = 0x8000,
+[NPCM8XX_CLK_CLKEN2]= 0x,
+[NPCM8XX_CLK_CLKDIV2]   = 0xaa4f8f9f,
+[NPCM8XX_CLK_CLKEN3]= 0x,
+[NPCM8XX_CLK_IPSRST3]   = 0x0300,
+[NPCM8XX_CLK_WD0RCR]= 0x,
+[NPCM8XX_CLK_WD1RCR]= 0x,
+[NPCM8XX_CLK_WD2RCR]= 0x,
+[NPCM8XX_CLK_SW

[PATCH for-7.1 10/11] hw/arm: Add NPCM8XX SoC

2022-04-05 Thread Hao Wu
The file contains a basic NPCM8XX SOC file. It's forked
from the NPCM7XX SOC with some changes.

Signed-off-by: Hao Wu 
Reviwed-by: Patrick Venture 
Reviwed-by: Titus Rwantare 
---
 configs/devices/aarch64-softmmu/default.mak |   1 +
 hw/arm/Kconfig  |  11 +
 hw/arm/meson.build  |   1 +
 hw/arm/npcm8xx.c| 806 
 include/hw/arm/npcm8xx.h| 106 +++
 5 files changed, 925 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 cf43ac8da1..1c3cf6dda1 100644
--- a/configs/devices/aarch64-softmmu/default.mak
+++ b/configs/devices/aarch64-softmmu/default.mak
@@ -6,3 +6,4 @@ include ../arm-softmmu/default.mak
 CONFIG_XLNX_ZYNQMP_ARM=y
 CONFIG_XLNX_VERSAL=y
 CONFIG_SBSA_REF=y
+CONFIG_NPCM8XX=y
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 97f3b38019..ed5d37ba01 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -408,6 +408,17 @@ config NPCM7XX
 select UNIMP
 select PCA954X
 
+config NPCM8XX
+bool
+select ARM_GIC
+select SMBUS
+select PL310  # cache controller
+select NPCM7XX
+select SERIAL
+select SSI
+select UNIMP
+
+
 config FSL_IMX25
 bool
 imply I2C_DEVICES
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index 721a8eb8be..cf824241c5 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -14,6 +14,7 @@ arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: 
files('musicpal.c'))
 arm_ss.add(when: 'CONFIG_NETDUINO2', if_true: files('netduino2.c'))
 arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.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_NSERIES', if_true: files('nseries.c'))
 arm_ss.add(when: 'CONFIG_SX1', if_true: files('omap_sx1.c'))
 arm_ss.add(when: 'CONFIG_CHEETAH', if_true: files('palm.c'))
diff --git a/hw/arm/npcm8xx.c b/hw/arm/npcm8xx.c
new file mode 100644
index 00..afcf8330d5
--- /dev/null
+++ b/hw/arm/npcm8xx.c
@@ -0,0 +1,806 @@
+/*
+ * 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.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 "sysemu/sysemu.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 (0x8000)
+#define NPCM8XX_MMIO_SZ (0x7ffd)
+
+/* 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  (0xf080)
+#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 (0xfffb)
+#define NPCM8XX_RAM2_SZ (256 * KiB)
+#define NPCM8XX_ROM_BA  (0x0100)
+#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_I

[PATCH for-7.1 02/11] hw/ssi: Make flash size a property in NPCM7XX FIU

2022-04-05 Thread 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 
Reviewed-by: Patrick Venture 
---
 hw/arm/npcm7xx.c | 6 ++
 hw/ssi/npcm7xx_fiu.c | 6 ++
 include/hw/ssi/npcm7xx_fiu.h | 1 +
 3 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index d85cc02765..9946b94120 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -274,17 +274,21 @@ static const struct {
 hwaddr regs_addr;
 int cs_count;
 const hwaddr *flash_addr;
+size_t flash_size;
 } npcm7xx_fiu[] = {
 {
 .name = "fiu0",
 .regs_addr = 0xfb00,
 .cs_count = ARRAY_SIZE(npcm7xx_fiu0_flash_addr),
 .flash_addr = npcm7xx_fiu0_flash_addr,
+.flash_size = 128 * MiB,
+
 }, {
 .name = "fiu3",
 .regs_addr = 0xc000,
 .cs_count = ARRAY_SIZE(npcm7xx_fiu3_flash_addr),
 .flash_addr = npcm7xx_fiu3_flash_addr,
+.flash_size = 128 * MiB,
 },
 };
 
@@ -686,6 +690,8 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 
 object_property_set_int(OBJECT(sbd), "cs-count",
 npcm7xx_fiu[i].cs_count, _abort);
+object_property_set_int(OBJECT(sbd), "flash-size",
+npcm7xx_fiu[i].flash_size, _abort);
 sysbus_realize(sbd, _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 4eedb2927e..ea490f1332 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)
 
@@ -525,7 +522,7 @@ static void npcm7xx_fiu_realize(DeviceState *dev, Error 
**errp)
 flash->fiu = s;
 memory_region_init_io(>direct_access, OBJECT(s),
   _fiu_flash_ops, >flash[i], "flash",
-  NPCM7XX_FIU_FLASH_WINDOW_SIZE);
+  s->flash_size);
 sysbus_init_mmio(sbd, >direct_access);
 }
 }
@@ -543,6 +540,7 @@ static const VMStateDescription vmstate_npcm7xx_fiu = {
 
 static Property npcm7xx_fiu_properties[] = {
 DEFINE_PROP_INT32("cs-count", NPCM7xxFIUState, cs_count, 0),
+DEFINE_PROP_SIZE("flash-size", NPCM7xxFIUState, flash_size, 0),
 DEFINE_PROP_END_OF_LIST(),
 };
 
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.35.1.1094.g7c7d902a7c-goog




[PATCH for-7.1 00/11] hw/arm: Add NPCM8XX support

2022-04-05 Thread Hao Wu
NPCM8XX BMCs are the successors of the NPCM7XX BMCs. They feature
quad-core ARM Cortex A35 that supports both 32 bits and 64 bits
operations. This patch set aims to support basic functionalities
of the NPCM7XX BMCs. The patch set includes:

1. We derive most devices from the 7XX models and
made some modifications.
2. We have constructed a minimum vBootROM similar to the 7XX one at
https://github.com/google/vbootrom/tree/master/npcm8xx
and included it in the patch set.
3.  We added a new NPCM8XX SOC and an evaluation
board machine npcm845-evb.

The OpenBMC for NPCM845 evaluation board can be found at:
https://github.com/Nuvoton-Israel/openbmc/tree/npcm-v2.10/meta-evb/meta-evb-nuvoton/meta-evb-npcm845

The patch set can boot the evaluation board image built from the source
above to login prompt.

Hao Wu (11):
  docs/system/arm: Add Description for NPCM8XX SoC
  hw/ssi: Make flash size a property in NPCM7XX FIU
  hw/misc: Support NPCM8XX GCR module
  hw/misc: Support NPCM8XX CLK Module Registers
  hw/misc: Store DRAM size in NPCM8XX GCR Module
  hw/intc: Add a property to allow GIC to reset into non secure mode
  hw/misc: Support 8-bytes memop in NPCM GCR module
  hw/net: Add NPCM8XX PCS Module
  pc-bios: Add NPCM8xx Bootrom
  hw/arm: Add NPCM8XX SoC
  hw/arm: Add NPCM845 Evaluation board

 MAINTAINERS   |   9 +-
 configs/devices/aarch64-softmmu/default.mak   |   1 +
 docs/system/arm/nuvoton.rst   |  20 +-
 hw/arm/Kconfig|  11 +
 hw/arm/meson.build|   1 +
 hw/arm/npcm7xx.c  |   6 +
 hw/arm/npcm8xx.c  | 806 ++
 hw/arm/npcm8xx_boards.c   | 257 ++
 hw/intc/arm_gic_common.c  |   2 +
 hw/misc/meson.build   |   4 +-
 hw/misc/npcm7xx_gcr.c | 269 --
 hw/misc/{npcm7xx_clk.c => npcm_clk.c} | 238 --
 hw/misc/npcm_gcr.c| 492 +++
 hw/misc/trace-events  |  12 +-
 hw/net/meson.build|   1 +
 hw/net/npcm_pcs.c | 409 +
 hw/net/trace-events   |   4 +
 hw/ssi/npcm7xx_fiu.c  |   6 +-
 include/hw/arm/npcm7xx.h  |   8 +-
 include/hw/arm/npcm8xx.h  | 126 +++
 include/hw/misc/{npcm7xx_clk.h => npcm_clk.h} |  43 +-
 include/hw/misc/{npcm7xx_gcr.h => npcm_gcr.h} |  30 +-
 include/hw/net/npcm_pcs.h |  42 +
 include/hw/ssi/npcm7xx_fiu.h  |   1 +
 pc-bios/npcm8xx_bootrom.bin   | Bin 0 -> 608 bytes
 25 files changed, 2428 insertions(+), 370 deletions(-)
 create mode 100644 hw/arm/npcm8xx.c
 create mode 100644 hw/arm/npcm8xx_boards.c
 delete mode 100644 hw/misc/npcm7xx_gcr.c
 rename hw/misc/{npcm7xx_clk.c => npcm_clk.c} (81%)
 create mode 100644 hw/misc/npcm_gcr.c
 create mode 100644 hw/net/npcm_pcs.c
 create mode 100644 include/hw/arm/npcm8xx.h
 rename include/hw/misc/{npcm7xx_clk.h => npcm_clk.h} (83%)
 rename include/hw/misc/{npcm7xx_gcr.h => npcm_gcr.h} (55%)
 create mode 100644 include/hw/net/npcm_pcs.h
 create mode 100644 pc-bios/npcm8xx_bootrom.bin

-- 
2.35.1.1094.g7c7d902a7c-goog




Re: [PATCH] hw/misc/npcm7xx_clk: Don't leak string in npcm7xx_clk_sel_init()

2022-03-08 Thread Hao Wu
On Tue, Mar 8, 2022 at 10:09 AM Richard Henderson <
richard.hender...@linaro.org> wrote:

> On 3/8/22 07:03, Peter Maydell wrote:
> > In npcm7xx_clk_sel_init() we allocate a string with g_strdup_printf().
> > Use g_autofree so we free it rather than leaking it.
> >
> > (Detected with the clang leak sanitizer.)
> >
> > Signed-off-by: Peter Maydell
> > ---
> >   hw/misc/npcm7xx_clk.c | 4 ++--
> >   1 file changed, 2 insertions(+), 2 deletions(-)
>
> Reviewed-by: Richard Henderson 
>
> Reviewed-by: Hao Wu 

> r~
>
>


[PATCH v5] tests/qtest: add qtests for npcm7xx sdhci

2022-02-25 Thread Hao Wu
From: Shengtan Mao 

Reviewed-by: Hao Wu 
Reviewed-by: Chris Rauer 
Signed-off-by: Shengtan Mao 
Signed-off-by: Patrick Venture 
---
v5
 * use memcmp to compare whether strings are expected
v4
 * use strncmp instead of strcmp
v3:
 * fixup compilation from missing macro value
v2:
 * update copyright year
 * check result of open
 * use g_free instead of free
 * move declarations to the top
 * use g_file_open_tmp
---
 tests/qtest/meson.build  |   1 +
 tests/qtest/npcm7xx_sdhci-test.c | 215 +++
 2 files changed, 216 insertions(+)
 create mode 100644 tests/qtest/npcm7xx_sdhci-test.c

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index f33d84d19b..721eafad12 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -190,6 +190,7 @@ qtests_npcm7xx = \
'npcm7xx_gpio-test',
'npcm7xx_pwm-test',
'npcm7xx_rng-test',
+   'npcm7xx_sdhci-test',
'npcm7xx_smbus-test',
'npcm7xx_timer-test',
'npcm7xx_watchdog_timer-test'] + \
diff --git a/tests/qtest/npcm7xx_sdhci-test.c b/tests/qtest/npcm7xx_sdhci-test.c
new file mode 100644
index 00..c1f496fb29
--- /dev/null
+++ b/tests/qtest/npcm7xx_sdhci-test.c
@@ -0,0 +1,215 @@
+/*
+ * QTests for NPCM7xx SD-3.0 / MMC-4.51 Host Controller
+ *
+ * Copyright (c) 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/sd/npcm7xx_sdhci.h"
+
+#include "libqos/libqtest.h"
+#include "libqtest-single.h"
+#include "libqos/sdhci-cmd.h"
+
+#define NPCM7XX_REG_SIZE 0x100
+#define NPCM7XX_MMC_BA 0xF0842000
+#define NPCM7XX_BLK_SIZE 512
+#define NPCM7XX_TEST_IMAGE_SIZE (1 << 30)
+
+char *sd_path;
+
+static QTestState *setup_sd_card(void)
+{
+QTestState *qts = qtest_initf(
+"-machine kudo-bmc "
+"-device sd-card,drive=drive0 "
+"-drive id=drive0,if=none,file=%s,format=raw,auto-read-only=off",
+sd_path);
+
+qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_SWRST, SDHC_RESET_ALL);
+qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_CLKCON,
+ SDHC_CLOCK_SDCLK_EN | SDHC_CLOCK_INT_STABLE |
+ SDHC_CLOCK_INT_EN);
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_APP_CMD);
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x4120, 0, (41 << 8));
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_ALL_SEND_CID);
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_SEND_RELATIVE_ADDR);
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x4567, 0,
+   SDHC_SELECT_DESELECT_CARD);
+
+return qts;
+}
+
+static void write_sdread(QTestState *qts, const char *msg)
+{
+int fd, ret;
+size_t len = strlen(msg);
+char *rmsg = g_malloc(len);
+
+/* write message to sd */
+fd = open(sd_path, O_WRONLY);
+g_assert(fd >= 0);
+ret = write(fd, msg, len);
+close(fd);
+g_assert(ret == len);
+
+/* read message using sdhci */
+ret = sdhci_read_cmd(qts, NPCM7XX_MMC_BA, rmsg, len);
+g_assert(ret == len);
+g_assert(!memcmp(rmsg, msg, len));
+
+g_free(rmsg);
+}
+
+/* Check MMC can read values from sd */
+static void test_read_sd(void)
+{
+QTestState *qts = setup_sd_card();
+
+write_sdread(qts, "hello world");
+write_sdread(qts, "goodbye");
+
+qtest_quit(qts);
+}
+
+static void sdwrite_read(QTestState *qts, const char *msg)
+{
+int fd, ret;
+size_t len = strlen(msg);
+char *rmsg = g_malloc(len);
+
+/* write message using sdhci */
+sdhci_write_cmd(qts, NPCM7XX_MMC_BA, msg, len, NPCM7XX_BLK_SIZE);
+
+/* read message from sd */
+fd = open(sd_path, O_RDONLY);
+g_assert(fd >= 0);
+ret = read(fd, rmsg, len);
+close(fd);
+g_assert(ret == len);
+
+g_assert(!memcmp(rmsg, msg, len));
+
+g_free(rmsg);
+}
+
+/* Check MMC can write values to sd */
+static void test_write_sd(void)
+{
+QTestState *qts = setup_sd_card();
+
+sdwrite_read(qts, "hello world");
+sdwrite_read(qts, "goodbye");
+
+qtest_quit(qts);
+}
+
+/* Check SDHCI has correct default values. */
+static void test_reset(void)
+{
+QTestState *qts = qtest_init("-machine kudo-bmc");
+uint64_t addr = NPCM7XX_MMC_BA;
+uint64_t end_addr = addr + NPCM7XX_REG_SIZE;
+uint16_t prstvals_resets[] = {NPCM7XX_PRSTVALS_0_RESET,
+  NPCM7XX_PRSTV

Re: [PATCH v4] tests/qtest: add qtests for npcm7xx sdhci

2022-02-25 Thread Hao Wu
I have sent an updated version that uses memcmp()

On Fri, Feb 25, 2022 at 3:44 AM Peter Maydell 
wrote:

> On Thu, 24 Feb 2022 at 19:03, Hao Wu  wrote:
> >
> > From: Shengtan Mao 
> >
> > Reviewed-by: Hao Wu 
> > Reviewed-by: Chris Rauer 
> > Signed-off-by: Shengtan Mao 
> > Signed-off-by: Patrick Venture 
> > Signed-off-by: Hao Wu 
> > ---
> > v4:
> >  * use strncmp to compare fixed length strings
> > v3:
> >  * fixup compilation from missing macro value
> > v2:
> >  * update copyright year
> >  * check result of open
> >  * use g_free instead of free
> >  * move declarations to the top
> >  * use g_file_open_tmp
> > ---
>
> > +static void write_sdread(QTestState *qts, const char *msg)
> > +{
> > +int fd, ret;
> > +size_t len = strlen(msg);
> > +char *rmsg = g_malloc(len);
> > +
> > +/* write message to sd */
> > +fd = open(sd_path, O_WRONLY);
> > +g_assert(fd >= 0);
> > +ret = write(fd, msg, len);
> > +close(fd);
> > +g_assert(ret == len);
> > +
> > +/* read message using sdhci */
> > +ret = sdhci_read_cmd(qts, NPCM7XX_MMC_BA, rmsg, len);
> > +g_assert(ret == len);
> > +g_assert(!strncmp(rmsg, msg, len));
>
> We always know we want to compare exactly 'len' bytes here, and we know
> the buffers in each case are at least that large. The right function
> for that is memcmp(), I think.
>
> thanks
> -- PMM
>


[PATCH v4] tests/qtest: add qtests for npcm7xx sdhci

2022-02-24 Thread Hao Wu
From: Shengtan Mao 

Reviewed-by: Hao Wu 
Reviewed-by: Chris Rauer 
Signed-off-by: Shengtan Mao 
Signed-off-by: Patrick Venture 
Signed-off-by: Hao Wu 
---
v4:
 * use strncmp to compare fixed length strings
v3:
 * fixup compilation from missing macro value
v2:
 * update copyright year
 * check result of open
 * use g_free instead of free
 * move declarations to the top
 * use g_file_open_tmp
---
 tests/qtest/meson.build  |   1 +
 tests/qtest/npcm7xx_sdhci-test.c | 215 +++
 2 files changed, 216 insertions(+)
 create mode 100644 tests/qtest/npcm7xx_sdhci-test.c

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 842b1df420..2b566999cd 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -189,6 +189,7 @@ qtests_npcm7xx = \
'npcm7xx_gpio-test',
'npcm7xx_pwm-test',
'npcm7xx_rng-test',
+   'npcm7xx_sdhci-test',
'npcm7xx_smbus-test',
'npcm7xx_timer-test',
'npcm7xx_watchdog_timer-test'] + \
diff --git a/tests/qtest/npcm7xx_sdhci-test.c b/tests/qtest/npcm7xx_sdhci-test.c
new file mode 100644
index 00..7de28f900b
--- /dev/null
+++ b/tests/qtest/npcm7xx_sdhci-test.c
@@ -0,0 +1,215 @@
+/*
+ * QTests for NPCM7xx SD-3.0 / MMC-4.51 Host Controller
+ *
+ * Copyright (c) 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/sd/npcm7xx_sdhci.h"
+
+#include "libqos/libqtest.h"
+#include "libqtest-single.h"
+#include "libqos/sdhci-cmd.h"
+
+#define NPCM7XX_REG_SIZE 0x100
+#define NPCM7XX_MMC_BA 0xF0842000
+#define NPCM7XX_BLK_SIZE 512
---
 tests/qtest/meson.build  |   1 +
 tests/qtest/npcm7xx_sdhci-test.c | 215 +++
 2 files changed, 216 insertions(+)
 create mode 100644 tests/qtest/npcm7xx_sdhci-test.c

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index f33d84d19b..721eafad12 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -190,6 +190,7 @@ qtests_npcm7xx = \
'npcm7xx_gpio-test',
'npcm7xx_pwm-test',
'npcm7xx_rng-test',
+   'npcm7xx_sdhci-test',
'npcm7xx_smbus-test',
'npcm7xx_timer-test',
'npcm7xx_watchdog_timer-test'] + \
diff --git a/tests/qtest/npcm7xx_sdhci-test.c b/tests/qtest/npcm7xx_sdhci-test.c
new file mode 100644
index 00..fbb4e2f2e1
--- /dev/null
+++ b/tests/qtest/npcm7xx_sdhci-test.c
@@ -0,0 +1,215 @@
+/*
+ * QTests for NPCM7xx SD-3.0 / MMC-4.51 Host Controller
+ *
+ * Copyright (c) 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/sd/npcm7xx_sdhci.h"
+
+#include "libqos/libqtest.h"
+#include "libqtest-single.h"
+#include "libqos/sdhci-cmd.h"
+
+#define NPCM7XX_REG_SIZE 0x100
+#define NPCM7XX_MMC_BA 0xF0842000
+#define NPCM7XX_BLK_SIZE 512
+#define NPCM7XX_TEST_IMAGE_SIZE (1 << 30)
+
+char *sd_path;
+
+static QTestState *setup_sd_card(void)
+{
+QTestState *qts = qtest_initf(
+"-machine kudo-bmc "
+"-device sd-card,drive=drive0 "
+"-drive id=drive0,if=none,file=%s,format=raw,auto-read-only=off",
+sd_path);
+
+qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_SWRST, SDHC_RESET_ALL);
+qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_CLKCON,
+ SDHC_CLOCK_SDCLK_EN | SDHC_CLOCK_INT_STABLE |
+ SDHC_CLOCK_INT_EN);
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_APP_CMD);
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x4120, 0, (41 << 8));
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_ALL_SEND_CID);
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_SEND_RELATIVE_ADDR);
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x4567, 0,
+   SDHC_SELECT_DESELECT_CARD);
+
+return qts;
+}
+
+static void write_sdread(QTestState *qts, const char *msg)
+{
+int fd, ret;
+size_t len = strlen(msg);
+char *rmsg = g_malloc(len);
+
+/* write

Re: [PATCH v3] tests/qtest: add qtests for npcm7xx sdhci

2022-02-24 Thread Hao Wu
The problem is probably because we read it in using "strcmp". strcmp
compares two strings that end with "\0". But one of the string is read in
using read() so it didn't read in the ending '\0' character.

We should use strncmp to compare the two strings. It probably avoids the
issue.

On Tue, Feb 22, 2022 at 5:28 PM Patrick Venture  wrote:

>
>
> On Mon, Feb 21, 2022 at 5:30 AM Peter Maydell 
> wrote:
>
>> On Wed, 16 Feb 2022 at 17:30, Peter Maydell 
>> wrote:
>> >
>> > On Tue, 8 Feb 2022 at 18:18, Patrick Venture 
>> wrote:
>> > >
>> > > From: Shengtan Mao 
>> > >
>> > > Reviewed-by: Hao Wu 
>> > > Reviewed-by: Chris Rauer 
>> > > Signed-off-by: Shengtan Mao 
>> > > Signed-off-by: Patrick Venture 
>> > > ---
>> >
>> >
>> >
>> > Applied to target-arm.next, thanks.
>>
>> This hits assertions in some of the CI jobs, eg:
>> https://gitlab.com/qemu-project/qemu/-/jobs/2116932769
>>
>> 258/717 qemu:qtest+qtest-arm / qtest-arm/npcm7xx_sdhci-test INTERRUPT
>> 643.16s killed by signal 6 SIGABRT
>> ― ✀
>> ―
>> stderr:
>> ** Message: 06:06:50.205: /tmp/sdhci_F7ETH1
>> **
>> ERROR:../tests/qtest/npcm7xx_sdhci-test.c:101:sdwrite_read: assertion
>> failed: (!strcmp(rmsg, msg))
>>
>> ――
>> ...terminated.
>>
>> so I've dropped it again.
>>
>
> I'm sorry to hear that, I'll have to pick up some cycles in a week or so
> and see if I can reproduce the issue.
>
>
>>
>> thanks
>> -- PMM
>>
>


Re: [PATCH 2/2] Kconfig: Add 'imply I2C_DEVICES' on boards with available i2c bus

2022-02-08 Thread Hao Wu
On Tue, Feb 8, 2022 at 9:23 AM Peter Maydell 
wrote:

> For arm boards with an i2c bus which a user could reasonably
> want to plug arbitrary devices, add 'imply I2C_DEVICES' to the
> Kconfig stanza.
>
> Signed-off-by: Peter Maydell 
>
Reviewed-by: Hao Wu 

> ---
> Again, slightly arbitrary but erring on the side of conservative.
> I leave non-Arm architectures out (afaict only ppc ppc4xx and e500
> enable any kind of I2C controller in their Kconfig anyway).
> ---
>  hw/arm/Kconfig | 10 ++
>  1 file changed, 10 insertions(+)
>
> diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> index 2e0049196d6..6945330030e 100644
> --- a/hw/arm/Kconfig
> +++ b/hw/arm/Kconfig
> @@ -46,6 +46,7 @@ config DIGIC
>
>  config EXYNOS4
>  bool
> +imply I2C_DEVICES
>  select A9MPCORE
>  select I2C
>  select LAN9118
> @@ -184,6 +185,7 @@ config REALVIEW
>  bool
>  imply PCI_DEVICES
>  imply PCI_TESTDEV
> +imply I2C_DEVICES
>  select SMC91C111
>  select LAN9118
>  select A9MPCORE
> @@ -229,6 +231,7 @@ config SABRELITE
>
>  config STELLARIS
>  bool
> +imply I2C_DEVICES
>  select ARM_V7M
>  select CMSDK_APB_WATCHDOG
>  select I2C
> @@ -406,6 +409,7 @@ config NPCM7XX
>
>  config FSL_IMX25
>  bool
> +imply I2C_DEVICES
>  select IMX
>  select IMX_FEC
>  select IMX_I2C
> @@ -414,6 +418,7 @@ config FSL_IMX25
>
>  config FSL_IMX31
>  bool
> +imply I2C_DEVICES
>  select SERIAL
>  select IMX
>  select IMX_I2C
> @@ -422,6 +427,7 @@ config FSL_IMX31
>
>  config FSL_IMX6
>  bool
> +imply I2C_DEVICES
>  select A9MPCORE
>  select IMX
>  select IMX_FEC
> @@ -450,6 +456,7 @@ config ASPEED_SOC
>
>  config MPS2
>  bool
> +imply I2C_DEVICES
>  select ARMSSE
>  select LAN9118
>  select MPS2_FPGAIO
> @@ -466,6 +473,7 @@ config FSL_IMX7
>  bool
>  imply PCI_DEVICES
>  imply TEST_DEVICES
> +imply I2C_DEVICES
>  select A15MPCORE
>  select PCI
>  select IMX
> @@ -481,6 +489,7 @@ config ARM_SMMUV3
>
>  config FSL_IMX6UL
>  bool
> +imply I2C_DEVICES
>  select A15MPCORE
>  select IMX
>  select IMX_FEC
> @@ -495,6 +504,7 @@ config MICROBIT
>
>  config NRF51_SOC
>  bool
> +imply I2C_DEVICES
>  select I2C
>  select ARM_V7M
>  select UNIMP
> --
> 2.25.1
>
>
>


Re: [PATCH 1/2] Kconfig: Add I2C_DEVICES device group

2022-02-08 Thread Hao Wu
On Tue, Feb 8, 2022 at 9:55 AM Peter Maydell 
wrote:

> Currently there is no way for a board model's Kconfig stanza to
> say "I have an i2c bus which the user can plug an i2c device into,
> build all the free-standing i2c devices". The Kconfig mechanism
> for this is the "device group". Add an I2C_DEVICES group along
> the same lines as the existing PCI_DEVICES. Simple free-standing
> i2c devices which a user might plausibly want to be able to
> plug in on the QEMU commandline should have
>default y if I2C_DEVICES
> and board models which have an i2c bus that is user-accessible
> should use
>imply I2C_DEVICES
> to cause those pluggable devices to be built.
>
> In this commit we mark only a fairly conservative set of i2c devices
> as belonging to the I2C_DEVICES group: the simple sensors and RTCs
> (not including PMBus devices or devices which need GPIO lines to be
> connected).
>
> Signed-off-by: Peter Maydell 
>
Reviewed-by: Hao Wu 

> ---
> Feel free to suggest other i2c devices that should be marked
> as in the group; as I say, I erred on the side of not putting
> devices in the group.
> ---
>  docs/devel/kconfig.rst | 8 ++--
>  hw/i2c/Kconfig | 5 +
>  hw/rtc/Kconfig | 2 ++
>  hw/sensor/Kconfig  | 5 +
>  4 files changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/docs/devel/kconfig.rst b/docs/devel/kconfig.rst
> index a1cdbec7512..aa5042f1569 100644
> --- a/docs/devel/kconfig.rst
> +++ b/docs/devel/kconfig.rst
> @@ -192,11 +192,15 @@ declares its dependencies in different ways:
>no directive and are not used in the Makefile either; they only appear
>as conditions for ``default y`` directives.
>
> -  QEMU currently has two device groups, ``PCI_DEVICES`` and
> -  ``TEST_DEVICES``.  PCI devices usually have a ``default y if
> +  QEMU currently has three device groups, ``PCI_DEVICES``,
> ``I2C_DEVICES``,
> +  and ``TEST_DEVICES``.  PCI devices usually have a ``default y if
>PCI_DEVICES`` directive rather than just ``default y``.  This lets
>some boards (notably s390) easily support a subset of PCI devices,
>for example only VFIO (passthrough) and virtio-pci devices.
> +  ``I2C_DEVICES`` is similar to ``PCI_DEVICES``. It contains i2c devices
> +  that users might reasonably want to plug in to an i2c bus on any
> +  board (and not ones which are very board-specific or that need
> +  to be wired up in a way that can't be done on the command line).
>``TEST_DEVICES`` instead is used for devices that are rarely used on
>production virtual machines, but provide useful hooks to test QEMU
>or KVM.
> diff --git a/hw/i2c/Kconfig b/hw/i2c/Kconfig
> index 8217cb50411..9bb8870517f 100644
> --- a/hw/i2c/Kconfig
> +++ b/hw/i2c/Kconfig
> @@ -1,6 +1,11 @@
>  config I2C
>  bool
>
> +config I2C_DEVICES
> +# Device group for i2c devices which can reasonably be user-plugged
> +# to any board's i2c bus
> +bool
> +
>  config SMBUS
>  bool
>  select I2C
> diff --git a/hw/rtc/Kconfig b/hw/rtc/Kconfig
> index f06e133b8a2..730c272bc54 100644
> --- a/hw/rtc/Kconfig
> +++ b/hw/rtc/Kconfig
> @@ -1,10 +1,12 @@
>  config DS1338
>  bool
>  depends on I2C
> +default y if I2C_DEVICES
>
>  config M41T80
>  bool
>  depends on I2C
> +default y if I2C_DEVICES
>
>  config M48T59
>  bool
> diff --git a/hw/sensor/Kconfig b/hw/sensor/Kconfig
> index b317f91b7b4..215944decc7 100644
> --- a/hw/sensor/Kconfig
> +++ b/hw/sensor/Kconfig
> @@ -1,18 +1,22 @@
>  config TMP105
>  bool
>  depends on I2C
> +default y if I2C_DEVICES
>
>  config TMP421
>  bool
>  depends on I2C
> +default y if I2C_DEVICES
>
>  config DPS310
>  bool
>  depends on I2C
> +default y if I2C_DEVICES
>
>  config EMC141X
>  bool
>  depends on I2C
> +default y if I2C_DEVICES
>
>  config ADM1272
>  bool
> @@ -25,3 +29,4 @@ config MAX34451
>  config LSM303DLHC_MAG
>  bool
>  depends on I2C
> +default y if I2C_DEVICES
> --
> 2.25.1
>
>
>


Re: [PATCH] hw/sensor: Add SB-TSI Temperature Sensor Interface

2022-01-27 Thread Hao Wu
On Thu, Jan 27, 2022 at 6:55 AM Corey Minyard  wrote:

> On Wed, Jan 26, 2022 at 04:09:03PM -0800, Hao Wu wrote:
> > Hi,
> >
> > Sorry for the late reply. I'm not sure what "auto-increment" means here.
>
> The question is: When a value is read, does the address automatically
> increment.  I2C devices very often do this.  If you do a multi-byte
> read, they often will read the value from address 0, then from address
> 1, etc.  Same for writes.
>
The datasheet does not suggest such behavior could happen.

>
> > The kernel driver at
> > https://lkml.org/lkml/2020/12/11/968
> > only has byte-size read/write operations, so I don't see a problem here.
> > The values are extracted
> > from the datasheet.
>
> The *Linux* kernel driver my only do byte-size operations, but other
> kernels may work different, and the Linux kernel may change.  You have
> to implement from the datasheet, not the device driver.
>
The implementation is already according to the datasheet.

> Thanks,
>
> -corey
>
> >
> > On Tue, Jan 18, 2022 at 9:10 AM Patrick Venture 
> wrote:
> >
> > >
> > >
> > > On Mon, Jan 17, 2022 at 6:05 AM Corey Minyard 
> wrote:
> > >
> > >> On Sun, Jan 09, 2022 at 06:17:34PM -0800, Patrick Venture wrote:
> > >> > On Fri, Jan 7, 2022 at 7:04 PM Patrick Venture 
> > >> wrote:
> > >> >
> > >> > > From: Hao Wu 
> > >> > >
> > >> > > SB Temperature Sensor Interface (SB-TSI) is an SMBus compatible
> > >> > > interface that reports AMD SoC's Ttcl (normalized temperature),
> > >> > > and resembles a typical 8-pin remote temperature sensor's I2C
> > >> interface
> > >> > > to BMC.
> > >> > >
> > >> > > This patch implements a basic AMD SB-TSI sensor that is
> > >> > > compatible with the open-source data sheet from AMD and Linux
> > >> > > kernel driver.
> > >> > >
> > >> > > Reference:
> > >> > > Linux kernel driver:
> > >> > > https://lkml.org/lkml/2020/12/11/968
> > >> > > Register Map:
> > >> > > https://developer.amd.com/wp-content/resources/56255_3_03.PDF
> > >> > > (Chapter 6)
> > >> > >
> > >> > > Signed-off-by: Hao Wu 
> > >> > > Reviewed-by: Doug Evans 
> > >> > > ---
> > >> > >  hw/sensor/Kconfig|   4 +
> > >> > >  hw/sensor/meson.build|   1 +
> > >> > >  hw/sensor/tmp_sbtsi.c| 393
> > >> +++
> > >> > >  hw/sensor/trace-events   |   5 +
> > >> > >  hw/sensor/trace.h|   1 +
> > >> > >  meson.build  |   1 +
> > >> > >  tests/qtest/meson.build  |   1 +
> > >> > >  tests/qtest/tmp_sbtsi-test.c | 180 
> > >> > >  8 files changed, 586 insertions(+)
> > >> > >  create mode 100644 hw/sensor/tmp_sbtsi.c
> > >> > >  create mode 100644 hw/sensor/trace-events
> > >> > >  create mode 100644 hw/sensor/trace.h
> > >> > >  create mode 100644 tests/qtest/tmp_sbtsi-test.c
> > >> > >
> > >> > > diff --git a/hw/sensor/Kconfig b/hw/sensor/Kconfig
> > >> > > index 9c8a049b06..27f6f79c84 100644
> > >> > > --- a/hw/sensor/Kconfig
> > >> > > +++ b/hw/sensor/Kconfig
> > >> > > @@ -21,3 +21,7 @@ config ADM1272
> > >> > >  config MAX34451
> > >> > >  bool
> > >> > >  depends on I2C
> > >> > > +
> > >> > > +config AMDSBTSI
> > >> > > +bool
> > >> > > +depends on I2C
> > >> > > diff --git a/hw/sensor/meson.build b/hw/sensor/meson.build
> > >> > > index 059c4ca935..f7b0e645eb 100644
> > >> > > --- a/hw/sensor/meson.build
> > >> > > +++ b/hw/sensor/meson.build
> > >> > > @@ -4,3 +4,4 @@ softmmu_ss.add(when: 'CONFIG_DPS310', if_true:
> > >> > > files('dps310.c'))
> > >> > >  softmmu_ss.add(when: 'CONFIG_EMC141X', if_true:
> files('emc141x.c'))
> > >> > >  softmmu_ss.add(when: 'CONFIG_ADM1272', if_true:
> files('adm1272.c'))
> > >> > >  softmmu_ss.add(when: 'CONFIG_MAX34

Re: [PATCH] hw/sensor: Add SB-TSI Temperature Sensor Interface

2022-01-26 Thread Hao Wu
Hi,

Sorry for the late reply. I'm not sure what "auto-increment" means here.
The kernel driver at
https://lkml.org/lkml/2020/12/11/968
only has byte-size read/write operations, so I don't see a problem here.
The values are extracted
from the datasheet.

On Tue, Jan 18, 2022 at 9:10 AM Patrick Venture  wrote:

>
>
> On Mon, Jan 17, 2022 at 6:05 AM Corey Minyard  wrote:
>
>> On Sun, Jan 09, 2022 at 06:17:34PM -0800, Patrick Venture wrote:
>> > On Fri, Jan 7, 2022 at 7:04 PM Patrick Venture 
>> wrote:
>> >
>> > > From: Hao Wu 
>> > >
>> > > SB Temperature Sensor Interface (SB-TSI) is an SMBus compatible
>> > > interface that reports AMD SoC's Ttcl (normalized temperature),
>> > > and resembles a typical 8-pin remote temperature sensor's I2C
>> interface
>> > > to BMC.
>> > >
>> > > This patch implements a basic AMD SB-TSI sensor that is
>> > > compatible with the open-source data sheet from AMD and Linux
>> > > kernel driver.
>> > >
>> > > Reference:
>> > > Linux kernel driver:
>> > > https://lkml.org/lkml/2020/12/11/968
>> > > Register Map:
>> > > https://developer.amd.com/wp-content/resources/56255_3_03.PDF
>> > > (Chapter 6)
>> > >
>> > > Signed-off-by: Hao Wu 
>> > > Reviewed-by: Doug Evans 
>> > > ---
>> > >  hw/sensor/Kconfig|   4 +
>> > >  hw/sensor/meson.build|   1 +
>> > >  hw/sensor/tmp_sbtsi.c| 393
>> +++
>> > >  hw/sensor/trace-events   |   5 +
>> > >  hw/sensor/trace.h|   1 +
>> > >  meson.build  |   1 +
>> > >  tests/qtest/meson.build  |   1 +
>> > >  tests/qtest/tmp_sbtsi-test.c | 180 
>> > >  8 files changed, 586 insertions(+)
>> > >  create mode 100644 hw/sensor/tmp_sbtsi.c
>> > >  create mode 100644 hw/sensor/trace-events
>> > >  create mode 100644 hw/sensor/trace.h
>> > >  create mode 100644 tests/qtest/tmp_sbtsi-test.c
>> > >
>> > > diff --git a/hw/sensor/Kconfig b/hw/sensor/Kconfig
>> > > index 9c8a049b06..27f6f79c84 100644
>> > > --- a/hw/sensor/Kconfig
>> > > +++ b/hw/sensor/Kconfig
>> > > @@ -21,3 +21,7 @@ config ADM1272
>> > >  config MAX34451
>> > >  bool
>> > >  depends on I2C
>> > > +
>> > > +config AMDSBTSI
>> > > +bool
>> > > +depends on I2C
>> > > diff --git a/hw/sensor/meson.build b/hw/sensor/meson.build
>> > > index 059c4ca935..f7b0e645eb 100644
>> > > --- a/hw/sensor/meson.build
>> > > +++ b/hw/sensor/meson.build
>> > > @@ -4,3 +4,4 @@ softmmu_ss.add(when: 'CONFIG_DPS310', if_true:
>> > > files('dps310.c'))
>> > >  softmmu_ss.add(when: 'CONFIG_EMC141X', if_true: files('emc141x.c'))
>> > >  softmmu_ss.add(when: 'CONFIG_ADM1272', if_true: files('adm1272.c'))
>> > >  softmmu_ss.add(when: 'CONFIG_MAX34451', if_true: files('max34451.c'))
>> > > +softmmu_ss.add(when: 'CONFIG_AMDSBTSI', if_true:
>> files('tmp_sbtsi.c'))
>> > > diff --git a/hw/sensor/tmp_sbtsi.c b/hw/sensor/tmp_sbtsi.c
>> > > new file mode 100644
>> > > index 00..b68c7ebf61
>> > > --- /dev/null
>> > > +++ b/hw/sensor/tmp_sbtsi.c
>> > > @@ -0,0 +1,393 @@
>> > > +/*
>> > > + * AMD SBI Temperature Sensor Interface (SB-TSI)
>> > > + *
>> > > + * 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 "hw/i2c/smbus_slave.h"
>> > > +#include &quo

Re: [PATCH v2 03/13] hw/arm/npcm7xx_boards: Replace drive_get_next() by drive_get()

2021-11-17 Thread Hao Wu
Yes, there's SD and MMC buses. It looks like the current code only supports
mmc ("soc->mmc.sdhci") but not the sd ("soc->sd.sdhci").

It's probably good to make the bus number a parameter as well and use them
to distinguish. We might need a separate patch to do that.

On Wed, Nov 17, 2021 at 8:54 AM Havard Skinnemoen 
wrote:

> On Wed, Nov 17, 2021 at 8:34 AM Markus Armbruster 
> wrote:
> >
> > drive_get_next() is basically a bad idea.  It returns the "next" block
> > backend of a certain interface type.  "Next" means bus=0,unit=N, where
> > subsequent calls count N up from zero, per interface type.
> >
> > This lets you define unit numbers implicitly by execution order.  If the
> > order changes, or new calls appear "in the middle", unit numbers change.
> > ABI break.  Hard to spot in review.
> >
> > Machine "quanta-gbs-bmc" connects just one backend with
> > drive_get_next(), but with a helper function.  Change it to use
> > drive_get() directly.  This makes the unit numbers explicit in the
> > code.
> >
> > Cc: Havard Skinnemoen 
> > Cc: Tyrone Ting 
> > Cc: Peter Maydell 
> > Cc: qemu-...@nongnu.org
> > Signed-off-by: Markus Armbruster 
> > ---
> >  hw/arm/npcm7xx_boards.c | 6 +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
> > index dec7d16ae5..d8a49e4e85 100644
> > --- a/hw/arm/npcm7xx_boards.c
> > +++ b/hw/arm/npcm7xx_boards.c
> > @@ -84,9 +84,9 @@ static void npcm7xx_connect_dram(NPCM7xxState *soc,
> MemoryRegion *dram)
> >   _abort);
> >  }
> >
> > -static void sdhci_attach_drive(SDHCIState *sdhci)
> > +static void sdhci_attach_drive(SDHCIState *sdhci, int unit)
> >  {
> > -DriveInfo *di = drive_get_next(IF_SD);
> > +DriveInfo *di = drive_get(IF_SD, 0, unit);
>
> +Hao Wu IIRC the chip has separate SD and eMMC buses. Would it make
> sense to take the bus number as a parameter as well? Is bus 0 the
> right one to use in this case?
>
> The existing code always uses bus 0, so this is an improvement either way.
>
> Reviewed-by: Havard Skinnemoen 
>
> >  BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
> >
> >  BusState *bus = qdev_get_child_bus(DEVICE(sdhci), "sd-bus");
> > @@ -374,7 +374,7 @@ static void quanta_gbs_init(MachineState *machine)
> >drive_get(IF_MTD, 0, 0));
> >
> >  quanta_gbs_i2c_init(soc);
> > -sdhci_attach_drive(>mmc.sdhci);
> > +sdhci_attach_drive(>mmc.sdhci, 0);
> >  npcm7xx_load_kernel(machine, soc);
> >  }
> >
> > --
> > 2.31.1
> >
>


[PATCH v4 5/7] blockdev: Add a new IF type IF_OTHER

2021-11-03 Thread Hao Wu
This type is used to represent block devs that are not suitable to
be represented by other existing types.

Signed-of-by: Hao Wu 
---
 blockdev.c| 3 ++-
 include/sysemu/blockdev.h | 1 +
 meson | 2 +-
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index b35072644e..c26cbcc422 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -80,6 +80,7 @@ static const char *const if_name[IF_COUNT] = {
 [IF_MTD] = "mtd",
 [IF_SD] = "sd",
 [IF_VIRTIO] = "virtio",
+[IF_OTHER] = "other",
 [IF_XEN] = "xen",
 };
 
@@ -739,7 +740,7 @@ QemuOptsList qemu_legacy_drive_opts = {
 },{
 .name = "if",
 .type = QEMU_OPT_STRING,
-.help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
+.help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio, 
other)",
 },{
 .name = "file",
 .type = QEMU_OPT_STRING,
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index 32c2d6023c..bce6aab573 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -24,6 +24,7 @@ typedef enum {
  */
 IF_NONE = 0,
 IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO, IF_XEN,
+IF_OTHER,
 IF_COUNT
 } BlockInterfaceType;
 
diff --git a/meson b/meson
index b25d94e7c7..776acd2a80 16
--- a/meson
+++ b/meson
@@ -1 +1 @@
-Subproject commit b25d94e7c77fda05a7fdfe8afe562cf9760d69da
+Subproject commit 776acd2a805c9b42b4f0375150977df42130317f
-- 
2.33.1.1089.g2158813163f-goog




[PATCH v4 4/7] hw/adc: Make adci[*] R/W in NPCM7XX ADC

2021-11-03 Thread Hao Wu
Our sensor test requires both reading and writing from a sensor's
QOM property. So we need to make the input of ADC module R/W instead
of write only for that to work.

Signed-off-by: Hao Wu 
Reviewed-by: Titus Rwantare 
Reviewed-by: Peter Maydell 
---
 hw/adc/npcm7xx_adc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/adc/npcm7xx_adc.c b/hw/adc/npcm7xx_adc.c
index 47fb9e5f74..bc6f3f55e6 100644
--- a/hw/adc/npcm7xx_adc.c
+++ b/hw/adc/npcm7xx_adc.c
@@ -242,7 +242,7 @@ static void npcm7xx_adc_init(Object *obj)
 
 for (i = 0; i < NPCM7XX_ADC_NUM_INPUTS; ++i) {
 object_property_add_uint32_ptr(obj, "adci[*]",
->adci[i], OBJ_PROP_FLAG_WRITE);
+>adci[i], OBJ_PROP_FLAG_READWRITE);
 }
 object_property_add_uint32_ptr(obj, "vref",
 >vref, OBJ_PROP_FLAG_WRITE);
-- 
2.33.1.1089.g2158813163f-goog




[PATCH v4 7/7] hw/arm: quanta-gbs-bmc add i2c devices

2021-11-03 Thread Hao Wu
From: Patrick Venture 

Adds supported i2c devices to the quanta-gbc-bmc board.

Signed-off-by: Patrick Venture 
Reviewed-by: Hao Wu 
---
 hw/arm/npcm7xx_boards.c | 82 -
 1 file changed, 49 insertions(+), 33 deletions(-)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 9121e081fa..7fb1b3dbc2 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -276,10 +276,12 @@ static void quanta_gsj_fan_init(NPCM7xxMachine *machine, 
NPCM7xxState *soc)
 
 static void quanta_gbs_i2c_init(NPCM7xxState *soc)
 {
+I2CSlave *i2c_mux;
+
+/* i2c-0: */
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 0), TYPE_PCA9546, 0x71);
+
 /*
- * i2c-0:
- * pca9546@71
- *
  * i2c-1:
  * pca9535@24
  * pca9535@20
@@ -288,46 +290,60 @@ static void quanta_gbs_i2c_init(NPCM7xxState *soc)
  * pca9535@23
  * pca9535@25
  * pca9535@26
- *
- * i2c-2:
- * sbtsi@4c
- *
- * i2c-5:
- * atmel,24c64@50 mb_fru
- * pca9546@71
- * - channel 0: max31725@54
- * - channel 1: max31725@55
- * - channel 2: max31725@5d
- *  atmel,24c64@51 fan_fru
- * - channel 3: atmel,24c64@52 hsbp_fru
- *
+ */
+
+/* i2c-2: sbtsi@4c */
+
+/* i2c-5: */
+/* mb_fru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 5), 5, 0x50, 8192, 0);
+i2c_mux = i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 5),
+  TYPE_PCA9546, 0x71);
+/* max31725 is tmp105 compatible. */
+i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 0), "tmp105", 0x54);
+i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 1), "tmp105", 0x55);
+i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 2), "tmp105", 0x5d);
+/* fan_fru */
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 5, 0x51, 8192, 1);
+/* hsbp_fru */
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 5, 0x52, 8192, 2);
+
+/*
  * i2c-6:
  * pca9545@73
  *
  * i2c-7:
  * pca9545@72
- *
- * i2c-8:
- * adi,adm1272@10
- *
- * i2c-9:
- * pca9546@71
- * - channel 0: isil,isl68137@60
- * - channel 1: isil,isl68137@61
- * - channel 2: isil,isl68137@63
- * - channel 3: isil,isl68137@45
- *
+ */
+
+/* i2c-8: */
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 8), "adm1272", 0x10);
+
+/* i2c-9: */
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 9), TYPE_PCA9546, 0x71);
+/*
+ * - channel 0: isil,isl68137@60
+ * - channel 1: isil,isl68137@61
+ * - channel 2: isil,isl68137@63
+ * - channel 3: isil,isl68137@45
+ */
+
+/*
  * i2c-10:
  * pca9545@71
  *
  * i2c-11:
  * pca9545@76
- *
- * i2c-12:
- * maxim,max34451@4e
- * isil,isl68137@5d
- * isil,isl68137@5e
- *
+ */
+
+/* i2c-12: */
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 12), "max34451", 0x4e);
+/*
+ * isil,isl68137@5d
+ * isil,isl68137@5e
+ */
+
+/*
  * i2c-14:
  * pca9545@70
  */
-- 
2.33.1.1089.g2158813163f-goog




[PATCH v4 6/7] hw/nvram: Update at24c EEPROM init function in NPCM7xx boards

2021-11-03 Thread Hao Wu
We made 3 changes to the at24c_eeprom_init function in
npcm7xx_boards.c:

1. We allow the function to take a I2CBus* as parameter. This allows
   us to attach an EEPROM device behind an I2C mux which is not
   possible with the old method.

2. We make at24c EEPROMs are backed by drives so that we can
   specify the content of the EEPROMs.

3. Instead of using i2c address as unit number, This patch assigns
   unique unit numbers for each eeproms in each board. This avoids
   conflict in providing multiple eeprom contents with the same address.
   In the old method if we specify two drives with the same unit number,
   the following error will occur: `Device with id 'none85' exists`.

Signed-off-by: Hao Wu 
---
 hw/arm/npcm7xx_boards.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index dec7d16ae5..9121e081fa 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -126,13 +126,17 @@ static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, 
uint32_t num)
 return I2C_BUS(qdev_get_child_bus(DEVICE(>smbus[num]), "i2c-bus"));
 }
 
-static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr,
-  uint32_t rsize)
+static void at24c_eeprom_init(I2CBus *i2c_bus, int bus, uint8_t addr,
+  uint32_t rsize, int unit_number)
 {
-I2CBus *i2c_bus = npcm7xx_i2c_get_bus(soc, bus);
 I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
 DeviceState *dev = DEVICE(i2c_dev);
+DriveInfo *dinfo;
 
+dinfo = drive_get(IF_OTHER, bus, unit_number);
+if (dinfo) {
+qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo));
+}
 qdev_prop_set_uint32(dev, "rom-size", rsize);
 i2c_slave_realize_and_unref(i2c_dev, i2c_bus, _abort);
 }
@@ -239,8 +243,8 @@ static void quanta_gsj_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x5c);
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x5c);
 
-at24c_eeprom_init(soc, 9, 0x55, 8192);
-at24c_eeprom_init(soc, 10, 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 9), 9, 0x55, 8192, 0);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 10), 10, 0x55, 8192, 1);
 
 /*
  * i2c-11:
-- 
2.33.1.1089.g2158813163f-goog




[PATCH v4 1/7] hw/i2c: Clear ACK bit in NPCM7xx SMBus module

2021-11-03 Thread Hao Wu
The ACK bit in NPCM7XX SMBus module should be cleared each time it
sends out a NACK signal. This patch fixes the bug that it fails to
do so.

Signed-off-by: Hao Wu 
Reviewed-by: Titus Rwantare 
Reviewed-by: Peter Maydell 
---
 hw/i2c/npcm7xx_smbus.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
index e7e0ba66fe..f18e311556 100644
--- a/hw/i2c/npcm7xx_smbus.c
+++ b/hw/i2c/npcm7xx_smbus.c
@@ -270,7 +270,7 @@ static void npcm7xx_smbus_recv_byte(NPCM7xxSMBusState *s)
 if (s->st & NPCM7XX_SMBCTL1_ACK) {
 trace_npcm7xx_smbus_nack(DEVICE(s)->canonical_path);
 i2c_nack(s->bus);
-s->st &= NPCM7XX_SMBCTL1_ACK;
+s->st &= ~NPCM7XX_SMBCTL1_ACK;
 }
 trace_npcm7xx_smbus_recv_byte((DEVICE(s)->canonical_path), s->sda);
 npcm7xx_smbus_update_irq(s);
-- 
2.33.1.1089.g2158813163f-goog




  1   2   3   >