Author: laurent
Date: 2009-11-10 21:39:42 +0000 (Tue, 10 Nov 2009)
New Revision: 603
Modified:
trunk/openbios-devel/drivers/pci.c
trunk/openbios-devel/forth/util/pci.fs
trunk/openbios-devel/include/libc/string.h
trunk/openbios-devel/libc/misc.c
Log:
Fully decode PCI unit name attribute.
Signed-off-by: Laurent Vivier <Laurent(a)vivier.eu>
Modified: trunk/openbios-devel/drivers/pci.c
===================================================================
--- trunk/openbios-devel/drivers/pci.c 2009-11-10 21:34:21 UTC (rev 602)
+++ trunk/openbios-devel/drivers/pci.c 2009-11-10 21:39:42 UTC (rev 603)
@@ -91,8 +91,106 @@
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 @@
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:
Modified: trunk/openbios-devel/forth/util/pci.fs
===================================================================
--- trunk/openbios-devel/forth/util/pci.fs 2009-11-10 21:34:21 UTC (rev 602)
+++ trunk/openbios-devel/forth/util/pci.fs 2009-11-10 21:39:42 UTC (rev 603)
@@ -90,17 +90,3 @@
\ : 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
-;
-
Modified: trunk/openbios-devel/include/libc/string.h
===================================================================
--- trunk/openbios-devel/include/libc/string.h 2009-11-10 21:34:21 UTC (rev 602)
+++ trunk/openbios-devel/include/libc/string.h 2009-11-10 21:39:42 UTC (rev 603)
@@ -23,7 +23,9 @@
#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);
extern char *strncpy(char * dest,const char *src,size_t count);
Modified: trunk/openbios-devel/libc/misc.c
===================================================================
--- trunk/openbios-devel/libc/misc.c 2009-11-10 21:34:21 UTC (rev 602)
+++ trunk/openbios-devel/libc/misc.c 2009-11-10 21:39:42 UTC (rev 603)
@@ -76,6 +76,41 @@
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