blob: eb15b890b19a4de527beeca341ac2b0a01ab6e0e [file] [log] [blame]
j_mayer3cbee152007-10-28 23:42:18 +00001/*
2 * PowerMac MacIO device emulation
3 *
4 * Copyright (c) 2005-2007 Fabrice Bellard
5 * Copyright (c) 2007 Jocelyn Mayer
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 */
pbrook87ecb682007-11-17 17:14:51 +000025#include "hw.h"
j_mayer3cbee152007-10-28 23:42:18 +000026#include "ppc_mac.h"
pbrook87ecb682007-11-17 17:14:51 +000027#include "pci.h"
blueswir17fa9ae12009-01-12 17:40:23 +000028#include "escc.h"
j_mayer3cbee152007-10-28 23:42:18 +000029
Anthony Liguorid8c51b02011-12-21 16:14:09 -060030typedef struct MacIOState
31{
32 PCIDevice parent;
j_mayer3cbee152007-10-28 23:42:18 +000033 int is_oldworld;
Avi Kivity23c5e4c2011-08-08 16:09:17 +030034 MemoryRegion bar;
35 MemoryRegion *pic_mem;
36 MemoryRegion *dbdma_mem;
37 MemoryRegion *cuda_mem;
38 MemoryRegion *escc_mem;
j_mayer74e91152007-11-04 01:16:04 +000039 void *nvram;
j_mayer3cbee152007-10-28 23:42:18 +000040 int nb_ide;
Avi Kivity23c5e4c2011-08-08 16:09:17 +030041 MemoryRegion *ide_mem[4];
Anthony Liguorid8c51b02011-12-21 16:14:09 -060042} MacIOState;
j_mayer3cbee152007-10-28 23:42:18 +000043
Anthony Liguorid8c51b02011-12-21 16:14:09 -060044static void macio_bar_setup(MacIOState *macio_state)
j_mayer3cbee152007-10-28 23:42:18 +000045{
j_mayer3cbee152007-10-28 23:42:18 +000046 int i;
Avi Kivity23c5e4c2011-08-08 16:09:17 +030047 MemoryRegion *bar = &macio_state->bar;
j_mayer3cbee152007-10-28 23:42:18 +000048
Avi Kivity23c5e4c2011-08-08 16:09:17 +030049 memory_region_init(bar, "macio", 0x80000);
50 if (macio_state->pic_mem) {
j_mayer3cbee152007-10-28 23:42:18 +000051 if (macio_state->is_oldworld) {
52 /* Heathrow PIC */
Avi Kivity23c5e4c2011-08-08 16:09:17 +030053 memory_region_add_subregion(bar, 0x00000, macio_state->pic_mem);
j_mayer3cbee152007-10-28 23:42:18 +000054 } else {
55 /* OpenPIC */
Avi Kivity23c5e4c2011-08-08 16:09:17 +030056 memory_region_add_subregion(bar, 0x40000, macio_state->pic_mem);
j_mayer3cbee152007-10-28 23:42:18 +000057 }
58 }
Avi Kivity23c5e4c2011-08-08 16:09:17 +030059 if (macio_state->dbdma_mem) {
60 memory_region_add_subregion(bar, 0x08000, macio_state->dbdma_mem);
j_mayer3cbee152007-10-28 23:42:18 +000061 }
Avi Kivity23c5e4c2011-08-08 16:09:17 +030062 if (macio_state->escc_mem) {
63 memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem);
blueswir17fa9ae12009-01-12 17:40:23 +000064 }
Avi Kivity23c5e4c2011-08-08 16:09:17 +030065 if (macio_state->cuda_mem) {
66 memory_region_add_subregion(bar, 0x16000, macio_state->cuda_mem);
j_mayer3cbee152007-10-28 23:42:18 +000067 }
68 for (i = 0; i < macio_state->nb_ide; i++) {
Avi Kivity23c5e4c2011-08-08 16:09:17 +030069 if (macio_state->ide_mem[i]) {
70 memory_region_add_subregion(bar, 0x1f000 + (i * 0x1000),
71 macio_state->ide_mem[i]);
j_mayer3cbee152007-10-28 23:42:18 +000072 }
73 }
j_mayer74e91152007-11-04 01:16:04 +000074 if (macio_state->nvram != NULL)
Avi Kivity23c5e4c2011-08-08 16:09:17 +030075 macio_nvram_setup_bar(macio_state->nvram, bar, 0x60000);
j_mayer3cbee152007-10-28 23:42:18 +000076}
77
Anthony Liguorid8c51b02011-12-21 16:14:09 -060078static int macio_initfn(PCIDevice *d)
79{
80 d->config[0x3d] = 0x01; // interrupt on pin 1
81 return 0;
82}
83
Anthony Liguori40021f02011-12-04 12:22:06 -060084static void macio_class_init(ObjectClass *klass, void *data)
85{
86 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
87
88 k->init = macio_initfn;
89 k->vendor_id = PCI_VENDOR_ID_APPLE;
90 k->class_id = PCI_CLASS_OTHERS << 8;
91}
92
Anthony Liguori39bffca2011-12-07 21:34:16 -060093static TypeInfo macio_info = {
94 .name = "macio",
95 .parent = TYPE_PCI_DEVICE,
96 .instance_size = sizeof(MacIOState),
97 .class_init = macio_class_init,
Anthony Liguorid8c51b02011-12-21 16:14:09 -060098};
99
Andreas Färber83f7d432012-02-09 15:20:55 +0100100static void macio_register_types(void)
Anthony Liguorid8c51b02011-12-21 16:14:09 -0600101{
Anthony Liguori39bffca2011-12-07 21:34:16 -0600102 type_register_static(&macio_info);
Anthony Liguorid8c51b02011-12-21 16:14:09 -0600103}
104
Andreas Färber83f7d432012-02-09 15:20:55 +0100105type_init(macio_register_types)
Anthony Liguorid8c51b02011-12-21 16:14:09 -0600106
Avi Kivity23c5e4c2011-08-08 16:09:17 +0300107void macio_init (PCIBus *bus, int device_id, int is_oldworld,
108 MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
109 MemoryRegion *cuda_mem, void *nvram,
110 int nb_ide, MemoryRegion **ide_mem,
111 MemoryRegion *escc_mem)
j_mayer3cbee152007-10-28 23:42:18 +0000112{
113 PCIDevice *d;
Anthony Liguorid8c51b02011-12-21 16:14:09 -0600114 MacIOState *macio_state;
j_mayer3cbee152007-10-28 23:42:18 +0000115 int i;
116
Anthony Liguorid8c51b02011-12-21 16:14:09 -0600117 d = pci_create_simple(bus, -1, "macio");
118
119 macio_state = DO_UPCAST(MacIOState, parent, d);
j_mayer3cbee152007-10-28 23:42:18 +0000120 macio_state->is_oldworld = is_oldworld;
Avi Kivity23c5e4c2011-08-08 16:09:17 +0300121 macio_state->pic_mem = pic_mem;
122 macio_state->dbdma_mem = dbdma_mem;
123 macio_state->cuda_mem = cuda_mem;
124 macio_state->escc_mem = escc_mem;
j_mayer74e91152007-11-04 01:16:04 +0000125 macio_state->nvram = nvram;
j_mayer3cbee152007-10-28 23:42:18 +0000126 if (nb_ide > 4)
127 nb_ide = 4;
128 macio_state->nb_ide = nb_ide;
129 for (i = 0; i < nb_ide; i++)
Avi Kivity23c5e4c2011-08-08 16:09:17 +0300130 macio_state->ide_mem[i] = ide_mem[i];
j_mayer3cbee152007-10-28 23:42:18 +0000131 for (; i < 4; i++)
Avi Kivity23c5e4c2011-08-08 16:09:17 +0300132 macio_state->ide_mem[i] = NULL;
j_mayer3cbee152007-10-28 23:42:18 +0000133 /* Note: this code is strongly inspirated from the corresponding code
134 in PearPC */
aliguorideb54392009-01-26 15:37:35 +0000135
aliguorideb54392009-01-26 15:37:35 +0000136 pci_config_set_device_id(d->config, device_id);
j_mayer3cbee152007-10-28 23:42:18 +0000137
Avi Kivity23c5e4c2011-08-08 16:09:17 +0300138 macio_bar_setup(macio_state);
Avi Kivitye824b2c2011-08-08 16:09:31 +0300139 pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &macio_state->bar);
j_mayer3cbee152007-10-28 23:42:18 +0000140}