qemu

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

shpc.c (25808B)


      1 #include "qemu/osdep.h"
      2 #include "qapi/error.h"
      3 #include "qemu/host-utils.h"
      4 #include "qemu/range.h"
      5 #include "qemu/error-report.h"
      6 #include "hw/pci/shpc.h"
      7 #include "migration/qemu-file-types.h"
      8 #include "hw/pci/pci.h"
      9 #include "hw/pci/pci_bus.h"
     10 #include "hw/pci/msi.h"
     11 
     12 /* TODO: model power only and disabled slot states. */
     13 /* TODO: handle SERR and wakeups */
     14 /* TODO: consider enabling 66MHz support */
     15 
     16 /* TODO: remove fully only on state DISABLED and LED off.
     17  * track state to properly record this. */
     18 
     19 /* SHPC Working Register Set */
     20 #define SHPC_BASE_OFFSET  0x00 /* 4 bytes */
     21 #define SHPC_SLOTS_33     0x04 /* 4 bytes. Also encodes PCI-X slots. */
     22 #define SHPC_SLOTS_66     0x08 /* 4 bytes. */
     23 #define SHPC_NSLOTS       0x0C /* 1 byte */
     24 #define SHPC_FIRST_DEV    0x0D /* 1 byte */
     25 #define SHPC_PHYS_SLOT    0x0E /* 2 byte */
     26 #define SHPC_PHYS_NUM_MAX 0x7ff
     27 #define SHPC_PHYS_NUM_UP  0x2000
     28 #define SHPC_PHYS_MRL     0x4000
     29 #define SHPC_PHYS_BUTTON  0x8000
     30 #define SHPC_SEC_BUS      0x10 /* 2 bytes */
     31 #define SHPC_SEC_BUS_33   0x0
     32 #define SHPC_SEC_BUS_66   0x1 /* Unused */
     33 #define SHPC_SEC_BUS_MASK 0x7
     34 #define SHPC_MSI_CTL      0x12 /* 1 byte */
     35 #define SHPC_PROG_IFC     0x13 /* 1 byte */
     36 #define SHPC_PROG_IFC_1_0 0x1
     37 #define SHPC_CMD_CODE     0x14 /* 1 byte */
     38 #define SHPC_CMD_TRGT     0x15 /* 1 byte */
     39 #define SHPC_CMD_TRGT_MIN 0x1
     40 #define SHPC_CMD_TRGT_MAX 0x1f
     41 #define SHPC_CMD_STATUS   0x16 /* 2 bytes */
     42 #define SHPC_CMD_STATUS_BUSY          0x1
     43 #define SHPC_CMD_STATUS_MRL_OPEN      0x2
     44 #define SHPC_CMD_STATUS_INVALID_CMD   0x4
     45 #define SHPC_CMD_STATUS_INVALID_MODE  0x8
     46 #define SHPC_INT_LOCATOR  0x18 /* 4 bytes */
     47 #define SHPC_INT_COMMAND  0x1
     48 #define SHPC_SERR_LOCATOR 0x1C /* 4 bytes */
     49 #define SHPC_SERR_INT     0x20 /* 4 bytes */
     50 #define SHPC_INT_DIS      0x1
     51 #define SHPC_SERR_DIS     0x2
     52 #define SHPC_CMD_INT_DIS  0x4
     53 #define SHPC_ARB_SERR_DIS 0x8
     54 #define SHPC_CMD_DETECTED 0x10000
     55 #define SHPC_ARB_DETECTED 0x20000
     56  /* 4 bytes * slot # (start from 0) */
     57 #define SHPC_SLOT_REG(s)         (0x24 + (s) * 4)
     58  /* 2 bytes */
     59 #define SHPC_SLOT_STATUS(s)       (0x0 + SHPC_SLOT_REG(s))
     60 
     61 /* Same slot state masks are used for command and status registers */
     62 #define SHPC_SLOT_STATE_MASK     0x03
     63 #define SHPC_SLOT_STATE_SHIFT \
     64     ctz32(SHPC_SLOT_STATE_MASK)
     65 
     66 #define SHPC_STATE_NO       0x0
     67 #define SHPC_STATE_PWRONLY  0x1
     68 #define SHPC_STATE_ENABLED  0x2
     69 #define SHPC_STATE_DISABLED 0x3
     70 
     71 #define SHPC_SLOT_PWR_LED_MASK   0xC
     72 #define SHPC_SLOT_PWR_LED_SHIFT \
     73     ctz32(SHPC_SLOT_PWR_LED_MASK)
     74 #define SHPC_SLOT_ATTN_LED_MASK  0x30
     75 #define SHPC_SLOT_ATTN_LED_SHIFT \
     76     ctz32(SHPC_SLOT_ATTN_LED_MASK)
     77 
     78 #define SHPC_LED_NO     0x0
     79 #define SHPC_LED_ON     0x1
     80 #define SHPC_LED_BLINK  0x2
     81 #define SHPC_LED_OFF    0x3
     82 
     83 #define SHPC_SLOT_STATUS_PWR_FAULT      0x40
     84 #define SHPC_SLOT_STATUS_BUTTON         0x80
     85 #define SHPC_SLOT_STATUS_MRL_OPEN       0x100
     86 #define SHPC_SLOT_STATUS_66             0x200
     87 #define SHPC_SLOT_STATUS_PRSNT_MASK     0xC00
     88 #define SHPC_SLOT_STATUS_PRSNT_EMPTY    0x3
     89 #define SHPC_SLOT_STATUS_PRSNT_25W      0x1
     90 #define SHPC_SLOT_STATUS_PRSNT_15W      0x2
     91 #define SHPC_SLOT_STATUS_PRSNT_7_5W     0x0
     92 
     93 #define SHPC_SLOT_STATUS_PRSNT_PCIX     0x3000
     94 
     95 
     96  /* 1 byte */
     97 #define SHPC_SLOT_EVENT_LATCH(s)        (0x2 + SHPC_SLOT_REG(s))
     98  /* 1 byte */
     99 #define SHPC_SLOT_EVENT_SERR_INT_DIS(d, s) (0x3 + SHPC_SLOT_REG(s))
    100 #define SHPC_SLOT_EVENT_PRESENCE        0x01
    101 #define SHPC_SLOT_EVENT_ISOLATED_FAULT  0x02
    102 #define SHPC_SLOT_EVENT_BUTTON          0x04
    103 #define SHPC_SLOT_EVENT_MRL             0x08
    104 #define SHPC_SLOT_EVENT_CONNECTED_FAULT 0x10
    105 /* Bits below are used for Serr/Int disable only */
    106 #define SHPC_SLOT_EVENT_MRL_SERR_DIS    0x20
    107 #define SHPC_SLOT_EVENT_CONNECTED_FAULT_SERR_DIS 0x40
    108 
    109 #define SHPC_MIN_SLOTS        1
    110 #define SHPC_MAX_SLOTS        31
    111 #define SHPC_SIZEOF(d)    SHPC_SLOT_REG((d)->shpc->nslots)
    112 
    113 /* SHPC Slot identifiers */
    114 
    115 /* Hotplug supported at 31 slots out of the total 32.  We reserve slot 0,
    116    and give the rest of them physical *and* pci numbers starting from 1, so
    117    they match logical numbers.  Note: this means that multiple slots must have
    118    different chassis number values, to make chassis+physical slot unique.
    119    TODO: make this configurable? */
    120 #define SHPC_IDX_TO_LOGICAL(slot) ((slot) + 1)
    121 #define SHPC_LOGICAL_TO_IDX(target) ((target) - 1)
    122 #define SHPC_IDX_TO_PCI(slot) ((slot) + 1)
    123 #define SHPC_PCI_TO_IDX(pci_slot) ((pci_slot) - 1)
    124 #define SHPC_IDX_TO_PHYSICAL(slot) ((slot) + 1)
    125 
    126 static uint16_t shpc_get_status(SHPCDevice *shpc, int slot, uint16_t msk)
    127 {
    128     uint8_t *status = shpc->config + SHPC_SLOT_STATUS(slot);
    129     return (pci_get_word(status) & msk) >> ctz32(msk);
    130 }
    131 
    132 static void shpc_set_status(SHPCDevice *shpc,
    133                             int slot, uint8_t value, uint16_t msk)
    134 {
    135     uint8_t *status = shpc->config + SHPC_SLOT_STATUS(slot);
    136     pci_word_test_and_clear_mask(status, msk);
    137     pci_word_test_and_set_mask(status, value << ctz32(msk));
    138 }
    139 
    140 static void shpc_interrupt_update(PCIDevice *d)
    141 {
    142     SHPCDevice *shpc = d->shpc;
    143     int slot;
    144     int level = 0;
    145     uint32_t serr_int;
    146     uint32_t int_locator = 0;
    147 
    148     /* Update interrupt locator register */
    149     for (slot = 0; slot < shpc->nslots; ++slot) {
    150         uint8_t event = shpc->config[SHPC_SLOT_EVENT_LATCH(slot)];
    151         uint8_t disable = shpc->config[SHPC_SLOT_EVENT_SERR_INT_DIS(d, slot)];
    152         uint32_t mask = 1U << SHPC_IDX_TO_LOGICAL(slot);
    153         if (event & ~disable) {
    154             int_locator |= mask;
    155         }
    156     }
    157     serr_int = pci_get_long(shpc->config + SHPC_SERR_INT);
    158     if ((serr_int & SHPC_CMD_DETECTED) && !(serr_int & SHPC_CMD_INT_DIS)) {
    159         int_locator |= SHPC_INT_COMMAND;
    160     }
    161     pci_set_long(shpc->config + SHPC_INT_LOCATOR, int_locator);
    162     level = (!(serr_int & SHPC_INT_DIS) && int_locator) ? 1 : 0;
    163     if (msi_enabled(d) && shpc->msi_requested != level)
    164         msi_notify(d, 0);
    165     else
    166         pci_set_irq(d, level);
    167     shpc->msi_requested = level;
    168 }
    169 
    170 static void shpc_set_sec_bus_speed(SHPCDevice *shpc, uint8_t speed)
    171 {
    172     switch (speed) {
    173     case SHPC_SEC_BUS_33:
    174         shpc->config[SHPC_SEC_BUS] &= ~SHPC_SEC_BUS_MASK;
    175         shpc->config[SHPC_SEC_BUS] |= speed;
    176         break;
    177     default:
    178         pci_word_test_and_set_mask(shpc->config + SHPC_CMD_STATUS,
    179                                    SHPC_CMD_STATUS_INVALID_MODE);
    180     }
    181 }
    182 
    183 void shpc_reset(PCIDevice *d)
    184 {
    185     SHPCDevice *shpc = d->shpc;
    186     int nslots = shpc->nslots;
    187     int i;
    188     memset(shpc->config, 0, SHPC_SIZEOF(d));
    189     pci_set_byte(shpc->config + SHPC_NSLOTS, nslots);
    190     pci_set_long(shpc->config + SHPC_SLOTS_33, nslots);
    191     pci_set_long(shpc->config + SHPC_SLOTS_66, 0);
    192     pci_set_byte(shpc->config + SHPC_FIRST_DEV, SHPC_IDX_TO_PCI(0));
    193     pci_set_word(shpc->config + SHPC_PHYS_SLOT,
    194                  SHPC_IDX_TO_PHYSICAL(0) |
    195                  SHPC_PHYS_NUM_UP |
    196                  SHPC_PHYS_MRL |
    197                  SHPC_PHYS_BUTTON);
    198     pci_set_long(shpc->config + SHPC_SERR_INT, SHPC_INT_DIS |
    199                  SHPC_SERR_DIS |
    200                  SHPC_CMD_INT_DIS |
    201                  SHPC_ARB_SERR_DIS);
    202     pci_set_byte(shpc->config + SHPC_PROG_IFC, SHPC_PROG_IFC_1_0);
    203     pci_set_word(shpc->config + SHPC_SEC_BUS, SHPC_SEC_BUS_33);
    204     for (i = 0; i < shpc->nslots; ++i) {
    205         pci_set_byte(shpc->config + SHPC_SLOT_EVENT_SERR_INT_DIS(d, i),
    206                      SHPC_SLOT_EVENT_PRESENCE |
    207                      SHPC_SLOT_EVENT_ISOLATED_FAULT |
    208                      SHPC_SLOT_EVENT_BUTTON |
    209                      SHPC_SLOT_EVENT_MRL |
    210                      SHPC_SLOT_EVENT_CONNECTED_FAULT |
    211                      SHPC_SLOT_EVENT_MRL_SERR_DIS |
    212                      SHPC_SLOT_EVENT_CONNECTED_FAULT_SERR_DIS);
    213         if (shpc->sec_bus->devices[PCI_DEVFN(SHPC_IDX_TO_PCI(i), 0)]) {
    214             shpc_set_status(shpc, i, SHPC_STATE_ENABLED, SHPC_SLOT_STATE_MASK);
    215             shpc_set_status(shpc, i, 0, SHPC_SLOT_STATUS_MRL_OPEN);
    216             shpc_set_status(shpc, i, SHPC_SLOT_STATUS_PRSNT_7_5W,
    217                             SHPC_SLOT_STATUS_PRSNT_MASK);
    218             shpc_set_status(shpc, i, SHPC_LED_ON, SHPC_SLOT_PWR_LED_MASK);
    219         } else {
    220             shpc_set_status(shpc, i, SHPC_STATE_DISABLED, SHPC_SLOT_STATE_MASK);
    221             shpc_set_status(shpc, i, 1, SHPC_SLOT_STATUS_MRL_OPEN);
    222             shpc_set_status(shpc, i, SHPC_SLOT_STATUS_PRSNT_EMPTY,
    223                             SHPC_SLOT_STATUS_PRSNT_MASK);
    224             shpc_set_status(shpc, i, SHPC_LED_OFF, SHPC_SLOT_PWR_LED_MASK);
    225         }
    226         shpc_set_status(shpc, i, 0, SHPC_SLOT_STATUS_66);
    227     }
    228     shpc_set_sec_bus_speed(shpc, SHPC_SEC_BUS_33);
    229     shpc->msi_requested = 0;
    230     shpc_interrupt_update(d);
    231 }
    232 
    233 static void shpc_invalid_command(SHPCDevice *shpc)
    234 {
    235     pci_word_test_and_set_mask(shpc->config + SHPC_CMD_STATUS,
    236                                SHPC_CMD_STATUS_INVALID_CMD);
    237 }
    238 
    239 static void shpc_free_devices_in_slot(SHPCDevice *shpc, int slot)
    240 {
    241     HotplugHandler *hotplug_ctrl;
    242     int devfn;
    243     int pci_slot = SHPC_IDX_TO_PCI(slot);
    244     for (devfn = PCI_DEVFN(pci_slot, 0);
    245          devfn <= PCI_DEVFN(pci_slot, PCI_FUNC_MAX - 1);
    246          ++devfn) {
    247         PCIDevice *affected_dev = shpc->sec_bus->devices[devfn];
    248         if (affected_dev) {
    249             hotplug_ctrl = qdev_get_hotplug_handler(DEVICE(affected_dev));
    250             hotplug_handler_unplug(hotplug_ctrl, DEVICE(affected_dev),
    251                                    &error_abort);
    252             object_unparent(OBJECT(affected_dev));
    253         }
    254     }
    255 }
    256 
    257 static void shpc_slot_command(SHPCDevice *shpc, uint8_t target,
    258                               uint8_t state, uint8_t power, uint8_t attn)
    259 {
    260     uint8_t current_state;
    261     int slot = SHPC_LOGICAL_TO_IDX(target);
    262     if (target < SHPC_CMD_TRGT_MIN || slot >= shpc->nslots) {
    263         shpc_invalid_command(shpc);
    264         return;
    265     }
    266     current_state = shpc_get_status(shpc, slot, SHPC_SLOT_STATE_MASK);
    267     if (current_state == SHPC_STATE_ENABLED && state == SHPC_STATE_PWRONLY) {
    268         shpc_invalid_command(shpc);
    269         return;
    270     }
    271 
    272     switch (power) {
    273     case SHPC_LED_NO:
    274         break;
    275     default:
    276         /* TODO: send event to monitor */
    277         shpc_set_status(shpc, slot, power, SHPC_SLOT_PWR_LED_MASK);
    278     }
    279     switch (attn) {
    280     case SHPC_LED_NO:
    281         break;
    282     default:
    283         /* TODO: send event to monitor */
    284         shpc_set_status(shpc, slot, attn, SHPC_SLOT_ATTN_LED_MASK);
    285     }
    286 
    287     if ((current_state == SHPC_STATE_DISABLED && state == SHPC_STATE_PWRONLY) ||
    288         (current_state == SHPC_STATE_DISABLED && state == SHPC_STATE_ENABLED)) {
    289         shpc_set_status(shpc, slot, state, SHPC_SLOT_STATE_MASK);
    290     } else if ((current_state == SHPC_STATE_ENABLED ||
    291                 current_state == SHPC_STATE_PWRONLY) &&
    292                state == SHPC_STATE_DISABLED) {
    293         shpc_set_status(shpc, slot, state, SHPC_SLOT_STATE_MASK);
    294         power = shpc_get_status(shpc, slot, SHPC_SLOT_PWR_LED_MASK);
    295         /* TODO: track what monitor requested. */
    296         /* Look at LED to figure out whether it's ok to remove the device. */
    297         if (power == SHPC_LED_OFF) {
    298             shpc_free_devices_in_slot(shpc, slot);
    299             shpc_set_status(shpc, slot, 1, SHPC_SLOT_STATUS_MRL_OPEN);
    300             shpc_set_status(shpc, slot, SHPC_SLOT_STATUS_PRSNT_EMPTY,
    301                             SHPC_SLOT_STATUS_PRSNT_MASK);
    302             shpc->config[SHPC_SLOT_EVENT_LATCH(slot)] |=
    303                 SHPC_SLOT_EVENT_MRL |
    304                 SHPC_SLOT_EVENT_PRESENCE;
    305         }
    306     }
    307 }
    308 
    309 static void shpc_command(SHPCDevice *shpc)
    310 {
    311     uint8_t code = pci_get_byte(shpc->config + SHPC_CMD_CODE);
    312     uint8_t speed;
    313     uint8_t target;
    314     uint8_t attn;
    315     uint8_t power;
    316     uint8_t state;
    317     int i;
    318 
    319     /* Clear status from the previous command. */
    320     pci_word_test_and_clear_mask(shpc->config + SHPC_CMD_STATUS,
    321                                  SHPC_CMD_STATUS_BUSY |
    322                                  SHPC_CMD_STATUS_MRL_OPEN |
    323                                  SHPC_CMD_STATUS_INVALID_CMD |
    324                                  SHPC_CMD_STATUS_INVALID_MODE);
    325     switch (code) {
    326     case 0x00 ... 0x3f:
    327         target = shpc->config[SHPC_CMD_TRGT] & SHPC_CMD_TRGT_MAX;
    328         state = (code & SHPC_SLOT_STATE_MASK) >> SHPC_SLOT_STATE_SHIFT;
    329         power = (code & SHPC_SLOT_PWR_LED_MASK) >> SHPC_SLOT_PWR_LED_SHIFT;
    330         attn = (code & SHPC_SLOT_ATTN_LED_MASK) >> SHPC_SLOT_ATTN_LED_SHIFT;
    331         shpc_slot_command(shpc, target, state, power, attn);
    332         break;
    333     case 0x40 ... 0x47:
    334         speed = code & SHPC_SEC_BUS_MASK;
    335         shpc_set_sec_bus_speed(shpc, speed);
    336         break;
    337     case 0x48:
    338         /* Power only all slots */
    339         /* first verify no slots are enabled */
    340         for (i = 0; i < shpc->nslots; ++i) {
    341             state = shpc_get_status(shpc, i, SHPC_SLOT_STATE_MASK);
    342             if (state == SHPC_STATE_ENABLED) {
    343                 shpc_invalid_command(shpc);
    344                 goto done;
    345             }
    346         }
    347         for (i = 0; i < shpc->nslots; ++i) {
    348             if (!(shpc_get_status(shpc, i, SHPC_SLOT_STATUS_MRL_OPEN))) {
    349                 shpc_slot_command(shpc, i + SHPC_CMD_TRGT_MIN,
    350                                   SHPC_STATE_PWRONLY, SHPC_LED_ON, SHPC_LED_NO);
    351             } else {
    352                 shpc_slot_command(shpc, i + SHPC_CMD_TRGT_MIN,
    353                                   SHPC_STATE_NO, SHPC_LED_OFF, SHPC_LED_NO);
    354             }
    355         }
    356         break;
    357     case 0x49:
    358         /* Enable all slots */
    359         /* TODO: Spec says this shall fail if some are already enabled.
    360          * This doesn't make sense - why not? a spec bug? */
    361         for (i = 0; i < shpc->nslots; ++i) {
    362             state = shpc_get_status(shpc, i, SHPC_SLOT_STATE_MASK);
    363             if (state == SHPC_STATE_ENABLED) {
    364                 shpc_invalid_command(shpc);
    365                 goto done;
    366             }
    367         }
    368         for (i = 0; i < shpc->nslots; ++i) {
    369             if (!(shpc_get_status(shpc, i, SHPC_SLOT_STATUS_MRL_OPEN))) {
    370                 shpc_slot_command(shpc, i + SHPC_CMD_TRGT_MIN,
    371                                   SHPC_STATE_ENABLED, SHPC_LED_ON, SHPC_LED_NO);
    372             } else {
    373                 shpc_slot_command(shpc, i + SHPC_CMD_TRGT_MIN,
    374                                   SHPC_STATE_NO, SHPC_LED_OFF, SHPC_LED_NO);
    375             }
    376         }
    377         break;
    378     default:
    379         shpc_invalid_command(shpc);
    380         break;
    381     }
    382 done:
    383     pci_long_test_and_set_mask(shpc->config + SHPC_SERR_INT, SHPC_CMD_DETECTED);
    384 }
    385 
    386 static void shpc_write(PCIDevice *d, unsigned addr, uint64_t val, int l)
    387 {
    388     SHPCDevice *shpc = d->shpc;
    389     int i;
    390     if (addr >= SHPC_SIZEOF(d)) {
    391         return;
    392     }
    393     l = MIN(l, SHPC_SIZEOF(d) - addr);
    394 
    395     /* TODO: code duplicated from pci.c */
    396     for (i = 0; i < l; val >>= 8, ++i) {
    397         unsigned a = addr + i;
    398         uint8_t wmask = shpc->wmask[a];
    399         uint8_t w1cmask = shpc->w1cmask[a];
    400         assert(!(wmask & w1cmask));
    401         shpc->config[a] = (shpc->config[a] & ~wmask) | (val & wmask);
    402         shpc->config[a] &= ~(val & w1cmask); /* W1C: Write 1 to Clear */
    403     }
    404     if (ranges_overlap(addr, l, SHPC_CMD_CODE, 2)) {
    405         shpc_command(shpc);
    406     }
    407     shpc_interrupt_update(d);
    408 }
    409 
    410 static uint64_t shpc_read(PCIDevice *d, unsigned addr, int l)
    411 {
    412     uint64_t val = 0x0;
    413     if (addr >= SHPC_SIZEOF(d)) {
    414         return val;
    415     }
    416     l = MIN(l, SHPC_SIZEOF(d) - addr);
    417     memcpy(&val, d->shpc->config + addr, l);
    418     return val;
    419 }
    420 
    421 /* SHPC Bridge Capability */
    422 #define SHPC_CAP_LENGTH 0x08
    423 #define SHPC_CAP_DWORD_SELECT 0x2 /* 1 byte */
    424 #define SHPC_CAP_CxP 0x3 /* 1 byte: CSP, CIP */
    425 #define SHPC_CAP_DWORD_DATA 0x4 /* 4 bytes */
    426 #define SHPC_CAP_CSP_MASK 0x4
    427 #define SHPC_CAP_CIP_MASK 0x8
    428 
    429 static uint8_t shpc_cap_dword(PCIDevice *d)
    430 {
    431     return pci_get_byte(d->config + d->shpc->cap + SHPC_CAP_DWORD_SELECT);
    432 }
    433 
    434 /* Update dword data capability register */
    435 static void shpc_cap_update_dword(PCIDevice *d)
    436 {
    437     unsigned data;
    438     data = shpc_read(d, shpc_cap_dword(d) * 4, 4);
    439     pci_set_long(d->config  + d->shpc->cap + SHPC_CAP_DWORD_DATA, data);
    440 }
    441 
    442 /* Add SHPC capability to the config space for the device. */
    443 static int shpc_cap_add_config(PCIDevice *d, Error **errp)
    444 {
    445     uint8_t *config;
    446     int config_offset;
    447     config_offset = pci_add_capability(d, PCI_CAP_ID_SHPC,
    448                                        0, SHPC_CAP_LENGTH,
    449                                        errp);
    450     if (config_offset < 0) {
    451         return config_offset;
    452     }
    453     config = d->config + config_offset;
    454 
    455     pci_set_byte(config + SHPC_CAP_DWORD_SELECT, 0);
    456     pci_set_byte(config + SHPC_CAP_CxP, 0);
    457     pci_set_long(config + SHPC_CAP_DWORD_DATA, 0);
    458     d->shpc->cap = config_offset;
    459     /* Make dword select and data writable. */
    460     pci_set_byte(d->wmask + config_offset + SHPC_CAP_DWORD_SELECT, 0xff);
    461     pci_set_long(d->wmask + config_offset + SHPC_CAP_DWORD_DATA, 0xffffffff);
    462     return 0;
    463 }
    464 
    465 static uint64_t shpc_mmio_read(void *opaque, hwaddr addr,
    466                                unsigned size)
    467 {
    468     return shpc_read(opaque, addr, size);
    469 }
    470 
    471 static void shpc_mmio_write(void *opaque, hwaddr addr,
    472                             uint64_t val, unsigned size)
    473 {
    474     shpc_write(opaque, addr, val, size);
    475 }
    476 
    477 static const MemoryRegionOps shpc_mmio_ops = {
    478     .read = shpc_mmio_read,
    479     .write = shpc_mmio_write,
    480     .endianness = DEVICE_LITTLE_ENDIAN,
    481     .valid = {
    482         /* SHPC ECN requires dword accesses, but the original 1.0 spec doesn't.
    483          * It's easier to support all sizes than worry about it.
    484          */
    485         .min_access_size = 1,
    486         .max_access_size = 4,
    487     },
    488 };
    489 static void shpc_device_plug_common(PCIDevice *affected_dev, int *slot,
    490                                     SHPCDevice *shpc, Error **errp)
    491 {
    492     int pci_slot = PCI_SLOT(affected_dev->devfn);
    493     *slot = SHPC_PCI_TO_IDX(pci_slot);
    494 
    495     if (pci_slot < SHPC_IDX_TO_PCI(0) || *slot >= shpc->nslots) {
    496         error_setg(errp, "Unsupported PCI slot %d for standard hotplug "
    497                    "controller. Valid slots are between %d and %d.",
    498                    pci_slot, SHPC_IDX_TO_PCI(0),
    499                    SHPC_IDX_TO_PCI(shpc->nslots) - 1);
    500         return;
    501     }
    502 }
    503 
    504 void shpc_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
    505                             Error **errp)
    506 {
    507     Error *local_err = NULL;
    508     PCIDevice *pci_hotplug_dev = PCI_DEVICE(hotplug_dev);
    509     SHPCDevice *shpc = pci_hotplug_dev->shpc;
    510     int slot;
    511 
    512     shpc_device_plug_common(PCI_DEVICE(dev), &slot, shpc, &local_err);
    513     if (local_err) {
    514         error_propagate(errp, local_err);
    515         return;
    516     }
    517 
    518     /* Don't send event when device is enabled during qemu machine creation:
    519      * it is present on boot, no hotplug event is necessary. We do send an
    520      * event when the device is disabled later. */
    521     if (!dev->hotplugged) {
    522         shpc_set_status(shpc, slot, 0, SHPC_SLOT_STATUS_MRL_OPEN);
    523         shpc_set_status(shpc, slot, SHPC_SLOT_STATUS_PRSNT_7_5W,
    524                         SHPC_SLOT_STATUS_PRSNT_MASK);
    525         return;
    526     }
    527 
    528     /* This could be a cancellation of the previous removal.
    529      * We check MRL state to figure out. */
    530     if (shpc_get_status(shpc, slot, SHPC_SLOT_STATUS_MRL_OPEN)) {
    531         shpc_set_status(shpc, slot, 0, SHPC_SLOT_STATUS_MRL_OPEN);
    532         shpc_set_status(shpc, slot, SHPC_SLOT_STATUS_PRSNT_7_5W,
    533                         SHPC_SLOT_STATUS_PRSNT_MASK);
    534         shpc->config[SHPC_SLOT_EVENT_LATCH(slot)] |=
    535             SHPC_SLOT_EVENT_BUTTON |
    536             SHPC_SLOT_EVENT_MRL |
    537             SHPC_SLOT_EVENT_PRESENCE;
    538     } else {
    539         /* Press attention button to cancel removal */
    540         shpc->config[SHPC_SLOT_EVENT_LATCH(slot)] |=
    541             SHPC_SLOT_EVENT_BUTTON;
    542     }
    543     shpc_set_status(shpc, slot, 0, SHPC_SLOT_STATUS_66);
    544     shpc_interrupt_update(pci_hotplug_dev);
    545 }
    546 
    547 void shpc_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
    548                            Error **errp)
    549 {
    550     qdev_unrealize(dev);
    551 }
    552 
    553 void shpc_device_unplug_request_cb(HotplugHandler *hotplug_dev,
    554                                    DeviceState *dev, Error **errp)
    555 {
    556     Error *local_err = NULL;
    557     PCIDevice *pci_hotplug_dev = PCI_DEVICE(hotplug_dev);
    558     SHPCDevice *shpc = pci_hotplug_dev->shpc;
    559     uint8_t state;
    560     uint8_t led;
    561     int slot;
    562 
    563     shpc_device_plug_common(PCI_DEVICE(dev), &slot, shpc, &local_err);
    564     if (local_err) {
    565         error_propagate(errp, local_err);
    566         return;
    567     }
    568 
    569     state = shpc_get_status(shpc, slot, SHPC_SLOT_STATE_MASK);
    570     led = shpc_get_status(shpc, slot, SHPC_SLOT_PWR_LED_MASK);
    571     if (state == SHPC_STATE_DISABLED && led == SHPC_LED_OFF) {
    572         shpc_free_devices_in_slot(shpc, slot);
    573         shpc_set_status(shpc, slot, 1, SHPC_SLOT_STATUS_MRL_OPEN);
    574         shpc_set_status(shpc, slot, SHPC_SLOT_STATUS_PRSNT_EMPTY,
    575                         SHPC_SLOT_STATUS_PRSNT_MASK);
    576         shpc->config[SHPC_SLOT_EVENT_LATCH(slot)] |=
    577             SHPC_SLOT_EVENT_MRL |
    578             SHPC_SLOT_EVENT_PRESENCE;
    579     } else {
    580         shpc->config[SHPC_SLOT_EVENT_LATCH(slot)] |= SHPC_SLOT_EVENT_BUTTON;
    581     }
    582     shpc_set_status(shpc, slot, 0, SHPC_SLOT_STATUS_66);
    583     shpc_interrupt_update(pci_hotplug_dev);
    584 }
    585 
    586 /* Initialize the SHPC structure in bridge's BAR. */
    587 int shpc_init(PCIDevice *d, PCIBus *sec_bus, MemoryRegion *bar,
    588               unsigned offset, Error **errp)
    589 {
    590     int i, ret;
    591     int nslots = SHPC_MAX_SLOTS; /* TODO: qdev property? */
    592     SHPCDevice *shpc = d->shpc = g_malloc0(sizeof(*d->shpc));
    593     shpc->sec_bus = sec_bus;
    594     ret = shpc_cap_add_config(d, errp);
    595     if (ret) {
    596         g_free(d->shpc);
    597         return ret;
    598     }
    599     if (nslots < SHPC_MIN_SLOTS) {
    600         return 0;
    601     }
    602     if (nslots > SHPC_MAX_SLOTS ||
    603         SHPC_IDX_TO_PCI(nslots) > PCI_SLOT_MAX) {
    604         /* TODO: report an error mesage that makes sense. */
    605         return -EINVAL;
    606     }
    607     shpc->nslots = nslots;
    608     shpc->config = g_malloc0(SHPC_SIZEOF(d));
    609     shpc->cmask = g_malloc0(SHPC_SIZEOF(d));
    610     shpc->wmask = g_malloc0(SHPC_SIZEOF(d));
    611     shpc->w1cmask = g_malloc0(SHPC_SIZEOF(d));
    612 
    613     shpc_reset(d);
    614 
    615     pci_set_long(shpc->config + SHPC_BASE_OFFSET, offset);
    616 
    617     pci_set_byte(shpc->wmask + SHPC_CMD_CODE, 0xff);
    618     pci_set_byte(shpc->wmask + SHPC_CMD_TRGT, SHPC_CMD_TRGT_MAX);
    619     pci_set_byte(shpc->wmask + SHPC_CMD_TRGT, SHPC_CMD_TRGT_MAX);
    620     pci_set_long(shpc->wmask + SHPC_SERR_INT,
    621                  SHPC_INT_DIS |
    622                  SHPC_SERR_DIS |
    623                  SHPC_CMD_INT_DIS |
    624                  SHPC_ARB_SERR_DIS);
    625     pci_set_long(shpc->w1cmask + SHPC_SERR_INT,
    626                  SHPC_CMD_DETECTED |
    627                  SHPC_ARB_DETECTED);
    628     for (i = 0; i < nslots; ++i) {
    629         pci_set_byte(shpc->wmask +
    630                      SHPC_SLOT_EVENT_SERR_INT_DIS(d, i),
    631                      SHPC_SLOT_EVENT_PRESENCE |
    632                      SHPC_SLOT_EVENT_ISOLATED_FAULT |
    633                      SHPC_SLOT_EVENT_BUTTON |
    634                      SHPC_SLOT_EVENT_MRL |
    635                      SHPC_SLOT_EVENT_CONNECTED_FAULT |
    636                      SHPC_SLOT_EVENT_MRL_SERR_DIS |
    637                      SHPC_SLOT_EVENT_CONNECTED_FAULT_SERR_DIS);
    638         pci_set_byte(shpc->w1cmask +
    639                      SHPC_SLOT_EVENT_LATCH(i),
    640                      SHPC_SLOT_EVENT_PRESENCE |
    641                      SHPC_SLOT_EVENT_ISOLATED_FAULT |
    642                      SHPC_SLOT_EVENT_BUTTON |
    643                      SHPC_SLOT_EVENT_MRL |
    644                      SHPC_SLOT_EVENT_CONNECTED_FAULT);
    645     }
    646 
    647     /* TODO: init cmask */
    648     memory_region_init_io(&shpc->mmio, OBJECT(d), &shpc_mmio_ops,
    649                           d, "shpc-mmio", SHPC_SIZEOF(d));
    650     shpc_cap_update_dword(d);
    651     memory_region_add_subregion(bar, offset, &shpc->mmio);
    652 
    653     qbus_set_hotplug_handler(BUS(sec_bus), OBJECT(d));
    654 
    655     d->cap_present |= QEMU_PCI_CAP_SHPC;
    656     return 0;
    657 }
    658 
    659 int shpc_bar_size(PCIDevice *d)
    660 {
    661     return pow2roundup32(SHPC_SLOT_REG(SHPC_MAX_SLOTS));
    662 }
    663 
    664 void shpc_cleanup(PCIDevice *d, MemoryRegion *bar)
    665 {
    666     SHPCDevice *shpc = d->shpc;
    667     d->cap_present &= ~QEMU_PCI_CAP_SHPC;
    668     memory_region_del_subregion(bar, &shpc->mmio);
    669     /* TODO: cleanup config space changes? */
    670 }
    671 
    672 void shpc_free(PCIDevice *d)
    673 {
    674     SHPCDevice *shpc = d->shpc;
    675     if (!shpc) {
    676         return;
    677     }
    678     object_unparent(OBJECT(&shpc->mmio));
    679     g_free(shpc->config);
    680     g_free(shpc->cmask);
    681     g_free(shpc->wmask);
    682     g_free(shpc->w1cmask);
    683     g_free(shpc);
    684     d->shpc = NULL;
    685 }
    686 
    687 void shpc_cap_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
    688 {
    689     if (!ranges_overlap(addr, l, d->shpc->cap, SHPC_CAP_LENGTH)) {
    690         return;
    691     }
    692     if (ranges_overlap(addr, l, d->shpc->cap + SHPC_CAP_DWORD_DATA, 4)) {
    693         unsigned dword_data;
    694         dword_data = pci_get_long(d->shpc->config + d->shpc->cap
    695                                   + SHPC_CAP_DWORD_DATA);
    696         shpc_write(d, shpc_cap_dword(d) * 4, dword_data, 4);
    697     }
    698     /* Update cap dword data in case guest is going to read it. */
    699     shpc_cap_update_dword(d);
    700 }
    701 
    702 static int shpc_save(QEMUFile *f, void *pv, size_t size,
    703                      const VMStateField *field, JSONWriter *vmdesc)
    704 {
    705     PCIDevice *d = container_of(pv, PCIDevice, shpc);
    706     qemu_put_buffer(f, d->shpc->config, SHPC_SIZEOF(d));
    707 
    708     return 0;
    709 }
    710 
    711 static int shpc_load(QEMUFile *f, void *pv, size_t size,
    712                      const VMStateField *field)
    713 {
    714     PCIDevice *d = container_of(pv, PCIDevice, shpc);
    715     int ret = qemu_get_buffer(f, d->shpc->config, SHPC_SIZEOF(d));
    716     if (ret != SHPC_SIZEOF(d)) {
    717         return -EINVAL;
    718     }
    719     /* Make sure we don't lose notifications. An extra interrupt is harmless. */
    720     d->shpc->msi_requested = 0;
    721     shpc_interrupt_update(d);
    722     return 0;
    723 }
    724 
    725 VMStateInfo shpc_vmstate_info = {
    726     .name = "shpc",
    727     .get  = shpc_load,
    728     .put  = shpc_save,
    729 };