Annotation of qemu/hw/acpi_piix4.c, revision 1.1.1.5

1.1       root        1: /*
                      2:  * ACPI implementation
                      3:  *
                      4:  * Copyright (c) 2006 Fabrice Bellard
                      5:  *
                      6:  * This library is free software; you can redistribute it and/or
                      7:  * modify it under the terms of the GNU Lesser General Public
                      8:  * License version 2 as published by the Free Software Foundation.
                      9:  *
                     10:  * This library is distributed in the hope that it will be useful,
                     11:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     12:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     13:  * Lesser General Public License for more details.
                     14:  *
                     15:  * You should have received a copy of the GNU Lesser General Public
                     16:  * License along with this library; if not, see <http://www.gnu.org/licenses/>
1.1.1.5 ! root       17:  *
        !            18:  * Contributions after 2012-01-13 are licensed under the terms of the
        !            19:  * GNU GPL, version 2 or (at your option) any later version.
1.1       root       20:  */
                     21: #include "hw.h"
                     22: #include "pc.h"
                     23: #include "apm.h"
                     24: #include "pm_smbus.h"
                     25: #include "pci.h"
                     26: #include "acpi.h"
                     27: #include "sysemu.h"
1.1.1.2   root       28: #include "range.h"
1.1.1.3   root       29: #include "ioport.h"
1.1       root       30: 
                     31: //#define DEBUG
                     32: 
                     33: #ifdef DEBUG
                     34: # define PIIX4_DPRINTF(format, ...)     printf(format, ## __VA_ARGS__)
                     35: #else
                     36: # define PIIX4_DPRINTF(format, ...)     do { } while (0)
                     37: #endif
                     38: 
                     39: #define ACPI_DBG_IO_ADDR  0xb044
                     40: 
                     41: #define GPE_BASE 0xafe0
1.1.1.3   root       42: #define GPE_LEN 4
1.1.1.5 ! root       43: #define PCI_UP_BASE 0xae00
        !            44: #define PCI_DOWN_BASE 0xae04
1.1       root       45: #define PCI_EJ_BASE 0xae08
1.1.1.2   root       46: #define PCI_RMV_BASE 0xae0c
                     47: 
                     48: #define PIIX4_PCI_HOTPLUG_STATUS 2
1.1       root       49: 
                     50: struct pci_status {
1.1.1.5 ! root       51:     uint32_t up; /* deprecated, maintained for migration compatibility */
1.1       root       52:     uint32_t down;
                     53: };
                     54: 
                     55: typedef struct PIIX4PMState {
                     56:     PCIDevice dev;
1.1.1.2   root       57:     IORange ioport;
1.1.1.5 ! root       58:     ACPIREGS ar;
1.1       root       59: 
                     60:     APMState apm;
                     61: 
                     62:     PMSMBus smb;
                     63:     uint32_t smb_io_base;
                     64: 
                     65:     qemu_irq irq;
                     66:     qemu_irq smi_irq;
                     67:     int kvm_enabled;
1.1.1.3   root       68:     Notifier machine_ready;
1.1       root       69: 
                     70:     /* for pci hotplug */
                     71:     struct pci_status pci0_status;
1.1.1.2   root       72:     uint32_t pci0_hotplug_enable;
1.1.1.5 ! root       73:     uint32_t pci0_slot_device_present;
1.1       root       74: } PIIX4PMState;
                     75: 
                     76: static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s);
                     77: 
                     78: #define ACPI_ENABLE 0xf1
                     79: #define ACPI_DISABLE 0xf0
                     80: 
                     81: static void pm_update_sci(PIIX4PMState *s)
                     82: {
                     83:     int sci_level, pmsts;
                     84: 
1.1.1.5 ! root       85:     pmsts = acpi_pm1_evt_get_sts(&s->ar);
        !            86:     sci_level = (((pmsts & s->ar.pm1.evt.en) &
1.1       root       87:                   (ACPI_BITMASK_RT_CLOCK_ENABLE |
                     88:                    ACPI_BITMASK_POWER_BUTTON_ENABLE |
                     89:                    ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
1.1.1.2   root       90:                    ACPI_BITMASK_TIMER_ENABLE)) != 0) ||
1.1.1.5 ! root       91:         (((s->ar.gpe.sts[0] & s->ar.gpe.en[0])
        !            92:           & PIIX4_PCI_HOTPLUG_STATUS) != 0);
1.1.1.2   root       93: 
1.1       root       94:     qemu_set_irq(s->irq, sci_level);
                     95:     /* schedule a timer interruption if needed */
1.1.1.5 ! root       96:     acpi_pm_tmr_update(&s->ar, (s->ar.pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
1.1.1.3   root       97:                        !(pmsts & ACPI_BITMASK_TIMER_STATUS));
1.1       root       98: }
                     99: 
1.1.1.5 ! root      100: static void pm_tmr_timer(ACPIREGS *ar)
1.1       root      101: {
1.1.1.5 ! root      102:     PIIX4PMState *s = container_of(ar, PIIX4PMState, ar);
1.1       root      103:     pm_update_sci(s);
                    104: }
                    105: 
1.1.1.2   root      106: static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width,
                    107:                             uint64_t val)
