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@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