Blame |
Last modification |
View Log
| RSS feed
#include <ll/i386/hw-instr.h>
#include <ll/i386/hw-data.h>
#include <ll/i386/hw-arch.h>
#include <ll/i386/hw-io.h>
#include <drivers/llpci.h>
int (*pcibios_read_config_byte)(BYTE bus, BYTE dev, BYTE where, BYTE *val);
int (*pcibios_read_config_word)(BYTE bus, BYTE dev, BYTE where, WORD *val);
int (*pcibios_read_config_dword)(BYTE bus, BYTE dev, BYTE where, DWORD *val);
int (*pcibios_write_config_byte)(BYTE bus, BYTE dev, BYTE where, BYTE val);
int (*pcibios_write_config_word)(BYTE bus, BYTE dev, BYTE where, WORD val);
int (*pcibios_write_config_dword)(BYTE bus, BYTE dev, BYTE where, DWORD val);
static int PCItype = 0;
/* LowLevel Functions */
int pci_conf1_read_config_dword(BYTE bus, BYTE dev, BYTE where, DWORD *val)
{
if (where & 3)
return -1;
outpd(0x0CF8, 0x80000000 | (bus <<16) | (dev << 8) | (where & ~3));
*val = inpd(0x0CFC);
return 1;
}
int pci_conf2_read_config_dword(BYTE bus, BYTE dev, BYTE where, DWORD *val)
{
if (dev & 0x80)
return -1;
outpw(0xCF8, (((dev & 7) << 1) | 0xf0));
outpw(0xCFA, bus);
*val = inpd((0xC000 | ((dev & 0x78) << 5)) + where);
outpw(0xCF8,0);
return 1;
}
int pci_conf1_read_config_byte(BYTE bus, BYTE dev, BYTE where, BYTE *val)
{
outpd(0x0CF8, 0x80000000 | (bus <<16) | (dev << 8) | (where & ~3));
*val = inp(0x0CFC + (where & 3));
return 1;
}
int pci_conf2_read_config_byte(BYTE bus, BYTE dev, BYTE where, BYTE *val)
{
if (dev & 0x80)
return -1;
outpw(0xCF8, (((dev & 7) << 1) | 0xf0));
outpw(0xCFA, bus);
*val = inp((0xC000 | ((dev & 0x78) << 5)) + where);
outpw(0xCF8,0);
return 1;
}
int pci_conf1_read_config_word(BYTE bus, BYTE dev, BYTE where, WORD *val)
{
if (where & 1)
return -1;
outpd(0x0CF8, 0x80000000 | (bus <<16) | (dev << 8) | (where & ~3));
*val = inpw(0x0CFC + (where & 2));
return 1;
}
int pci_conf2_read_config_word(BYTE bus, BYTE dev, BYTE where, WORD *val)
{
if (dev & 0x80)
return -1;
outpw(0xCF8, (((dev & 7) << 1) | 0xf0));
outpw(0xCFA, bus);
*val = inpw((0xC000 | ((dev & 0x78) << 5)) + where);
/* *val = inpw(0xC000 | ((dev & 0x78) << 5) + where); */
outpw(0xCF8,0);
return 1;
}
int pci_conf1_write_config_dword(BYTE bus, BYTE dev, BYTE where, DWORD val)
{
if (where & 3)
return -1;
outpd(0x0CF8, 0x80000000 | (bus <<16) | (dev << 8) | (where & ~3));
outpd(0x0CFC, val);
return 1;
}
int pci_conf2_write_config_dword(BYTE bus, BYTE dev, BYTE where, DWORD val)
{
if (dev & 0x80)
return -1;
outpw(0xCF8, (((dev & 7) << 1) | 0xf0));
outpw(0xCFA, bus);
outpd((0xC000 | ((dev & 0x78) << 5)) + where, val);
outpw(0xCF8,0);
return 1;
}
int pci_conf1_write_config_byte(BYTE bus, BYTE dev, BYTE where, BYTE val)
{
outpd(0x0CF8, 0x80000000 | (bus <<16) | (dev << 8) | (where & ~3));
outp(0x0CFC + (where & 3), val);
return 1;
}
int pci_conf2_write_config_byte(BYTE bus, BYTE dev, BYTE where, BYTE val)
{
if (dev & 0x80)
return -1;
outpw(0xCF8, (((dev & 7) << 1) | 0xf0));
outpw(0xCFA, bus);
outp((0xC000 | ((dev & 0x78) << 5)) + where, val);
outpw(0xCF8,0);
return 1;
}
int pci_conf1_write_config_word(BYTE bus, BYTE dev, BYTE where, WORD val)
{
if (where & 1)
return -1;
outpd(0x0CF8, 0x80000000 | (bus <<16) | (dev << 8) | (where & ~3));
outpw(0x0CFC + (where & 2), val);
return 1;
}
int pci_conf2_write_config_word(BYTE bus, BYTE dev, BYTE where, WORD val)
{
if (dev & 0x80)
return -1;
outpw(0xCF8, (((dev & 7) << 1) | 0xf0));
outpw(0xCFA, bus);
outpw((0xC000 | ((dev & 0x78) << 5)) + where, val);
outpw(0xCF8,0);
return 1;
}
int pci_check_direct()
{
int PCItype;
DWORD tmp;
PCItype = 0;
outp(0xCFB, 0x01);
tmp = inpd(0xCF8);
outpd(0xCF8, 0x80000000);
if (inpd(0xCF8) == 0x80000000) {
outpd(0xCF8, tmp);
pcibios_read_config_dword = pci_conf1_read_config_dword;
pcibios_read_config_word = pci_conf1_read_config_word;
pcibios_read_config_byte = pci_conf1_read_config_byte;
pcibios_write_config_dword = pci_conf1_write_config_dword;
pcibios_write_config_word = pci_conf1_write_config_word;
pcibios_write_config_byte = pci_conf1_write_config_byte;
PCItype = 1;
}
outpw(0x0CF8,tmp);
outp(0xCFB, 0);
outp(0xCF8, 0);
outp(0x0CFA,0);
if ((inp(0x0CF8) == 0) && (inp(0x0CFA) == 0)) {
pcibios_read_config_dword = pci_conf2_read_config_dword;
pcibios_read_config_word = pci_conf2_read_config_word;
pcibios_read_config_byte = pci_conf2_read_config_byte;
pcibios_write_config_dword = pci_conf2_write_config_dword;
pcibios_write_config_word = pci_conf2_write_config_word;
pcibios_write_config_byte = pci_conf2_write_config_byte;
PCItype = 2;
}
return PCItype;
}
/*__________________________________________________________________________*/
/*__________________________________________________________________________*/
int pcibios_present(void)
{
return (PCItype != 0);
}
int pcibios_init(void)
{
if (ll_arch.x86.cpu < 3) {
return -1; /* CPU < 386 --> No PCI */
}
PCItype = pci_check_direct();
if (PCItype == 0) {
return -1;
}
return 1;
}