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