]> git.proxmox.com Git - qemu.git/blame - hw/apb_pci.c
Revert "vga: do not resize the screen on hw_invalidate"
[qemu.git] / hw / apb_pci.c
CommitLineData
502a5395
PB
1/*
2 * QEMU Ultrasparc APB PCI host
3 *
4 * Copyright (c) 2006 Fabrice Bellard
5fafdf24 5 *
502a5395
PB
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
80b3ada7 24
a94fd955 25/* XXX This file and most of its contents are somewhat misnamed. The
80b3ada7
PB
26 Ultrasparc PCI host is called the PCI Bus Module (PBM). The APB is
27 the secondary PCI bridge. */
28
72f44c8c 29#include "sysbus.h"
87ecb68b 30#include "pci.h"
4f5e19e6 31#include "pci_host.h"
a94fd955
BS
32
33/* debug APB */
34//#define DEBUG_APB
35
36#ifdef DEBUG_APB
001faf32
BS
37#define APB_DPRINTF(fmt, ...) \
38do { printf("APB: " fmt , ## __VA_ARGS__); } while (0)
a94fd955 39#else
001faf32 40#define APB_DPRINTF(fmt, ...)
a94fd955
BS
41#endif
42
930f3fe1
BS
43/*
44 * Chipset docs:
45 * PBM: "UltraSPARC IIi User's Manual",
46 * http://www.sun.com/processors/manuals/805-0087.pdf
47 *
48 * APB: "Advanced PCI Bridge (APB) User's Manual",
49 * http://www.sun.com/processors/manuals/805-1251.pdf
50 */
51
72f44c8c
BS
52typedef struct APBState {
53 SysBusDevice busdev;
54 PCIHostState host_state;
55} APBState;
502a5395 56
c227f099 57static void apb_config_writel (void *opaque, target_phys_addr_t addr,
f930d07e 58 uint32_t val)
502a5395
PB
59{
60 //PCIBus *s = opaque;
61
62 switch (addr & 0x3f) {
63 case 0x00: // Control/Status
64 case 0x10: // AFSR
65 case 0x18: // AFAR
66 case 0x20: // Diagnostic
67 case 0x28: // Target address space
f930d07e 68 // XXX
502a5395 69 default:
f930d07e 70 break;
502a5395
PB
71 }
72}
73
74static uint32_t apb_config_readl (void *opaque,
c227f099 75 target_phys_addr_t addr)
502a5395
PB
76{
77 //PCIBus *s = opaque;
78 uint32_t val;
79
80 switch (addr & 0x3f) {
81 case 0x00: // Control/Status
82 case 0x10: // AFSR
83 case 0x18: // AFAR
84 case 0x20: // Diagnostic
85 case 0x28: // Target address space
f930d07e 86 // XXX
502a5395 87 default:
f930d07e
BS
88 val = 0;
89 break;
502a5395
PB
90 }
91 return val;
92}
93
d60efc6b 94static CPUWriteMemoryFunc * const apb_config_write[] = {
502a5395
PB
95 &apb_config_writel,
96 &apb_config_writel,
97 &apb_config_writel,
98};
99
d60efc6b 100static CPUReadMemoryFunc * const apb_config_read[] = {
502a5395
PB
101 &apb_config_readl,
102 &apb_config_readl,
103 &apb_config_readl,
104};
105
c227f099 106static void pci_apb_iowriteb (void *opaque, target_phys_addr_t addr,
502a5395
PB
107 uint32_t val)
108{
afcea8cb 109 cpu_outb(addr & IOPORTS_MASK, val);
502a5395
PB
110}
111
c227f099 112static void pci_apb_iowritew (void *opaque, target_phys_addr_t addr,
502a5395
PB
113 uint32_t val)
114{
afcea8cb 115 cpu_outw(addr & IOPORTS_MASK, val);
502a5395
PB
116}
117
c227f099 118static void pci_apb_iowritel (void *opaque, target_phys_addr_t addr,
502a5395
PB
119 uint32_t val)
120{
afcea8cb 121 cpu_outl(addr & IOPORTS_MASK, val);
502a5395
PB
122}
123
c227f099 124static uint32_t pci_apb_ioreadb (void *opaque, target_phys_addr_t addr)
502a5395
PB
125{
126 uint32_t val;
127
afcea8cb 128 val = cpu_inb(addr & IOPORTS_MASK);
502a5395
PB
129 return val;
130}
131
c227f099 132static uint32_t pci_apb_ioreadw (void *opaque, target_phys_addr_t addr)
502a5395
PB
133{
134 uint32_t val;
135
afcea8cb 136 val = cpu_inw(addr & IOPORTS_MASK);
502a5395
PB
137 return val;
138}
139
c227f099 140static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr)
502a5395
PB
141{
142 uint32_t val;
143
afcea8cb 144 val = cpu_inl(addr & IOPORTS_MASK);
502a5395
PB
145 return val;
146}
147
d60efc6b 148static CPUWriteMemoryFunc * const pci_apb_iowrite[] = {
502a5395
PB
149 &pci_apb_iowriteb,
150 &pci_apb_iowritew,
151 &pci_apb_iowritel,
152};
153
d60efc6b 154static CPUReadMemoryFunc * const pci_apb_ioread[] = {
502a5395
PB
155 &pci_apb_ioreadb,
156 &pci_apb_ioreadw,
157 &pci_apb_ioreadl,
158};
159
80b3ada7 160/* The APB host has an IRQ line for each IRQ line of each slot. */
d2b59317 161static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
502a5395 162{
80b3ada7
PB
163 return ((pci_dev->devfn & 0x18) >> 1) + irq_num;
164}
165
166static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
167{
168 int bus_offset;
169 if (pci_dev->devfn & 1)
170 bus_offset = 16;
171 else
172 bus_offset = 0;
173 return bus_offset + irq_num;
d2b59317
PB
174}
175
5d4e84c8 176static void pci_apb_set_irq(void *opaque, int irq_num, int level)
d2b59317 177{
5d4e84c8
JQ
178 qemu_irq *pic = opaque;
179
80b3ada7 180 /* PCI IRQ map onto the first 32 INO. */
d537cf6c 181 qemu_set_irq(pic[irq_num], level);
502a5395
PB
182}
183
c227f099
AL
184PCIBus *pci_apb_init(target_phys_addr_t special_base,
185 target_phys_addr_t mem_base,
c190ea07 186 qemu_irq *pic, PCIBus **bus2, PCIBus **bus3)
502a5395 187{
72f44c8c
BS
188 DeviceState *dev;
189 SysBusDevice *s;
190 APBState *d;
502a5395 191
80b3ada7 192 /* Ultrasparc PBM main bus */
72f44c8c 193 dev = qdev_create(NULL, "pbm");
e23a1b33 194 qdev_init_nofail(dev);
72f44c8c
BS
195 s = sysbus_from_qdev(dev);
196 /* apb_config */
197 sysbus_mmio_map(s, 0, special_base + 0x2000ULL);
198 /* pci_ioport */
199 sysbus_mmio_map(s, 1, special_base + 0x2000000ULL);
200 /* mem_config: XXX size should be 4G-prom */
201 sysbus_mmio_map(s, 2, special_base + 0x1000000ULL);
202 /* mem_data */
203 sysbus_mmio_map(s, 3, mem_base);
204 d = FROM_SYSBUS(APBState, s);
c5ff6d54 205 d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
72f44c8c
BS
206 pci_apb_set_irq, pci_pbm_map_irq, pic,
207 0, 32);
208 pci_create_simple(d->host_state.bus, 0, "pbm");
209 /* APB secondary busses */
2217dcff
IY
210 *bus2 = pci_bridge_init(d->host_state.bus, PCI_DEVFN(1, 0),
211 PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_SIMBA,
212 pci_apb_map_irq,
72f44c8c 213 "Advanced PCI Bus secondary bridge 1");
2217dcff
IY
214 *bus3 = pci_bridge_init(d->host_state.bus, PCI_DEVFN(1, 1),
215 PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_SIMBA,
216 pci_apb_map_irq,
72f44c8c 217 "Advanced PCI Bus secondary bridge 2");
502a5395 218
72f44c8c
BS
219 return d->host_state.bus;
220}
221
81a322d4 222static int pci_pbm_init_device(SysBusDevice *dev)
72f44c8c
BS
223{
224
225 APBState *s;
226 int pci_mem_config, pci_mem_data, apb_config, pci_ioport;
227
228 s = FROM_SYSBUS(APBState, dev);
229 /* apb_config */
1eed09cb 230 apb_config = cpu_register_io_memory(apb_config_read,
f930d07e 231 apb_config_write, s);
72f44c8c
BS
232 sysbus_init_mmio(dev, 0x40ULL, apb_config);
233 /* pci_ioport */
1eed09cb 234 pci_ioport = cpu_register_io_memory(pci_apb_ioread,
502a5395 235 pci_apb_iowrite, s);
72f44c8c
BS
236 sysbus_init_mmio(dev, 0x10000ULL, pci_ioport);
237 /* mem_config */
a455783b 238 pci_mem_config = pci_host_config_register_io_memory(&s->host_state);
72f44c8c
BS
239 sysbus_init_mmio(dev, 0x10ULL, pci_mem_config);
240 /* mem_data */
4f5e19e6 241 pci_mem_data = pci_host_data_register_io_memory(&s->host_state);
72f44c8c 242 sysbus_init_mmio(dev, 0x10000000ULL, pci_mem_data);
81a322d4 243 return 0;
72f44c8c 244}
502a5395 245
81a322d4 246static int pbm_pci_host_init(PCIDevice *d)
72f44c8c 247{
deb54399
AL
248 pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_SUN);
249 pci_config_set_device_id(d->config, PCI_DEVICE_ID_SUN_SABRE);
502a5395
PB
250 d->config[0x04] = 0x06; // command = bus master, pci mem
251 d->config[0x05] = 0x00;
252 d->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
253 d->config[0x07] = 0x03; // status = medium devsel
254 d->config[0x08] = 0x00; // revision
255 d->config[0x09] = 0x00; // programming i/f
173a543b 256 pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
502a5395 257 d->config[0x0D] = 0x10; // latency_timer
110c50fd 258 d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
81a322d4 259 return 0;
72f44c8c 260}
80b3ada7 261
72f44c8c
BS
262static PCIDeviceInfo pbm_pci_host_info = {
263 .qdev.name = "pbm",
264 .qdev.size = sizeof(PCIDevice),
265 .init = pbm_pci_host_init,
266};
267
268static void pbm_register_devices(void)
269{
270 sysbus_register_dev("pbm", sizeof(APBState), pci_pbm_init_device);
271 pci_qdev_register(&pbm_pci_host_info);
502a5395 272}
72f44c8c
BS
273
274device_init(pbm_register_devices)