cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

msf2-emac.c (17729B)


      1/*
      2 * QEMU model of the Smartfusion2 Ethernet MAC.
      3 *
      4 * Copyright (c) 2020 Subbaraya Sundeep <sundeep.lkml@gmail.com>.
      5 *
      6 * Permission is hereby granted, free of charge, to any person obtaining a copy
      7 * of this software and associated documentation files (the "Software"), to deal
      8 * in the Software without restriction, including without limitation the rights
      9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10 * copies of the Software, and to permit persons to whom the Software is
     11 * furnished to do so, subject to the following conditions:
     12 *
     13 * The above copyright notice and this permission notice shall be included in
     14 * all copies or substantial portions of the Software.
     15 *
     16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     22 * THE SOFTWARE.
     23 *
     24 * Refer to section Ethernet MAC in the document:
     25 * UG0331: SmartFusion2 Microcontroller Subsystem User Guide
     26 * Datasheet URL:
     27 * https://www.microsemi.com/document-portal/cat_view/56661-internal-documents/
     28 * 56758-soc?lang=en&limit=20&limitstart=220
     29 */
     30
     31#include "qemu/osdep.h"
     32#include "qemu-common.h"
     33#include "qemu/log.h"
     34#include "qapi/error.h"
     35#include "hw/registerfields.h"
     36#include "hw/net/msf2-emac.h"
     37#include "hw/net/mii.h"
     38#include "hw/irq.h"
     39#include "hw/qdev-properties.h"
     40#include "migration/vmstate.h"
     41
     42REG32(CFG1, 0x0)
     43    FIELD(CFG1, RESET, 31, 1)
     44    FIELD(CFG1, RX_EN, 2, 1)
     45    FIELD(CFG1, TX_EN, 0, 1)
     46    FIELD(CFG1, LB_EN, 8, 1)
     47REG32(CFG2, 0x4)
     48REG32(IFG, 0x8)
     49REG32(HALF_DUPLEX, 0xc)
     50REG32(MAX_FRAME_LENGTH, 0x10)
     51REG32(MII_CMD, 0x24)
     52    FIELD(MII_CMD, READ, 0, 1)
     53REG32(MII_ADDR, 0x28)
     54    FIELD(MII_ADDR, REGADDR, 0, 5)
     55    FIELD(MII_ADDR, PHYADDR, 8, 5)
     56REG32(MII_CTL, 0x2c)
     57REG32(MII_STS, 0x30)
     58REG32(STA1, 0x40)
     59REG32(STA2, 0x44)
     60REG32(FIFO_CFG0, 0x48)
     61REG32(FIFO_CFG4, 0x58)
     62    FIELD(FIFO_CFG4, BCAST, 9, 1)
     63    FIELD(FIFO_CFG4, MCAST, 8, 1)
     64REG32(FIFO_CFG5, 0x5C)
     65    FIELD(FIFO_CFG5, BCAST, 9, 1)
     66    FIELD(FIFO_CFG5, MCAST, 8, 1)
     67REG32(DMA_TX_CTL, 0x180)
     68    FIELD(DMA_TX_CTL, EN, 0, 1)
     69REG32(DMA_TX_DESC, 0x184)
     70REG32(DMA_TX_STATUS, 0x188)
     71    FIELD(DMA_TX_STATUS, PKTCNT, 16, 8)
     72    FIELD(DMA_TX_STATUS, UNDERRUN, 1, 1)
     73    FIELD(DMA_TX_STATUS, PKT_SENT, 0, 1)
     74REG32(DMA_RX_CTL, 0x18c)
     75    FIELD(DMA_RX_CTL, EN, 0, 1)
     76REG32(DMA_RX_DESC, 0x190)
     77REG32(DMA_RX_STATUS, 0x194)
     78    FIELD(DMA_RX_STATUS, PKTCNT, 16, 8)
     79    FIELD(DMA_RX_STATUS, OVERFLOW, 2, 1)
     80    FIELD(DMA_RX_STATUS, PKT_RCVD, 0, 1)
     81REG32(DMA_IRQ_MASK, 0x198)
     82REG32(DMA_IRQ, 0x19c)
     83
     84#define EMPTY_MASK              (1 << 31)
     85#define PKT_SIZE                0x7FF
     86#define PHYADDR                 0x1
     87#define MAX_PKT_SIZE            2048
     88
     89typedef struct {
     90    uint32_t pktaddr;
     91    uint32_t pktsize;
     92    uint32_t next;
     93} EmacDesc;
     94
     95static uint32_t emac_get_isr(MSF2EmacState *s)
     96{
     97    uint32_t ier = s->regs[R_DMA_IRQ_MASK];
     98    uint32_t tx = s->regs[R_DMA_TX_STATUS] & 0xF;
     99    uint32_t rx = s->regs[R_DMA_RX_STATUS] & 0xF;
    100    uint32_t isr = (rx << 4) | tx;
    101
    102    s->regs[R_DMA_IRQ] = ier & isr;
    103    return s->regs[R_DMA_IRQ];
    104}
    105
    106static void emac_update_irq(MSF2EmacState *s)
    107{
    108    bool intr = emac_get_isr(s);
    109
    110    qemu_set_irq(s->irq, intr);
    111}
    112
    113static void emac_load_desc(MSF2EmacState *s, EmacDesc *d, hwaddr desc)
    114{
    115    address_space_read(&s->dma_as, desc, MEMTXATTRS_UNSPECIFIED, d, sizeof *d);
    116    /* Convert from LE into host endianness. */
    117    d->pktaddr = le32_to_cpu(d->pktaddr);
    118    d->pktsize = le32_to_cpu(d->pktsize);
    119    d->next = le32_to_cpu(d->next);
    120}
    121
    122static void emac_store_desc(MSF2EmacState *s, EmacDesc *d, hwaddr desc)
    123{
    124    /* Convert from host endianness into LE. */
    125    d->pktaddr = cpu_to_le32(d->pktaddr);
    126    d->pktsize = cpu_to_le32(d->pktsize);
    127    d->next = cpu_to_le32(d->next);
    128
    129    address_space_write(&s->dma_as, desc, MEMTXATTRS_UNSPECIFIED, d, sizeof *d);
    130}
    131
    132static void msf2_dma_tx(MSF2EmacState *s)
    133{
    134    NetClientState *nc = qemu_get_queue(s->nic);
    135    hwaddr desc = s->regs[R_DMA_TX_DESC];
    136    uint8_t buf[MAX_PKT_SIZE];
    137    EmacDesc d;
    138    int size;
    139    uint8_t pktcnt;
    140    uint32_t status;
    141
    142    if (!(s->regs[R_CFG1] & R_CFG1_TX_EN_MASK)) {
    143        return;
    144    }
    145
    146    while (1) {
    147        emac_load_desc(s, &d, desc);
    148        if (d.pktsize & EMPTY_MASK) {
    149            break;
    150        }
    151        size = d.pktsize & PKT_SIZE;
    152        address_space_read(&s->dma_as, d.pktaddr, MEMTXATTRS_UNSPECIFIED,
    153                           buf, size);
    154        /*
    155         * This is very basic way to send packets. Ideally there should be
    156         * a FIFO and packets should be sent out from FIFO only when
    157         * R_CFG1 bit 0 is set.
    158         */
    159        if (s->regs[R_CFG1] & R_CFG1_LB_EN_MASK) {
    160            qemu_receive_packet(nc, buf, size);
    161        } else {
    162            qemu_send_packet(nc, buf, size);
    163        }
    164        d.pktsize |= EMPTY_MASK;
    165        emac_store_desc(s, &d, desc);
    166        /* update sent packets count */
    167        status = s->regs[R_DMA_TX_STATUS];
    168        pktcnt = FIELD_EX32(status, DMA_TX_STATUS, PKTCNT);
    169        pktcnt++;
    170        s->regs[R_DMA_TX_STATUS] = FIELD_DP32(status, DMA_TX_STATUS,
    171                                              PKTCNT, pktcnt);
    172        s->regs[R_DMA_TX_STATUS] |= R_DMA_TX_STATUS_PKT_SENT_MASK;
    173        desc = d.next;
    174    }
    175    s->regs[R_DMA_TX_STATUS] |= R_DMA_TX_STATUS_UNDERRUN_MASK;
    176    s->regs[R_DMA_TX_CTL] &= ~R_DMA_TX_CTL_EN_MASK;
    177}
    178
    179static void msf2_phy_update_link(MSF2EmacState *s)
    180{
    181    /* Autonegotiation status mirrors link status. */
    182    if (qemu_get_queue(s->nic)->link_down) {
    183        s->phy_regs[MII_BMSR] &= ~(MII_BMSR_AN_COMP |
    184                                   MII_BMSR_LINK_ST);
    185    } else {
    186        s->phy_regs[MII_BMSR] |= (MII_BMSR_AN_COMP |
    187                                  MII_BMSR_LINK_ST);
    188    }
    189}
    190
    191static void msf2_phy_reset(MSF2EmacState *s)
    192{
    193    memset(&s->phy_regs[0], 0, sizeof(s->phy_regs));
    194    s->phy_regs[MII_BMCR] = 0x1140;
    195    s->phy_regs[MII_BMSR] = 0x7968;
    196    s->phy_regs[MII_PHYID1] = 0x0022;
    197    s->phy_regs[MII_PHYID2] = 0x1550;
    198    s->phy_regs[MII_ANAR] = 0x01E1;
    199    s->phy_regs[MII_ANLPAR] = 0xCDE1;
    200
    201    msf2_phy_update_link(s);
    202}
    203
    204static void write_to_phy(MSF2EmacState *s)
    205{
    206    uint8_t reg_addr = s->regs[R_MII_ADDR] & R_MII_ADDR_REGADDR_MASK;
    207    uint8_t phy_addr = (s->regs[R_MII_ADDR] >> R_MII_ADDR_PHYADDR_SHIFT) &
    208                       R_MII_ADDR_REGADDR_MASK;
    209    uint16_t data = s->regs[R_MII_CTL] & 0xFFFF;
    210
    211    if (phy_addr != PHYADDR) {
    212        return;
    213    }
    214
    215    switch (reg_addr) {
    216    case MII_BMCR:
    217        if (data & MII_BMCR_RESET) {
    218            /* Phy reset */
    219            msf2_phy_reset(s);
    220            data &= ~MII_BMCR_RESET;
    221        }
    222        if (data & MII_BMCR_AUTOEN) {
    223            /* Complete autonegotiation immediately */
    224            data &= ~MII_BMCR_AUTOEN;
    225            s->phy_regs[MII_BMSR] |= MII_BMSR_AN_COMP;
    226        }
    227        break;
    228    }
    229
    230    s->phy_regs[reg_addr] = data;
    231}
    232
    233static uint16_t read_from_phy(MSF2EmacState *s)
    234{
    235    uint8_t reg_addr = s->regs[R_MII_ADDR] & R_MII_ADDR_REGADDR_MASK;
    236    uint8_t phy_addr = (s->regs[R_MII_ADDR] >> R_MII_ADDR_PHYADDR_SHIFT) &
    237                       R_MII_ADDR_REGADDR_MASK;
    238
    239    if (phy_addr == PHYADDR) {
    240        return s->phy_regs[reg_addr];
    241    } else {
    242        return 0xFFFF;
    243    }
    244}
    245
    246static void msf2_emac_do_reset(MSF2EmacState *s)
    247{
    248    memset(&s->regs[0], 0, sizeof(s->regs));
    249    s->regs[R_CFG1] = 0x80000000;
    250    s->regs[R_CFG2] = 0x00007000;
    251    s->regs[R_IFG] = 0x40605060;
    252    s->regs[R_HALF_DUPLEX] = 0x00A1F037;
    253    s->regs[R_MAX_FRAME_LENGTH] = 0x00000600;
    254    s->regs[R_FIFO_CFG5] = 0X3FFFF;
    255
    256    msf2_phy_reset(s);
    257}
    258
    259static uint64_t emac_read(void *opaque, hwaddr addr, unsigned int size)
    260{
    261    MSF2EmacState *s = opaque;
    262    uint32_t r = 0;
    263
    264    addr >>= 2;
    265
    266    switch (addr) {
    267    case R_DMA_IRQ:
    268        r = emac_get_isr(s);
    269        break;
    270    default:
    271        if (addr >= ARRAY_SIZE(s->regs)) {
    272            qemu_log_mask(LOG_GUEST_ERROR,
    273                          "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__,
    274                          addr * 4);
    275            return r;
    276        }
    277        r = s->regs[addr];
    278        break;
    279    }
    280    return r;
    281}
    282
    283static void emac_write(void *opaque, hwaddr addr, uint64_t val64,
    284        unsigned int size)
    285{
    286    MSF2EmacState *s = opaque;
    287    uint32_t value = val64;
    288    uint32_t enreqbits;
    289    uint8_t pktcnt;
    290
    291    addr >>= 2;
    292    switch (addr) {
    293    case R_DMA_TX_CTL:
    294        s->regs[addr] = value;
    295        if (value & R_DMA_TX_CTL_EN_MASK) {
    296            msf2_dma_tx(s);
    297        }
    298        break;
    299    case R_DMA_RX_CTL:
    300        s->regs[addr] = value;
    301        if (value & R_DMA_RX_CTL_EN_MASK) {
    302            s->rx_desc = s->regs[R_DMA_RX_DESC];
    303            qemu_flush_queued_packets(qemu_get_queue(s->nic));
    304        }
    305        break;
    306    case R_CFG1:
    307        s->regs[addr] = value;
    308        if (value & R_CFG1_RESET_MASK) {
    309            msf2_emac_do_reset(s);
    310        }
    311        break;
    312    case R_FIFO_CFG0:
    313       /*
    314        * For our implementation, turning on modules is instantaneous,
    315        * so the states requested via the *ENREQ bits appear in the
    316        * *ENRPLY bits immediately. Also the reset bits to reset PE-MCXMAC
    317        * module are not emulated here since it deals with start of frames,
    318        * inter-packet gap and control frames.
    319        */
    320        enreqbits = extract32(value, 8, 5);
    321        s->regs[addr] = deposit32(value, 16, 5, enreqbits);
    322        break;
    323    case R_DMA_TX_DESC:
    324        if (value & 0x3) {
    325            qemu_log_mask(LOG_GUEST_ERROR, "Tx Descriptor address should be"
    326                          " 32 bit aligned\n");
    327        }
    328        /* Ignore [1:0] bits */
    329        s->regs[addr] = value & ~3;
    330        break;
    331    case R_DMA_RX_DESC:
    332        if (value & 0x3) {
    333            qemu_log_mask(LOG_GUEST_ERROR, "Rx Descriptor address should be"
    334                          " 32 bit aligned\n");
    335        }
    336        /* Ignore [1:0] bits */
    337        s->regs[addr] = value & ~3;
    338        break;
    339    case R_DMA_TX_STATUS:
    340        if (value & R_DMA_TX_STATUS_UNDERRUN_MASK) {
    341            s->regs[addr] &= ~R_DMA_TX_STATUS_UNDERRUN_MASK;
    342        }
    343        if (value & R_DMA_TX_STATUS_PKT_SENT_MASK) {
    344            pktcnt = FIELD_EX32(s->regs[addr], DMA_TX_STATUS, PKTCNT);
    345            pktcnt--;
    346            s->regs[addr] = FIELD_DP32(s->regs[addr], DMA_TX_STATUS,
    347                                       PKTCNT, pktcnt);
    348            if (pktcnt == 0) {
    349                s->regs[addr] &= ~R_DMA_TX_STATUS_PKT_SENT_MASK;
    350            }
    351        }
    352        break;
    353    case R_DMA_RX_STATUS:
    354        if (value & R_DMA_RX_STATUS_OVERFLOW_MASK) {
    355            s->regs[addr] &= ~R_DMA_RX_STATUS_OVERFLOW_MASK;
    356        }
    357        if (value & R_DMA_RX_STATUS_PKT_RCVD_MASK) {
    358            pktcnt = FIELD_EX32(s->regs[addr], DMA_RX_STATUS, PKTCNT);
    359            pktcnt--;
    360            s->regs[addr] = FIELD_DP32(s->regs[addr], DMA_RX_STATUS,
    361                                       PKTCNT, pktcnt);
    362            if (pktcnt == 0) {
    363                s->regs[addr] &= ~R_DMA_RX_STATUS_PKT_RCVD_MASK;
    364            }
    365        }
    366        break;
    367    case R_DMA_IRQ:
    368        break;
    369    case R_MII_CMD:
    370        if (value & R_MII_CMD_READ_MASK) {
    371            s->regs[R_MII_STS] = read_from_phy(s);
    372        }
    373        break;
    374    case R_MII_CTL:
    375        s->regs[addr] = value;
    376        write_to_phy(s);
    377        break;
    378    case R_STA1:
    379        s->regs[addr] = value;
    380       /*
    381        * R_STA1 [31:24] : octet 1 of mac address
    382        * R_STA1 [23:16] : octet 2 of mac address
    383        * R_STA1 [15:8] : octet 3 of mac address
    384        * R_STA1 [7:0] : octet 4 of mac address
    385        */
    386        stl_be_p(s->mac_addr, value);
    387        break;
    388    case R_STA2:
    389        s->regs[addr] = value;
    390       /*
    391        * R_STA2 [31:24] : octet 5 of mac address
    392        * R_STA2 [23:16] : octet 6 of mac address
    393        */
    394        stw_be_p(s->mac_addr + 4, value >> 16);
    395        break;
    396    default:
    397        if (addr >= ARRAY_SIZE(s->regs)) {
    398            qemu_log_mask(LOG_GUEST_ERROR,
    399                          "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__,
    400                          addr * 4);
    401            return;
    402        }
    403        s->regs[addr] = value;
    404        break;
    405    }
    406    emac_update_irq(s);
    407}
    408
    409static const MemoryRegionOps emac_ops = {
    410    .read = emac_read,
    411    .write = emac_write,
    412    .endianness = DEVICE_NATIVE_ENDIAN,
    413    .impl = {
    414        .min_access_size = 4,
    415        .max_access_size = 4
    416    }
    417};
    418
    419static bool emac_can_rx(NetClientState *nc)
    420{
    421    MSF2EmacState *s = qemu_get_nic_opaque(nc);
    422
    423    return (s->regs[R_CFG1] & R_CFG1_RX_EN_MASK) &&
    424           (s->regs[R_DMA_RX_CTL] & R_DMA_RX_CTL_EN_MASK);
    425}
    426
    427static bool addr_filter_ok(MSF2EmacState *s, const uint8_t *buf)
    428{
    429    /* The broadcast MAC address: FF:FF:FF:FF:FF:FF */
    430    const uint8_t broadcast_addr[] = { 0xFF, 0xFF, 0xFF, 0xFF,
    431                                              0xFF, 0xFF };
    432    bool bcast_en = true;
    433    bool mcast_en = true;
    434
    435    if (s->regs[R_FIFO_CFG5] & R_FIFO_CFG5_BCAST_MASK) {
    436        bcast_en = true; /* Broadcast dont care for drop circuitry */
    437    } else if (s->regs[R_FIFO_CFG4] & R_FIFO_CFG4_BCAST_MASK) {
    438        bcast_en = false;
    439    }
    440
    441    if (s->regs[R_FIFO_CFG5] & R_FIFO_CFG5_MCAST_MASK) {
    442        mcast_en = true; /* Multicast dont care for drop circuitry */
    443    } else if (s->regs[R_FIFO_CFG4] & R_FIFO_CFG4_MCAST_MASK) {
    444        mcast_en = false;
    445    }
    446
    447    if (!memcmp(buf, broadcast_addr, sizeof(broadcast_addr))) {
    448        return bcast_en;
    449    }
    450
    451    if (buf[0] & 1) {
    452        return mcast_en;
    453    }
    454
    455    return !memcmp(buf, s->mac_addr, sizeof(s->mac_addr));
    456}
    457
    458static ssize_t emac_rx(NetClientState *nc, const uint8_t *buf, size_t size)
    459{
    460    MSF2EmacState *s = qemu_get_nic_opaque(nc);
    461    EmacDesc d;
    462    uint8_t pktcnt;
    463    uint32_t status;
    464
    465    if (size > (s->regs[R_MAX_FRAME_LENGTH] & 0xFFFF)) {
    466        return size;
    467    }
    468    if (!addr_filter_ok(s, buf)) {
    469        return size;
    470    }
    471
    472    emac_load_desc(s, &d, s->rx_desc);
    473
    474    if (d.pktsize & EMPTY_MASK) {
    475        address_space_write(&s->dma_as, d.pktaddr, MEMTXATTRS_UNSPECIFIED,
    476                            buf, size & PKT_SIZE);
    477        d.pktsize = size & PKT_SIZE;
    478        emac_store_desc(s, &d, s->rx_desc);
    479        /* update received packets count */
    480        status = s->regs[R_DMA_RX_STATUS];
    481        pktcnt = FIELD_EX32(status, DMA_RX_STATUS, PKTCNT);
    482        pktcnt++;
    483        s->regs[R_DMA_RX_STATUS] = FIELD_DP32(status, DMA_RX_STATUS,
    484                                              PKTCNT, pktcnt);
    485        s->regs[R_DMA_RX_STATUS] |= R_DMA_RX_STATUS_PKT_RCVD_MASK;
    486        s->rx_desc = d.next;
    487    } else {
    488        s->regs[R_DMA_RX_CTL] &= ~R_DMA_RX_CTL_EN_MASK;
    489        s->regs[R_DMA_RX_STATUS] |= R_DMA_RX_STATUS_OVERFLOW_MASK;
    490    }
    491    emac_update_irq(s);
    492    return size;
    493}
    494
    495static void msf2_emac_reset(DeviceState *dev)
    496{
    497    MSF2EmacState *s = MSS_EMAC(dev);
    498
    499    msf2_emac_do_reset(s);
    500}
    501
    502static void emac_set_link(NetClientState *nc)
    503{
    504    MSF2EmacState *s = qemu_get_nic_opaque(nc);
    505
    506    msf2_phy_update_link(s);
    507}
    508
    509static NetClientInfo net_msf2_emac_info = {
    510    .type = NET_CLIENT_DRIVER_NIC,
    511    .size = sizeof(NICState),
    512    .can_receive = emac_can_rx,
    513    .receive = emac_rx,
    514    .link_status_changed = emac_set_link,
    515};
    516
    517static void msf2_emac_realize(DeviceState *dev, Error **errp)
    518{
    519    MSF2EmacState *s = MSS_EMAC(dev);
    520
    521    if (!s->dma_mr) {
    522        error_setg(errp, "MSS_EMAC 'ahb-bus' link not set");
    523        return;
    524    }
    525
    526    address_space_init(&s->dma_as, s->dma_mr, "emac-ahb");
    527
    528    qemu_macaddr_default_if_unset(&s->conf.macaddr);
    529    s->nic = qemu_new_nic(&net_msf2_emac_info, &s->conf,
    530                          object_get_typename(OBJECT(dev)), dev->id, s);
    531    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
    532}
    533
    534static void msf2_emac_init(Object *obj)
    535{
    536    MSF2EmacState *s = MSS_EMAC(obj);
    537
    538    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
    539
    540    memory_region_init_io(&s->mmio, obj, &emac_ops, s,
    541                          "msf2-emac", R_MAX * 4);
    542    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
    543}
    544
    545static Property msf2_emac_properties[] = {
    546    DEFINE_PROP_LINK("ahb-bus", MSF2EmacState, dma_mr,
    547                     TYPE_MEMORY_REGION, MemoryRegion *),
    548    DEFINE_NIC_PROPERTIES(MSF2EmacState, conf),
    549    DEFINE_PROP_END_OF_LIST(),
    550};
    551
    552static const VMStateDescription vmstate_msf2_emac = {
    553    .name = TYPE_MSS_EMAC,
    554    .version_id = 1,
    555    .minimum_version_id = 1,
    556    .fields = (VMStateField[]) {
    557        VMSTATE_UINT8_ARRAY(mac_addr, MSF2EmacState, ETH_ALEN),
    558        VMSTATE_UINT32(rx_desc, MSF2EmacState),
    559        VMSTATE_UINT16_ARRAY(phy_regs, MSF2EmacState, PHY_MAX_REGS),
    560        VMSTATE_UINT32_ARRAY(regs, MSF2EmacState, R_MAX),
    561        VMSTATE_END_OF_LIST()
    562    }
    563};
    564
    565static void msf2_emac_class_init(ObjectClass *klass, void *data)
    566{
    567    DeviceClass *dc = DEVICE_CLASS(klass);
    568
    569    dc->realize = msf2_emac_realize;
    570    dc->reset = msf2_emac_reset;
    571    dc->vmsd = &vmstate_msf2_emac;
    572    device_class_set_props(dc, msf2_emac_properties);
    573}
    574
    575static const TypeInfo msf2_emac_info = {
    576    .name          = TYPE_MSS_EMAC,
    577    .parent        = TYPE_SYS_BUS_DEVICE,
    578    .instance_size = sizeof(MSF2EmacState),
    579    .instance_init = msf2_emac_init,
    580    .class_init    = msf2_emac_class_init,
    581};
    582
    583static void msf2_emac_register_types(void)
    584{
    585    type_register_static(&msf2_emac_info);
    586}
    587
    588type_init(msf2_emac_register_types)