Show
Ignore:
Timestamp:
04/25/04 15:26:45 (9 years ago)
Author:
khali
Message:

Add bank support to flat address space mode.

Default to bank register 0x07 for Super-I/O chips.
Move default bank register selection to a separate function.
Move setting/restoring bank to a separate function.
Allow dumping of shorter ranges (flat address space mode).
Limit I2C-like dumps to addresses up to 0x3fff.
Print expected ranges on range errors.

This should allow us to work with the PC87360 family of chips.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • lm-sensors/trunk/prog/dump/isadump.c

    r2452 r2475  
    2424        isadump 0x295 0x296             Basic winbond dump using address/data registers 
    2525        isadump 0x295 0x296 2           Winbond dump, bank 2 
    26         isadump 0x2e 0x2f 0x09 0x07     Super-I/O, logical device 9 
     26        isadump 0x2e 0x2f 0x09          Super-I/O, logical device 9 
    2727        isadump -f 0x5000               Flat address space dump like for Via 686a 
     28        isadump -f 0xecf0 0x10 1        PC87366, temperature channel 2 
    2829*/ 
    2930 
     
    5758void help(void) 
    5859{ 
    59   fprintf(stderr,"Syntax: isadump ADDRREG DATAREG [BANK [BANKREG]]\n"); 
    60   fprintf(stderr,"        isadump -f ADDRESS (for flat address space)\n"); 
     60        fprintf(stderr, 
     61                "Syntax for I2C-like access:\n" 
     62                "  isadump ADDRREG DATAREG [BANK [BANKREG]]\n" 
     63                "Syntax for flat address space:\n" 
     64                "  isadump -f ADDRESS [RANGE [BANK [BANKREG]]]\n"); 
     65} 
     66 
     67int default_bankreg(int flat, int addrreg, int datareg) 
     68{ 
     69        if (flat) { 
     70                return 0x09; /* Works for National Semiconductor 
     71                                Super-IO chips */ 
     72        } 
     73 
     74        if ((addrreg == 0x2e && datareg == 0x2f) 
     75         || (addrreg == 0x4e && datareg == 0x4f)) { 
     76                return 0x07; /* Works for all Super-I/O chips */ 
     77        } 
     78         
     79        return 0x4e; /* Works for Winbond ISA chips, default */ 
     80} 
     81 
     82int set_bank(int flat, int addrreg, int datareg, int bank, int bankreg) 
     83{ 
     84        int oldbank; 
     85 
     86        if (flat) { 
     87                oldbank = inb(addrreg+bankreg); 
     88                outb(bank, addrreg+bankreg); 
     89        } else { 
     90                outb(bankreg, addrreg); 
     91                oldbank = inb(datareg); 
     92                outb(bank, datareg); 
     93        } 
     94 
     95        return oldbank; 
    6196} 
    6297 
    6398int main(int argc, char *argv[]) 
    6499{ 
    65   int addrreg, datareg = 0, bank = -1, bankreg = 0x4E; 
     100  int addrreg;        /* addess in flat mode */ 
     101  int datareg = 0;    /* unused in flat mode */ 
     102  int range = 256;    /* can be changed only in flat mode */ 
     103  int bank = -1;      /* -1 means no bank operation */ 
     104  int bankreg; 
    66105  int oldbank = 0; 
    67106  int i,j,res; 
     
    74113  } 
    75114 
    76   if(strcmp(argv[1], "-f")) { 
    77     addrreg = strtol(argv[1],&end,0); 
    78   } else { 
    79     if(argc != 3) { 
    80       help(); 
    81       exit(1); 
    82     } 
     115  if (!strcmp(argv[1], "-f")) { 
    83116    flat = 1; 
    84     addrreg = strtol(argv[2],&end,0) & 0xff00; 
    85   } 
     117  } 
     118 
     119  addrreg = strtol(argv[1+flat], &end, 0); 
    86120  if (*end) { 
    87121    fprintf(stderr,"Error: Invalid address!\n"); 
     
    89123    exit(1); 
    90124  } 
    91   if ((addrreg < 0) || (addrreg > 0xffff)) { 
    92     fprintf(stderr,"Error: Address out of range!\n"); 
     125  if (addrreg < 0 || addrreg > (flat?0xffff:0x3fff)) { 
     126    fprintf(stderr, "Error: Address out of range (0x0000-0x%04x)!\n", 
     127            flat?0xffff:0x3fff); 
    93128    help(); 
    94129    exit(1); 
    95130  } 
    96131 
    97   if(flat) 
    98     goto START; 
    99  
    100   datareg = strtol(argv[2],&end,0); 
    101   if (*end) { 
    102     fprintf(stderr,"Error: Invalid data register!\n"); 
    103     help(); 
    104     exit(1); 
    105   } 
    106   if ((datareg < 0) || (datareg > 0xffff)) { 
    107     fprintf(stderr,"Error: Data register out of range!\n"); 
    108     help(); 
    109     exit(1); 
    110   } 
    111  
    112   if(argc > 3) { 
    113     bank = strtol(argv[3],&end,0); 
     132  if (flat) { 
     133    if (argc > 3) { 
     134      range = strtol(argv[3], &end, 0); 
     135      if (*end || range <= 0 || range > 0x100 || range & 0xf) { 
     136        fprintf(stderr, "Error: Invalid range!\n" 
     137                "Hint: Must be a multiple of 16 no greater than 256.\n"); 
     138        help(); 
     139        exit(1); 
     140      } 
     141    } else { 
     142      addrreg &= 0xff00; /* Force alignment */ 
     143    } 
     144  } else { 
     145    datareg = strtol(argv[2], &end, 0); 
     146    if (*end) { 
     147      fprintf(stderr, "Error: Invalid data register!\n"); 
     148      help(); 
     149      exit(1); 
     150    } 
     151    if (datareg < 0 || datareg > 0x3fff) { 
     152      fprintf(stderr, "Error: Data register out of range (0x0000-0x3fff)!\n"); 
     153      help(); 
     154      exit(1); 
     155    } 
     156  } 
     157 
     158  bankreg = default_bankreg(flat, addrreg, datareg); 
     159 
     160  if(argc > 3+flat) { 
     161    bank = strtol(argv[3+flat],&end,0); 
    114162    if (*end) { 
    115163      fprintf(stderr,"Error: Invalid bank number!\n"); 
     
    123171    } 
    124172 
    125     if(argc > 4) { 
    126       bankreg = strtol(argv[4],&end,0); 
     173    if(argc > 4+flat) { 
     174      bankreg = strtol(argv[4+flat],&end,0); 
    127175      if (*end) { 
    128176        fprintf(stderr,"Error: Invalid bank register!\n"); 
     
    130178        exit(1); 
    131179      } 
    132       if ((bankreg < 0) || (bankreg > 0xff)) { 
    133         fprintf(stderr,"Error: bank out of range (0-0xff)!\n"); 
     180      if (bankreg < 0 || bankreg >= range) { 
     181        fprintf(stderr, 
     182                "Error: bank out of range (0x00-0x%02x)!\n", 
     183                range-1); 
    134184        help(); 
    135185        exit(1); 
     
    137187    } 
    138188  } 
    139  
    140 START: 
    141189 
    142190  if (getuid()) { 
     
    149197  if(flat) 
    150198        fprintf(stderr,"  I will probe address range 0x%04x to " 
    151                  "0x%04x.\n",addrreg, addrreg + 0xff); 
     199                 "0x%04x.\n", addrreg, addrreg + range - 1); 
    152200  else 
    153201        fprintf(stderr,"  I will probe address register 0x%04x and " 
     
    177225#endif 
    178226 
    179   if(bank>=0) { 
    180     outb(bankreg,addrreg); 
    181     oldbank=inb(datareg); 
    182     outb(bank,datareg); 
    183   } 
     227  if (bank >= 0) 
     228    oldbank = set_bank(flat, addrreg, datareg, bank, bankreg); 
    184229 
    185230  printf("     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f\n"); 
    186   for (i = 0; i < 256; i+=16) { 
     231  for (i = 0; i < range; i += 16) { 
    187232    printf("%c0: ",hexchar(i/16)); 
    188233    for(j = 0; j < 16; j++) { 
     
    197242    printf("\n"); 
    198243  } 
    199   if(bank>=0) { 
    200     outb(bankreg,addrreg); 
    201     outb(oldbank,datareg); /* restore original value */ 
    202   } 
     244 
     245  /* Restore the original bank value */ 
     246  if (bank >= 0) 
     247    set_bank(flat, addrreg, datareg, oldbank, bankreg); 
     248 
    203249  exit(0); 
    204250}