diff options
author | Stefan Reinauer <stepan@coresystems.de> | 2008-08-07 19:09:17 +0000 |
---|---|---|
committer | Stefan Reinauer <stepan@openbios.org> | 2008-08-07 19:09:17 +0000 |
commit | 88ad6b0f919bcb3b86e0a91c903be26934097125 (patch) | |
tree | e07d2c8389c5e3d7881aad0088c95fccebe0f8e4 /payloads | |
parent | 85c7aec73ea37136a158fd7fd98249ddedaffba5 (diff) |
Add a full set of pci access functions.
Signed-off-by: Stefan Reinauer <stepan@coresystems.de>
Acked-by: Jordan Crouse <jordan.crouse@amd.com>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3479 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'payloads')
-rw-r--r-- | payloads/coreinfo/pci_module.c | 13 | ||||
-rw-r--r-- | payloads/libpayload/drivers/pci.c | 74 | ||||
-rw-r--r-- | payloads/libpayload/include/pci.h | 29 |
3 files changed, 73 insertions, 43 deletions
diff --git a/payloads/coreinfo/pci_module.c b/payloads/coreinfo/pci_module.c index 3e05b8bd54..b2cd8a01f5 100644 --- a/payloads/coreinfo/pci_module.c +++ b/payloads/coreinfo/pci_module.c @@ -94,7 +94,8 @@ static void show_config_space(WINDOW *win, int row, int col, int index) devfn = devices[index].device & 0xff; for (i = 0; i < 64; i += 4) - pci_read_dword(bus, devfn, i, ((unsigned int *)&cspace[i])); + cspace[i] = pci_read_config32(PCI_DEV(bus, PCI_SLOT(devfn), + PCI_FUNC(devfn)), i); for (y = 0; y < 4; y++) { for (x = 0; x < 16; x++) @@ -180,7 +181,10 @@ static void pci_scan_bus(int bus) for (devfn = 0; devfn < 0x100;) { for (func = 0; func < 8; func++, devfn++) { - pci_read_dword(bus, devfn, REG_VENDOR_ID, &val); + pcidev_t dev = PCI_DEV(bus, PCI_SLOT(devfn), + PCI_FUNC(devfn)); + + val = pci_read_config32(dev, REG_VENDOR_ID); /* Nobody home. */ if (val == 0xffffffff || val == 0x00000000 || @@ -197,14 +201,13 @@ static void pci_scan_bus(int bus) devices[devices_index++].id = val; /* If this is a bridge, then follow it. */ - pci_read_byte(bus, devfn, REG_HEADER_TYPE, &hdr); + hdr = pci_read_config8(dev, REG_HEADER_TYPE); hdr &= 0x7f; if (hdr == HEADER_TYPE_BRIDGE || hdr == HEADER_TYPE_CARDBUS) { unsigned int busses; - pci_read_dword(bus, devfn, REG_PRIMARY_BUS, - &busses); + busses = pci_read_config32(dev, REG_PRIMARY_BUS); pci_scan_bus((busses >> 8) & 0xff); diff --git a/payloads/libpayload/drivers/pci.c b/payloads/libpayload/drivers/pci.c index c6f48dd987..fc1940afbc 100644 --- a/payloads/libpayload/drivers/pci.c +++ b/payloads/libpayload/drivers/pci.c @@ -2,6 +2,7 @@ * This file is part of the libpayload project. * * Copyright (C) 2008 Advanced Micro Devices, Inc. + * Copyright (C) 2008 coresystems GmbH * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,32 +31,70 @@ #include <libpayload.h> #include <pci.h> +u8 pci_read_config8(pcidev_t device, u16 reg) +{ + outl(device | (reg & ~3), 0xCF8); + return inb(0xCFC + (reg & 3)); +} + +u16 pci_read_config16(pcidev_t device, u16 reg) +{ + outl(device | (reg & ~3), 0xCF8); + return inw(0xCFC + (reg & 3)); +} + +u32 pci_read_config32(pcidev_t device, u16 reg) +{ + outl(device | (reg & ~3), 0xCF8); + return inl(0xCFC + (reg & 3)); +} + +void pci_write_config8(pcidev_t device, u16 reg, u8 val) +{ + outl(device | (reg & ~3), 0xCF8); + outb(val, 0xCFC + (reg & 3)); +} + +void pci_write_config16(pcidev_t device, u16 reg, u16 val) +{ + outl(device | (reg & ~3), 0xCF8); + outw(val, 0xCFC + (reg & 3)); +} + +void pci_write_config32(pcidev_t device, u16 reg, u32 val) +{ + outl(device | (reg & ~3), 0xCF8); + outl(val, 0xCFC + (reg & 3)); +} + static int find_on_bus(int bus, unsigned short vid, unsigned short did, pcidev_t * dev) { int devfn; - unsigned int val; + u32 val; unsigned char hdr; for (devfn = 0; devfn < 0x100; devfn++) { - pci_read_dword(bus, devfn, REG_VENDOR_ID, &val); + val = pci_read_config32(PCI_DEV(bus, PCI_SLOT(devfn), + PCI_FUNC(devfn)), REG_VENDOR_ID); if (val == 0xffffffff || val == 0x00000000 || val == 0x0000ffff || val == 0xffff0000) continue; if (val == ((did << 16) | vid)) { - *dev = PCIDEV(bus, devfn); + *dev = PCI_DEV(bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); return 1; } - pci_read_byte(bus, devfn, REG_HEADER_TYPE, &hdr); - + hdr = pci_read_config8(PCI_DEV(bus, PCI_SLOT(devfn), + PCI_FUNC(devfn)), REG_HEADER_TYPE); hdr &= 0x7F; if (hdr == HEADER_TYPE_BRIDGE || hdr == HEADER_TYPE_CARDBUS) { unsigned int busses; - pci_read_dword(bus, devfn, REG_PRIMARY_BUS, &busses); + busses = pci_read_config32(PCI_DEV(bus, PCI_SLOT(devfn), + PCI_FUNC(devfn)), REG_PRIMARY_BUS); if (find_on_bus((busses >> 8) & 0xFF, vid, did, dev)) return 1; } @@ -64,29 +103,12 @@ static int find_on_bus(int bus, unsigned short vid, unsigned short did, return 0; } -void pci_read_dword(unsigned int bus, unsigned int devfn, - unsigned int reg, unsigned int *val) -{ - outl(PCI_ADDR(bus, devfn, reg), 0xCF8); - *val = inl(0xCFC); -} - -void pci_read_byte(unsigned int bus, unsigned int devfn, - unsigned int reg, unsigned char *val) -{ - outl(PCI_ADDR(bus, devfn, reg), 0xCF8); - *val = inb(0xCFC + (reg & 3)); -} - -int pci_find_device(unsigned short vid, unsigned short did, pcidev_t * dev) +int pci_find_device(u16 vid, u16 did, pcidev_t * dev) { return find_on_bus(0, vid, did, dev); } -unsigned int pci_read_resource(pcidev_t dev, int bar) +u32 pci_read_resource(pcidev_t dev, int bar) { - unsigned int val; - pci_read_dword(PCIDEV_BUS(dev), PCIDEV_DEVFN(dev), 0x10 + (bar * 4), - &val); - return val; + return pci_read_config32(dev, 0x10 + (bar * 4)); } diff --git a/payloads/libpayload/include/pci.h b/payloads/libpayload/include/pci.h index df88e098ab..bcc333ce9e 100644 --- a/payloads/libpayload/include/pci.h +++ b/payloads/libpayload/include/pci.h @@ -2,6 +2,7 @@ * This file is part of the libpayload project. * * Copyright (C) 2008 Advanced Micro Devices, Inc. + * Copyright (C) 2008 coresystems GmbH * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +31,8 @@ #ifndef _PCI_H #define _PCI_H -typedef unsigned short pcidev_t; +#include <arch/types.h> +typedef u32 pcidev_t; #define REG_VENDOR_ID 0x00 #define REG_DEVICE_ID 0x04 @@ -41,21 +43,24 @@ typedef unsigned short pcidev_t; #define HEADER_TYPE_BRIDGE 1 #define HEADER_TYPE_CARDBUS 2 -#define PCIDEV(_b, _d) ((((_b) & 0xFF) << 8) | ((_d) & 0xFF)) +#define PCI_ADDR(_bus, _dev, _fn, _reg) \ +(0x80000000 | (_bus << 16) | (_dev << 11) | (_fn << 8) | (_reg & ~3)) -#define PCIDEV_BUS(_d) (((_d) >> 8) & 0xFF) -#define PCIDEV_DEVFN(_d) ((_d) & 0xFF) +#define PCI_DEV(_bus, _dev, _fn) \ +(0x80000000 | (_bus << 16) | (_dev << 11) | (_fn << 8)) -#define PCI_ADDR(_bus, _dev, _reg) \ -(0x80000000 | (_bus << 16) | (_dev << 8) | (_reg & ~3)) +#define PCI_SLOT(_d) ((_d >> 11) & 0x1f) +#define PCI_FUNC(_d) ((_d >> 8) & 0x7) -void pci_read_dword(unsigned int bus, unsigned int devfn, - unsigned int reg, unsigned int *val); +u8 pci_read_config8(u32 device, u16 reg); +u16 pci_read_config16(u32 device, u16 reg); +u32 pci_read_config32(u32 device, u16 reg); -void pci_read_byte(unsigned int bus, unsigned int devfn, - unsigned int reg, unsigned char *val); +void pci_write_config8(u32 device, u16 reg, u8 val); +void pci_write_config16(u32 device, u16 reg, u16 val); +void pci_write_config32(u32 device, u16 reg, u32 val); -int pci_find_device(unsigned short vid, unsigned short did, pcidev_t *dev); -unsigned int pci_read_resource(pcidev_t dev, int bar); +int pci_find_device(u16 vid, u16 did, pcidev_t *dev); +u32 pci_read_resource(pcidev_t dev, int bar); #endif |