1.1       root      108: {
1.1.1.2   root      109:     PIIX4PMState *s = container_of(ioport, PIIX4PMState, ioport);
                    110: 
                    111:     if (width != 2) {
                    112:         PIIX4_DPRINTF("PM write port=0x%04x width=%d val=0x%08x\n",
                    113:                       (unsigned)addr, width, (unsigned)val);
                    114:     }
                    115: 
1.1       root      116:     switch(addr) {
                    117:     case 0x00:
1.1.1.5 ! root      118:         acpi_pm1_evt_write_sts(&s->ar, val);
1.1.1.3   root      119:         pm_update_sci(s);
1.1       root      120:         break;
                    121:     case 0x02:
1.1.1.5 ! root      122:         acpi_pm1_evt_write_en(&s->ar, val);
1.1       root      123:         pm_update_sci(s);
                    124:         break;
                    125:     case 0x04:
1.1.1.5 ! root      126:         acpi_pm1_cnt_write(&s->ar, val);
1.1       root      127:         break;
                    128:     default:
                    129:         break;
                    130:     }
1.1.1.3   root      131:     PIIX4_DPRINTF("PM writew port=0x%04x val=0x%04x\n", (unsigned int)addr,
                    132:                   (unsigned int)val);
1.1       root      133: }
                    134: 
1.1.1.2   root      135: static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width,
                    136:                             uint64_t *data)
1.1       root      137: {
1.1.1.2   root      138:     PIIX4PMState *s = container_of(ioport, PIIX4PMState, ioport);
1.1       root      139:     uint32_t val;
                    140: 
                    141:     switch(addr) {
                    142:     case 0x00:
1.1.1.5 ! root      143:         val = acpi_pm1_evt_get_sts(&s->ar);
1.1       root      144:         break;
                    145:     case 0x02:
1.1.1.5 ! root      146:         val = s->ar.pm1.evt.en;
1.1       root      147:         break;
                    148:     case 0x04:
1.1.1.5 ! root      149:         val = s->ar.pm1.cnt.cnt;
1.1       root      150:         break;
                    151:     case 0x08:
1.1.1.5 ! root      152:         val = acpi_pm_tmr_get(&s->ar);
1.1       root      153:         break;
                    154:     default:
                    155:         val = 0;
                    156:         break;
                    157:     }
1.1.1.3   root      158:     PIIX4_DPRINTF("PM readw port=0x%04x val=0x%04x\n", (unsigned int)addr, val);
1.1.1.2   root      159:     *data = val;
1.1       root      160: }
                    161: 
1.1.1.2   root      162: static const IORangeOps pm_iorange_ops = {
                    163:     .read = pm_ioport_read,
                    164:     .write = pm_ioport_write,
                    165: };
                    166: 
