4 * Copyright (c) 2004 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
28 typedef struct PCIBridge
{
30 PCIDevice
**pci_bus
[256];
33 static PCIBridge pci_bridge
;
34 target_phys_addr_t pci_mem_base
;
36 /* -1 for devfn means auto assign */
37 PCIDevice
*pci_register_device(const char *name
, int instance_size
,
38 int bus_num
, int devfn
,
39 PCIConfigReadFunc
*config_read
,
40 PCIConfigWriteFunc
*config_write
)
42 PCIBridge
*s
= &pci_bridge
;
43 PCIDevice
*pci_dev
, **bus
;
45 if (!s
->pci_bus
[bus_num
]) {
46 s
->pci_bus
[bus_num
] = qemu_mallocz(256 * sizeof(PCIDevice
*));
47 if (!s
->pci_bus
[bus_num
])
50 bus
= s
->pci_bus
[bus_num
];
52 for(devfn
= 0 ; devfn
< 256; devfn
+= 8) {
59 pci_dev
= qemu_mallocz(instance_size
);
62 pci_dev
->bus_num
= bus_num
;
63 pci_dev
->devfn
= devfn
;
64 pstrcpy(pci_dev
->name
, sizeof(pci_dev
->name
), name
);
65 pci_dev
->config_read
= config_read
;
66 pci_dev
->config_write
= config_write
;
71 void pci_register_io_region(PCIDevice
*pci_dev
, int region_num
,
72 uint32_t size
, int type
,
73 PCIMapIORegionFunc
*map_func
)
77 if ((unsigned int)region_num
>= 6)
79 r
= &pci_dev
->io_regions
[region_num
];
83 r
->map_func
= map_func
;
86 static void pci_config_writel(void* opaque
, uint32_t addr
, uint32_t val
)
88 PCIBridge
*s
= opaque
;
92 static uint32_t pci_config_readl(void* opaque
, uint32_t addr
)
94 PCIBridge
*s
= opaque
;
98 static void unmap_region(PCIIORegion
*r
)
103 printf("unmap addr=%08x size=%08x\n", r
->addr
, r
->size
);
105 if (r
->type
& PCI_ADDRESS_SPACE_IO
) {
106 isa_unassign_ioport(r
->addr
, r
->size
);
108 cpu_register_physical_memory(r
->addr
+ pci_mem_base
, r
->size
,
113 static void pci_data_write(void *opaque
, uint32_t addr
,
114 uint32_t val
, int len
)
116 PCIBridge
*s
= opaque
;
117 PCIDevice
**bus
, *pci_dev
;
118 int config_addr
, reg
;
120 #if defined(DEBUG_PCI) && 0
121 printf("pci_data_write: addr=%08x val=%08x len=%d\n",
122 s
->config_reg
, val
, len
);
124 if (!(s
->config_reg
& (1 << 31))) {
127 if ((s
->config_reg
& 0x3) != 0) {
130 bus
= s
->pci_bus
[(s
->config_reg
>> 16) & 0xff];
133 pci_dev
= bus
[(s
->config_reg
>> 8) & 0xff];
136 config_addr
= (s
->config_reg
& 0xfc) | (addr
& 3);
138 #if defined(DEBUG_PCI)
139 printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
140 pci_dev
->name
, config_addr
, val
, len
);
142 if (len
== 4 && (config_addr
>= 0x10 && config_addr
< 0x10 + 4 * 6)) {
144 reg
= (config_addr
- 0x10) >> 2;
145 r
= &pci_dev
->io_regions
[reg
];
148 if (val
!= 0xffffffff && val
!= 0) {
149 /* XXX: the memory assignment should be global to handle
150 overlaps, but it is not needed at this stage */
151 /* first unmap the old region */
153 /* change the address */
154 if (r
->type
& PCI_ADDRESS_SPACE_IO
)
155 r
->addr
= val
& ~0x3;
157 r
->addr
= val
& ~0xf;
159 printf("map addr=%08x size=%08x type=%d\n",
160 r
->addr
, r
->size
, r
->type
);
162 r
->map_func(pci_dev
, reg
, r
->addr
, r
->size
, r
->type
);
164 /* now compute the stored value */
165 val
&= ~(r
->size
- 1);
167 *(uint32_t *)(pci_dev
->config
+ 0x10 + reg
* 4) = cpu_to_le32(val
);
170 pci_dev
->config_write(pci_dev
, config_addr
, val
, len
);
174 static uint32_t pci_data_read(void *opaque
, uint32_t addr
,
177 PCIBridge
*s
= opaque
;
178 PCIDevice
**bus
, *pci_dev
;
182 if (!(s
->config_reg
& (1 << 31)))
184 if ((s
->config_reg
& 0x3) != 0)
186 bus
= s
->pci_bus
[(s
->config_reg
>> 16) & 0xff];
189 pci_dev
= bus
[(s
->config_reg
>> 8) & 0xff];
195 config_addr
= (s
->config_reg
& 0xfc) | (addr
& 3);
196 val
= pci_dev
->config_read(pci_dev
, config_addr
, len
);
197 #if defined(DEBUG_PCI)
198 printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
199 pci_dev
->name
, config_addr
, val
, len
);
202 #if defined(DEBUG_PCI) && 0
203 printf("pci_data_read: addr=%08x val=%08x len=%d\n",
204 s
->config_reg
, val
, len
);
209 static void pci_data_writeb(void* opaque
, uint32_t addr
, uint32_t val
)
211 pci_data_write(opaque
, addr
, val
, 1);
214 static void pci_data_writew(void* opaque
, uint32_t addr
, uint32_t val
)
216 pci_data_write(opaque
, addr
, val
, 2);
219 static void pci_data_writel(void* opaque
, uint32_t addr
, uint32_t val
)
221 pci_data_write(opaque
, addr
, val
, 4);
224 static uint32_t pci_data_readb(void* opaque
, uint32_t addr
)
226 return pci_data_read(opaque
, addr
, 1);
229 static uint32_t pci_data_readw(void* opaque
, uint32_t addr
)
231 return pci_data_read(opaque
, addr
, 2);
234 static uint32_t pci_data_readl(void* opaque
, uint32_t addr
)
236 return pci_data_read(opaque
, addr
, 4);
239 /* i440FX PCI bridge */
241 static uint32_t i440_read_config(PCIDevice
*d
,
242 uint32_t address
, int len
)
246 memcpy(&val
, d
->config
+ address
, len
);
250 static void i440_write_config(PCIDevice
*d
,
251 uint32_t address
, uint32_t val
, int len
)
253 memcpy(d
->config
+ address
, &val
, len
);
256 void i440fx_init(void)
258 PCIBridge
*s
= &pci_bridge
;
261 register_ioport_write(0xcf8, 4, 4, pci_config_writel
, s
);
262 register_ioport_read(0xcf8, 4, 4, pci_config_readl
, s
);
264 register_ioport_write(0xcfc, 4, 1, pci_data_writeb
, s
);
265 register_ioport_write(0xcfc, 4, 2, pci_data_writew
, s
);
266 register_ioport_write(0xcfc, 4, 4, pci_data_writel
, s
);
267 register_ioport_read(0xcfc, 4, 1, pci_data_readb
, s
);
268 register_ioport_read(0xcfc, 4, 2, pci_data_readw
, s
);
269 register_ioport_read(0xcfc, 4, 4, pci_data_readl
, s
);
271 d
= pci_register_device("i440FX", sizeof(PCIDevice
), 0, 0,
272 i440_read_config
, i440_write_config
);
274 d
->config
[0x00] = 0x86; // vendor_id
275 d
->config
[0x01] = 0x80;
276 d
->config
[0x02] = 0x37; // device_id
277 d
->config
[0x03] = 0x12;
278 d
->config
[0x08] = 0x02; // revision
279 d
->config
[0x0a] = 0x04; // class_sub = pci2pci
280 d
->config
[0x0b] = 0x06; // class_base = PCI_bridge
281 d
->config
[0x0c] = 0x01; // line_size in 32 bit words
282 d
->config
[0x0e] = 0x01; // header_type
285 /* NOTE: the following should be done by the BIOS */
287 static uint32_t pci_bios_io_addr
;
288 static uint32_t pci_bios_mem_addr
;
290 static void pci_set_io_region_addr(PCIDevice
*d
, int region_num
, uint32_t addr
)
292 PCIBridge
*s
= &pci_bridge
;
295 s
->config_reg
= 0x80000000 | (d
->bus_num
<< 16) |
296 (d
->devfn
<< 8) | (0x10 + region_num
* 4);
297 pci_data_write(s
, 0, addr
, 4);
298 r
= &d
->io_regions
[region_num
];
300 /* enable memory mappings */
301 if (r
->type
& PCI_ADDRESS_SPACE_IO
)
302 d
->config
[0x04] |= 1;
304 d
->config
[0x04] |= 2;
308 static void pci_bios_init_device(PCIDevice
*d
)
315 class = d
->config
[0x0a] | (d
->config
[0x0b] << 8);
318 /* IDE: we map it as in ISA mode */
319 pci_set_io_region_addr(d
, 0, 0x1f0);
320 pci_set_io_region_addr(d
, 1, 0x3f4);
321 pci_set_io_region_addr(d
, 2, 0x170);
322 pci_set_io_region_addr(d
, 3, 0x374);
325 /* default memory mappings */
326 for(i
= 0; i
< 6; i
++) {
327 r
= &d
->io_regions
[i
];
329 if (r
->type
& PCI_ADDRESS_SPACE_IO
)
330 paddr
= &pci_bios_io_addr
;
332 paddr
= &pci_bios_mem_addr
;
333 *paddr
= (*paddr
+ r
->size
- 1) & ~(r
->size
- 1);
334 pci_set_io_region_addr(d
, i
, *paddr
);
343 * This function initializes the PCI devices as a normal PCI BIOS
344 * would do. It is provided just in case the BIOS has no support for
347 void pci_bios_init(void)
349 PCIBridge
*s
= &pci_bridge
;
353 pci_bios_io_addr
= 0xc000;
354 pci_bios_mem_addr
= 0xf0000000;
356 for(bus_num
= 0; bus_num
< 256; bus_num
++) {
357 bus
= s
->pci_bus
[bus_num
];
359 for(devfn
= 0; devfn
< 256; devfn
++) {
361 pci_bios_init_device(bus
[devfn
]);