Statistics
| Branch: | Revision:

root / hw / macio.c @ 4e4fa398

History | View | Annotate | Download (4.3 kB)

1
/*
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
 */
25
#include "hw.h"
26
#include "ppc_mac.h"
27
#include "pci.h"
28
#include "escc.h"
29

    
30
typedef struct MacIOState
31
{
32
    PCIDevice parent;
33
    int is_oldworld;
34
    MemoryRegion bar;
35
    MemoryRegion *pic_mem;
36
    MemoryRegion *dbdma_mem;
37
    MemoryRegion *cuda_mem;
38
    MemoryRegion *escc_mem;
39
    void *nvram;
40
    int nb_ide;
41
    MemoryRegion *ide_mem[4];
42
} MacIOState;
43

    
44
static void macio_bar_setup(MacIOState *macio_state)
45
{
46
    int i;
47
    MemoryRegion *bar = &macio_state->bar;
48

    
49
    memory_region_init(bar, "macio", 0x80000);
50
    if (macio_state->pic_mem) {
51
        if (macio_state->is_oldworld) {
52
            /* Heathrow PIC */
53
            memory_region_add_subregion(bar, 0x00000, macio_state->pic_mem);
54
        } else {
55
            /* OpenPIC */
56
            memory_region_add_subregion(bar, 0x40000, macio_state->pic_mem);
57
        }
58
    }
59
    if (macio_state->dbdma_mem) {
60
        memory_region_add_subregion(bar, 0x08000, macio_state->dbdma_mem);
61
    }
62
    if (macio_state->escc_mem) {
63
        memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem);
64
    }
65
    if (macio_state->cuda_mem) {
66
        memory_region_add_subregion(bar, 0x16000, macio_state->cuda_mem);
67
    }
68
    for (i = 0; i < macio_state->nb_ide; i++) {
69
        if (macio_state->ide_mem[i]) {
70
            memory_region_add_subregion(bar, 0x1f000 + (i * 0x1000),
71
                                        macio_state->ide_mem[i]);
72
        }
73
    }
74
    if (macio_state->nvram != NULL)
75
        macio_nvram_setup_bar(macio_state->nvram, bar, 0x60000);
76
}
77

    
78
static int macio_initfn(PCIDevice *d)
79
{
80
    d->config[0x3d] = 0x01; // interrupt on pin 1
81
    return 0;
82
}
83

    
84
static 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

    
93
static DeviceInfo macio_info = {
94
    .name = "macio",
95
    .size = sizeof(MacIOState),
96
    .class_init = macio_class_init,
97
};
98

    
99
static void macio_register(void)
100
{
101
    pci_qdev_register(&macio_info);
102
}
103

    
104
device_init(macio_register);
105

    
106
void macio_init (PCIBus *bus, int device_id, int is_oldworld,
107
                 MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
108
                 MemoryRegion *cuda_mem, void *nvram,
109
                 int nb_ide, MemoryRegion **ide_mem,
110
                 MemoryRegion *escc_mem)
111
{
112
    PCIDevice *d;
113
    MacIOState *macio_state;
114
    int i;
115

    
116
    d = pci_create_simple(bus, -1, "macio");
117

    
118
    macio_state = DO_UPCAST(MacIOState, parent, d);
119
    macio_state->is_oldworld = is_oldworld;
120
    macio_state->pic_mem = pic_mem;
121
    macio_state->dbdma_mem = dbdma_mem;
122
    macio_state->cuda_mem = cuda_mem;
123
    macio_state->escc_mem = escc_mem;
124
    macio_state->nvram = nvram;
125
    if (nb_ide > 4)
126
        nb_ide = 4;
127
    macio_state->nb_ide = nb_ide;
128
    for (i = 0; i < nb_ide; i++)
129
        macio_state->ide_mem[i] = ide_mem[i];
130
    for (; i < 4; i++)
131
        macio_state->ide_mem[i] = NULL;
132
    /* Note: this code is strongly inspirated from the corresponding code
133
       in PearPC */
134

    
135
    pci_config_set_device_id(d->config, device_id);
136

    
137
    macio_bar_setup(macio_state);
138
    pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &macio_state->bar);
139
}