2 * libqos PCI bindings for PC
4 * Copyright IBM, Corp. 2012-2013
7 * Anthony Liguori <aliguori@us.ibm.com>
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
13 #include "qemu/osdep.h"
15 #include "libqos/pci-pc.h"
17 #include "hw/pci/pci_regs.h"
19 #include "qemu-common.h"
22 #define ACPI_PCIHP_ADDR 0xae00
23 #define PCI_EJ_BASE 0x0008
25 typedef struct QPCIBusPC
30 static uint8_t qpci_pc_pio_readb(QPCIBus
*bus
, uint32_t addr
)
35 static void qpci_pc_pio_writeb(QPCIBus
*bus
, uint32_t addr
, uint8_t val
)
40 static uint16_t qpci_pc_pio_readw(QPCIBus
*bus
, uint32_t addr
)
45 static void qpci_pc_pio_writew(QPCIBus
*bus
, uint32_t addr
, uint16_t val
)
50 static uint32_t qpci_pc_pio_readl(QPCIBus
*bus
, uint32_t addr
)
55 static void qpci_pc_pio_writel(QPCIBus
*bus
, uint32_t addr
, uint32_t val
)
60 static uint64_t qpci_pc_pio_readq(QPCIBus
*bus
, uint32_t addr
)
62 return (uint64_t)inl(addr
) + ((uint64_t)inl(addr
+ 4) << 32);
65 static void qpci_pc_pio_writeq(QPCIBus
*bus
, uint32_t addr
, uint64_t val
)
67 outl(addr
, val
& 0xffffffff);
68 outl(addr
+ 4, val
>> 32);
71 static void qpci_pc_memread(QPCIBus
*bus
, uint32_t addr
, void *buf
, size_t len
)
73 memread(addr
, buf
, len
);
76 static void qpci_pc_memwrite(QPCIBus
*bus
, uint32_t addr
,
77 const void *buf
, size_t len
)
79 memwrite(addr
, buf
, len
);
82 static uint8_t qpci_pc_config_readb(QPCIBus
*bus
, int devfn
, uint8_t offset
)
84 outl(0xcf8, (1U << 31) | (devfn
<< 8) | offset
);
88 static uint16_t qpci_pc_config_readw(QPCIBus
*bus
, int devfn
, uint8_t offset
)
90 outl(0xcf8, (1U << 31) | (devfn
<< 8) | offset
);
94 static uint32_t qpci_pc_config_readl(QPCIBus
*bus
, int devfn
, uint8_t offset
)
96 outl(0xcf8, (1U << 31) | (devfn
<< 8) | offset
);
100 static void qpci_pc_config_writeb(QPCIBus
*bus
, int devfn
, uint8_t offset
, uint8_t value
)
102 outl(0xcf8, (1U << 31) | (devfn
<< 8) | offset
);
106 static void qpci_pc_config_writew(QPCIBus
*bus
, int devfn
, uint8_t offset
, uint16_t value
)
108 outl(0xcf8, (1U << 31) | (devfn
<< 8) | offset
);
112 static void qpci_pc_config_writel(QPCIBus
*bus
, int devfn
, uint8_t offset
, uint32_t value
)
114 outl(0xcf8, (1U << 31) | (devfn
<< 8) | offset
);
118 QPCIBus
*qpci_init_pc(QGuestAllocator
*alloc
)
122 ret
= g_malloc(sizeof(*ret
));
124 ret
->bus
.pio_readb
= qpci_pc_pio_readb
;
125 ret
->bus
.pio_readw
= qpci_pc_pio_readw
;
126 ret
->bus
.pio_readl
= qpci_pc_pio_readl
;
127 ret
->bus
.pio_readq
= qpci_pc_pio_readq
;
129 ret
->bus
.pio_writeb
= qpci_pc_pio_writeb
;
130 ret
->bus
.pio_writew
= qpci_pc_pio_writew
;
131 ret
->bus
.pio_writel
= qpci_pc_pio_writel
;
132 ret
->bus
.pio_writeq
= qpci_pc_pio_writeq
;
134 ret
->bus
.memread
= qpci_pc_memread
;
135 ret
->bus
.memwrite
= qpci_pc_memwrite
;
137 ret
->bus
.config_readb
= qpci_pc_config_readb
;
138 ret
->bus
.config_readw
= qpci_pc_config_readw
;
139 ret
->bus
.config_readl
= qpci_pc_config_readl
;
141 ret
->bus
.config_writeb
= qpci_pc_config_writeb
;
142 ret
->bus
.config_writew
= qpci_pc_config_writew
;
143 ret
->bus
.config_writel
= qpci_pc_config_writel
;
145 ret
->bus
.pio_alloc_ptr
= 0xc000;
146 ret
->bus
.mmio_alloc_ptr
= 0xE0000000;
147 ret
->bus
.mmio_limit
= 0x100000000ULL
;
152 void qpci_free_pc(QPCIBus
*bus
)
154 QPCIBusPC
*s
= container_of(bus
, QPCIBusPC
, bus
);
159 void qpci_unplug_acpi_device_test(const char *id
, uint8_t slot
)
164 cmd
= g_strdup_printf("{'execute': 'device_del',"
171 g_assert(!qdict_haskey(response
, "error"));
174 outb(ACPI_PCIHP_ADDR
+ PCI_EJ_BASE
, 1 << slot
);
178 g_assert(qdict_haskey(response
, "event"));
179 g_assert(!strcmp(qdict_get_str(response
, "event"), "DEVICE_DELETED"));