source: trunk/packages/xen-3.1/xen-3.1/tools/ioemu/hw/apb_pci.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

File size: 6.5 KB
Line 
1/*
2 * QEMU Ultrasparc APB PCI host
3 *
4 * Copyright (c) 2006 Fabrice Bellard
5 *
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 */
24#include "vl.h"
25typedef target_phys_addr_t pci_addr_t;
26#include "pci_host.h"
27
28typedef PCIHostState APBState;
29
30static void pci_apb_config_writel (void *opaque, target_phys_addr_t addr,
31                                         uint32_t val)
32{
33    APBState *s = opaque;
34    int i;
35
36    for (i = 11; i < 32; i++) {
37        if ((val & (1 << i)) != 0)
38            break;
39    }
40    s->config_reg = (1 << 16) | (val & 0x7FC) | (i << 11);
41}
42
43static uint32_t pci_apb_config_readl (void *opaque,
44                                            target_phys_addr_t addr)
45{
46    APBState *s = opaque;
47    uint32_t val;
48    int devfn;
49
50    devfn = (s->config_reg >> 8) & 0xFF;
51    val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC);
52    return val;
53}
54
55static CPUWriteMemoryFunc *pci_apb_config_write[] = {
56    &pci_apb_config_writel,
57    &pci_apb_config_writel,
58    &pci_apb_config_writel,
59};
60
61static CPUReadMemoryFunc *pci_apb_config_read[] = {
62    &pci_apb_config_readl,
63    &pci_apb_config_readl,
64    &pci_apb_config_readl,
65};
66
67static void apb_config_writel (void *opaque, target_phys_addr_t addr,
68                               uint32_t val)
69{
70    //PCIBus *s = opaque;
71
72    switch (addr & 0x3f) {
73    case 0x00: // Control/Status
74    case 0x10: // AFSR
75    case 0x18: // AFAR
76    case 0x20: // Diagnostic
77    case 0x28: // Target address space
78        // XXX
79    default:
80        break;
81    }
82}
83
84static uint32_t apb_config_readl (void *opaque,
85                                  target_phys_addr_t addr)
86{
87    //PCIBus *s = opaque;
88    uint32_t val;
89
90    switch (addr & 0x3f) {
91    case 0x00: // Control/Status
92    case 0x10: // AFSR
93    case 0x18: // AFAR
94    case 0x20: // Diagnostic
95    case 0x28: // Target address space
96        // XXX
97    default:
98        val = 0;
99        break;
100    }
101    return val;
102}
103
104static CPUWriteMemoryFunc *apb_config_write[] = {
105    &apb_config_writel,
106    &apb_config_writel,
107    &apb_config_writel,
108};
109
110static CPUReadMemoryFunc *apb_config_read[] = {
111    &apb_config_readl,
112    &apb_config_readl,
113    &apb_config_readl,
114};
115
116static CPUWriteMemoryFunc *pci_apb_write[] = {
117    &pci_host_data_writeb,
118    &pci_host_data_writew,
119    &pci_host_data_writel,
120};
121
122static CPUReadMemoryFunc *pci_apb_read[] = {
123    &pci_host_data_readb,
124    &pci_host_data_readw,
125    &pci_host_data_readl,
126};
127
128static void pci_apb_iowriteb (void *opaque, target_phys_addr_t addr,
129                                  uint32_t val)
130{
131    cpu_outb(NULL, addr & 0xffff, val);
132}
133
134static void pci_apb_iowritew (void *opaque, target_phys_addr_t addr,
135                                  uint32_t val)
136{
137    cpu_outw(NULL, addr & 0xffff, val);
138}
139
140static void pci_apb_iowritel (void *opaque, target_phys_addr_t addr,
141                                uint32_t val)
142{
143    cpu_outl(NULL, addr & 0xffff, val);
144}
145
146static uint32_t pci_apb_ioreadb (void *opaque, target_phys_addr_t addr)
147{
148    uint32_t val;
149
150    val = cpu_inb(NULL, addr & 0xffff);
151    return val;
152}
153
154static uint32_t pci_apb_ioreadw (void *opaque, target_phys_addr_t addr)
155{
156    uint32_t val;
157
158    val = cpu_inw(NULL, addr & 0xffff);
159    return val;
160}
161
162static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr)
163{
164    uint32_t val;
165
166    val = cpu_inl(NULL, addr & 0xffff);
167    return val;
168}
169
170static CPUWriteMemoryFunc *pci_apb_iowrite[] = {
171    &pci_apb_iowriteb,
172    &pci_apb_iowritew,
173    &pci_apb_iowritel,
174};
175
176static CPUReadMemoryFunc *pci_apb_ioread[] = {
177    &pci_apb_ioreadb,
178    &pci_apb_ioreadw,
179    &pci_apb_ioreadl,
180};
181
182/* ??? This is probably wrong.  */
183static void pci_apb_set_irq(PCIDevice *d, void *pic, int irq_num, int level)
184{
185    pic_set_irq_new(pic, d->config[PCI_INTERRUPT_LINE], level);
186}
187
188PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base,
189                     void *pic)
190{
191    APBState *s;
192    PCIDevice *d;
193    int pci_mem_config, pci_mem_data, apb_config, pci_ioport;
194
195    s = qemu_mallocz(sizeof(APBState));
196    /* Ultrasparc APB main bus */
197    s->bus = pci_register_bus(pci_apb_set_irq, pic, 0);
198
199    pci_mem_config = cpu_register_io_memory(0, pci_apb_config_read,
200                                            pci_apb_config_write, s);
201    apb_config = cpu_register_io_memory(0, apb_config_read,
202                                        apb_config_write, s);
203    pci_mem_data = cpu_register_io_memory(0, pci_apb_read,
204                                          pci_apb_write, s);
205    pci_ioport = cpu_register_io_memory(0, pci_apb_ioread,
206                                          pci_apb_iowrite, s);
207
208    cpu_register_physical_memory(special_base + 0x2000ULL, 0x40, apb_config);
209    cpu_register_physical_memory(special_base + 0x1000000ULL, 0x10, pci_mem_config);
210    cpu_register_physical_memory(special_base + 0x2000000ULL, 0x10000, pci_ioport);
211    cpu_register_physical_memory(mem_base, 0x10000000, pci_mem_data); // XXX size should be 4G-prom
212
213    d = pci_register_device(s->bus, "Advanced PCI Bus", sizeof(PCIDevice), 
214                            -1, NULL, NULL);
215    d->config[0x00] = 0x8e; // vendor_id : Sun
216    d->config[0x01] = 0x10;
217    d->config[0x02] = 0x00; // device_id
218    d->config[0x03] = 0xa0;
219    d->config[0x04] = 0x06; // command = bus master, pci mem
220    d->config[0x05] = 0x00;
221    d->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
222    d->config[0x07] = 0x03; // status = medium devsel
223    d->config[0x08] = 0x00; // revision
224    d->config[0x09] = 0x00; // programming i/f
225    d->config[0x0A] = 0x00; // class_sub = pci host
226    d->config[0x0B] = 0x06; // class_base = PCI_bridge
227    d->config[0x0D] = 0x10; // latency_timer
228    d->config[0x0E] = 0x00; // header_type
229    return s->bus;
230}
231
232
Note: See TracBrowser for help on using the repository browser.