mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
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:
104
drivers/pci.c
104
drivers/pci.c
@@ -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:
|
||||
|
||||
@@ -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
|
||||
;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
35
libc/misc.c
35
libc/misc.c
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user