Bug #2880, add functions for byte and word level access to pci config

space.
Fix broken utf8 again.
This commit is contained in:
Kristian Høgsberg 2005-11-08 19:04:56 +00:00
parent 5390c7ab05
commit f8430a1b86
3 changed files with 128 additions and 14 deletions

View File

@ -319,14 +319,24 @@ pciReadWord(PCITAG tag, int offset)
CARD32 tmp;
int shift = (offset & 3) * 8;
int aligned_offset = offset & ~3;
int bus = PCI_BUS_FROM_TAG(tag);
if (shift != 0 && shift != 16)
FatalError("pciReadWord: Alignment error: Cannot read 16 bits "
"at offset %d\n", offset);
tmp = pciReadLong(tag, aligned_offset);
pciInit();
return((CARD16)((tmp >> shift) & 0xffff));
if ((bus >= 0) && ((bus < pciNumBuses) || inProbe) && pciBusInfo[bus] &&
pciBusInfo[bus]->funcs->pciReadWord) {
CARD32 rv = (*pciBusInfo[bus]->funcs->pciReadWord)(tag, offset);
return(rv);
} else {
tmp = pciReadLong(tag, aligned_offset);
return((CARD16)((tmp >> shift) & 0xffff));
}
}
CARD8
@ -335,10 +345,20 @@ pciReadByte(PCITAG tag, int offset)
CARD32 tmp;
int shift = (offset & 3) * 8;
int aligned_offset = offset & ~3;
int bus = PCI_BUS_FROM_TAG(tag);
tmp = pciReadLong(tag, aligned_offset);
pciInit();
return((CARD8)((tmp >> shift) & 0xff));
if ((bus >= 0) && ((bus < pciNumBuses) || inProbe) && pciBusInfo[bus] &&
pciBusInfo[bus]->funcs->pciReadByte) {
CARD8 rv = (*pciBusInfo[bus]->funcs->pciReadByte)(tag, offset);
return(rv);
} else {
tmp = pciReadLong(tag, aligned_offset);
return((CARD8)((tmp >> shift) & 0xff));
}
}
void
@ -359,17 +379,25 @@ pciWriteWord(PCITAG tag, int offset, CARD16 val)
CARD32 tmp;
int aligned_offset = offset & ~3;
int shift = (offset & 3) * 8;
int bus = PCI_BUS_FROM_TAG(tag);
if (shift != 0 && shift != 16)
FatalError("pciWriteWord: Alignment Error: Cannot read 16 bits "
"from offset %d\n", offset);
tmp = pciReadLong(tag, aligned_offset);
pciInit();
tmp &= ~(0xffffL << shift);
tmp |= (((CARD32)val) << shift);
if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] &&
pciBusInfo[bus]->funcs->pciWriteWord) {
(*pciBusInfo[bus]->funcs->pciWriteWord)(tag, offset, val);
} else {
tmp = pciReadLong(tag, aligned_offset);
pciWriteLong(tag, aligned_offset, tmp);
tmp &= ~(0xffffL << shift);
tmp |= (((CARD32)val) << shift);
pciWriteLong(tag, aligned_offset, tmp);
}
}
void
@ -378,13 +406,22 @@ pciWriteByte(PCITAG tag, int offset, CARD8 val)
CARD32 tmp;
int aligned_offset = offset & ~3;
int shift = (offset & 3) *8 ;
int bus = PCI_BUS_FROM_TAG(tag);
tmp = pciReadLong(tag, aligned_offset);
pciInit();
tmp &= ~(0xffL << shift);
tmp |= (((CARD32)val) << shift);
if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] &&
pciBusInfo[bus]->funcs->pciWriteByte) {
(*pciBusInfo[bus]->funcs->pciWriteByte)(tag, offset, val);
} else {
pciWriteLong(tag, aligned_offset, tmp);
tmp = pciReadLong(tag, aligned_offset);
tmp &= ~(0xffL << shift);
tmp |= (((CARD32)val) << shift);
pciWriteLong(tag, aligned_offset, tmp);
}
}
void

View File

