1 /* PCI config support for emulated PCI devices (SI cores) only */
3 * Machine-specific functions for PCI autoconfiguration.
5 * Copyright (c) 2000-2001, Algorithmics Ltd. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the "Free MIPS" License Agreement, a copy of
9 * which is available at:
11 * http://www.algor.co.uk/ftp/pub/doc/freemips-license.txt
13 * You may not, however, modify or remove any part of this copyright
14 * message if this program is redistributed or reused in whole or in
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * "Free MIPS" License for more details.
26 #include "pci_internal.h"
34 /* default PCI mem regions in PCI space */
35 #define PCI_MEM_SPACE_BASE SI_PCI_DMA
36 #define PCI_MEM_SPACE_SIZE SI_PCI_DMA_SZ
38 const cons_t pci_optnames
[] = {
39 {"verbose",PCI_FLG_VERBOSE
},
43 static struct pci_bus _pci_bus
[1] = {
45 0, /* minimum grant */
46 255, /* maximum latency */
47 0, /* devsel time = fast */
48 0, /* we don't support fast back-to-back */
49 0, /* we don't support prefetch */
50 0, /* we don't support 66 MHz */
51 0, /* we don't support 64 bits */
52 4000000, /* bandwidth: in 0.25us cycles / sec */
53 1 /* initially one device on bus (i.e. us) */
56 static int _pci_nbus
= 1;
58 static si_t
*sih
= NULL
;
60 extern int _pciverbose
;
62 /* The following functions provide for device-specific setup required
63 during configuration. There is nothing host-specific about them,
64 and it would be better to do the packaging and registration in a
80 pci_businfo(int port
, int bus
)
82 return bus
< _pci_nbus
? &_pci_bus
[bus
] : NULL
;
86 pci_minmemaddr(int port
)
88 return PCI_MEM_SPACE_BASE
;
92 pci_maxmemaddr(int port
)
94 return pci_minmemaddr(port
) + PCI_MEM_SPACE_SIZE
;
98 pci_minioaddr(int port
)
104 pci_maxioaddr(int port
)
110 * Called to initialise the bridge at the beginning of time
113 pci_hwinit(int port
, pci_flags_t flags
)
115 /* attach to backplane */
116 if (!(sih
= si_kattach(SI_OSH
)))
119 /* emulate PCI devices */
120 hndpci_init_cores(sih
);
126 * Called to reinitialise the bridge after we've scanned each PCI device
127 * and know what is possible.
130 pci_hwreinit(int port
, pci_flags_t flags
)
140 pci_make_tag(int port
, int bus
, int device
, int function
)
142 return (bus
<< 16) | (device
<< 11) | (function
<< 8);
146 pci_break_tag(pcitag_t tag
, int *portp
, int *busp
, int *devicep
, int *functionp
)
148 if (portp
) *portp
= 0;
149 if (busp
) *busp
= (tag
>> 16) & 0xff;
150 if (devicep
) *devicep
= (tag
>> 11) & 0x1f;
151 if (functionp
) *functionp
= (tag
>> 8) & 0x07;
155 pci_canscan(pcitag_t tag
)
159 pci_break_tag(tag
, NULL
, &bus
, NULL
, NULL
);
165 pci_conf_read(pcitag_t tag
, int reg
)
167 int bus
, device
, function
;
170 pci_break_tag(tag
, NULL
, &bus
, &device
, &function
);
172 if (hndpci_read_config(sih
, (uint32_t)bus
, (uint32_t)device
,
173 (uint32_t)function
, (uint32_t)reg
,
174 (void *)&data
, sizeof(pcireg_t
)))
182 pci_conf_write(pcitag_t tag
, int reg
, pcireg_t data
)
184 int bus
, device
, function
;
186 pci_break_tag(tag
, NULL
, &bus
, &device
, &function
);
188 hndpci_write_config(sih
, (uint32_t)bus
, (uint32_t)device
,
189 (uint32_t)function
, (uint32_t)reg
,
190 (void *)&data
, sizeof(pcireg_t
));
194 pci_conf_write_acked(pcitag_t tag
, int reg
, pcireg_t data
)
196 pci_conf_write(tag
, reg
, data
);
201 pci_conf_read16(pcitag_t tag
, int reg
)
203 int bus
, device
, function
;
206 pci_break_tag(tag
, NULL
, &bus
, &device
, &function
);
208 if (hndpci_read_config(sih
, (uint32_t)bus
, (uint32_t)device
,
209 (uint32_t)function
, (uint32_t)reg
,
210 (void *)&data
, sizeof(data
)))
217 pci_conf_write16(pcitag_t tag
, int reg
, pcireg_t data
)
219 int bus
, device
, function
;
220 uint16_t tmp
= (uint16_t)data
;
222 pci_break_tag(tag
, NULL
, &bus
, &device
, &function
);
224 hndpci_write_config(sih
, (uint32_t)bus
, (uint32_t)device
,
225 (uint32_t)function
, (uint32_t)reg
,
226 (void *)&tmp
, sizeof(tmp
));
230 pci_map_io(pcitag_t tag
, int reg
, pci_endian_t endian
, phys_addr_t
*pap
)
236 pci_map_mem(pcitag_t tag
, int reg
, pci_endian_t endian
, phys_addr_t
*pap
)
241 if (reg
== PCI_MAPREG_ROM
) {
243 address
= pci_conf_read(tag
, reg
);
244 if (!(address
& PCI_MAPREG_ROM
)) {
245 pci_tagprintf(tag
, "pci_map_mem: attempt to map missing rom\n");
248 pa
= address
& PCI_MAPREG_ROM_ADDR_MASK
;
251 if (reg
< PCI_MAPREG_START
|| reg
>= PCI_MAPREG_END
|| (reg
& 3)) {
252 if (_pciverbose
>= 1)
253 pci_tagprintf(tag
, "pci_map_mem: bad request\n");
257 address
= pci_conf_read(tag
, reg
);
258 if ((address
& PCI_MAPREG_TYPE_IO
) != 0) {
259 if (_pciverbose
>= 1)
260 pci_tagprintf(tag
, "pci_map_mem: attempt to memory map an I/O region\n");
264 switch (address
& PCI_MAPREG_MEM_TYPE_MASK
) {
265 case PCI_MAPREG_MEM_TYPE_32BIT
:
266 case PCI_MAPREG_MEM_TYPE_32BIT_1M
:
268 case PCI_MAPREG_MEM_TYPE_64BIT
:
269 if (_pciverbose
>= 1)
270 pci_tagprintf (tag
, "pci_map_mem: attempt to map 64-bit region tag=0x%X @ addr=%X\n", tag
, address
);
273 if (_pciverbose
>= 1)
274 pci_tagprintf (tag
, "pci_map_mem: reserved mapping type\n");
277 pa
= address
& PCI_MAPREG_MEM_ADDR_MASK
;
280 if (_pciverbose
>= 1)
281 pci_tagprintf (tag
, "pci_map_mem: addr=0x%X pa=0x%X\n", address
, pa
);
288 pci_probe_tag(pcitag_t tag
)
292 if (!pci_canscan(tag
))
295 data
= pci_conf_read(tag
,PCI_ID_REG
);
296 if ((data
== 0) || (data
== 0xffffffff))
303 pci_map_window(phys_addr_t va
,
304 unsigned int offset
, unsigned int len
,
305 int l2ca
, int endian
)
311 pci_unmap_window(unsigned int offset
, unsigned int len
)
317 pci_device_preset(pcitag_t tag
)
323 pci_device_setup(pcitag_t tag
)
327 /* Called for each bridge after configuring the secondary bus, to allow
328 device-specific initialization. */
330 pci_bridge_setup(pcitag_t tag
, pci_flags_t flags
)
334 /* The base shift of a slot or device on the motherboard. */
336 pci_int_shift_0(pcitag_t tag
)
342 pci_int_map_0(pcitag_t tag
)
348 pci_int_line(uint8_t pci_int
)