1.1       root      167: static void apm_ctrl_changed(uint32_t val, void *arg)
                    168: {
                    169:     PIIX4PMState *s = arg;
                    170: 
                    171:     /* ACPI specs 3.0, 4.7.2.5 */
1.1.1.5 ! root      172:     acpi_pm1_cnt_update(&s->ar, val == ACPI_ENABLE, val == ACPI_DISABLE);
1.1       root      173: 
                    174:     if (s->dev.config[0x5b] & (1 << 1)) {
                    175:         if (s->smi_irq) {
                    176:             qemu_irq_raise(s->smi_irq);
                    177:         }
                    178:     }
                    179: }
                    180: 
                    181: static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
                    182: {
                    183:     PIIX4_DPRINTF("ACPI: DBG: 0x%08x\n", val);
                    184: }
                    185: 
                    186: static void pm_io_space_update(PIIX4PMState *s)
                    187: {
                    188:     uint32_t pm_io_base;
                    189: 
                    190:     if (s->dev.config[0x80] & 1) {
                    191:         pm_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x40));
                    192:         pm_io_base &= 0xffc0;
                    193: 
                    194:         /* XXX: need to improve memory and ioport allocation */
                    195:         PIIX4_DPRINTF("PM: mapping to 0x%x\n", pm_io_base);
1.1.1.2   root      196:         iorange_init(&s->ioport, &pm_iorange_ops, pm_io_base, 64);
                    197:         ioport_register(&s->ioport);
1.1       root      198:     }
                    199: }
                    200: 
                    201: static void pm_write_config(PCIDevice *d,
                    202:                             uint32_t address, uint32_t val, int len)
                    203: {
                    204:     pci_default_write_config(d, address, val, len);
                    205:     if (range_covers_byte(address, len, 0x80))
                    206:         pm_io_space_update((PIIX4PMState *)d);
                    207: }
                    208: 
1.1.1.5 ! root      209: static void vmstate_pci_status_pre_save(void *opaque)
        !           210: {
        !           211:     struct pci_status *pci0_status = opaque;
        !           212:     PIIX4PMState *s = container_of(pci0_status, PIIX4PMState, pci0_status);
        !           213: 
        !           214:     /* We no longer track up, so build a safe value for migrating
        !           215:      * to a version that still does... of course these might get lost
        !           216:      * by an old buggy implementation, but we try. */
        !           217:     pci0_status->up = s->pci0_slot_device_present & s->pci0_hotplug_enable;
        !           218: }
        !           219: 
1.1       root      220: static int vmstate_acpi_post_load(void *opaque, int version_id)
                    221: {
                    222:     PIIX4PMState *s = opaque;
                    223: 
                    224:     pm_io_space_update(s);
                    225:     return 0;
                    226: }
                    227: 
1.1.1.3   root      228: #define VMSTATE_GPE_ARRAY(_field, _state)                            \
                    229:  {                                                                   \
                    230:      .name       = (stringify(_field)),                              \
                    231:      .version_id = 0,                                                \
                    232:      .num        = GPE_LEN,                                          \
                    233:      .info       = &vmstate_info_uint16,                             \
                    234:      .size       = sizeof(uint16_t),                                 \
                    235:      .flags      = VMS_ARRAY | VMS_POINTER,                          \
                    236:      .offset     = vmstate_offset_pointer(_state, _field, uint8_t),  \
                    237:  }
                    238: 
1.1       root      239: static const VMStateDescription vmstate_gpe = {
                    240:     .name = "gpe",
                    241:     .version_id = 1,
                    242:     .minimum_version_id = 1,
                    243:     .minimum_version_id_old = 1,
                    244:     .fields      = (VMStateField []) {
1.1.1.3   root      245:         VMSTATE_GPE_ARRAY(sts, ACPIGPE),
                    246:         VMSTATE_GPE_ARRAY(en, ACPIGPE),
1.1       root      247:         VMSTATE_END_OF_LIST()
                    248:     }
                    249: };
                    250: 
                    251: static const VMStateDescription vmstate_pci_status = {
                    252:     .name = "pci_status",
                    253:     .version_id = 1,
                    254:     .minimum_version_id = 1,
                    255:     .minimum_version_id_old = 1,
1.1.1.5 ! root      256:     .pre_save = vmstate_pci_status_pre_save,
1.1       root      257:     .fields      = (VMStateField []) {
                    258:         VMSTATE_UINT32(up, struct pci_status),
                    259:         VMSTATE_UINT32(down, struct pci_status),
                    260:         VMSTATE_END_OF_LIST()
                    261:     }
                    262: };
                    263: 
                    264: static const VMStateDescription vmstate_acpi = {
                    265:     .name = "piix4_pm",
                    266:     .version_id = 2,
                    267:     .minimum_version_id = 1,
                    268:     .minimum_version_id_old = 1,
                    269:     .post_load = vmstate_acpi_post_load,
                    270:     .fields      = (VMStateField []) {
                    271:         VMSTATE_PCI_DEVICE(dev, PIIX4PMState),
1.1.1.5 ! root      272:         VMSTATE_UINT16(ar.pm1.evt.sts, PIIX4PMState),
        !           273:         VMSTATE_UINT16(ar.pm1.evt.en, PIIX4PMState),
        !           274:         VMSTATE_UINT16(ar.pm1.cnt.cnt, PIIX4PMState),
1.1       root      275:         VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState),
1.1.1.5 ! root      276:         VMSTATE_TIMER(ar.tmr.timer, PIIX4PMState),
        !           277:         VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState),
        !           278:         VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE),
