1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
/*
* QEMU Alpha PCI support functions.
*
* Some of this isn't very Alpha specific at all.
*
* ??? Sparse memory access not implemented.
*/
#include "config.h"
#include "alpha_sys.h"
#include "qemu-log.h"
#include "sysemu.h"
#include "vmware_vga.h"
/* PCI IO reads/writes, to byte-word addressable memory. */
/* ??? Doesn't handle multiple PCI busses. */
static uint64_t bw_io_read(void *opaque, target_phys_addr_t addr, unsigned size)
{
switch (size) {
case 1:
return cpu_inb(addr);
case 2:
return cpu_inw(addr);
case 4:
return cpu_inl(addr);
}
abort();
}
static void bw_io_write(void *opaque, target_phys_addr_t addr,
uint64_t val, unsigned size)
{
switch (size) {
case 1:
cpu_outb(addr, val);
break;
case 2:
cpu_outw(addr, val);
break;
case 4:
cpu_outl(addr, val);
break;
default:
abort();
}
}
const MemoryRegionOps alpha_pci_bw_io_ops = {
.read = bw_io_read,
.write = bw_io_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.impl = {
.min_access_size = 1,
.max_access_size = 4,
},
};
/* PCI config space reads/writes, to byte-word addressable memory. */
static uint64_t bw_conf1_read(void *opaque, target_phys_addr_t addr,
unsigned size)
{
PCIBus *b = opaque;
return pci_data_read(b, addr, size);
}
static void bw_conf1_write(void *opaque, target_phys_addr_t addr,
uint64_t val, unsigned size)
{
PCIBus *b = opaque;
pci_data_write(b, addr, val, size);
}
const MemoryRegionOps alpha_pci_conf1_ops = {
.read = bw_conf1_read,
.write = bw_conf1_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.impl = {
.min_access_size = 1,
.max_access_size = 4,
},
};
/* PCI/EISA Interrupt Acknowledge Cycle. */
static uint64_t iack_read(void *opaque, target_phys_addr_t addr, unsigned size)
{
return pic_read_irq(isa_pic);
}
static void special_write(void *opaque, target_phys_addr_t addr,
uint64_t val, unsigned size)
{
qemu_log("pci: special write cycle");
}
const MemoryRegionOps alpha_pci_iack_ops = {
.read = iack_read,
.write = special_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 4,
.max_access_size = 4,
},
.impl = {
.min_access_size = 4,
.max_access_size = 4,
},
};
void alpha_pci_vga_setup(PCIBus *pci_bus)
{
switch (vga_interface_type) {
#ifdef CONFIG_SPICE
case VGA_QXL:
pci_create_simple(pci_bus, -1, "qxl-vga");
return;
#endif
case VGA_CIRRUS:
pci_cirrus_vga_init(pci_bus);
return;
case VGA_VMWARE:
pci_vmsvga_init(pci_bus);
return;
}
/* If VGA is enabled at all, and one of the above didn't work, then
fallback to Standard VGA. */
if (vga_interface_type != VGA_NONE) {
pci_vga_init(pci_bus);
}
}
|