Date: 1 Jun 1998 10:50:31 +0100 From: Graeme Brown <graeme.brown@bt-sys.bt.co.uk> To: David Greenman <dg@root.com> Cc: "FreeBSD-Net (FreeBSD.Org) List" <freebsd-net@FreeBSD.ORG> Subject: My fxp troubles under FreeBSD 2.2.6 Message-ID: <n1315424303.32309@maczebedee>
next in thread | raw e-mail | index | archive | help
David
I looked a little into the FreeBSD 2.2.6 kernel source code under
/usr/src/sys/pci at function pci_map_mem() in file pci.c
/*-----------------------------------------------------------------------
**
** Map device into virtual and physical space
**
** Actually the device should have been mapped by the bios.
** This function only reads and verifies the value.
**
** PCI-Specification: 6.2.5.1: address maps
**
**-----------------------------------------------------------------------
*/
int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa)
{
struct pcicb *link = pcicb;
unsigned data ,paddr;
vm_size_t psize, poffs;
vm_offset_t vaddr;
/*
** sanity check
*/
if (reg < PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3)) {
printf ("pci_map_mem failed: bad register=0x%x\n",
(unsigned)reg);
return (0);
};
/*
** save old mapping, get size and type of memory
**
** type is in the lowest four bits.
** If device requires 2^n bytes, the next
** n-4 bits are read as 0.
*/
paddr = pci_conf_read (tag, reg) & PCI_MAP_MEMORY_ADDRESS_MASK;
pci_conf_write (tag, reg, 0xfffffffful);
data = pci_conf_read (tag, reg);
pci_conf_write (tag, reg, paddr);
/*
** check the type
*/
if (!((data & PCI_MAP_MEMORY_TYPE_MASK) == PCI_MAP_MEMORY_TYPE_32BIT_1M
&& (paddr & ~0xfffff) == 0)
&& (data & PCI_MAP_MEMORY_TYPE_MASK) != PCI_MAP_MEMORY_TYPE_32BIT){
printf ("pci_map_mem failed: bad memory type=0x%x\n",
(unsigned) data);
return (0);
};
/*
** get the size.
*/
psize = -(data & PCI_MAP_MEMORY_ADDRESS_MASK);
if (!paddr || paddr == PCI_MAP_MEMORY_ADDRESS_MASK) {
paddr = pci_memalloc (pcicb, 0, psize);
if (!paddr) {
printf ("pci_map_mem: not configured by bios.\n");
return (0);
};
pci_register_memory (pcicb, paddr, paddr+psize-1);
};
if (paddr < pcicb->pcicb_membase ||
paddr + psize - 1 > pcicb->pcicb_memlimit) {
printf ("pci_map_mem failed: device's memrange 0x%x-0x%x is "
"incompatible with its bridge's memrange 0x%x-0x%x\n",
(unsigned) paddr,
(unsigned) (paddr + psize - 1),
(unsigned) pcicb->pcicb_membase,
(unsigned) pcicb->pcicb_memlimit);
/* return (0);*/
/* ACHTUNG: Ist der Code richtig, wenn eine PCI-PCI-Bridge fuer
* die PCI-Slots verwendet wird, aber die Onboard-Devices direkt
* an der CPU-PCI-Bridge haengen (Siehe Compaq Prolinea Problem) ???
*/
}
pci_conf_write (tag, reg, paddr);
/*
** Truncate paddr to page boundary.
** (Or does pmap_mapdev the job?)
*/
poffs = paddr - trunc_page (paddr);
vaddr = (vm_offset_t) pmap_mapdev (paddr-poffs, psize+poffs);
if (!vaddr) return (0);
vaddr += poffs;
#ifndef PCI_QUIET
/*
** display values.
*/
if (bootverbose)
printf ("\treg%d: virtual=0x%lx physical=0x%lx size=0x%lx\n",
(unsigned) reg, (u_long)vaddr, (u_long)paddr, (u_long)psize);
#endif
/*
** set the configuration register and
** return the address to the driver
** Make sure to enable each upstream bridge
** so memory and DMA can go all the way.
*/
for (;;) {
data = pci_conf_read (tag, PCI_COMMAND_STATUS_REG) & 0xffff;
data |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE;
(void) pci_conf_write(tag, PCI_COMMAND_STATUS_REG, data);
if ((link = link->pcicb_up) == NULL)
break;
tag = link->pcicb_bridge;
}
*va = vaddr;
*pa = paddr;
return (1);
}
The error message being triggered by the test
if (paddr < pcicb->pcicb_membase ||
paddr + psize - 1 > pcicb->pcicb_memlimit) {
printf ("pci_map_mem failed: device's memrange 0x%x-0x%x is "
"incompatible with its bridge's memrange 0x%x-0x%x\n",
(unsigned) paddr,
(unsigned) (paddr + psize - 1),
(unsigned) pcicb->pcicb_membase,
(unsigned) pcicb->pcicb_memlimit);
/* return (0);*/
/* ACHTUNG: Ist der Code richtig, wenn eine PCI-PCI-Bridge fuer
* die PCI-Slots verwendet wird, aber die Onboard-Devices direkt
* an der CPU-PCI-Bridge haengen (Siehe Compaq Prolinea Problem) ???
*/
I notice the comment in German translates (if I remenber my high-school
German) as
ATTENTION: Is the code correct if a PCI-PCI-Bridge for the PCI slots
is changed but the Onboard-Devices directly on the CPU-PCI bridge
hang (as in "get hung-up" or as in "are connected-to" ??) ( See Compaq
Prolinea Problem) ???
I notice the author of pci.c is Wolfgang Stanglmeier. Is he contactable
via email ? Who is/are the PCI bus specialist(s) within the FreeBSD Org ? Can
we have his/their comments on my problem ?
TIA
Graeme N Brown
BT Laboratories, UK
email: graeme.brown@bt-sys.bt.co.uk
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?n1315424303.32309>