1.1       root      279:         VMSTATE_STRUCT(pci0_status, PIIX4PMState, 2, vmstate_pci_status,
                    280:                        struct pci_status),
                    281:         VMSTATE_END_OF_LIST()
                    282:     }
                    283: };
                    284: 
1.1.1.5 ! root      285: static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots)
        !           286: {
        !           287:     DeviceState *qdev, *next;
        !           288:     BusState *bus = qdev_get_parent_bus(&s->dev.qdev);
        !           289:     int slot = ffs(slots) - 1;
        !           290:     bool slot_free = true;
        !           291: 
        !           292:     /* Mark request as complete */
        !           293:     s->pci0_status.down &= ~(1U << slot);
        !           294: 
        !           295:     QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
        !           296:         PCIDevice *dev = PCI_DEVICE(qdev);
        !           297:         PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
        !           298:         if (PCI_SLOT(dev->devfn) == slot) {
        !           299:             if (pc->no_hotplug) {
        !           300:                 slot_free = false;
        !           301:             } else {
        !           302:                 object_unparent(OBJECT(dev));
        !           303:                 qdev_free(qdev);
        !           304:             }
        !           305:         }
        !           306:     }
        !           307:     if (slot_free) {
        !           308:         s->pci0_slot_device_present &= ~(1U << slot);
        !           309:     }
        !           310: }
        !           311: 
1.1.1.2   root      312: static void piix4_update_hotplug(PIIX4PMState *s)
                    313: {
                    314:     PCIDevice *dev = &s->dev;
                    315:     BusState *bus = qdev_get_parent_bus(&dev->qdev);
                    316:     DeviceState *qdev, *next;
                    317: 
1.1.1.5 ! root      318:     /* Execute any pending removes during reset */
        !           319:     while (s->pci0_status.down) {
        !           320:         acpi_piix_eject_slot(s, s->pci0_status.down);
        !           321:     }
        !           322: 
1.1.1.2   root      323:     s->pci0_hotplug_enable = ~0;
1.1.1.5 ! root      324:     s->pci0_slot_device_present = 0;
1.1.1.2   root      325: 
1.1.1.4   root      326:     QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
1.1.1.5 ! root      327:         PCIDevice *pdev = PCI_DEVICE(qdev);
        !           328:         PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pdev);
1.1.1.2   root      329:         int slot = PCI_SLOT(pdev->devfn);
                    330: 
1.1.1.5 ! root      331:         if (pc->no_hotplug) {
        !           332:             s->pci0_hotplug_enable &= ~(1U << slot);
1.1.1.2   root      333:         }
1.1.1.5 ! root      334: 
        !           335:         s->pci0_slot_device_present |= (1U << slot);
1.1.1.2   root      336:     }
                    337: }
                    338: 