@ -194,8 +194,11 @@
((val >> 8) & 0x0000ff00) | \
((val << 8) & 0x00ff0000) | \
((val << 24) & 0xff000000))
#define PCI_CPU16(val) (((val >> 8) & 0x000000ff) | \
((val << 8) & 0x0000ff00))
#else
#define PCI_CPU(val) (val)
#define PCI_CPU16(val) (val)
#endif
/*
@ -382,6 +385,14 @@ typedef struct pci_bus_funcs {
void (*pciGetBridgeBuses)(int, int *, int *, int *);
/* Use pointer's to avoid #include recursion */
void (*pciGetBridgeResources)(int, pointer *, pointer *, pointer *);
/* These are optional and will be implemented using read long
* if not present. */
CARD8 (*pciReadByte)(PCITAG, int);
void (*pciWriteByte)(PCITAG, int, CARD8);
CARD16 (*pciReadWord)(PCITAG, int);
void (*pciWriteWord)(PCITAG, int, CARD16);
} pciBusFuncs_t, *pciBusFuncs_p;
/*

View File

@ -69,17 +69,32 @@ static ADDRESS linuxPpcBusAddrToHostAddr(PCITAG, PciAddrType, ADDRESS);
static ADDRESS linuxPpcHostAddrToBusAddr(PCITAG, PciAddrType, ADDRESS);
#endif
static CARD8 linuxPciCfgReadByte(PCITAG tag, int off);
static void linuxPciCfgWriteByte(PCITAG tag, int off, CARD8 val);
static CARD16 linuxPciCfgReadWord(PCITAG tag, int off);
static void linuxPciCfgWriteWord(PCITAG tag, int off, CARD16 val);
static pciBusFuncs_t linuxFuncs0 = {
/* pciReadLong */ linuxPciCfgRead,
/* pciWriteLong */ linuxPciCfgWrite,
/* pciSetBitsLong */ linuxPciCfgSetBits,
#if defined(__powerpc__)
/* pciAddrHostToBus */ linuxPpcHostAddrToBusAddr,
/* pciAddrBusToHost */ linuxPpcBusAddrToHostAddr
/* pciAddrBusToHost */ linuxPpcBusAddrToHostAddr,
#else
/* pciAddrHostToBus */ pciAddrNOOP,
/* pciAddrBusToHost */ linuxTransAddrBusToHost
/* pciAddrBusToHost */ linuxTransAddrBusToHost,
#endif
/* pciControlBridge */ NULL,
/* pciGetBridgeBuses */ NULL,
/* pciGetBridgeResources */ NULL,
/* pciReadByte */ linuxPciCfgReadByte,
/* pciWriteByte */ linuxPciCfgWriteByte,
/* pciReadWord */ linuxPciCfgReadWord,
/* pciWriteWord */ linuxPciCfgWriteWord,
};
static pciBusInfo_t linuxPci0 = {
@ -270,6 +285,57 @@ linuxPpcHostAddrToBusAddr(PCITAG tag, PciAddrType type, ADDRESS addr)
#endif /* __powerpc__ */
static CARD8
linuxPciCfgReadByte(PCITAG tag, int off)
{
int fd;
CARD8 val = 0xff;
if (-1 != (fd = linuxPciOpenFile(tag,FALSE))) {
lseek(fd,off,SEEK_SET);
read(fd,&val,1);
}
return val;
}
static void
linuxPciCfgWriteByte(PCITAG tag, int off, CARD8 val)
{
int fd;
if (-1 != (fd = linuxPciOpenFile(tag,TRUE))) {
lseek(fd,off,SEEK_SET);
write(fd, &val, 1);
}
}
static CARD16
linuxPciCfgReadWord(PCITAG tag, int off)
{
int fd;
CARD16 val = 0xff;
if (-1 != (fd = linuxPciOpenFile(tag,FALSE))) {
lseek(fd, off, SEEK_SET);
read(fd, &val, 2);
}
return PCI_CPU16(val);
}
static void
linuxPciCfgWriteWord(PCITAG tag, int off, CARD16 val)
{
int fd;
if (-1 != (fd = linuxPciOpenFile(tag,TRUE))) {
lseek(fd, off, SEEK_SET);
val = PCI_CPU16(val);
write(fd, &val, 2);
}
}
#ifndef INCLUDE_XF86_NO_DOMAIN
/*