Fully decode PCI unit name attribute.

Signed-off-by: Laurent Vivier <Laurent@vivier.eu>


git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@603 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
Laurent Vivier
2009-11-10 21:39:42 +00:00
parent 92e6599c92
commit d6365bca24
4 changed files with 138 additions and 17 deletions

View File

@@ -91,8 +91,106 @@ ob_pci_initialize(int *idx)
static void
ob_pci_decode_unit(int *idx)
{
PUSH(0);
fword("decode-unit-pci-bus");
ucell hi, mid, lo;
const char *arg = pop_fstr_copy();
int dev, fn, reg, ss, n, p, t;
int bus = 0; /* no information */
char *ptr;
dev = 0;
fn = 0;
reg = 0;
ss = 0;
n = 0;
p = 0;
t = 0;
ptr = (char*)arg;
if (*ptr == 'n') {
n = IS_NOT_RELOCATABLE;
ptr++;
}
if (*ptr == 'i') {
ss = IO_SPACE;
ptr++;
if (*ptr == 't') {
t = IS_ALIASED;
ptr++;
}
/* DD,F,RR,NNNNNNNN */
dev = strtol(ptr, &ptr, 16);
ptr++;
fn = strtol(ptr, &ptr, 16);
ptr++;
reg = strtol(ptr, &ptr, 16);
ptr++;
lo = strtol(ptr, &ptr, 16);
mid = 0;
} else if (*ptr == 'm') {
ss = MEMORY_SPACE_32;
ptr++;
if (*ptr == 't') {
t = IS_ALIASED;
ptr++;
}
if (*ptr == 'p') {
p = IS_PREFETCHABLE;
ptr++;
}
/* DD,F,RR,NNNNNNNN */
dev = strtol(ptr, &ptr, 16);
ptr++;
fn = strtol(ptr, &ptr, 16);
ptr++;
reg = strtol(ptr, &ptr, 16);
ptr++;
lo = strtol(ptr, &ptr, 16);
mid = 0;
} else if (*ptr == 'x') {
unsigned long long addr64;
ss = MEMORY_SPACE_64;
ptr++;
if (*ptr == 'p') {
p = IS_PREFETCHABLE;
ptr++;
}
/* DD,F,RR,NNNNNNNNNNNNNNNN */
dev = strtol(ptr, &ptr, 16);
ptr++;
fn = strtol(ptr, &ptr, 16);
ptr++;
reg = strtol(ptr, &ptr, 16);
ptr++;
addr64 = strtoll(ptr, &ptr, 16);
lo = (ucell)addr64;
mid = addr64 >> 32;
} else {
ss = CONFIGURATION_SPACE;
/* "DD" or "DD,FF" */
dev = strtol(ptr, &ptr, 16);
if (*ptr == ',') {
ptr++;
fn = strtol(ptr, NULL, 16);
}
lo = 0;
mid = 0;
}
free((char*)arg);
hi = n | p | t | (ss << 24) | (bus << 16) | (dev << 11) | (fn << 8) | reg;
PUSH(lo);
PUSH(mid);
PUSH(hi);
}
/* ( phys.lo phy.mid phys.hi -- str len ) */
@@ -122,7 +220,7 @@ ob_pci_encode_unit(int *idx)
if (fn == 0) /* DD */
snprintf(buf, sizeof(buf), "%x", dev);
else /* DD,F */
snprintf(buf, sizeof(buf), "%x,%d", dev, fn);
snprintf(buf, sizeof(buf), "%x,%x", dev, fn);
break;
case IO_SPACE:

View File

@@ -90,17 +90,3 @@ hex
\ : test-pci
\ 0 2 0 dump-pci-device
\ ;
\ only forth
: decode-unit-pci-bus ( str len bus -- phys.lo phys.mid phys.hi )
-rot ascii , left-split
( addr-R len-R addr-L len-L )
parse-hex b << f800 and
-rot parse-hex 8 << 700 and
or
( bus phys.hi )
swap ff and 10 << or
0 0 rot
;

View File

@@ -23,6 +23,8 @@
#define atol(nptr) strtol(nptr, NULL, 10 )
extern long strtol( const char *nptr, char **endptr, int base );
extern long long int strtoll( const char *nptr, char **endptr, int base );
extern int strnicmp(const char *s1, const char *s2, size_t len);
extern char *strcpy(char * dest,const char *src);

View File

@@ -76,6 +76,41 @@ strtol( const char *nptr, char **endptr, int base )
return sum * sign;
}
long long int
strtoll( const char *nptr, char **endptr, int base )
{
long long int sum;
int n, sign=1;
while( isspace(*nptr) )
nptr++;
if( *nptr == '-' || *nptr == '+' )
sign = (*nptr++ == '-') ? -1 : 1;
if( base == 16 || base == 0) {
if( !base )
base = (nptr[0] == '0')? 8 : 10;
if( nptr[0] == '0' && nptr[1] == 'x' ) {
nptr += 2;
base = 16;
}
}
for( sum=0 ;; nptr++ ) {
char ch = *nptr;
if( !isalnum(ch) )
break;
n = isdigit(ch) ? ch - '0' : toupper(ch) - 'A' + 10;
if( n >= base || n < 0 )
break;
sum *= base;
sum += n;
}
if( endptr )
*endptr = (char*)nptr;
return sum * sign;
}
// Propolice support
long __guard[8] = {
#ifdef CONFIG_BIG_ENDIAN