]> Git Repo - qemu.git/blame - hw/pci-host/apb.c
apb: rename QOM type from TYPE_APB to TYPE_SABRE
[qemu.git] / hw / pci-host / apb.c
CommitLineData
502a5395
PB
1/*
2 * QEMU Ultrasparc APB PCI host
3 *
4 * Copyright (c) 2006 Fabrice Bellard
9625036d 5 * Copyright (c) 2012,2013 Artyom Tarasenko
5fafdf24 6 *
502a5395
PB
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 */
80b3ada7 25
a94fd955 26/* XXX This file and most of its contents are somewhat misnamed. The
80b3ada7
PB
27 Ultrasparc PCI host is called the PCI Bus Module (PBM). The APB is
28 the secondary PCI bridge. */
29
97d5408f 30#include "qemu/osdep.h"
83c9f4ca
PB
31#include "hw/sysbus.h"
32#include "hw/pci/pci.h"
33#include "hw/pci/pci_host.h"
34#include "hw/pci/pci_bridge.h"
35#include "hw/pci/pci_bus.h"
ffd9589e 36#include "hw/pci-bridge/simba.h"
0d09e41a 37#include "hw/pci-host/apb.h"
9c17d615 38#include "sysemu/sysemu.h"
022c62cb 39#include "exec/address-spaces.h"
aea5b071 40#include "qapi/error.h"
03dd024f 41#include "qemu/log.h"
a94fd955
BS
42
43/* debug APB */
44//#define DEBUG_APB
45
46#ifdef DEBUG_APB
001faf32
BS
47#define APB_DPRINTF(fmt, ...) \
48do { printf("APB: " fmt , ## __VA_ARGS__); } while (0)
a94fd955 49#else
001faf32 50#define APB_DPRINTF(fmt, ...)
a94fd955
BS
51#endif
52
930f3fe1
BS
53/*
54 * Chipset docs:
55 * PBM: "UltraSPARC IIi User's Manual",
56 * http://www.sun.com/processors/manuals/805-0087.pdf
930f3fe1
BS
57 */
58
95819af0
BS
59#define PBM_PCI_IMR_MASK 0x7fffffff
60#define PBM_PCI_IMR_ENABLED 0x80000000
61
af23906d
PM
62#define POR (1U << 31)
63#define SOFT_POR (1U << 30)
64#define SOFT_XIR (1U << 29)
65#define BTN_POR (1U << 28)
66#define BTN_XIR (1U << 27)
95819af0
BS
67#define RESET_MASK 0xf8000000
68#define RESET_WCMASK 0x98000000
69#define RESET_WMASK 0x60000000
70
9625036d 71#define NO_IRQ_REQUEST (MAX_IVEC + 1)
361dea40 72
b14dcaf4 73static inline void sabre_set_request(SabreState *s, unsigned int irq_num)
9625036d
AT
74{
75 APB_DPRINTF("%s: request irq %d\n", __func__, irq_num);
76
77 s->irq_request = irq_num;
78 qemu_set_irq(s->ivec_irqs[irq_num], 1);
79}
80
b14dcaf4 81static inline void sabre_check_irqs(SabreState *s)
9625036d 82{
9625036d
AT
83 unsigned int i;
84
85 /* Previous request is not acknowledged, resubmit */
86 if (s->irq_request != NO_IRQ_REQUEST) {
fe984c7d 87 sabre_set_request(s, s->irq_request);
9625036d
AT
88 return;
89 }
90 /* no request pending */
91 if (s->pci_irq_in == 0ULL) {
92 return;
93 }
94 for (i = 0; i < 32; i++) {
95 if (s->pci_irq_in & (1ULL << i)) {
96 if (s->pci_irq_map[i >> 2] & PBM_PCI_IMR_ENABLED) {
fe984c7d 97 sabre_set_request(s, i);
9625036d
AT
98 return;
99 }
100 }
101 }
102 for (i = 32; i < 64; i++) {
103 if (s->pci_irq_in & (1ULL << i)) {
104 if (s->obio_irq_map[i - 32] & PBM_PCI_IMR_ENABLED) {
fe984c7d 105 sabre_set_request(s, i);
9625036d
AT
106 break;
107 }
108 }
109 }
110}
111
b14dcaf4 112static inline void sabre_clear_request(SabreState *s, unsigned int irq_num)
9625036d
AT
113{
114 APB_DPRINTF("%s: clear request irq %d\n", __func__, irq_num);
115 qemu_set_irq(s->ivec_irqs[irq_num], 0);
116 s->irq_request = NO_IRQ_REQUEST;
117}
94d19914 118
fe984c7d 119static AddressSpace *sabre_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
ae74bbe7
MCA
120{
121 IOMMUState *is = opaque;
122
123 return &is->iommu_as;
124}
125
fe984c7d 126static void sabre_config_write(void *opaque, hwaddr addr,
3812ed0b 127 uint64_t val, unsigned size)
502a5395 128{
b14dcaf4 129 SabreState *s = opaque;
95819af0 130
c0907c9e 131 APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
95819af0
BS
132
133 switch (addr & 0xffff) {
134 case 0x30 ... 0x4f: /* DMA error registers */
135 /* XXX: not implemented yet */
136 break;
95819af0
BS
137 case 0xc00 ... 0xc3f: /* PCI interrupt control */
138 if (addr & 4) {
9625036d
AT
139 unsigned int ino = (addr & 0x3f) >> 3;
140 s->pci_irq_map[ino] &= PBM_PCI_IMR_MASK;
141 s->pci_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
142 if ((s->irq_request == ino) && !(val & ~PBM_PCI_IMR_MASK)) {
fe984c7d 143 sabre_clear_request(s, ino);
9625036d 144 }
fe984c7d 145 sabre_check_irqs(s);
95819af0
BS
146 }
147 break;
de739df8 148 case 0x1000 ... 0x107f: /* OBIO interrupt control */
361dea40 149 if (addr & 4) {
9625036d
AT
150 unsigned int ino = ((addr & 0xff) >> 3);
151 s->obio_irq_map[ino] &= PBM_PCI_IMR_MASK;
152 s->obio_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
153 if ((s->irq_request == (ino | 0x20))
154 && !(val & ~PBM_PCI_IMR_MASK)) {
fe984c7d 155 sabre_clear_request(s, ino | 0x20);
9625036d 156 }
fe984c7d 157 sabre_check_irqs(s);
361dea40
BS
158 }
159 break;
9625036d 160 case 0x1400 ... 0x14ff: /* PCI interrupt clear */
94d19914 161 if (addr & 4) {
9625036d
AT
162 unsigned int ino = (addr & 0xff) >> 5;
163 if ((s->irq_request / 4) == ino) {
fe984c7d
MCA
164 sabre_clear_request(s, s->irq_request);
165 sabre_check_irqs(s);
9625036d 166 }
94d19914
AT
167 }
168 break;
169 case 0x1800 ... 0x1860: /* OBIO interrupt clear */
170 if (addr & 4) {
9625036d
AT
171 unsigned int ino = ((addr & 0xff) >> 3) | 0x20;
172 if (s->irq_request == ino) {
fe984c7d
MCA
173 sabre_clear_request(s, ino);
174 sabre_check_irqs(s);
9625036d 175 }
94d19914
AT
176 }
177 break;
95819af0
BS
178 case 0x2000 ... 0x202f: /* PCI control */
179 s->pci_control[(addr & 0x3f) >> 2] = val;
180 break;
181 case 0xf020 ... 0xf027: /* Reset control */
182 if (addr & 4) {
183 val &= RESET_MASK;
184 s->reset_control &= ~(val & RESET_WCMASK);
185 s->reset_control |= val & RESET_WMASK;
186 if (val & SOFT_POR) {
9c0afd0e 187 s->nr_resets = 0;
cf83f140 188 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
95819af0 189 } else if (val & SOFT_XIR) {
cf83f140 190 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
95819af0
BS
191 }
192 }
193 break;
194 case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
195 case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
196 case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
197 case 0xf000 ... 0xf01f: /* FFB config, memory control */
198 /* we don't care */
502a5395 199 default:
f930d07e 200 break;
502a5395
PB
201 }
202}
203
fe984c7d 204static uint64_t sabre_config_read(void *opaque,
a8170e5e 205 hwaddr addr, unsigned size)
502a5395 206{
b14dcaf4 207 SabreState *s = opaque;
502a5395
PB
208 uint32_t val;
209
95819af0
BS
210 switch (addr & 0xffff) {
211 case 0x30 ... 0x4f: /* DMA error registers */
212 val = 0;
213 /* XXX: not implemented yet */
214 break;
95819af0
BS
215 case 0xc00 ... 0xc3f: /* PCI interrupt control */
216 if (addr & 4) {
217 val = s->pci_irq_map[(addr & 0x3f) >> 3];
218 } else {
219 val = 0;
220 }
221 break;
de739df8 222 case 0x1000 ... 0x107f: /* OBIO interrupt control */
361dea40
BS
223 if (addr & 4) {
224 val = s->obio_irq_map[(addr & 0xff) >> 3];
225 } else {
226 val = 0;
227 }
228 break;
de739df8
MCA
229 case 0x1080 ... 0x108f: /* PCI bus error */
230 if (addr & 4) {
231 val = s->pci_err_irq_map[(addr & 0xf) >> 3];
232 } else {
233 val = 0;
234 }
235 break;
95819af0
BS
236 case 0x2000 ... 0x202f: /* PCI control */
237 val = s->pci_control[(addr & 0x3f) >> 2];
238 break;
239 case 0xf020 ... 0xf027: /* Reset control */
240 if (addr & 4) {
241 val = s->reset_control;
242 } else {
243 val = 0;
244 }
245 break;
246 case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
247 case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
248 case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
249 case 0xf000 ... 0xf01f: /* FFB config, memory control */
250 /* we don't care */
502a5395 251 default:
f930d07e
BS
252 val = 0;
253 break;
502a5395 254 }
c0907c9e 255 APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, val);
95819af0 256
502a5395
PB
257 return val;
258}
259
fe984c7d
MCA
260static const MemoryRegionOps sabre_config_ops = {
261 .read = sabre_config_read,
262 .write = sabre_config_write,
b2f9005a 263 .endianness = DEVICE_BIG_ENDIAN,
502a5395
PB
264};
265
fe984c7d
MCA
266static void sabre_pci_config_write(void *opaque, hwaddr addr,
267 uint64_t val, unsigned size)
5a5d4a76 268{
b14dcaf4 269 SabreState *s = opaque;
2b8fbcd8 270 PCIHostState *phb = PCI_HOST_BRIDGE(s);
63e6f31d 271
c0907c9e 272 APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
2b8fbcd8 273 pci_data_write(phb->bus, addr, val, size);
5a5d4a76
BS
274}
275
fe984c7d
MCA
276static uint64_t sabre_pci_config_read(void *opaque, hwaddr addr,
277 unsigned size)
5a5d4a76
BS
278{
279 uint32_t ret;
b14dcaf4 280 SabreState *s = opaque;
2b8fbcd8 281 PCIHostState *phb = PCI_HOST_BRIDGE(s);
5a5d4a76 282
2b8fbcd8 283 ret = pci_data_read(phb->bus, addr, size);
c0907c9e 284 APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, ret);
5a5d4a76
BS
285 return ret;
286}
287
fe984c7d
MCA
288/* The sabre host has an IRQ line for each IRQ line of each slot. */
289static int pci_sabre_map_irq(PCIDevice *pci_dev, int irq_num)
502a5395 290{
6864fa38
MCA
291 /* Return the irq as swizzled by the PBM */
292 return irq_num;
80b3ada7
PB
293}
294
90302ada 295static int pci_simbaA_map_irq(PCIDevice *pci_dev, int irq_num)
80b3ada7 296{
d9e4d682
MCA
297 /* The on-board devices have fixed (legacy) OBIO intnos */
298 switch (PCI_SLOT(pci_dev->devfn)) {
299 case 1:
300 /* Onboard NIC */
a5546222 301 return OBIO_NIC_IRQ;
d9e4d682
MCA
302 case 3:
303 /* Onboard IDE */
a5546222 304 return OBIO_HDD_IRQ;
d9e4d682
MCA
305 default:
306 /* Normal intno, fall through */
307 break;
6864fa38 308 }
6864fa38 309
d9e4d682
MCA
310 return ((PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;
311}
6864fa38 312
90302ada 313static int pci_simbaB_map_irq(PCIDevice *pci_dev, int irq_num)
d9e4d682
MCA
314{
315 return (0x10 + (PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;
d2b59317
PB
316}
317
fe984c7d 318static void pci_sabre_set_irq(void *opaque, int irq_num, int level)
d2b59317 319{
b14dcaf4 320 SabreState *s = opaque;
5d4e84c8 321
9625036d 322 APB_DPRINTF("%s: set irq_in %d level %d\n", __func__, irq_num, level);
80b3ada7 323 /* PCI IRQ map onto the first 32 INO. */
95819af0 324 if (irq_num < 32) {
9625036d
AT
325 if (level) {
326 s->pci_irq_in |= 1ULL << irq_num;
327 if (s->pci_irq_map[irq_num >> 2] & PBM_PCI_IMR_ENABLED) {
fe984c7d 328 sabre_set_request(s, irq_num);
9625036d 329 }
361dea40 330 } else {
9625036d 331 s->pci_irq_in &= ~(1ULL << irq_num);
361dea40
BS
332 }
333 } else {
9625036d
AT
334 /* OBIO IRQ map onto the next 32 INO. */
335 if (level) {
361dea40 336 APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
9625036d
AT
337 s->pci_irq_in |= 1ULL << irq_num;
338 if ((s->irq_request == NO_IRQ_REQUEST)
339 && (s->obio_irq_map[irq_num - 32] & PBM_PCI_IMR_ENABLED)) {
fe984c7d 340 sabre_set_request(s, irq_num);
9625036d 341 }
95819af0 342 } else {
9625036d 343 s->pci_irq_in &= ~(1ULL << irq_num);
95819af0
BS
344 }
345 }
502a5395
PB
346}
347
fe984c7d 348static void sabre_reset(DeviceState *d)
72f44c8c 349{
b14dcaf4 350 SabreState *s = SABRE_DEVICE(d);
33c5eb02
MCA
351 PCIDevice *pci_dev;
352 unsigned int i;
353 uint16_t cmd;
72f44c8c 354
95819af0
BS
355 for (i = 0; i < 8; i++) {
356 s->pci_irq_map[i] &= PBM_PCI_IMR_MASK;
357 }
d1d80055
AT
358 for (i = 0; i < 32; i++) {
359 s->obio_irq_map[i] &= PBM_PCI_IMR_MASK;
360 }
95819af0 361
9625036d
AT
362 s->irq_request = NO_IRQ_REQUEST;
363 s->pci_irq_in = 0ULL;
364
9c0afd0e 365 if (s->nr_resets++ == 0) {
95819af0
BS
366 /* Power on reset */
367 s->reset_control = POR;
368 }
33c5eb02
MCA
369
370 /* As this is the busA PCI bridge which contains the on-board devices
371 * attached to the ebus, ensure that we initially allow IO transactions
372 * so that we get the early serial console until OpenBIOS can properly
373 * configure the PCI bridge itself */
374 pci_dev = PCI_DEVICE(s->bridgeA);
375 cmd = pci_get_word(pci_dev->config + PCI_COMMAND);
376 pci_set_word(pci_dev->config + PCI_COMMAND, cmd | PCI_COMMAND_IO);
377 pci_bridge_update_mappings(PCI_BRIDGE(pci_dev));
95819af0
BS
378}
379
3812ed0b 380static const MemoryRegionOps pci_config_ops = {
fe984c7d
MCA
381 .read = sabre_pci_config_read,
382 .write = sabre_pci_config_write,
b2f9005a 383 .endianness = DEVICE_LITTLE_ENDIAN,
3812ed0b
AK
384};
385
fe984c7d 386static void sabre_realize(DeviceState *dev, Error **errp)
95819af0 387{
b14dcaf4 388 SabreState *s = SABRE_DEVICE(dev);
cacd0580
MCA
389 PCIHostState *phb = PCI_HOST_BRIDGE(dev);
390 SysBusDevice *sbd = SYS_BUS_DEVICE(s);
68f79994 391 PCIDevice *pci_dev;
502a5395 392
72f44c8c 393 /* apb_config */
cacd0580 394 sysbus_mmio_map(sbd, 0, s->special_base);
d63baf92 395 /* PCI configuration space */
cacd0580 396 sysbus_mmio_map(sbd, 1, s->special_base + 0x1000000ULL);
72f44c8c 397 /* pci_ioport */
cacd0580 398 sysbus_mmio_map(sbd, 2, s->special_base + 0x2000000ULL);
d63baf92 399
cacd0580
MCA
400 memory_region_init(&s->pci_mmio, OBJECT(s), "pci-mmio", 0x100000000ULL);
401 memory_region_add_subregion(get_system_memory(), s->mem_base,
402 &s->pci_mmio);
403
acc95bc8 404 phb->bus = pci_register_root_bus(dev, "pci",
fe984c7d 405 pci_sabre_set_irq, pci_sabre_map_irq, s,
acc95bc8
MT
406 &s->pci_mmio,
407 &s->pci_ioport,
408 0, 32, TYPE_PCI_BUS);
f69539b1 409
8fb28035 410 pci_create_simple(phb->bus, 0, TYPE_SABRE_PCI_DEVICE);
d63baf92 411
fe984c7d 412 /* IOMMU */
aea5b071
MCA
413 memory_region_add_subregion_overlap(&s->apb_config, 0x200,
414 sysbus_mmio_get_region(SYS_BUS_DEVICE(s->iommu), 0), 1);
fe984c7d 415 pci_setup_iommu(phb->bus, sabre_pci_dma_iommu, s->iommu);
ae74bbe7 416
72f44c8c 417 /* APB secondary busses */
2b8fbcd8 418 pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 0), true,
90302ada 419 TYPE_SIMBA_PCI_BRIDGE);
cacd0580 420 s->bridgeB = PCI_BRIDGE(pci_dev);
90302ada 421 pci_bridge_map_irq(s->bridgeB, "pciB", pci_simbaB_map_irq);
68f79994 422 qdev_init_nofail(&pci_dev->qdev);
68f79994 423
2b8fbcd8 424 pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 1), true,
90302ada 425 TYPE_SIMBA_PCI_BRIDGE);
cacd0580 426 s->bridgeA = PCI_BRIDGE(pci_dev);
90302ada 427 pci_bridge_map_irq(s->bridgeA, "pciA", pci_simbaA_map_irq);
68f79994 428 qdev_init_nofail(&pci_dev->qdev);
95819af0
BS
429}
430
fe984c7d 431static void sabre_init(Object *obj)
95819af0 432{
b14dcaf4 433 SabreState *s = SABRE_DEVICE(obj);
cacd0580 434 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
95819af0 435 unsigned int i;
72f44c8c 436
95819af0
BS
437 for (i = 0; i < 8; i++) {
438 s->pci_irq_map[i] = (0x1f << 6) | (i << 2);
439 }
de739df8
MCA
440 for (i = 0; i < 2; i++) {
441 s->pci_err_irq_map[i] = (0x1f << 6) | 0x30;
442 }
d1d80055
AT
443 for (i = 0; i < 32; i++) {
444 s->obio_irq_map[i] = ((0x1f << 6) | 0x20) + i;
445 }
fe984c7d 446 qdev_init_gpio_in_named(DEVICE(s), pci_sabre_set_irq, "pbm-irq", MAX_IVEC);
2a4d6af5 447 qdev_init_gpio_out_named(DEVICE(s), s->ivec_irqs, "ivec-irq", MAX_IVEC);
9625036d
AT
448 s->irq_request = NO_IRQ_REQUEST;
449 s->pci_irq_in = 0ULL;
95819af0 450
aea5b071
MCA
451 /* IOMMU */
452 object_property_add_link(obj, "iommu", TYPE_SUN4U_IOMMU,
453 (Object **) &s->iommu,
454 qdev_prop_allow_set_link_before_realize,
455 0, NULL);
456
72f44c8c 457 /* apb_config */
fe984c7d 458 memory_region_init_io(&s->apb_config, OBJECT(s), &sabre_config_ops, s,
40c5dce9 459 "apb-config", 0x10000);
d63baf92 460 /* at region 0 */
b26f4419 461 sysbus_init_mmio(sbd, &s->apb_config);
d63baf92 462
40c5dce9
PB
463 memory_region_init_io(&s->pci_config, OBJECT(s), &pci_config_ops, s,
464 "apb-pci-config", 0x1000000);
d63baf92 465 /* at region 1 */
b26f4419 466 sysbus_init_mmio(sbd, &s->pci_config);
d63baf92
IK
467
468 /* pci_ioport */
6864fa38
MCA
469 memory_region_init(&s->pci_ioport, OBJECT(s), "apb-pci-ioport", 0x1000000);
470
d63baf92 471 /* at region 2 */
b26f4419 472 sysbus_init_mmio(sbd, &s->pci_ioport);
72f44c8c 473}
502a5395 474
5560c58a 475static void sabre_pci_realize(PCIDevice *d, Error **errp)
72f44c8c 476{
9fe52c7f
BS
477 pci_set_word(d->config + PCI_COMMAND,
478 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
479 pci_set_word(d->config + PCI_STATUS,
480 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
481 PCI_STATUS_DEVSEL_MEDIUM);
72f44c8c 482}
80b3ada7 483
5560c58a 484static void sabre_pci_class_init(ObjectClass *klass, void *data)
40021f08
AL
485{
486 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
08c58f92 487 DeviceClass *dc = DEVICE_CLASS(klass);
40021f08 488
5560c58a 489 k->realize = sabre_pci_realize;
40021f08
AL
490 k->vendor_id = PCI_VENDOR_ID_SUN;
491 k->device_id = PCI_DEVICE_ID_SUN_SABRE;
492 k->class_id = PCI_CLASS_BRIDGE_HOST;
08c58f92
MA
493 /*
494 * PCI-facing part of the host bridge, not usable without the
495 * host-facing part, which can't be device_add'ed, yet.
496 */
e90f2a8c 497 dc->user_creatable = false;
40021f08
AL
498}
499
5560c58a 500static const TypeInfo sabre_pci_info = {
8fb28035 501 .name = TYPE_SABRE_PCI_DEVICE,
39bffca2 502 .parent = TYPE_PCI_DEVICE,
8fb28035 503 .instance_size = sizeof(SabrePCIState),
5560c58a 504 .class_init = sabre_pci_class_init,
fd3b02c8
EH
505 .interfaces = (InterfaceInfo[]) {
506 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
507 { },
508 },
72f44c8c
BS
509};
510
fe984c7d 511static Property sabre_properties[] = {
b14dcaf4
MCA
512 DEFINE_PROP_UINT64("special-base", SabreState, special_base, 0),
513 DEFINE_PROP_UINT64("mem-base", SabreState, mem_base, 0),
cacd0580
MCA
514 DEFINE_PROP_END_OF_LIST(),
515};
516
fe984c7d 517static void sabre_class_init(ObjectClass *klass, void *data)
999e12bb 518{
39bffca2 519 DeviceClass *dc = DEVICE_CLASS(klass);
999e12bb 520
fe984c7d
MCA
521 dc->realize = sabre_realize;
522 dc->reset = sabre_reset;
523 dc->props = sabre_properties;
b26f4419 524 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
999e12bb
AL
525}
526
fe984c7d 527static const TypeInfo sabre_info = {
b14dcaf4 528 .name = TYPE_SABRE,
2b8fbcd8 529 .parent = TYPE_PCI_HOST_BRIDGE,
b14dcaf4 530 .instance_size = sizeof(SabreState),
fe984c7d
MCA
531 .instance_init = sabre_init,
532 .class_init = sabre_class_init,
95819af0 533};
68f79994 534
fe984c7d 535static void sabre_register_types(void)
72f44c8c 536{
fe984c7d 537 type_register_static(&sabre_info);
5560c58a 538 type_register_static(&sabre_pci_info);
502a5395 539}
72f44c8c 540
fe984c7d 541type_init(sabre_register_types)
This page took 0.855588 seconds and 4 git commands to generate.