Teach the PCI bus driver to handle PCIR_BIOS BARs properly and remove special
handling for the PCIR_BIOS decoding enable bit from the cardbus driver. The PCIR_BIOS BAR does include type bits like other BARs. Instead, it is always a 32-bit non-prefetchable memory BAR where the low bit is used as a flag to enable decoding. Reviewed by: imp
This commit is contained in:
parent
f26d7f8e95
commit
4e8790e943
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=201279
@ -430,9 +430,6 @@ cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid,
|
||||
{
|
||||
if (res != CIS_CONFIG_SPACE) {
|
||||
bus_release_resource(child, SYS_RES_MEMORY, rid, res);
|
||||
if (rid == PCIM_CIS_ASI_ROM)
|
||||
pci_write_config(child, rid, pci_read_config(child,
|
||||
rid, 4) & ~PCIR_BIOS, 4);
|
||||
}
|
||||
}
|
||||
|
||||
@ -477,9 +474,6 @@ cardbus_read_tuple_init(device_t cbdev, device_t child, uint32_t *start,
|
||||
return (NULL);
|
||||
}
|
||||
DEVPRINTF((cbdev, "CIS Mapped to %#lx\n", rman_get_start(res)));
|
||||
if (*rid == PCIR_BIOS)
|
||||
pci_write_config(child, *rid,
|
||||
rman_get_start(res) | PCIM_BIOS_ENABLE, 4);
|
||||
|
||||
/* Flip to the right ROM image if CIS is in ROM */
|
||||
if (space == PCIM_CIS_ASI_ROM) {
|
||||
|
@ -80,6 +80,8 @@ static pci_addr_t pci_mapbase(uint64_t mapreg);
|
||||
static const char *pci_maptype(uint64_t mapreg);
|
||||
static int pci_mapsize(uint64_t testval);
|
||||
static int pci_maprange(uint64_t mapreg);
|
||||
static pci_addr_t pci_rombase(uint64_t mapreg);
|
||||
static int pci_romsize(uint64_t testval);
|
||||
static void pci_fixancient(pcicfgregs *cfg);
|
||||
static int pci_printf(pcicfgregs *cfg, const char *fmt, ...);
|
||||
|
||||
@ -142,7 +144,7 @@ static device_method_t pci_methods[] = {
|
||||
DEVMETHOD(bus_alloc_resource, pci_alloc_resource),
|
||||
DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource),
|
||||
DEVMETHOD(bus_activate_resource, pci_activate_resource),
|
||||
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
|
||||
DEVMETHOD(bus_deactivate_resource, pci_deactivate_resource),
|
||||
DEVMETHOD(bus_child_pnpinfo_str, pci_child_pnpinfo_str_method),
|
||||
DEVMETHOD(bus_child_location_str, pci_child_location_str_method),
|
||||
|
||||
@ -388,6 +390,34 @@ pci_mapsize(uint64_t testval)
|
||||
return (ln2size);
|
||||
}
|
||||
|
||||
/* return base address of device ROM */
|
||||
|
||||
static pci_addr_t
|
||||
pci_rombase(uint64_t mapreg)
|
||||
{
|
||||
|
||||
return (mapreg & PCIM_BIOS_ADDR_MASK);
|
||||
}
|
||||
|
||||
/* return log2 of map size decided for device ROM */
|
||||
|
||||
static int
|
||||
pci_romsize(uint64_t testval)
|
||||
{
|
||||
int ln2size;
|
||||
|
||||
testval = pci_rombase(testval);
|
||||
ln2size = 0;
|
||||
if (testval != 0) {
|
||||
while ((testval & 1) == 0)
|
||||
{
|
||||
ln2size++;
|
||||
testval >>= 1;
|
||||
}
|
||||
}
|
||||
return (ln2size);
|
||||
}
|
||||
|
||||
/* return log2 of address range supported by map register */
|
||||
|
||||
static int
|
||||
@ -2280,6 +2310,21 @@ pci_read_bar(device_t dev, int reg, pci_addr_t *mapp, pci_addr_t *testvalp)
|
||||
int ln2range;
|
||||
uint16_t cmd;
|
||||
|
||||
/*
|
||||
* The device ROM BAR is special. It is always a 32-bit
|
||||
* memory BAR. Bit 0 is special and should not be set when
|
||||
* sizing the BAR.
|
||||
*/
|
||||
if (reg == PCIR_BIOS) {
|
||||
map = pci_read_config(dev, reg, 4);
|
||||
pci_write_config(dev, reg, 0xfffffffe, 4);
|
||||
testval = pci_read_config(dev, reg, 4);
|
||||
pci_write_config(dev, reg, map, 4);
|
||||
*mapp = map;
|
||||
*testvalp = testval;
|
||||
return;
|
||||
}
|
||||
|
||||
map = pci_read_config(dev, reg, 4);
|
||||
ln2range = pci_maprange(map);
|
||||
if (ln2range == 64)
|
||||
@ -2327,6 +2372,10 @@ pci_write_bar(device_t dev, int reg, pci_addr_t base)
|
||||
int ln2range;
|
||||
|
||||
map = pci_read_config(dev, reg, 4);
|
||||
|
||||
/* The device ROM BAR is always 32-bits. */
|
||||
if (reg == PCIR_BIOS)
|
||||
return;
|
||||
ln2range = pci_maprange(map);
|
||||
pci_write_config(dev, reg, base, 4);
|
||||
if (ln2range == 64)
|
||||
@ -3579,10 +3628,11 @@ pci_reserve_map(device_t dev, device_t child, int type, int *rid,
|
||||
pci_read_bar(child, *rid, &map, &testval);
|
||||
|
||||
/* Ignore a BAR with a base of 0. */
|
||||
if (pci_mapbase(testval) == 0)
|
||||
if ((*rid == PCIR_BIOS && pci_rombase(testval) == 0) ||
|
||||
pci_mapbase(testval) == 0)
|
||||
goto out;
|
||||
|
||||
if (PCI_BAR_MEM(testval)) {
|
||||
if (PCI_BAR_MEM(testval) || *rid == PCIR_BIOS) {
|
||||
if (type != SYS_RES_MEMORY) {
|
||||
if (bootverbose)
|
||||
device_printf(dev,
|
||||
@ -3608,8 +3658,13 @@ pci_reserve_map(device_t dev, device_t child, int type, int *rid,
|
||||
* actually uses and we would otherwise have a
|
||||
* situation where we might allocate the excess to
|
||||
* another driver, which won't work.
|
||||
*
|
||||
* Device ROM BARs use a different mask value.
|
||||
*/
|
||||
mapsize = pci_mapsize(testval);
|
||||
if (*rid == PCIR_BIOS)
|
||||
mapsize = pci_romsize(testval);
|
||||
else
|
||||
mapsize = pci_mapsize(testval);
|
||||
count = 1UL << mapsize;
|
||||
if (RF_ALIGNMENT(flags) < mapsize)
|
||||
flags = (flags & ~RF_ALIGNMENT_MASK) | RF_ALIGNMENT_LOG2(mapsize);
|
||||
@ -3711,6 +3766,10 @@ pci_activate_resource(device_t dev, device_t child, int type, int rid,
|
||||
|
||||
/* Enable decoding in the command register when activating BARs. */
|
||||
if (device_get_parent(child) == dev) {
|
||||
/* Device ROMs need their decoding explicitly enabled. */
|
||||
if (rid == PCIR_BIOS)
|
||||
pci_write_config(child, rid, rman_get_start(r) |
|
||||
PCIM_BIOS_ENABLE, 4);
|
||||
switch (type) {
|
||||
case SYS_RES_IOPORT:
|
||||
case SYS_RES_MEMORY:
|
||||
@ -3721,6 +3780,22 @@ pci_activate_resource(device_t dev, device_t child, int type, int rid,
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
pci_deactivate_resource(device_t dev, device_t child, int type,
|
||||
int rid, struct resource *r)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = bus_generic_deactivate_resource(dev, child, type, rid, r);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
/* Disable decoding for device ROMs. */
|
||||
if (rid == PCIR_BIOS)
|
||||
pci_write_config(child, rid, rman_get_start(r), 4);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
pci_delete_resource(device_t dev, device_t child, int type, int rid)
|
||||
{
|
||||
|
@ -84,6 +84,8 @@ struct resource *pci_alloc_resource(device_t dev, device_t child,
|
||||
u_int flags);
|
||||
int pci_activate_resource(device_t dev, device_t child, int type,
|
||||
int rid, struct resource *r);
|
||||
int pci_deactivate_resource(device_t dev, device_t child, int type,
|
||||
int rid, struct resource *r);
|
||||
void pci_delete_resource(device_t dev, device_t child,
|
||||
int type, int rid);
|
||||
struct resource_list *pci_get_resource_list (device_t dev, device_t child);
|
||||
|
Loading…
Reference in New Issue
Block a user