diff options
Diffstat (limited to 'pcitool/cli.c')
-rw-r--r-- | pcitool/cli.c | 191 |
1 files changed, 114 insertions, 77 deletions
diff --git a/pcitool/cli.c b/pcitool/cli.c index 26bd087..d140b98 100644 --- a/pcitool/cli.c +++ b/pcitool/cli.c @@ -192,7 +192,7 @@ static struct option long_options[] = { {"output", required_argument, 0, OPT_OUTPUT }, {"timeout", required_argument, 0, OPT_TIMEOUT }, {"iterations", required_argument, 0, OPT_ITERATIONS }, - {"info", no_argument, 0, OPT_INFO }, + {"info", optional_argument, 0, OPT_INFO }, {"list", no_argument, 0, OPT_LIST }, {"reset", no_argument, 0, OPT_RESET }, {"benchmark", optional_argument, 0, OPT_BENCHMARK }, @@ -257,7 +257,7 @@ void Usage(int argc, char *argv[], const char *format, ...) { "Usage:\n" " %s <mode> [options] [hex data]\n" " Modes:\n" -" -i - Device Info\n" +" -i [target] - Device or Register (target) Info\n" " -l[l] - List (detailed) Data Banks & Registers\n" " -r <addr|reg|dmaX> - Read Data/Register\n" " -w <addr|reg|dmaX> - Write Data/Register\n" @@ -572,7 +572,90 @@ void List(pcilib_t *handle, const pcilib_model_description_t *model_info, const } } -void Info(pcilib_t *handle, const pcilib_model_description_t *model_info) { +void RegisterInfo(pcilib_t *handle, pcilib_register_t reg) { + int err; + pcilib_register_value_t val; + + const pcilib_model_description_t *model_info = pcilib_get_model_description(handle); + const pcilib_register_description_t *r = &model_info->registers[reg]; + pcilib_register_bank_t bank = pcilib_find_register_bank_by_addr(handle, r->bank); + const pcilib_register_bank_description_t *b = &model_info->banks[bank]; + + err = pcilib_read_register_by_id(handle, reg, &val); + + + printf("%s/%s\n", b->name, r->name); + printf(" Current value: "); + if (err) printf("error %i", err); + else printf(b->format, val); + + if (r->mode&PCILIB_REGISTER_W) { + printf(" (default: "); + printf(b->format, r->defvalue); + printf(")"); + } + printf("\n"); + + printf(" Address : 0x%x [%u:%u]\n", r->addr, r->offset, r->offset + r->bits); + printf(" Access : "); + if ((r->mode&PCILIB_REGISTER_RW) == 0) printf("-"); + if (r->mode&PCILIB_REGISTER_R) printf("R"); + if (r->mode&PCILIB_REGISTER_W) printf("W"); + if (r->mode&PCILIB_REGISTER_W1C) printf("/reset"); + if (r->mode&PCILIB_REGISTER_W1I) printf("/invert"); + printf("\n"); + + + if (r->description) + printf(" Description : %s\n", r->description); + + if (r->views) { + int i; + printf("\nSupported Views:\n"); + for (i = 0; r->views[i].name; i++) { + pcilib_view_t view = pcilib_find_view_by_name(handle, r->views[i].view); + if (view == PCILIB_VIEW_INVALID) continue; + + const pcilib_view_description_t *v = model_info->views[view]; + + printf(" View %s (", r->views[i].name); + switch (v->type) { + case PCILIB_TYPE_STRING: + printf("char*"); + break; + case PCILIB_TYPE_DOUBLE: + printf("double"); + break; + default: + printf("unknown"); + } + printf(")\n"); + + if (v->unit) { + pcilib_unit_t unit = pcilib_find_unit_by_name(handle, v->unit); + + printf(" Supported units: %s", v->unit); + + if (unit != PCILIB_UNIT_INVALID) { + int j; + const pcilib_unit_description_t *u = &model_info->units[unit]; + + for (j = 0; u->transforms[j].unit; j++) + printf(", %s", u->transforms[j].unit); + } + printf("\n"); + } + + if (v->description) + printf(" Description : %s\n", v->description); + } + } + + +// printf("Type: %s". r->rw +} + +void Info(pcilib_t *handle, const pcilib_model_description_t *model_info, const char *target) { int i, j; DIR *dir; void *plugin; @@ -595,9 +678,20 @@ void Info(pcilib_t *handle, const pcilib_model_description_t *model_info) { if (board_info) printf(" Interrupt - Pin: %i, Line: %i\n", board_info->interrupt_pin, board_info->interrupt_line); + printf("\n"); + + if (target) { + pcilib_register_t reg; + + reg = pcilib_find_register(handle, NULL, target); + if (reg != PCILIB_REGISTER_INVALID) + return RegisterInfo(handle, reg); + + Error(" No register %s is found", target); + } + List(handle, model_info, (char*)-1, 0); - printf("\n"); printf("Available models:\n"); dir = opendir(path); @@ -1024,15 +1118,13 @@ int ReadRegister(pcilib_t *handle, const pcilib_model_description_t *model_info, int i; int err; const char *format; - char *s1,*regname,*viewname; - - char* fullreg=strdup(reg); pcilib_register_bank_t bank_id; pcilib_register_bank_addr_t bank_addr = 0; pcilib_register_value_t value; - if (reg && !(strchr(fullreg,'/'))) { + + if (reg) { pcilib_register_t regid = pcilib_find_register(handle, bank, reg); bank_id = pcilib_find_register_bank_by_addr(handle, model_info->registers[regid].bank); format = model_info->banks[bank_id].format; @@ -1046,33 +1138,6 @@ int ReadRegister(pcilib_t *handle, const pcilib_model_description_t *model_info, printf(format, value); printf("\n"); } - }else if(reg && (s1=strchr(fullreg,'/'))){ - char* enum_command=malloc(50*sizeof(char)); - if(!enum_command){ - printf("Error allocating memory for the result\n"); - return PCILIB_ERROR_MEMORY; - } - *s1=0; - regname=fullreg; - viewname=s1+1; - if(!strcasecmp(viewname,"name")){ - err = pcilib_read_view(handle,bank,regname,viewname,50*sizeof(char),enum_command); - if (err) printf("Error reading register %s with an enum view\n", reg); - else { - printf("%s = %s\n", regname, (char*)enum_command); - } - free(enum_command); - }else{ - format = "%lf"; - - err = pcilib_read_view(handle,bank,regname,viewname,sizeof(pcilib_register_value_t),&value); - if (err) printf("Error reading register %s with a formula view\n", reg); - else { - printf("%s = ", reg); - printf(format, value); - printf("%s\n",viewname); - } - } } else { // Adding DMA registers pcilib_get_dma_description(handle); @@ -1281,20 +1346,10 @@ int WriteRegister(pcilib_t *handle, const pcilib_model_description_t *model_info unsigned long val; pcilib_register_value_t value; - pcilib_register_t regid; const char *format = NULL; - char *s1,*regname=NULL; - - char *fullregister=strdup(reg); - if((s1=strchr(fullregister,'/'))){ - *s1=0; - regname=fullregister; - regid=pcilib_find_register(handle,bank,regname); - }else{ - regid = pcilib_find_register(handle, bank, reg); - } + pcilib_register_t regid = pcilib_find_register(handle, bank, reg); if (regid == PCILIB_REGISTER_INVALID) Error("Can't find register (%s) from bank (%s)", reg, bank?bank:"autodetected"); /* @@ -1319,29 +1374,15 @@ int WriteRegister(pcilib_t *handle, const pcilib_model_description_t *model_info } format = "0x%lx"; - } else if((data) && !(regname)){ - err = pcilib_write_view(handle,bank,reg,"name",0,*data); - if(err) Error("can't write to the register using an enum view"); - else return 0; - } - /* should i put strchr not null here?* } else { Error("Can't parse data value (%s) is not valid decimal number", *data); - }*/ + } value = val; + + err = pcilib_write_register(handle, bank, reg, value); + if (err) Error("Error writting register %s\n", reg); - if((regname)){ - char *view_name; - view_name=s1+1;; - err = pcilib_write_view(handle,bank,regname,view_name,0,&value); - if (err) printf("Error writing register %s using view %s\n",regname,view_name); - free(fullregister); - }else{ - err = pcilib_write_register(handle, bank, reg, value); - if (err) Error("Error writting register %s\n", reg); - } - if ((model_info->registers[regid].mode&PCILIB_REGISTER_RW) == PCILIB_REGISTER_RW) { err = pcilib_read_register(handle, bank, reg, &value); if (err) Error("Error reading back register %s for verification\n", reg); @@ -2709,6 +2750,7 @@ int main(int argc, char **argv) { const char *dma_channel = NULL; const char *use = NULL; const char *lock = NULL; + const char *info_target = NULL; size_t block = (size_t)-1; pcilib_irq_type_t irq_type = PCILIB_IRQ_TYPE_ALL; pcilib_irq_hw_source_t irq_source = PCILIB_IRQ_SOURCE_DEFAULT; @@ -2746,6 +2788,9 @@ int main(int argc, char **argv) { case OPT_INFO: if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); + if (optarg) info_target = optarg; + else if ((optind < argc)&&(argv[optind][0] != '-')) info_target = argv[optind++]; + mode = MODE_INFO; break; case OPT_LIST: @@ -2773,11 +2818,6 @@ int main(int argc, char **argv) { mode = MODE_READ; if (optarg) addr = optarg; else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++]; - - /* char* s; - if(!(s=strchr(addr,'/'))){ - mode=MODE_READ_VIEW;*/ - break; case OPT_WRITE: if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); @@ -3302,10 +3342,7 @@ int main(int argc, char **argv) { ++mode; } } - } else if(strchr(addr,'/')) { - reg=addr; - ++mode; - }else { + } else { if (pcilib_find_register(handle, bank, addr) == PCILIB_REGISTER_INVALID) { Usage(argc, argv, "Invalid address (%s) is specified", addr); } else { @@ -3389,7 +3426,7 @@ int main(int argc, char **argv) { switch (mode) { case MODE_INFO: - Info(handle, model_info); + Info(handle, model_info, info_target); break; case MODE_LIST: List(handle, model_info, bank, details); @@ -3405,12 +3442,12 @@ int main(int argc, char **argv) { } else if (addr) { err = ReadData(handle, amode, flags, dma, bar, start, size, access, endianess, (size_t)-1, ofile); } else { - Error("Address to read is not specified"); + Error("Address to read is not specified"); } break; case MODE_READ_REGISTER: - if ((reg)||(!addr)) ReadRegister(handle, model_info, bank, reg); - else ReadRegisterRange(handle, model_info, bank, start, addr_shift, size, ofile); + if ((reg)||(!addr)) ReadRegister(handle, model_info, bank, reg); + else ReadRegisterRange(handle, model_info, bank, start, addr_shift, size, ofile); break; case MODE_WRITE: WriteData(handle, amode, dma, bar, start, size, access, endianess, data, verify); |