PCI IDE Controller Base Address Register setting
John Baldwin
jhb at freebsd.org
Tue Dec 28 15:20:17 UTC 2010
On Monday, December 27, 2010 6:07:35 am Darmawan Salihun wrote:
> Hi,
>
> I'm trying to install FreeBSD 8.0 on AMD Geode LX800 (CS5536 "southbridge").
However, it cannot detect the IDE controller (in the CS5536) correctly. It
says something similar to this:
> "IDE controller not present"
Hmm, I can't find a message like that anywhere. Can you get the exact message
you are seeing?
> I did lspci in Linux (BackTrack 3)
> and I saw that the IDE controller Base Address Registers (BARs)
> are all disabled (only contains zeros),
> except for one of them (BAR4).
> BAR4 decodes 16-bytes I/O ports (FFF0h-FFFFh).
> The decoded ports "seems" to conform to the PCI IDE specification
> for "native-PCI IDE controller" (relocatable within the
> 16-bit I/O address space).
>
> I did "cat /proc/ioports" and I found that
> the following I/O port address ranges decoded correctly
> to the IDE controller in the CS5536 "southbridge":
>
> 1F0h-1F7h
> 3F6h
> 170h-177h
> FFF0h-FFFFh
>
> My question:
> Does FreeBSD require the IDE controller BARs
> to be programmed to also decode
> legacy I/O ports ranges (1F0h-1F7h,3F6h and 170h-177h)?
No. We hardcode the ISA ranges for BARs 0 through 3 if a PCI IDE controller
has the "Primary" or "Secondary" bits set in its programming interface
register and don't even look at the BARs. We do always examines BARs 4 and 5
using the normal probing scheme of writing all 1's, etc. The code in question
looks like this:
/*
* For ATA devices we need to decide early what addressing mode to use.
* Legacy demands that the primary and secondary ATA ports sits on the
* same addresses that old ISA hardware did. This dictates that we use
* those addresses and ignore the BAR's if we cannot set PCI native
* addressing mode.
*/
static void
pci_ata_maps(device_t bus, device_t dev, struct resource_list *rl, int force,
uint32_t prefetchmask)
{
struct resource *r;
int rid, type, progif;
#if 0
/* if this device supports PCI native addressing use it */
progif = pci_read_config(dev, PCIR_PROGIF, 1);
if ((progif & 0x8a) == 0x8a) {
if (pci_mapbase(pci_read_config(dev, PCIR_BAR(0), 4)) &&
pci_mapbase(pci_read_config(dev, PCIR_BAR(2), 4))) {
printf("Trying ATA native PCI addressing mode\n");
pci_write_config(dev, PCIR_PROGIF, progif | 0x05, 1);
}
}
#endif
progif = pci_read_config(dev, PCIR_PROGIF, 1);
type = SYS_RES_IOPORT;
if (progif & PCIP_STORAGE_IDE_MODEPRIM) {
pci_add_map(bus, dev, PCIR_BAR(0), rl, force,
prefetchmask & (1 << 0));
pci_add_map(bus, dev, PCIR_BAR(1), rl, force,
prefetchmask & (1 << 1));
} else {
rid = PCIR_BAR(0);
resource_list_add(rl, type, rid, 0x1f0, 0x1f7, 8);
r = resource_list_reserve(rl, bus, dev, type, &rid, 0x1f0,
0x1f7, 8, 0);
rid = PCIR_BAR(1);
resource_list_add(rl, type, rid, 0x3f6, 0x3f6, 1);
r = resource_list_reserve(rl, bus, dev, type, &rid, 0x3f6,
0x3f6, 1, 0);
}
if (progif & PCIP_STORAGE_IDE_MODESEC) {
pci_add_map(bus, dev, PCIR_BAR(2), rl, force,
prefetchmask & (1 << 2));
pci_add_map(bus, dev, PCIR_BAR(3), rl, force,
prefetchmask & (1 << 3));
} else {
rid = PCIR_BAR(2);
resource_list_add(rl, type, rid, 0x170, 0x177, 8);
r = resource_list_reserve(rl, bus, dev, type, &rid, 0x170,
0x177, 8, 0);
rid = PCIR_BAR(3);
resource_list_add(rl, type, rid, 0x376, 0x376, 1);
r = resource_list_reserve(rl, bus, dev, type, &rid, 0x376,
0x376, 1, 0);
}
pci_add_map(bus, dev, PCIR_BAR(4), rl, force,
prefetchmask & (1 << 4));
pci_add_map(bus, dev, PCIR_BAR(5), rl, force,
prefetchmask & (1 << 5));
}
--
John Baldwin
More information about the freebsd-hackers
mailing list