Re: [PATCH v3 11/11] tests/qtest: Adding PCS Module test to GMAC Qtest
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
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
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
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
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
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
> > 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
[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
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
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
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
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
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
[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
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
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
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
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
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
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
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
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
[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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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()
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
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
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
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
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
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
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
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
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()
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
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
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
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
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
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