summaryrefslogtreecommitdiffstats
path: root/pcitool
diff options
context:
space:
mode:
Diffstat (limited to 'pcitool')
-rw-r--r--pcitool/cli.c191
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);