Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 3867
b: refs/heads/master
c: 1cde8a1
h: refs/heads/master
i:
  3865: fe6ed34
  3863: ff37e6b
v: v3
  • Loading branch information
Greg Kroah-Hartman committed Jun 28, 2005
1 parent 0c52117 commit 6a43aaa
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d57e26ceb7dbf44cd08128cb6146116d4281b58b
refs/heads/master: 1cde8a16815bd85c8137d1ea556398983c597c11
58 changes: 48 additions & 10 deletions trunk/arch/x86_64/pci/mmconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,44 @@
#define MMCONFIG_APER_SIZE (256*1024*1024)

/* Static virtual mapping of the MMCONFIG aperture */
static char *pci_mmcfg_virt;
struct mmcfg_virt {
struct acpi_table_mcfg_config *cfg;
char *virt;
};
static struct mmcfg_virt *pci_mmcfg_virt;

static inline char *pci_dev_base(unsigned int bus, unsigned int devfn)
static char *get_virt(unsigned int seg, int bus)
{
return pci_mmcfg_virt + ((bus << 20) | (devfn << 12));
int cfg_num = -1;
struct acpi_table_mcfg_config *cfg;

while (1) {
++cfg_num;
if (cfg_num >= pci_mmcfg_config_num) {
/* something bad is going on, no cfg table is found. */
/* so we fall back to the old way we used to do this */
/* and just rely on the first entry to be correct. */
return pci_mmcfg_virt[0].virt;
}
cfg = pci_mmcfg_virt[cfg_num].cfg;
if (cfg->pci_segment_group_number != seg)
continue;
if ((cfg->start_bus_number <= bus) &&
(cfg->end_bus_number >= bus))
return pci_mmcfg_virt[cfg_num].virt;
}
}

static inline char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
{

return get_virt(seg, bus) + ((bus << 20) | (devfn << 12));
}

static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
unsigned int devfn, int reg, int len, u32 *value)
{
char *addr = pci_dev_base(bus, devfn);
char *addr = pci_dev_base(seg, bus, devfn);

if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095)))
return -EINVAL;
Expand All @@ -46,7 +73,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
unsigned int devfn, int reg, int len, u32 value)
{
char *addr = pci_dev_base(bus,devfn);
char *addr = pci_dev_base(seg, bus, devfn);

if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
return -EINVAL;
Expand All @@ -73,6 +100,8 @@ static struct pci_raw_ops pci_mmcfg = {

static int __init pci_mmcfg_init(void)
{
int i;

if ((pci_probe & PCI_PROBE_MMCONF) == 0)
return 0;

Expand All @@ -90,13 +119,22 @@ static int __init pci_mmcfg_init(void)
return 0;

/* RED-PEN i386 doesn't do _nocache right now */
pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_config[0].base_address, MMCONFIG_APER_SIZE);
if (!pci_mmcfg_virt) {
printk("PCI: Cannot map mmconfig aperture\n");
pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
if (pci_mmcfg_virt == NULL) {
printk("PCI: Can not allocate memory for mmconfig structures\n");
return 0;
}
}
for (i = 0; i < pci_mmcfg_config_num; ++i) {
pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE);
if (!pci_mmcfg_virt[i].virt) {
printk("PCI: Cannot map mmconfig aperture for segment %d\n",
pci_mmcfg_config[i].pci_segment_group_number);
return 0;
}
printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address);
}

printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[0].base_address);
raw_pci_ops = &pci_mmcfg;
pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;

Expand Down

0 comments on commit 6a43aaa

Please sign in to comment.