1.1       root      339: static void piix4_reset(void *opaque)
                    340: {
                    341:     PIIX4PMState *s = opaque;
                    342:     uint8_t *pci_conf = s->dev.config;
                    343: 
                    344:     pci_conf[0x58] = 0;
                    345:     pci_conf[0x59] = 0;
                    346:     pci_conf[0x5a] = 0;
                    347:     pci_conf[0x5b] = 0;
                    348: 
                    349:     if (s->kvm_enabled) {
                    350:         /* Mark SMM as already inited (until KVM supports SMM). */
                    351:         pci_conf[0x5B] = 0x02;
                    352:     }
1.1.1.2   root      353:     piix4_update_hotplug(s);
1.1       root      354: }
                    355: 
                    356: static void piix4_powerdown(void *opaque, int irq, int power_failing)
                    357: {
                    358:     PIIX4PMState *s = opaque;
1.1.1.3   root      359: 
1.1.1.5 ! root      360:     assert(s != NULL);
        !           361:     acpi_pm1_evt_power_down(&s->ar);
1.1.1.3   root      362: }
                    363: 
                    364: static void piix4_pm_machine_ready(Notifier *n, void *opaque)
                    365: {
                    366:     PIIX4PMState *s = container_of(n, PIIX4PMState, machine_ready);
                    367:     uint8_t *pci_conf;
                    368: 
                    369:     pci_conf = s->dev.config;
                    370:     pci_conf[0x5f] = (isa_is_ioport_assigned(0x378) ? 0x80 : 0) | 0x10;
                    371:     pci_conf[0x63] = 0x60;
                    372:     pci_conf[0x67] = (isa_is_ioport_assigned(0x3f8) ? 0x08 : 0) |
                    373:        (isa_is_ioport_assigned(0x2f8) ? 0x90 : 0);
1.1       root      374: 
                    375: }
                    376: 
                    377: static int piix4_pm_initfn(PCIDevice *dev)
                    378: {
                    379:     PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev, dev);
                    380:     uint8_t *pci_conf;
                    381: 
                    382:     pci_conf = s->dev.config;
                    383:     pci_conf[0x06] = 0x80;
                    384:     pci_conf[0x07] = 0x02;
                    385:     pci_conf[0x09] = 0x00;
                    386:     pci_conf[0x3d] = 0x01; // interrupt pin 1
                    387: 
                    388:     pci_conf[0x40] = 0x01; /* PM io base read only bit */
                    389: 
                    390:     /* APM */
                    391:     apm_init(&s->apm, apm_ctrl_changed, s);
                    392: 
                    393:     register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s);
                    394: 
                    395:     if (s->kvm_enabled) {
                    396:         /* Mark SMM as already inited to prevent SMM from running.  KVM does not
                    397:          * support SMM mode. */
                    398:         pci_conf[0x5B] = 0x02;
                    399:     }
                    400: 
                    401:     /* XXX: which specification is used ? The i82731AB has different
                    402:        mappings */
                    403:     pci_conf[0x90] = s->smb_io_base | 1;
                    404:     pci_conf[0x91] = s->smb_io_base >> 8;
                    405:     pci_conf[0xd2] = 0x09;
                    406:     register_ioport_write(s->smb_io_base, 64, 1, smb_ioport_writeb, &s->smb);
                    407:     register_ioport_read(s->smb_io_base, 64, 1, smb_ioport_readb, &s->smb);
                    408: 
1.1.1.5 ! root      409:     acpi_pm_tmr_init(&s->ar, pm_tmr_timer);
        !           410:     acpi_gpe_init(&s->ar, GPE_LEN);
1.1       root      411: 
                    412:     qemu_system_powerdown = *qemu_allocate_irqs(piix4_powerdown, s, 1);
                    413: 
                    414:     pm_smbus_init(&s->dev.qdev, &s->smb);
1.1.1.3   root      415:     s->machine_ready.notify = piix4_pm_machine_ready;
                    416:     qemu_add_machine_init_done_notifier(&s->machine_ready);
1.1       root      417:     qemu_register_reset(piix4_reset, s);
                    418:     piix4_acpi_system_hot_add_init(dev->bus, s);
                    419: 
                    420:     return 0;
                    421: }
                    422: 
                    423: i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
