qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

npcm7xx_smbus.c (32992B)


      1 /*
      2  * Nuvoton NPCM7xx SMBus Module.
      3  *
      4  * Copyright 2020 Google LLC
      5  *
      6  * This program is free software; you can redistribute it and/or modify it
      7  * under the terms of the GNU General Public License as published by the
      8  * Free Software Foundation; either version 2 of the License, or
      9  * (at your option) any later version.
     10  *
     11  * This program is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
     14  * for more details.
     15  */
     16 
     17 #include "qemu/osdep.h"
     18 
     19 #include "hw/i2c/npcm7xx_smbus.h"
     20 #include "migration/vmstate.h"
     21 #include "qemu/bitops.h"
     22 #include "qemu/guest-random.h"
     23 #include "qemu/log.h"
     24 #include "qemu/module.h"
     25 #include "qemu/units.h"
     26 
     27 #include "trace.h"
     28 
     29 enum NPCM7xxSMBusCommonRegister {
     30     NPCM7XX_SMB_SDA     = 0x0,
     31     NPCM7XX_SMB_ST      = 0x2,
     32     NPCM7XX_SMB_CST     = 0x4,
     33     NPCM7XX_SMB_CTL1    = 0x6,
     34     NPCM7XX_SMB_ADDR1   = 0x8,
     35     NPCM7XX_SMB_CTL2    = 0xa,
     36     NPCM7XX_SMB_ADDR2   = 0xc,
     37     NPCM7XX_SMB_CTL3    = 0xe,
     38     NPCM7XX_SMB_CST2    = 0x18,
     39     NPCM7XX_SMB_CST3    = 0x19,
     40     NPCM7XX_SMB_VER     = 0x1f,
     41 };
     42 
     43 enum NPCM7xxSMBusBank0Register {
     44     NPCM7XX_SMB_ADDR3   = 0x10,
     45     NPCM7XX_SMB_ADDR7   = 0x11,
     46     NPCM7XX_SMB_ADDR4   = 0x12,
     47     NPCM7XX_SMB_ADDR8   = 0x13,
     48     NPCM7XX_SMB_ADDR5   = 0x14,
     49     NPCM7XX_SMB_ADDR9   = 0x15,
     50     NPCM7XX_SMB_ADDR6   = 0x16,
     51     NPCM7XX_SMB_ADDR10  = 0x17,
     52     NPCM7XX_SMB_CTL4    = 0x1a,
     53     NPCM7XX_SMB_CTL5    = 0x1b,
     54     NPCM7XX_SMB_SCLLT   = 0x1c,
     55     NPCM7XX_SMB_FIF_CTL = 0x1d,
     56     NPCM7XX_SMB_SCLHT   = 0x1e,
     57 };
     58 
     59 enum NPCM7xxSMBusBank1Register {
     60     NPCM7XX_SMB_FIF_CTS  = 0x10,
     61     NPCM7XX_SMB_FAIR_PER = 0x11,
     62     NPCM7XX_SMB_TXF_CTL  = 0x12,
     63     NPCM7XX_SMB_T_OUT    = 0x14,
     64     NPCM7XX_SMB_TXF_STS  = 0x1a,
     65     NPCM7XX_SMB_RXF_STS  = 0x1c,
     66     NPCM7XX_SMB_RXF_CTL  = 0x1e,
     67 };
     68 
     69 /* ST fields */
     70 #define NPCM7XX_SMBST_STP           BIT(7)
     71 #define NPCM7XX_SMBST_SDAST         BIT(6)
     72 #define NPCM7XX_SMBST_BER           BIT(5)
     73 #define NPCM7XX_SMBST_NEGACK        BIT(4)
     74 #define NPCM7XX_SMBST_STASTR        BIT(3)
     75 #define NPCM7XX_SMBST_NMATCH        BIT(2)
     76 #define NPCM7XX_SMBST_MODE          BIT(1)
     77 #define NPCM7XX_SMBST_XMIT          BIT(0)
     78 
     79 /* CST fields */
     80 #define NPCM7XX_SMBCST_ARPMATCH        BIT(7)
     81 #define NPCM7XX_SMBCST_MATCHAF         BIT(6)
     82 #define NPCM7XX_SMBCST_TGSCL           BIT(5)
     83 #define NPCM7XX_SMBCST_TSDA            BIT(4)
     84 #define NPCM7XX_SMBCST_GCMATCH         BIT(3)
     85 #define NPCM7XX_SMBCST_MATCH           BIT(2)
     86 #define NPCM7XX_SMBCST_BB              BIT(1)
     87 #define NPCM7XX_SMBCST_BUSY            BIT(0)
     88 
     89 /* CST2 fields */
     90 #define NPCM7XX_SMBCST2_INTSTS         BIT(7)
     91 #define NPCM7XX_SMBCST2_MATCH7F        BIT(6)
     92 #define NPCM7XX_SMBCST2_MATCH6F        BIT(5)
     93 #define NPCM7XX_SMBCST2_MATCH5F        BIT(4)
     94 #define NPCM7XX_SMBCST2_MATCH4F        BIT(3)
     95 #define NPCM7XX_SMBCST2_MATCH3F        BIT(2)
     96 #define NPCM7XX_SMBCST2_MATCH2F        BIT(1)
     97 #define NPCM7XX_SMBCST2_MATCH1F        BIT(0)
     98 
     99 /* CST3 fields */
    100 #define NPCM7XX_SMBCST3_EO_BUSY        BIT(7)
    101 #define NPCM7XX_SMBCST3_MATCH10F       BIT(2)
    102 #define NPCM7XX_SMBCST3_MATCH9F        BIT(1)
    103 #define NPCM7XX_SMBCST3_MATCH8F        BIT(0)
    104 
    105 /* CTL1 fields */
    106 #define NPCM7XX_SMBCTL1_STASTRE     BIT(7)
    107 #define NPCM7XX_SMBCTL1_NMINTE      BIT(6)
    108 #define NPCM7XX_SMBCTL1_GCMEN       BIT(5)
    109 #define NPCM7XX_SMBCTL1_ACK         BIT(4)
    110 #define NPCM7XX_SMBCTL1_EOBINTE     BIT(3)
    111 #define NPCM7XX_SMBCTL1_INTEN       BIT(2)
    112 #define NPCM7XX_SMBCTL1_STOP        BIT(1)
    113 #define NPCM7XX_SMBCTL1_START       BIT(0)
    114 
    115 /* CTL2 fields */
    116 #define NPCM7XX_SMBCTL2_SCLFRQ(rv)  extract8((rv), 1, 6)
    117 #define NPCM7XX_SMBCTL2_ENABLE      BIT(0)
    118 
    119 /* CTL3 fields */
    120 #define NPCM7XX_SMBCTL3_SCL_LVL     BIT(7)
    121 #define NPCM7XX_SMBCTL3_SDA_LVL     BIT(6)
    122 #define NPCM7XX_SMBCTL3_BNK_SEL     BIT(5)
    123 #define NPCM7XX_SMBCTL3_400K_MODE   BIT(4)
    124 #define NPCM7XX_SMBCTL3_IDL_START   BIT(3)
    125 #define NPCM7XX_SMBCTL3_ARPMEN      BIT(2)
    126 #define NPCM7XX_SMBCTL3_SCLFRQ(rv)  extract8((rv), 0, 2)
    127 
    128 /* ADDR fields */
    129 #define NPCM7XX_ADDR_EN             BIT(7)
    130 #define NPCM7XX_ADDR_A(rv)          extract8((rv), 0, 6)
    131 
    132 /* FIFO Mode Register Fields */
    133 /* FIF_CTL fields */
    134 #define NPCM7XX_SMBFIF_CTL_FIFO_EN          BIT(4)
    135 #define NPCM7XX_SMBFIF_CTL_FAIR_RDY_IE      BIT(2)
    136 #define NPCM7XX_SMBFIF_CTL_FAIR_RDY         BIT(1)
    137 #define NPCM7XX_SMBFIF_CTL_FAIR_BUSY        BIT(0)
    138 /* FIF_CTS fields */
    139 #define NPCM7XX_SMBFIF_CTS_STR              BIT(7)
    140 #define NPCM7XX_SMBFIF_CTS_CLR_FIFO         BIT(6)
    141 #define NPCM7XX_SMBFIF_CTS_RFTE_IE          BIT(3)
    142 #define NPCM7XX_SMBFIF_CTS_RXF_TXE          BIT(1)
    143 /* TXF_CTL fields */
    144 #define NPCM7XX_SMBTXF_CTL_THR_TXIE         BIT(6)
    145 #define NPCM7XX_SMBTXF_CTL_TX_THR(rv)       extract8((rv), 0, 5)
    146 /* T_OUT fields */
    147 #define NPCM7XX_SMBT_OUT_ST                 BIT(7)
    148 #define NPCM7XX_SMBT_OUT_IE                 BIT(6)
    149 #define NPCM7XX_SMBT_OUT_CLKDIV(rv)         extract8((rv), 0, 6)
    150 /* TXF_STS fields */
    151 #define NPCM7XX_SMBTXF_STS_TX_THST          BIT(6)
    152 #define NPCM7XX_SMBTXF_STS_TX_BYTES(rv)     extract8((rv), 0, 5)
    153 /* RXF_STS fields */
    154 #define NPCM7XX_SMBRXF_STS_RX_THST          BIT(6)
    155 #define NPCM7XX_SMBRXF_STS_RX_BYTES(rv)     extract8((rv), 0, 5)
    156 /* RXF_CTL fields */
    157 #define NPCM7XX_SMBRXF_CTL_THR_RXIE         BIT(6)
    158 #define NPCM7XX_SMBRXF_CTL_LAST             BIT(5)
    159 #define NPCM7XX_SMBRXF_CTL_RX_THR(rv)       extract8((rv), 0, 5)
    160 
    161 #define KEEP_OLD_BIT(o, n, b)       (((n) & (~(b))) | ((o) & (b)))
    162 #define WRITE_ONE_CLEAR(o, n, b)    ((n) & (b) ? (o) & (~(b)) : (o))
    163 
    164 #define NPCM7XX_SMBUS_ENABLED(s)    ((s)->ctl2 & NPCM7XX_SMBCTL2_ENABLE)
    165 #define NPCM7XX_SMBUS_FIFO_ENABLED(s) ((s)->fif_ctl & \
    166                                        NPCM7XX_SMBFIF_CTL_FIFO_EN)
    167 
    168 /* VERSION fields values, read-only. */
    169 #define NPCM7XX_SMBUS_VERSION_NUMBER 1
    170 #define NPCM7XX_SMBUS_VERSION_FIFO_SUPPORTED 1
    171 
    172 /* Reset values */
    173 #define NPCM7XX_SMB_ST_INIT_VAL     0x00
    174 #define NPCM7XX_SMB_CST_INIT_VAL    0x10
    175 #define NPCM7XX_SMB_CST2_INIT_VAL   0x00
    176 #define NPCM7XX_SMB_CST3_INIT_VAL   0x00
    177 #define NPCM7XX_SMB_CTL1_INIT_VAL   0x00
    178 #define NPCM7XX_SMB_CTL2_INIT_VAL   0x00
    179 #define NPCM7XX_SMB_CTL3_INIT_VAL   0xc0
    180 #define NPCM7XX_SMB_CTL4_INIT_VAL   0x07
    181 #define NPCM7XX_SMB_CTL5_INIT_VAL   0x00
    182 #define NPCM7XX_SMB_ADDR_INIT_VAL   0x00
    183 #define NPCM7XX_SMB_SCLLT_INIT_VAL  0x00
    184 #define NPCM7XX_SMB_SCLHT_INIT_VAL  0x00
    185 #define NPCM7XX_SMB_FIF_CTL_INIT_VAL 0x00
    186 #define NPCM7XX_SMB_FIF_CTS_INIT_VAL 0x00
    187 #define NPCM7XX_SMB_FAIR_PER_INIT_VAL 0x00
    188 #define NPCM7XX_SMB_TXF_CTL_INIT_VAL 0x00
    189 #define NPCM7XX_SMB_T_OUT_INIT_VAL 0x3f
    190 #define NPCM7XX_SMB_TXF_STS_INIT_VAL 0x00
    191 #define NPCM7XX_SMB_RXF_STS_INIT_VAL 0x00
    192 #define NPCM7XX_SMB_RXF_CTL_INIT_VAL 0x01
    193 
    194 static uint8_t npcm7xx_smbus_get_version(void)
    195 {
    196     return NPCM7XX_SMBUS_VERSION_FIFO_SUPPORTED << 7 |
    197            NPCM7XX_SMBUS_VERSION_NUMBER;
    198 }
    199 
    200 static void npcm7xx_smbus_update_irq(NPCM7xxSMBusState *s)
    201 {
    202     int level;
    203 
    204     if (s->ctl1 & NPCM7XX_SMBCTL1_INTEN) {
    205         level = !!((s->ctl1 & NPCM7XX_SMBCTL1_NMINTE &&
    206                     s->st & NPCM7XX_SMBST_NMATCH) ||
    207                    (s->st & NPCM7XX_SMBST_BER) ||
    208                    (s->st & NPCM7XX_SMBST_NEGACK) ||
    209                    (s->st & NPCM7XX_SMBST_SDAST) ||
    210                    (s->ctl1 & NPCM7XX_SMBCTL1_STASTRE &&
    211                     s->st & NPCM7XX_SMBST_SDAST) ||
    212                    (s->ctl1 & NPCM7XX_SMBCTL1_EOBINTE &&
    213                     s->cst3 & NPCM7XX_SMBCST3_EO_BUSY) ||
    214                    (s->rxf_ctl & NPCM7XX_SMBRXF_CTL_THR_RXIE &&
    215                     s->rxf_sts & NPCM7XX_SMBRXF_STS_RX_THST) ||
    216                    (s->txf_ctl & NPCM7XX_SMBTXF_CTL_THR_TXIE &&
    217                     s->txf_sts & NPCM7XX_SMBTXF_STS_TX_THST) ||
    218                    (s->fif_cts & NPCM7XX_SMBFIF_CTS_RFTE_IE &&
    219                     s->fif_cts & NPCM7XX_SMBFIF_CTS_RXF_TXE));
    220 
    221         if (level) {
    222             s->cst2 |= NPCM7XX_SMBCST2_INTSTS;
    223         } else {
    224             s->cst2 &= ~NPCM7XX_SMBCST2_INTSTS;
    225         }
    226         qemu_set_irq(s->irq, level);
    227     }
    228 }
    229 
    230 static void npcm7xx_smbus_nack(NPCM7xxSMBusState *s)
    231 {
    232     s->st &= ~NPCM7XX_SMBST_SDAST;
    233     s->st |= NPCM7XX_SMBST_NEGACK;
    234     s->status = NPCM7XX_SMBUS_STATUS_NEGACK;
    235 }
    236 
    237 static void npcm7xx_smbus_clear_buffer(NPCM7xxSMBusState *s)
    238 {
    239     s->fif_cts &= ~NPCM7XX_SMBFIF_CTS_RXF_TXE;
    240     s->txf_sts = 0;
    241     s->rxf_sts = 0;
    242 }
    243 
    244 static void npcm7xx_smbus_send_byte(NPCM7xxSMBusState *s, uint8_t value)
    245 {
    246     int rv = i2c_send(s->bus, value);
    247 
    248     if (rv) {
    249         npcm7xx_smbus_nack(s);
    250     } else {
    251         s->st |= NPCM7XX_SMBST_SDAST;
    252         if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
    253             s->fif_cts |= NPCM7XX_SMBFIF_CTS_RXF_TXE;
    254             if (NPCM7XX_SMBTXF_STS_TX_BYTES(s->txf_sts) ==
    255                 NPCM7XX_SMBTXF_CTL_TX_THR(s->txf_ctl)) {
    256                 s->txf_sts = NPCM7XX_SMBTXF_STS_TX_THST;
    257             } else {
    258                 s->txf_sts = 0;
    259             }
    260         }
    261     }
    262     trace_npcm7xx_smbus_send_byte((DEVICE(s)->canonical_path), value, !rv);
    263     npcm7xx_smbus_update_irq(s);
    264 }
    265 
    266 static void npcm7xx_smbus_recv_byte(NPCM7xxSMBusState *s)
    267 {
    268     s->sda = i2c_recv(s->bus);
    269     s->st |= NPCM7XX_SMBST_SDAST;
    270     if (s->st & NPCM7XX_SMBCTL1_ACK) {
    271         trace_npcm7xx_smbus_nack(DEVICE(s)->canonical_path);
    272         i2c_nack(s->bus);
    273         s->st &= NPCM7XX_SMBCTL1_ACK;
    274     }
    275     trace_npcm7xx_smbus_recv_byte((DEVICE(s)->canonical_path), s->sda);
    276     npcm7xx_smbus_update_irq(s);
    277 }
    278 
    279 static void npcm7xx_smbus_recv_fifo(NPCM7xxSMBusState *s)
    280 {
    281     uint8_t expected_bytes = NPCM7XX_SMBRXF_CTL_RX_THR(s->rxf_ctl);
    282     uint8_t received_bytes = NPCM7XX_SMBRXF_STS_RX_BYTES(s->rxf_sts);
    283     uint8_t pos;
    284 
    285     if (received_bytes == expected_bytes) {
    286         return;
    287     }
    288 
    289     while (received_bytes < expected_bytes &&
    290            received_bytes < NPCM7XX_SMBUS_FIFO_SIZE) {
    291         pos = (s->rx_cur + received_bytes) % NPCM7XX_SMBUS_FIFO_SIZE;
    292         s->rx_fifo[pos] = i2c_recv(s->bus);
    293         trace_npcm7xx_smbus_recv_byte((DEVICE(s)->canonical_path),
    294                                       s->rx_fifo[pos]);
    295         ++received_bytes;
    296     }
    297 
    298     trace_npcm7xx_smbus_recv_fifo((DEVICE(s)->canonical_path),
    299                                   received_bytes, expected_bytes);
    300     s->rxf_sts = received_bytes;
    301     if (unlikely(received_bytes < expected_bytes)) {
    302         qemu_log_mask(LOG_GUEST_ERROR,
    303                       "%s: invalid rx_thr value: 0x%02x\n",
    304                       DEVICE(s)->canonical_path, expected_bytes);
    305         return;
    306     }
    307 
    308     s->rxf_sts |= NPCM7XX_SMBRXF_STS_RX_THST;
    309     if (s->rxf_ctl & NPCM7XX_SMBRXF_CTL_LAST) {
    310         trace_npcm7xx_smbus_nack(DEVICE(s)->canonical_path);
    311         i2c_nack(s->bus);
    312         s->rxf_ctl &= ~NPCM7XX_SMBRXF_CTL_LAST;
    313     }
    314     if (received_bytes == NPCM7XX_SMBUS_FIFO_SIZE) {
    315         s->st |= NPCM7XX_SMBST_SDAST;
    316         s->fif_cts |= NPCM7XX_SMBFIF_CTS_RXF_TXE;
    317     } else if (!(s->rxf_ctl & NPCM7XX_SMBRXF_CTL_THR_RXIE)) {
    318         s->st |= NPCM7XX_SMBST_SDAST;
    319     } else {
    320         s->st &= ~NPCM7XX_SMBST_SDAST;
    321     }
    322     npcm7xx_smbus_update_irq(s);
    323 }
    324 
    325 static void npcm7xx_smbus_read_byte_fifo(NPCM7xxSMBusState *s)
    326 {
    327     uint8_t received_bytes = NPCM7XX_SMBRXF_STS_RX_BYTES(s->rxf_sts);
    328 
    329     if (received_bytes == 0) {
    330         npcm7xx_smbus_recv_fifo(s);
    331         return;
    332     }
    333 
    334     s->sda = s->rx_fifo[s->rx_cur];
    335     s->rx_cur = (s->rx_cur + 1u) % NPCM7XX_SMBUS_FIFO_SIZE;
    336     --s->rxf_sts;
    337     npcm7xx_smbus_update_irq(s);
    338 }
    339 
    340 static void npcm7xx_smbus_start(NPCM7xxSMBusState *s)
    341 {
    342     /*
    343      * We can start the bus if one of these is true:
    344      * 1. The bus is idle (so we can request it)
    345      * 2. We are the occupier (it's a repeated start condition.)
    346      */
    347     int available = !i2c_bus_busy(s->bus) ||
    348                     s->status != NPCM7XX_SMBUS_STATUS_IDLE;
    349 
    350     if (available) {
    351         s->st |= NPCM7XX_SMBST_MODE | NPCM7XX_SMBST_XMIT | NPCM7XX_SMBST_SDAST;
    352         s->cst |= NPCM7XX_SMBCST_BUSY;
    353         if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
    354             s->fif_cts |= NPCM7XX_SMBFIF_CTS_RXF_TXE;
    355         }
    356     } else {
    357         s->st &= ~NPCM7XX_SMBST_MODE;
    358         s->cst &= ~NPCM7XX_SMBCST_BUSY;
    359         s->st |= NPCM7XX_SMBST_BER;
    360     }
    361 
    362     trace_npcm7xx_smbus_start(DEVICE(s)->canonical_path, available);
    363     s->cst |= NPCM7XX_SMBCST_BB;
    364     s->status = NPCM7XX_SMBUS_STATUS_IDLE;
    365     npcm7xx_smbus_update_irq(s);
    366 }
    367 
    368 static void npcm7xx_smbus_send_address(NPCM7xxSMBusState *s, uint8_t value)
    369 {
    370     int recv;
    371     int rv;
    372 
    373     recv = value & BIT(0);
    374     rv = i2c_start_transfer(s->bus, value >> 1, recv);
    375     trace_npcm7xx_smbus_send_address(DEVICE(s)->canonical_path,
    376                                      value >> 1, recv, !rv);
    377     if (rv) {
    378         qemu_log_mask(LOG_GUEST_ERROR,
    379                       "%s: requesting i2c bus for 0x%02x failed: %d\n",
    380                       DEVICE(s)->canonical_path, value, rv);
    381         /* Failed to start transfer. NACK to reject.*/
    382         if (recv) {
    383             s->st &= ~NPCM7XX_SMBST_XMIT;
    384         } else {
    385             s->st |= NPCM7XX_SMBST_XMIT;
    386         }
    387         npcm7xx_smbus_nack(s);
    388         npcm7xx_smbus_update_irq(s);
    389         return;
    390     }
    391 
    392     s->st &= ~NPCM7XX_SMBST_NEGACK;
    393     if (recv) {
    394         s->status = NPCM7XX_SMBUS_STATUS_RECEIVING;
    395         s->st &= ~NPCM7XX_SMBST_XMIT;
    396     } else {
    397         s->status = NPCM7XX_SMBUS_STATUS_SENDING;
    398         s->st |= NPCM7XX_SMBST_XMIT;
    399     }
    400 
    401     if (s->ctl1 & NPCM7XX_SMBCTL1_STASTRE) {
    402         s->st |= NPCM7XX_SMBST_STASTR;
    403         if (!recv) {
    404             s->st |= NPCM7XX_SMBST_SDAST;
    405         }
    406     } else if (recv) {
    407         s->st |= NPCM7XX_SMBST_SDAST;
    408         if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
    409             npcm7xx_smbus_recv_fifo(s);
    410         } else {
    411             npcm7xx_smbus_recv_byte(s);
    412         }
    413     } else if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
    414         s->st |= NPCM7XX_SMBST_SDAST;
    415         s->fif_cts |= NPCM7XX_SMBFIF_CTS_RXF_TXE;
    416     }
    417     npcm7xx_smbus_update_irq(s);
    418 }
    419 
    420 static void npcm7xx_smbus_execute_stop(NPCM7xxSMBusState *s)
    421 {
    422     i2c_end_transfer(s->bus);
    423     s->st = 0;
    424     s->cst = 0;
    425     s->status = NPCM7XX_SMBUS_STATUS_IDLE;
    426     s->cst3 |= NPCM7XX_SMBCST3_EO_BUSY;
    427     trace_npcm7xx_smbus_stop(DEVICE(s)->canonical_path);
    428     npcm7xx_smbus_update_irq(s);
    429 }
    430 
    431 
    432 static void npcm7xx_smbus_stop(NPCM7xxSMBusState *s)
    433 {
    434     if (s->st & NPCM7XX_SMBST_MODE) {
    435         switch (s->status) {
    436         case NPCM7XX_SMBUS_STATUS_RECEIVING:
    437         case NPCM7XX_SMBUS_STATUS_STOPPING_LAST_RECEIVE:
    438             s->status = NPCM7XX_SMBUS_STATUS_STOPPING_LAST_RECEIVE;
    439             break;
    440 
    441         case NPCM7XX_SMBUS_STATUS_NEGACK:
    442             s->status = NPCM7XX_SMBUS_STATUS_STOPPING_NEGACK;
    443             break;
    444 
    445         default:
    446             npcm7xx_smbus_execute_stop(s);
    447             break;
    448         }
    449     }
    450 }
    451 
    452 static uint8_t npcm7xx_smbus_read_sda(NPCM7xxSMBusState *s)
    453 {
    454     uint8_t value = s->sda;
    455 
    456     switch (s->status) {
    457     case NPCM7XX_SMBUS_STATUS_STOPPING_LAST_RECEIVE:
    458         if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
    459             if (NPCM7XX_SMBRXF_STS_RX_BYTES(s->rxf_sts) <= 1) {
    460                 npcm7xx_smbus_execute_stop(s);
    461             }
    462             if (NPCM7XX_SMBRXF_STS_RX_BYTES(s->rxf_sts) == 0) {
    463                 qemu_log_mask(LOG_GUEST_ERROR,
    464                               "%s: read to SDA with an empty rx-fifo buffer, "
    465                               "result undefined: %u\n",
    466                               DEVICE(s)->canonical_path, s->sda);
    467                 break;
    468             }
    469             npcm7xx_smbus_read_byte_fifo(s);
    470             value = s->sda;
    471         } else {
    472             npcm7xx_smbus_execute_stop(s);
    473         }
    474         break;
    475 
    476     case NPCM7XX_SMBUS_STATUS_RECEIVING:
    477         if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
    478             npcm7xx_smbus_read_byte_fifo(s);
    479             value = s->sda;
    480         } else {
    481             npcm7xx_smbus_recv_byte(s);
    482         }
    483         break;
    484 
    485     default:
    486         /* Do nothing */
    487         break;
    488     }
    489 
    490     return value;
    491 }
    492 
    493 static void npcm7xx_smbus_write_sda(NPCM7xxSMBusState *s, uint8_t value)
    494 {
    495     s->sda = value;
    496     if (s->st & NPCM7XX_SMBST_MODE) {
    497         switch (s->status) {
    498         case NPCM7XX_SMBUS_STATUS_IDLE:
    499             npcm7xx_smbus_send_address(s, value);
    500             break;
    501         case NPCM7XX_SMBUS_STATUS_SENDING:
    502             npcm7xx_smbus_send_byte(s, value);
    503             break;
    504         default:
    505             qemu_log_mask(LOG_GUEST_ERROR,
    506                           "%s: write to SDA in invalid status %d: %u\n",
    507                           DEVICE(s)->canonical_path, s->status, value);
    508             break;
    509         }
    510     }
    511 }
    512 
    513 static void npcm7xx_smbus_write_st(NPCM7xxSMBusState *s, uint8_t value)
    514 {
    515     s->st = WRITE_ONE_CLEAR(s->st, value, NPCM7XX_SMBST_STP);
    516     s->st = WRITE_ONE_CLEAR(s->st, value, NPCM7XX_SMBST_BER);
    517     s->st = WRITE_ONE_CLEAR(s->st, value, NPCM7XX_SMBST_STASTR);
    518     s->st = WRITE_ONE_CLEAR(s->st, value, NPCM7XX_SMBST_NMATCH);
    519 
    520     if (value & NPCM7XX_SMBST_NEGACK) {
    521         s->st &= ~NPCM7XX_SMBST_NEGACK;
    522         if (s->status == NPCM7XX_SMBUS_STATUS_STOPPING_NEGACK) {
    523             npcm7xx_smbus_execute_stop(s);
    524         }
    525     }
    526 
    527     if (value & NPCM7XX_SMBST_STASTR &&
    528         s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
    529         if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
    530             npcm7xx_smbus_recv_fifo(s);
    531         } else {
    532             npcm7xx_smbus_recv_byte(s);
    533         }
    534     }
    535 
    536     npcm7xx_smbus_update_irq(s);
    537 }
    538 
    539 static void npcm7xx_smbus_write_cst(NPCM7xxSMBusState *s, uint8_t value)
    540 {
    541     uint8_t new_value = s->cst;
    542 
    543     s->cst = WRITE_ONE_CLEAR(new_value, value, NPCM7XX_SMBCST_BB);
    544     npcm7xx_smbus_update_irq(s);
    545 }
    546 
    547 static void npcm7xx_smbus_write_cst3(NPCM7xxSMBusState *s, uint8_t value)
    548 {
    549     s->cst3 = WRITE_ONE_CLEAR(s->cst3, value, NPCM7XX_SMBCST3_EO_BUSY);
    550     npcm7xx_smbus_update_irq(s);
    551 }
    552 
    553 static void npcm7xx_smbus_write_ctl1(NPCM7xxSMBusState *s, uint8_t value)
    554 {
    555     s->ctl1 = KEEP_OLD_BIT(s->ctl1, value,
    556             NPCM7XX_SMBCTL1_START | NPCM7XX_SMBCTL1_STOP | NPCM7XX_SMBCTL1_ACK);
    557 
    558     if (value & NPCM7XX_SMBCTL1_START) {
    559         npcm7xx_smbus_start(s);
    560     }
    561 
    562     if (value & NPCM7XX_SMBCTL1_STOP) {
    563         npcm7xx_smbus_stop(s);
    564     }
    565 
    566     npcm7xx_smbus_update_irq(s);
    567 }
    568 
    569 static void npcm7xx_smbus_write_ctl2(NPCM7xxSMBusState *s, uint8_t value)
    570 {
    571     s->ctl2 = value;
    572 
    573     if (!NPCM7XX_SMBUS_ENABLED(s)) {
    574         /* Disable this SMBus module. */
    575         s->ctl1 = 0;
    576         s->st = 0;
    577         s->cst3 = s->cst3 & (~NPCM7XX_SMBCST3_EO_BUSY);
    578         s->cst = 0;
    579         npcm7xx_smbus_clear_buffer(s);
    580     }
    581 }
    582 
    583 static void npcm7xx_smbus_write_ctl3(NPCM7xxSMBusState *s, uint8_t value)
    584 {
    585     uint8_t old_ctl3 = s->ctl3;
    586 
    587     /* Write to SDA and SCL bits are ignored. */
    588     s->ctl3 =  KEEP_OLD_BIT(old_ctl3, value,
    589                             NPCM7XX_SMBCTL3_SCL_LVL | NPCM7XX_SMBCTL3_SDA_LVL);
    590 }
    591 
    592 static void npcm7xx_smbus_write_fif_ctl(NPCM7xxSMBusState *s, uint8_t value)
    593 {
    594     uint8_t new_ctl = value;
    595 
    596     new_ctl = KEEP_OLD_BIT(s->fif_ctl, new_ctl, NPCM7XX_SMBFIF_CTL_FAIR_RDY);
    597     new_ctl = WRITE_ONE_CLEAR(new_ctl, value, NPCM7XX_SMBFIF_CTL_FAIR_RDY);
    598     new_ctl = KEEP_OLD_BIT(s->fif_ctl, new_ctl, NPCM7XX_SMBFIF_CTL_FAIR_BUSY);
    599     s->fif_ctl = new_ctl;
    600 }
    601 
    602 static void npcm7xx_smbus_write_fif_cts(NPCM7xxSMBusState *s, uint8_t value)
    603 {
    604     s->fif_cts = WRITE_ONE_CLEAR(s->fif_cts, value, NPCM7XX_SMBFIF_CTS_STR);
    605     s->fif_cts = WRITE_ONE_CLEAR(s->fif_cts, value, NPCM7XX_SMBFIF_CTS_RXF_TXE);
    606     s->fif_cts = KEEP_OLD_BIT(value, s->fif_cts, NPCM7XX_SMBFIF_CTS_RFTE_IE);
    607 
    608     if (value & NPCM7XX_SMBFIF_CTS_CLR_FIFO) {
    609         npcm7xx_smbus_clear_buffer(s);
    610     }
    611 }
    612 
    613 static void npcm7xx_smbus_write_txf_ctl(NPCM7xxSMBusState *s, uint8_t value)
    614 {
    615     s->txf_ctl = value;
    616 }
    617 
    618 static void npcm7xx_smbus_write_t_out(NPCM7xxSMBusState *s, uint8_t value)
    619 {
    620     uint8_t new_t_out = value;
    621 
    622     if ((value & NPCM7XX_SMBT_OUT_ST) || (!(s->t_out & NPCM7XX_SMBT_OUT_ST))) {
    623         new_t_out &= ~NPCM7XX_SMBT_OUT_ST;
    624     } else {
    625         new_t_out |= NPCM7XX_SMBT_OUT_ST;
    626     }
    627 
    628     s->t_out = new_t_out;
    629 }
    630 
    631 static void npcm7xx_smbus_write_txf_sts(NPCM7xxSMBusState *s, uint8_t value)
    632 {
    633     s->txf_sts = WRITE_ONE_CLEAR(s->txf_sts, value, NPCM7XX_SMBTXF_STS_TX_THST);
    634 }
    635 
    636 static void npcm7xx_smbus_write_rxf_sts(NPCM7xxSMBusState *s, uint8_t value)
    637 {
    638     if (value & NPCM7XX_SMBRXF_STS_RX_THST) {
    639         s->rxf_sts &= ~NPCM7XX_SMBRXF_STS_RX_THST;
    640         if (s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
    641             npcm7xx_smbus_recv_fifo(s);
    642         }
    643     }
    644 }
    645 
    646 static void npcm7xx_smbus_write_rxf_ctl(NPCM7xxSMBusState *s, uint8_t value)
    647 {
    648     uint8_t new_ctl = value;
    649 
    650     if (!(value & NPCM7XX_SMBRXF_CTL_LAST)) {
    651         new_ctl = KEEP_OLD_BIT(s->rxf_ctl, new_ctl, NPCM7XX_SMBRXF_CTL_LAST);
    652     }
    653     s->rxf_ctl = new_ctl;
    654 }
    655 
    656 static uint64_t npcm7xx_smbus_read(void *opaque, hwaddr offset, unsigned size)
    657 {
    658     NPCM7xxSMBusState *s = opaque;
    659     uint64_t value = 0;
    660     uint8_t bank = s->ctl3 & NPCM7XX_SMBCTL3_BNK_SEL;
    661 
    662     /* The order of the registers are their order in memory. */
    663     switch (offset) {
    664     case NPCM7XX_SMB_SDA:
    665         value = npcm7xx_smbus_read_sda(s);
    666         break;
    667 
    668     case NPCM7XX_SMB_ST:
    669         value = s->st;
    670         break;
    671 
    672     case NPCM7XX_SMB_CST:
    673         value = s->cst;
    674         break;
    675 
    676     case NPCM7XX_SMB_CTL1:
    677         value = s->ctl1;
    678         break;
    679 
    680     case NPCM7XX_SMB_ADDR1:
    681         value = s->addr[0];
    682         break;
    683 
    684     case NPCM7XX_SMB_CTL2:
    685         value = s->ctl2;
    686         break;
    687 
    688     case NPCM7XX_SMB_ADDR2:
    689         value = s->addr[1];
    690         break;
    691 
    692     case NPCM7XX_SMB_CTL3:
    693         value = s->ctl3;
    694         break;
    695 
    696     case NPCM7XX_SMB_CST2:
    697         value = s->cst2;
    698         break;
    699 
    700     case NPCM7XX_SMB_CST3:
    701         value = s->cst3;
    702         break;
    703 
    704     case NPCM7XX_SMB_VER:
    705         value = npcm7xx_smbus_get_version();
    706         break;
    707 
    708     /* This register is either invalid or banked at this point. */
    709     default:
    710         if (bank) {
    711             /* Bank 1 */
    712             switch (offset) {
    713             case NPCM7XX_SMB_FIF_CTS:
    714                 value = s->fif_cts;
    715                 break;
    716 
    717             case NPCM7XX_SMB_FAIR_PER:
    718                 value = s->fair_per;
    719                 break;
    720 
    721             case NPCM7XX_SMB_TXF_CTL:
    722                 value = s->txf_ctl;
    723                 break;
    724 
    725             case NPCM7XX_SMB_T_OUT:
    726                 value = s->t_out;
    727                 break;
    728 
    729             case NPCM7XX_SMB_TXF_STS:
    730                 value = s->txf_sts;
    731                 break;
    732 
    733             case NPCM7XX_SMB_RXF_STS:
    734                 value = s->rxf_sts;
    735                 break;
    736 
    737             case NPCM7XX_SMB_RXF_CTL:
    738                 value = s->rxf_ctl;
    739                 break;
    740 
    741             default:
    742                 qemu_log_mask(LOG_GUEST_ERROR,
    743                         "%s: read from invalid offset 0x%" HWADDR_PRIx "\n",
    744                         DEVICE(s)->canonical_path, offset);
    745                 break;
    746             }
    747         } else {
    748             /* Bank 0 */
    749             switch (offset) {
    750             case NPCM7XX_SMB_ADDR3:
    751                 value = s->addr[2];
    752                 break;
    753 
    754             case NPCM7XX_SMB_ADDR7:
    755                 value = s->addr[6];
    756                 break;
    757 
    758             case NPCM7XX_SMB_ADDR4:
    759                 value = s->addr[3];
    760                 break;
    761 
    762             case NPCM7XX_SMB_ADDR8:
    763                 value = s->addr[7];
    764                 break;
    765 
    766             case NPCM7XX_SMB_ADDR5:
    767                 value = s->addr[4];
    768                 break;
    769 
    770             case NPCM7XX_SMB_ADDR9:
    771                 value = s->addr[8];
    772                 break;
    773 
    774             case NPCM7XX_SMB_ADDR6:
    775                 value = s->addr[5];
    776                 break;
    777 
    778             case NPCM7XX_SMB_ADDR10:
    779                 value = s->addr[9];
    780                 break;
    781 
    782             case NPCM7XX_SMB_CTL4:
    783                 value = s->ctl4;
    784                 break;
    785 
    786             case NPCM7XX_SMB_CTL5:
    787                 value = s->ctl5;
    788                 break;
    789 
    790             case NPCM7XX_SMB_SCLLT:
    791                 value = s->scllt;
    792                 break;
    793 
    794             case NPCM7XX_SMB_FIF_CTL:
    795                 value = s->fif_ctl;
    796                 break;
    797 
    798             case NPCM7XX_SMB_SCLHT:
    799                 value = s->sclht;
    800                 break;
    801 
    802             default:
    803                 qemu_log_mask(LOG_GUEST_ERROR,
    804                         "%s: read from invalid offset 0x%" HWADDR_PRIx "\n",
    805                         DEVICE(s)->canonical_path, offset);
    806                 break;
    807             }
    808         }
    809         break;
    810     }
    811 
    812     trace_npcm7xx_smbus_read(DEVICE(s)->canonical_path, offset, value, size);
    813 
    814     return value;
    815 }
    816 
    817 static void npcm7xx_smbus_write(void *opaque, hwaddr offset, uint64_t value,
    818                               unsigned size)
    819 {
    820     NPCM7xxSMBusState *s = opaque;
    821     uint8_t bank = s->ctl3 & NPCM7XX_SMBCTL3_BNK_SEL;
    822 
    823     trace_npcm7xx_smbus_write(DEVICE(s)->canonical_path, offset, value, size);
    824 
    825     /* The order of the registers are their order in memory. */
    826     switch (offset) {
    827     case NPCM7XX_SMB_SDA:
    828         npcm7xx_smbus_write_sda(s, value);
    829         break;
    830 
    831     case NPCM7XX_SMB_ST:
    832         npcm7xx_smbus_write_st(s, value);
    833         break;
    834 
    835     case NPCM7XX_SMB_CST:
    836         npcm7xx_smbus_write_cst(s, value);
    837         break;
    838 
    839     case NPCM7XX_SMB_CTL1:
    840         npcm7xx_smbus_write_ctl1(s, value);
    841         break;
    842 
    843     case NPCM7XX_SMB_ADDR1:
    844         s->addr[0] = value;
    845         break;
    846 
    847     case NPCM7XX_SMB_CTL2:
    848         npcm7xx_smbus_write_ctl2(s, value);
    849         break;
    850 
    851     case NPCM7XX_SMB_ADDR2:
    852         s->addr[1] = value;
    853         break;
    854 
    855     case NPCM7XX_SMB_CTL3:
    856         npcm7xx_smbus_write_ctl3(s, value);
    857         break;
    858 
    859     case NPCM7XX_SMB_CST2:
    860         qemu_log_mask(LOG_GUEST_ERROR,
    861                 "%s: write to read-only reg: offset 0x%" HWADDR_PRIx "\n",
    862                 DEVICE(s)->canonical_path, offset);
    863         break;
    864 
    865     case NPCM7XX_SMB_CST3:
    866         npcm7xx_smbus_write_cst3(s, value);
    867         break;
    868 
    869     case NPCM7XX_SMB_VER:
    870         qemu_log_mask(LOG_GUEST_ERROR,
    871                 "%s: write to read-only reg: offset 0x%" HWADDR_PRIx "\n",
    872                 DEVICE(s)->canonical_path, offset);
    873         break;
    874 
    875     /* This register is either invalid or banked at this point. */
    876     default:
    877         if (bank) {
    878             /* Bank 1 */
    879             switch (offset) {
    880             case NPCM7XX_SMB_FIF_CTS:
    881                 npcm7xx_smbus_write_fif_cts(s, value);
    882                 break;
    883 
    884             case NPCM7XX_SMB_FAIR_PER:
    885                 s->fair_per = value;
    886                 break;
    887 
    888             case NPCM7XX_SMB_TXF_CTL:
    889                 npcm7xx_smbus_write_txf_ctl(s, value);
    890                 break;
    891 
    892             case NPCM7XX_SMB_T_OUT:
    893                 npcm7xx_smbus_write_t_out(s, value);
    894                 break;
    895 
    896             case NPCM7XX_SMB_TXF_STS:
    897                 npcm7xx_smbus_write_txf_sts(s, value);
    898                 break;
    899 
    900             case NPCM7XX_SMB_RXF_STS:
    901                 npcm7xx_smbus_write_rxf_sts(s, value);
    902                 break;
    903 
    904             case NPCM7XX_SMB_RXF_CTL:
    905                 npcm7xx_smbus_write_rxf_ctl(s, value);
    906                 break;
    907 
    908             default:
    909                 qemu_log_mask(LOG_GUEST_ERROR,
    910                         "%s: write to invalid offset 0x%" HWADDR_PRIx "\n",
    911                         DEVICE(s)->canonical_path, offset);
    912                 break;
    913             }
    914         } else {
    915             /* Bank 0 */
    916             switch (offset) {
    917             case NPCM7XX_SMB_ADDR3:
    918                 s->addr[2] = value;
    919                 break;
    920 
    921             case NPCM7XX_SMB_ADDR7:
    922                 s->addr[6] = value;
    923                 break;
    924 
    925             case NPCM7XX_SMB_ADDR4:
    926                 s->addr[3] = value;
    927                 break;
    928 
    929             case NPCM7XX_SMB_ADDR8:
    930                 s->addr[7] = value;
    931                 break;
    932 
    933             case NPCM7XX_SMB_ADDR5:
    934                 s->addr[4] = value;
    935                 break;
    936 
    937             case NPCM7XX_SMB_ADDR9:
    938                 s->addr[8] = value;
    939                 break;
    940 
    941             case NPCM7XX_SMB_ADDR6:
    942                 s->addr[5] = value;
    943                 break;
    944 
    945             case NPCM7XX_SMB_ADDR10:
    946                 s->addr[9] = value;
    947                 break;
    948 
    949             case NPCM7XX_SMB_CTL4:
    950                 s->ctl4 = value;
    951                 break;
    952 
    953             case NPCM7XX_SMB_CTL5:
    954                 s->ctl5 = value;
    955                 break;
    956 
    957             case NPCM7XX_SMB_SCLLT:
    958                 s->scllt = value;
    959                 break;
    960 
    961             case NPCM7XX_SMB_FIF_CTL:
    962                 npcm7xx_smbus_write_fif_ctl(s, value);
    963                 break;
    964 
    965             case NPCM7XX_SMB_SCLHT:
    966                 s->sclht = value;
    967                 break;
    968 
    969             default:
    970                 qemu_log_mask(LOG_GUEST_ERROR,
    971                         "%s: write to invalid offset 0x%" HWADDR_PRIx "\n",
    972                         DEVICE(s)->canonical_path, offset);
    973                 break;
    974             }
    975         }
    976         break;
    977     }
    978 }
    979 
    980 static const MemoryRegionOps npcm7xx_smbus_ops = {
    981     .read = npcm7xx_smbus_read,
    982     .write = npcm7xx_smbus_write,
    983     .endianness = DEVICE_LITTLE_ENDIAN,
    984     .valid = {
    985         .min_access_size = 1,
    986         .max_access_size = 1,
    987         .unaligned = false,
    988     },
    989 };
    990 
    991 static void npcm7xx_smbus_enter_reset(Object *obj, ResetType type)
    992 {
    993     NPCM7xxSMBusState *s = NPCM7XX_SMBUS(obj);
    994 
    995     s->st = NPCM7XX_SMB_ST_INIT_VAL;
    996     s->cst = NPCM7XX_SMB_CST_INIT_VAL;
    997     s->cst2 = NPCM7XX_SMB_CST2_INIT_VAL;
    998     s->cst3 = NPCM7XX_SMB_CST3_INIT_VAL;
    999     s->ctl1 = NPCM7XX_SMB_CTL1_INIT_VAL;
   1000     s->ctl2 = NPCM7XX_SMB_CTL2_INIT_VAL;
   1001     s->ctl3 = NPCM7XX_SMB_CTL3_INIT_VAL;
   1002     s->ctl4 = NPCM7XX_SMB_CTL4_INIT_VAL;
   1003     s->ctl5 = NPCM7XX_SMB_CTL5_INIT_VAL;
   1004 
   1005     for (int i = 0; i < NPCM7XX_SMBUS_NR_ADDRS; ++i) {
   1006         s->addr[i] = NPCM7XX_SMB_ADDR_INIT_VAL;
   1007     }
   1008     s->scllt = NPCM7XX_SMB_SCLLT_INIT_VAL;
   1009     s->sclht = NPCM7XX_SMB_SCLHT_INIT_VAL;
   1010 
   1011     s->fif_ctl = NPCM7XX_SMB_FIF_CTL_INIT_VAL;
   1012     s->fif_cts = NPCM7XX_SMB_FIF_CTS_INIT_VAL;
   1013     s->fair_per = NPCM7XX_SMB_FAIR_PER_INIT_VAL;
   1014     s->txf_ctl = NPCM7XX_SMB_TXF_CTL_INIT_VAL;
   1015     s->t_out = NPCM7XX_SMB_T_OUT_INIT_VAL;
   1016     s->txf_sts = NPCM7XX_SMB_TXF_STS_INIT_VAL;
   1017     s->rxf_sts = NPCM7XX_SMB_RXF_STS_INIT_VAL;
   1018     s->rxf_ctl = NPCM7XX_SMB_RXF_CTL_INIT_VAL;
   1019 
   1020     npcm7xx_smbus_clear_buffer(s);
   1021     s->status = NPCM7XX_SMBUS_STATUS_IDLE;
   1022     s->rx_cur = 0;
   1023 }
   1024 
   1025 static void npcm7xx_smbus_hold_reset(Object *obj)
   1026 {
   1027     NPCM7xxSMBusState *s = NPCM7XX_SMBUS(obj);
   1028 
   1029     qemu_irq_lower(s->irq);
   1030 }
   1031 
   1032 static void npcm7xx_smbus_init(Object *obj)
   1033 {
   1034     NPCM7xxSMBusState *s = NPCM7XX_SMBUS(obj);
   1035     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
   1036 
   1037     sysbus_init_irq(sbd, &s->irq);
   1038     memory_region_init_io(&s->iomem, obj, &npcm7xx_smbus_ops, s,
   1039                           "regs", 4 * KiB);
   1040     sysbus_init_mmio(sbd, &s->iomem);
   1041 
   1042     s->bus = i2c_init_bus(DEVICE(s), "i2c-bus");
   1043 }
   1044 
   1045 static const VMStateDescription vmstate_npcm7xx_smbus = {
   1046     .name = "npcm7xx-smbus",
   1047     .version_id = 0,
   1048     .minimum_version_id = 0,
   1049     .fields = (VMStateField[]) {
   1050         VMSTATE_UINT8(sda, NPCM7xxSMBusState),
   1051         VMSTATE_UINT8(st, NPCM7xxSMBusState),
   1052         VMSTATE_UINT8(cst, NPCM7xxSMBusState),
   1053         VMSTATE_UINT8(cst2, NPCM7xxSMBusState),
   1054         VMSTATE_UINT8(cst3, NPCM7xxSMBusState),
   1055         VMSTATE_UINT8(ctl1, NPCM7xxSMBusState),
   1056         VMSTATE_UINT8(ctl2, NPCM7xxSMBusState),
   1057         VMSTATE_UINT8(ctl3, NPCM7xxSMBusState),
   1058         VMSTATE_UINT8(ctl4, NPCM7xxSMBusState),
   1059         VMSTATE_UINT8(ctl5, NPCM7xxSMBusState),
   1060         VMSTATE_UINT8_ARRAY(addr, NPCM7xxSMBusState, NPCM7XX_SMBUS_NR_ADDRS),
   1061         VMSTATE_UINT8(scllt, NPCM7xxSMBusState),
   1062         VMSTATE_UINT8(sclht, NPCM7xxSMBusState),
   1063         VMSTATE_UINT8(fif_ctl, NPCM7xxSMBusState),
   1064         VMSTATE_UINT8(fif_cts, NPCM7xxSMBusState),
   1065         VMSTATE_UINT8(fair_per, NPCM7xxSMBusState),
   1066         VMSTATE_UINT8(txf_ctl, NPCM7xxSMBusState),
   1067         VMSTATE_UINT8(t_out, NPCM7xxSMBusState),
   1068         VMSTATE_UINT8(txf_sts, NPCM7xxSMBusState),
   1069         VMSTATE_UINT8(rxf_sts, NPCM7xxSMBusState),
   1070         VMSTATE_UINT8(rxf_ctl, NPCM7xxSMBusState),
   1071         VMSTATE_UINT8_ARRAY(rx_fifo, NPCM7xxSMBusState,
   1072                             NPCM7XX_SMBUS_FIFO_SIZE),
   1073         VMSTATE_UINT8(rx_cur, NPCM7xxSMBusState),
   1074         VMSTATE_END_OF_LIST(),
   1075     },
   1076 };
   1077 
   1078 static void npcm7xx_smbus_class_init(ObjectClass *klass, void *data)
   1079 {
   1080     ResettableClass *rc = RESETTABLE_CLASS(klass);
   1081     DeviceClass *dc = DEVICE_CLASS(klass);
   1082 
   1083     dc->desc = "NPCM7xx System Management Bus";
   1084     dc->vmsd = &vmstate_npcm7xx_smbus;
   1085     rc->phases.enter = npcm7xx_smbus_enter_reset;
   1086     rc->phases.hold = npcm7xx_smbus_hold_reset;
   1087 }
   1088 
   1089 static const TypeInfo npcm7xx_smbus_types[] = {
   1090     {
   1091         .name = TYPE_NPCM7XX_SMBUS,
   1092         .parent = TYPE_SYS_BUS_DEVICE,
   1093         .instance_size = sizeof(NPCM7xxSMBusState),
   1094         .class_init = npcm7xx_smbus_class_init,
   1095         .instance_init = npcm7xx_smbus_init,
   1096     },
   1097 };
   1098 DEFINE_TYPES(npcm7xx_smbus_types);