qemu

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

piix4.c (9282B)


      1 /*
      2  * QEMU PIIX4 PCI Bridge Emulation
      3  *
      4  * Copyright (c) 2006 Fabrice Bellard
      5  * Copyright (c) 2018 Hervé Poussineau
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a copy
      8  * of this software and associated documentation files (the "Software"), to deal
      9  * in the Software without restriction, including without limitation the rights
     10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     11  * copies of the Software, and to permit persons to whom the Software is
     12  * furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included in
     15  * all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     23  * THE SOFTWARE.
     24  */
     25 
     26 #include "qemu/osdep.h"
     27 #include "qapi/error.h"
     28 #include "hw/irq.h"
     29 #include "hw/southbridge/piix.h"
     30 #include "hw/pci/pci.h"
     31 #include "hw/ide/piix.h"
     32 #include "hw/isa/isa.h"
     33 #include "hw/intc/i8259.h"
     34 #include "hw/dma/i8257.h"
     35 #include "hw/timer/i8254.h"
     36 #include "hw/rtc/mc146818rtc.h"
     37 #include "hw/ide/pci.h"
     38 #include "hw/acpi/piix4.h"
     39 #include "hw/usb/hcd-uhci.h"
     40 #include "migration/vmstate.h"
     41 #include "sysemu/reset.h"
     42 #include "sysemu/runstate.h"
     43 #include "qom/object.h"
     44 
     45 struct PIIX4State {
     46     PCIDevice dev;
     47     qemu_irq cpu_intr;
     48     qemu_irq *isa;
     49 
     50     RTCState rtc;
     51     PCIIDEState ide;
     52     UHCIState uhci;
     53     PIIX4PMState pm;
     54     /* Reset Control Register */
     55     MemoryRegion rcr_mem;
     56     uint8_t rcr;
     57 };
     58 
     59 OBJECT_DECLARE_SIMPLE_TYPE(PIIX4State, PIIX4_PCI_DEVICE)
     60 
     61 static void piix4_set_irq(void *opaque, int irq_num, int level)
     62 {
     63     int i, pic_irq, pic_level;
     64     PIIX4State *s = opaque;
     65     PCIBus *bus = pci_get_bus(&s->dev);
     66 
     67     /* now we change the pic irq level according to the piix irq mappings */
     68     /* XXX: optimize */
     69     pic_irq = s->dev.config[PIIX_PIRQCA + irq_num];
     70     if (pic_irq < ISA_NUM_IRQS) {
     71         /* The pic level is the logical OR of all the PCI irqs mapped to it. */
     72         pic_level = 0;
     73         for (i = 0; i < PIIX_NUM_PIRQS; i++) {
     74             if (pic_irq == s->dev.config[PIIX_PIRQCA + i]) {
     75                 pic_level |= pci_bus_get_irq_level(bus, i);
     76             }
     77         }
     78         qemu_set_irq(s->isa[pic_irq], pic_level);
     79     }
     80 }
     81 
     82 static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
     83 {
     84     int slot;
     85 
     86     slot = PCI_SLOT(pci_dev->devfn);
     87 
     88     switch (slot) {
     89     /* PIIX4 USB */
     90     case 10:
     91         return 3;
     92     /* AMD 79C973 Ethernet */
     93     case 11:
     94         return 1;
     95     /* Crystal 4281 Sound */
     96     case 12:
     97         return 2;
     98     /* PCI slot 1 to 4 */
     99     case 18 ... 21:
    100         return ((slot - 18) + irq_num) & 0x03;
    101     /* Unknown device, don't do any translation */
    102     default:
    103         return irq_num;
    104     }
    105 }
    106 
    107 static void piix4_isa_reset(DeviceState *dev)
    108 {
    109     PIIX4State *d = PIIX4_PCI_DEVICE(dev);
    110     uint8_t *pci_conf = d->dev.config;
    111 
    112     pci_conf[0x04] = 0x07; // master, memory and I/O
    113     pci_conf[0x05] = 0x00;
    114     pci_conf[0x06] = 0x00;
    115     pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
    116     pci_conf[0x4c] = 0x4d;
    117     pci_conf[0x4e] = 0x03;
    118     pci_conf[0x4f] = 0x00;
    119     pci_conf[0x60] = 0x0a; // PCI A -> IRQ 10
    120     pci_conf[0x61] = 0x0a; // PCI B -> IRQ 10
    121     pci_conf[0x62] = 0x0b; // PCI C -> IRQ 11
    122     pci_conf[0x63] = 0x0b; // PCI D -> IRQ 11
    123     pci_conf[0x69] = 0x02;
    124     pci_conf[0x70] = 0x80;
    125     pci_conf[0x76] = 0x0c;
    126     pci_conf[0x77] = 0x0c;
    127     pci_conf[0x78] = 0x02;
    128     pci_conf[0x79] = 0x00;
    129     pci_conf[0x80] = 0x00;
    130     pci_conf[0x82] = 0x00;
    131     pci_conf[0xa0] = 0x08;
    132     pci_conf[0xa2] = 0x00;
    133     pci_conf[0xa3] = 0x00;
    134     pci_conf[0xa4] = 0x00;
    135     pci_conf[0xa5] = 0x00;
    136     pci_conf[0xa6] = 0x00;
    137     pci_conf[0xa7] = 0x00;
    138     pci_conf[0xa8] = 0x0f;
    139     pci_conf[0xaa] = 0x00;
    140     pci_conf[0xab] = 0x00;
    141     pci_conf[0xac] = 0x00;
    142     pci_conf[0xae] = 0x00;
    143 
    144     d->rcr = 0;
    145 }
    146 
    147 static int piix4_post_load(void *opaque, int version_id)
    148 {
    149     PIIX4State *s = opaque;
    150 
    151     if (version_id == 2) {
    152         s->rcr = 0;
    153     }
    154 
    155     return 0;
    156 }
    157 
    158 static const VMStateDescription vmstate_piix4 = {
    159     .name = "PIIX4",
    160     .version_id = 3,
    161     .minimum_version_id = 2,
    162     .post_load = piix4_post_load,
    163     .fields = (VMStateField[]) {
    164         VMSTATE_PCI_DEVICE(dev, PIIX4State),
    165         VMSTATE_UINT8_V(rcr, PIIX4State, 3),
    166         VMSTATE_END_OF_LIST()
    167     }
    168 };
    169 
    170 static void piix4_request_i8259_irq(void *opaque, int irq, int level)
    171 {
    172     PIIX4State *s = opaque;
    173     qemu_set_irq(s->cpu_intr, level);
    174 }
    175 
    176 static void piix4_set_i8259_irq(void *opaque, int irq, int level)
    177 {
    178     PIIX4State *s = opaque;
    179     qemu_set_irq(s->isa[irq], level);
    180 }
    181 
    182 static void piix4_rcr_write(void *opaque, hwaddr addr, uint64_t val,
    183                             unsigned int len)
    184 {
    185     PIIX4State *s = opaque;
    186 
    187     if (val & 4) {
    188         qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
    189         return;
    190     }
    191 
    192     s->rcr = val & 2; /* keep System Reset type only */
    193 }
    194 
    195 static uint64_t piix4_rcr_read(void *opaque, hwaddr addr, unsigned int len)
    196 {
    197     PIIX4State *s = opaque;
    198 
    199     return s->rcr;
    200 }
    201 
    202 static const MemoryRegionOps piix4_rcr_ops = {
    203     .read = piix4_rcr_read,
    204     .write = piix4_rcr_write,
    205     .endianness = DEVICE_LITTLE_ENDIAN,
    206     .impl = {
    207         .min_access_size = 1,
    208         .max_access_size = 1,
    209     },
    210 };
    211 
    212 static void piix4_realize(PCIDevice *dev, Error **errp)
    213 {
    214     PIIX4State *s = PIIX4_PCI_DEVICE(dev);
    215     PCIBus *pci_bus = pci_get_bus(dev);
    216     ISABus *isa_bus;
    217     qemu_irq *i8259_out_irq;
    218 
    219     isa_bus = isa_bus_new(DEVICE(dev), pci_address_space(dev),
    220                           pci_address_space_io(dev), errp);
    221     if (!isa_bus) {
    222         return;
    223     }
    224 
    225     qdev_init_gpio_in_named(DEVICE(dev), piix4_set_i8259_irq,
    226                             "isa", ISA_NUM_IRQS);
    227     qdev_init_gpio_out_named(DEVICE(dev), &s->cpu_intr,
    228                              "intr", 1);
    229 
    230     memory_region_init_io(&s->rcr_mem, OBJECT(dev), &piix4_rcr_ops, s,
    231                           "reset-control", 1);
    232     memory_region_add_subregion_overlap(pci_address_space_io(dev),
    233                                         PIIX_RCR_IOPORT, &s->rcr_mem, 1);
    234 
    235     /* initialize i8259 pic */
    236     i8259_out_irq = qemu_allocate_irqs(piix4_request_i8259_irq, s, 1);
    237     s->isa = i8259_init(isa_bus, *i8259_out_irq);
    238 
    239     /* initialize ISA irqs */
    240     isa_bus_irqs(isa_bus, s->isa);
    241 
    242     /* initialize pit */
    243     i8254_pit_init(isa_bus, 0x40, 0, NULL);
    244 
    245     /* DMA */
    246     i8257_dma_init(isa_bus, 0);
    247 
    248     /* RTC */
    249     qdev_prop_set_int32(DEVICE(&s->rtc), "base_year", 2000);
    250     if (!qdev_realize(DEVICE(&s->rtc), BUS(isa_bus), errp)) {
    251         return;
    252     }
    253     s->rtc.irq = isa_get_irq(ISA_DEVICE(&s->rtc), s->rtc.isairq);
    254 
    255     /* IDE */
    256     qdev_prop_set_int32(DEVICE(&s->ide), "addr", dev->devfn + 1);
    257     if (!qdev_realize(DEVICE(&s->ide), BUS(pci_bus), errp)) {
    258         return;
    259     }
    260 
    261     /* USB */
    262     qdev_prop_set_int32(DEVICE(&s->uhci), "addr", dev->devfn + 2);
    263     if (!qdev_realize(DEVICE(&s->uhci), BUS(pci_bus), errp)) {
    264         return;
    265     }
    266 
    267     /* ACPI controller */
    268     qdev_prop_set_int32(DEVICE(&s->pm), "addr", dev->devfn + 3);
    269     if (!qdev_realize(DEVICE(&s->pm), BUS(pci_bus), errp)) {
    270         return;
    271     }
    272     qdev_connect_gpio_out(DEVICE(&s->pm), 0, s->isa[9]);
    273 
    274     pci_bus_irqs(pci_bus, piix4_set_irq, pci_slot_get_pirq, s, PIIX_NUM_PIRQS);
    275 }
    276 
    277 static void piix4_init(Object *obj)
    278 {
    279     PIIX4State *s = PIIX4_PCI_DEVICE(obj);
    280 
    281     object_initialize_child(obj, "rtc", &s->rtc, TYPE_MC146818_RTC);
    282     object_initialize_child(obj, "ide", &s->ide, TYPE_PIIX4_IDE);
    283     object_initialize_child(obj, "uhci", &s->uhci, "piix4-usb-uhci");
    284 
    285     object_initialize_child(obj, "pm", &s->pm, TYPE_PIIX4_PM);
    286     qdev_prop_set_uint32(DEVICE(&s->pm), "smb_io_base", 0x1100);
    287     qdev_prop_set_bit(DEVICE(&s->pm), "smm-enabled", 0);
    288 }
    289 
    290 static void piix4_class_init(ObjectClass *klass, void *data)
    291 {
    292     DeviceClass *dc = DEVICE_CLASS(klass);
    293     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
    294 
    295     k->realize = piix4_realize;
    296     k->vendor_id = PCI_VENDOR_ID_INTEL;
    297     k->device_id = PCI_DEVICE_ID_INTEL_82371AB_0;
    298     k->class_id = PCI_CLASS_BRIDGE_ISA;
    299     dc->reset = piix4_isa_reset;
    300     dc->desc = "ISA bridge";
    301     dc->vmsd = &vmstate_piix4;
    302     /*
    303      * Reason: part of PIIX4 southbridge, needs to be wired up,
    304      * e.g. by mips_malta_init()
    305      */
    306     dc->user_creatable = false;
    307     dc->hotpluggable = false;
    308 }
    309 
    310 static const TypeInfo piix4_info = {
    311     .name          = TYPE_PIIX4_PCI_DEVICE,
    312     .parent        = TYPE_PCI_DEVICE,
    313     .instance_size = sizeof(PIIX4State),
    314     .instance_init = piix4_init,
    315     .class_init    = piix4_class_init,
    316     .interfaces = (InterfaceInfo[]) {
    317         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
    318         { },
    319     },
    320 };
    321 
    322 static void piix4_register_types(void)
    323 {
    324     type_register_static(&piix4_info);
    325 }
    326 
    327 type_init(piix4_register_types)