1.1.1.5 ! root      424:                        qemu_irq sci_irq, qemu_irq smi_irq,
1.1       root      425:                        int kvm_enabled)
                    426: {
                    427:     PCIDevice *dev;
                    428:     PIIX4PMState *s;
                    429: 
                    430:     dev = pci_create(bus, devfn, "PIIX4_PM");
                    431:     qdev_prop_set_uint32(&dev->qdev, "smb_io_base", smb_io_base);
                    432: 
                    433:     s = DO_UPCAST(PIIX4PMState, dev, dev);
                    434:     s->irq = sci_irq;
1.1.1.5 ! root      435:     acpi_pm1_cnt_init(&s->ar);
1.1       root      436:     s->smi_irq = smi_irq;
                    437:     s->kvm_enabled = kvm_enabled;
                    438: 
                    439:     qdev_init_nofail(&dev->qdev);
                    440: 
                    441:     return s->smb.smbus;
                    442: }
                    443: 
1.1.1.5 ! root      444: static Property piix4_pm_properties[] = {
        !           445:     DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
        !           446:     DEFINE_PROP_END_OF_LIST(),
1.1       root      447: };
                    448: 
1.1.1.5 ! root      449: static void piix4_pm_class_init(ObjectClass *klass, void *data)
1.1       root      450: {
1.1.1.5 ! root      451:     DeviceClass *dc = DEVICE_CLASS(klass);
        !           452:     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
        !           453: 
        !           454:     k->no_hotplug = 1;
        !           455:     k->init = piix4_pm_initfn;
        !           456:     k->config_write = pm_write_config;
        !           457:     k->vendor_id = PCI_VENDOR_ID_INTEL;
        !           458:     k->device_id = PCI_DEVICE_ID_INTEL_82371AB_3;
        !           459:     k->revision = 0x03;
        !           460:     k->class_id = PCI_CLASS_BRIDGE_OTHER;
        !           461:     dc->desc = "PM";
        !           462:     dc->no_user = 1;
        !           463:     dc->vmsd = &vmstate_acpi;
        !           464:     dc->props = piix4_pm_properties;
        !           465: }
        !           466: 
        !           467: static TypeInfo piix4_pm_info = {
        !           468:     .name          = "PIIX4_PM",
        !           469:     .parent        = TYPE_PCI_DEVICE,
        !           470:     .instance_size = sizeof(PIIX4PMState),
        !           471:     .class_init    = piix4_pm_class_init,
        !           472: };
        !           473: 
        !           474: static void piix4_pm_register_types(void)
        !           475: {
        !           476:     type_register_static(&piix4_pm_info);
1.1       root      477: }
                    478: 
1.1.1.5 ! root      479: type_init(piix4_pm_register_types)
1.1       root      480: 
                    481: static uint32_t gpe_readb(void *opaque, uint32_t addr)
                    482: {
1.1.1.2   root      483:     PIIX4PMState *s = opaque;
1.1.1.5 ! root      484:     uint32_t val = acpi_gpe_ioport_readb(&s->ar, addr);
1.1       root      485: 
                    486:     PIIX4_DPRINTF("gpe read %x == %x\n", addr, val);
                    487:     return val;
                    488: }
                    489: 
                    490: static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
                    491: {
1.1.1.2   root      492:     PIIX4PMState *s = opaque;
                    493: 
1.1.1.5 ! root      494:     acpi_gpe_ioport_writeb(&s->ar, addr, val);
1.1.1.2   root      495:     pm_update_sci(s);
1.1       root      496: 
                    497:     PIIX4_DPRINTF("gpe write %x <== %d\n", addr, val);
                    498: }
                    499: 
1.1.1.5 ! root      500: static uint32_t pci_up_read(void *opaque, uint32_t addr)
1.1       root      501: {
1.1.1.5 ! root      502:     PIIX4PMState *s = opaque;
        !           503:     uint32_t val;
        !           504: 
        !           505:     /* Manufacture an "up" value to cause a device check on any hotplug
        !           506:      * slot with a device.  Extra device checks are harmless. */
        !           507:     val = s->pci0_slot_device_present & s->pci0_hotplug_enable;
1.1       root      508: 
1.1.1.5 ! root      509:     PIIX4_DPRINTF("pci_up_read %x\n", val);
1.1       root      510:     return val;
                    511: }
                    512: 
