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/libpayload/drivers/pci.c | |
parent | 85c7aec73ea37136a158fd7fd98249ddedaffba5 (diff) | |
download | coreboot-88ad6b0f919bcb3b86e0a91c903be26934097125.tar.xz |
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/libpayload/drivers/pci.c')
-rw-r--r-- | payloads/libpayload/drivers/pci.c | 74 |
1 files changed, 48 insertions, 26 deletions
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)); } |