1.1.1.5 ! root      513: static uint32_t pci_down_read(void *opaque, uint32_t addr)
1.1       root      514: {
1.1.1.5 ! root      515:     PIIX4PMState *s = opaque;
        !           516:     uint32_t val = s->pci0_status.down;
1.1       root      517: 
1.1.1.5 ! root      518:     PIIX4_DPRINTF("pci_down_read %x\n", val);
        !           519:     return val;
1.1       root      520: }
                    521: 
1.1.1.5 ! root      522: static uint32_t pci_features_read(void *opaque, uint32_t addr)
1.1       root      523: {
1.1.1.5 ! root      524:     /* No feature defined yet */
        !           525:     PIIX4_DPRINTF("pci_features_read %x\n", 0);
1.1       root      526:     return 0;
                    527: }
                    528: 
                    529: static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
                    530: {
1.1.1.5 ! root      531:     acpi_piix_eject_slot(opaque, val);
1.1       root      532: 
                    533:     PIIX4_DPRINTF("pciej write %x <== %d\n", addr, val);
                    534: }
                    535: 
1.1.1.2   root      536: static uint32_t pcirmv_read(void *opaque, uint32_t addr)
                    537: {
                    538:     PIIX4PMState *s = opaque;
                    539: 
                    540:     return s->pci0_hotplug_enable;
                    541: }
                    542: 
                    543: static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
                    544:                                 PCIHotplugState state);
1.1       root      545: 
                    546: static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
                    547: {
                    548: 
1.1.1.3   root      549:     register_ioport_write(GPE_BASE, GPE_LEN, 1, gpe_writeb, s);
                    550:     register_ioport_read(GPE_BASE, GPE_LEN, 1,  gpe_readb, s);
1.1.1.5 ! root      551:     acpi_gpe_blk(&s->ar, GPE_BASE);
1.1       root      552: 
1.1.1.5 ! root      553:     register_ioport_read(PCI_UP_BASE, 4, 4, pci_up_read, s);
        !           554:     register_ioport_read(PCI_DOWN_BASE, 4, 4, pci_down_read, s);
1.1       root      555: 
1.1.1.5 ! root      556:     register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, s);
        !           557:     register_ioport_read(PCI_EJ_BASE, 4, 4,  pci_features_read, s);
1.1       root      558: 
1.1.1.2   root      559:     register_ioport_read(PCI_RMV_BASE, 4, 4,  pcirmv_read, s);
                    560: 
1.1       root      561:     pci_bus_hotplug(bus, piix4_device_hotplug, &s->dev.qdev);
                    562: }
                    563: 
                    564: static void enable_device(PIIX4PMState *s, int slot)
                    565: {
1.1.1.5 ! root      566:     s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
        !           567:     s->pci0_slot_device_present |= (1U << slot);
1.1       root      568: }
                    569: 
                    570: static void disable_device(PIIX4PMState *s, int slot)
                    571: {
1.1.1.5 ! root      572:     s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
        !           573:     s->pci0_status.down |= (1U << slot);
1.1       root      574: }
                    575: 
1.1.1.2   root      576: static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
                    577:                                PCIHotplugState state)
1.1       root      578: {
                    579:     int slot = PCI_SLOT(dev->devfn);
                    580:     PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev,
1.1.1.5 ! root      581:                                 PCI_DEVICE(qdev));
1.1       root      582: 
1.1.1.2   root      583:     /* Don't send event when device is enabled during qemu machine creation:
                    584:      * it is present on boot, no hotplug event is necessary. We do send an
                    585:      * event when the device is disabled later. */
                    586:     if (state == PCI_COLDPLUG_ENABLED) {
1.1.1.5 ! root      587:         s->pci0_slot_device_present |= (1U << slot);
1.1.1.2   root      588:         return 0;
                    589:     }
                    590: 
                    591:     if (state == PCI_HOTPLUG_ENABLED) {
1.1       root      592:         enable_device(s, slot);
                    593:     } else {
                    594:         disable_device(s, slot);
                    595:     }
1.1.1.2   root      596: 
                    597:     pm_update_sci(s);
                    598: 
1.1       root      599:     return 0;
                    600: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.