File indexing completed on 2025-05-11 08:24:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #ifdef HAVE_CONFIG_H
0032 #include "config.h"
0033 #endif
0034
0035 #include <inttypes.h>
0036 #include <limits.h>
0037 #include <stdlib.h>
0038 #include <stdio.h>
0039 #include <string.h>
0040 #include <errno.h>
0041 #include <drvmgr/drvmgr.h>
0042
0043 #include <rtems.h>
0044 #include <rtems/shell.h>
0045 #include "internal.h"
0046
0047 static void usage(void);
0048
0049 static void *get_obj_adr(char *arg)
0050 {
0051 unsigned long obj_adr;
0052
0053 obj_adr = strtoul(arg, NULL, 16);
0054 if (obj_adr == ULONG_MAX || obj_adr == 0) {
0055 puts(" Not a valid ID");
0056 return NULL;
0057 }
0058
0059 return (void *)obj_adr;
0060 }
0061
0062
0063 static void show_drvmgr_info(void)
0064 {
0065 drvmgr_summary();
0066 drvmgr_print_devs(PRINT_DEVS_ALL);
0067 }
0068
0069 static int shell_drvmgr_topo(int argc, char *argv[])
0070 {
0071 drvmgr_print_topo();
0072 return 0;
0073 }
0074
0075 static int shell_drvmgr_short(int argc, char *argv[])
0076 {
0077 void *obj;
0078
0079 if (argc < 2)
0080 return -1;
0081 if (argc < 3) {
0082
0083 drvmgr_info_drvs(0);
0084 drvmgr_info_buses(0);
0085 drvmgr_info_devs(OPTION_DEV_GENINFO);
0086 return 0;
0087 }
0088
0089
0090 obj = get_obj_adr(argv[2]);
0091 if (!obj)
0092 return -3;
0093
0094 drvmgr_info(obj, OPTION_DEV_GENINFO);
0095
0096 return 0;
0097 }
0098
0099 static int shell_drvmgr_info(int argc, char *argv[])
0100 {
0101 void *obj;
0102
0103 if (argc < 2)
0104 return -1;
0105 if (argc < 3) {
0106
0107 drvmgr_info_drvs(OPTION_INFO_ALL);
0108 drvmgr_info_buses(OPTION_INFO_ALL);
0109 drvmgr_info_devs(OPTION_INFO_ALL);
0110 return 0;
0111 }
0112
0113
0114 obj = get_obj_adr(argv[2]);
0115 if (!obj)
0116 return -3;
0117
0118 drvmgr_info(obj, OPTION_INFO_ALL);
0119
0120 return 0;
0121 }
0122
0123 static int shell_drvmgr_remove(int argc, char *argv[])
0124 {
0125 puts(" Not implemented");
0126 return 0;
0127 }
0128
0129 static int shell_drvmgr_parent(int argc, char *argv[])
0130 {
0131 void *obj;
0132 int obj_type;
0133 struct drvmgr_dev *dev;
0134 struct drvmgr_bus *bus;
0135
0136
0137 if (argc < 3)
0138 return -2;
0139 obj = get_obj_adr(argv[2]);
0140 if (!obj)
0141 return -3;
0142
0143 obj_type = *(int *)obj;
0144 if (obj_type == DRVMGR_OBJ_BUS) {
0145 bus = obj;
0146 if (!bus->dev) {
0147 puts(" bus has no bridge device");
0148 } else if(!bus->dev->parent) {
0149 puts(" bridge device has no parent");
0150 } else {
0151 dev = bus->dev;
0152 printf(" BUSID=%p\n", dev->parent);
0153 }
0154 } else if (obj_type == DRVMGR_OBJ_DEV) {
0155 dev = obj;
0156 if (!dev->parent) {
0157 puts(" device has no parent bus");
0158 } else {
0159 printf(" BUSID=%p\n", dev->parent);
0160 }
0161 } else {
0162 puts(" ID is not a device or bus");
0163 return 1;
0164 }
0165
0166 return 0;
0167 }
0168
0169 static void shell_drvmgr_print_key_array(struct drvmgr_key *keys)
0170 {
0171 struct drvmgr_key *key;
0172 static char *type_strs[4] = {"UNKNOWN","INTEGER","STRING ","POINTER"};
0173 enum drvmgr_kt type;
0174 union drvmgr_key_value *val;
0175
0176 if (keys == NULL) {
0177 printf(" DEV HAS NO KEYS\n");
0178 return;
0179 }
0180
0181 key = &keys[0];
0182 while (key->key_type != DRVMGR_KT_NONE) {
0183 if (key->key_type > DRVMGR_KT_POINTER)
0184 type = DRVMGR_KT_NONE;
0185 else
0186 type = key->key_type;
0187 printf(" NAME=%-14s TYPE=%s VALUE=", key->key_name, type_strs[type]);
0188 val = &key->key_value;
0189 switch (type) {
0190 default:
0191 case DRVMGR_KT_NONE:
0192 case DRVMGR_KT_INT:
0193 printf("0x%x (%d)\n", val->i, val->i);
0194 break;
0195 case DRVMGR_KT_STRING:
0196 printf("%s\n", val->str);
0197 break;
0198 case DRVMGR_KT_POINTER:
0199 printf("%p\n", val->ptr);
0200 break;
0201 }
0202 key++;
0203 }
0204 }
0205
0206 static void shell_drvmgr_print_res_array(struct drvmgr_drv_res *resources)
0207 {
0208 struct drvmgr_drv_res *res = &resources[0];
0209 struct drvmgr_drv *drv;
0210 char *drv_name;
0211
0212 while (res->drv_id) {
0213
0214 drv = drvmgr_drv_by_id(res->drv_id);
0215 if (drv && drv->name)
0216 drv_name = drv->name;
0217 else
0218 drv_name = "UNKNOWN";
0219 printf(" RESOURCES FOR DEVICE[%02d] DRIVER[0x%" PRIu64 " (%s)]\n",
0220 res->minor_bus, res->drv_id, drv_name);
0221 shell_drvmgr_print_key_array(res->keys);
0222 res++;
0223 }
0224 }
0225
0226 static int shell_drvmgr_res(int argc, char *argv[])
0227 {
0228 void *obj;
0229 int obj_type;
0230 struct drvmgr_dev *dev;
0231 struct drvmgr_bus *bus;
0232 struct drvmgr_key *keys;
0233 struct drvmgr_bus_res *lst;
0234 int i;
0235
0236
0237 if (argc < 3)
0238 return -2;
0239 obj = get_obj_adr(argv[2]);
0240 if (!obj)
0241 return -3;
0242
0243 obj_type = *(int *)obj;
0244 if (obj_type == DRVMGR_OBJ_BUS) {
0245 bus = obj;
0246 lst = bus->reslist;
0247 if (lst == NULL) {
0248 puts(" BUS does not have resources\n");
0249 return 0;
0250 }
0251 i = 0;
0252 while (lst) {
0253 printf(" -- RESOURCES ARRAY %d --\n", i);
0254 shell_drvmgr_print_res_array(lst->resource);
0255 puts("");
0256 i++;
0257 lst = lst->next;
0258 }
0259 } else if (obj_type == DRVMGR_OBJ_DEV) {
0260 dev = obj;
0261 if (dev->drv == NULL) {
0262 puts(" DEVICE has no driver ==> resources not available\n");
0263 return 0;
0264 }
0265 drvmgr_keys_get(dev, &keys);
0266 if (keys == NULL) {
0267 puts(" DEVICE does not have resources\n");
0268 return 0;
0269 }
0270 shell_drvmgr_print_key_array(keys);
0271 } else {
0272 puts(" ID is not a device or bus");
0273 return 1;
0274 }
0275
0276 return 0;
0277 }
0278
0279 static int shell_drvmgr_buses(int argc, char *argv[])
0280 {
0281 drvmgr_info_buses(OPTION_INFO_ALL);
0282 return 0;
0283 }
0284
0285 static int shell_drvmgr_devs(int argc, char *argv[])
0286 {
0287 drvmgr_info_devs(OPTION_INFO_ALL);
0288 return 0;
0289 }
0290
0291 static int shell_drvmgr_drvs(int argc, char *argv[])
0292 {
0293 drvmgr_info_drvs(OPTION_INFO_ALL);
0294 return 0;
0295 }
0296
0297 static int shell_drvmgr_mem(int argc, char *argv[])
0298 {
0299 drvmgr_print_mem();
0300 return 0;
0301 }
0302
0303 static int shell_drvmgr_translate(int argc, char *argv[])
0304 {
0305 int rc, rev, up, obj_type;
0306 void *obj, *dst;
0307 unsigned long src, tmp;
0308
0309 if (argc != 5)
0310 return -1;
0311
0312 obj = get_obj_adr(argv[2]);
0313 if (!obj)
0314 return -3;
0315
0316 obj_type = *(int *)obj;
0317 if (obj_type != DRVMGR_OBJ_DEV) {
0318 puts(" ID is not a device\n");
0319 return 0;
0320 }
0321
0322 tmp = strtoul(argv[3], NULL, 0);
0323 if (tmp > 3) {
0324 puts(" Not a valid option OPT, only [0..3] is valid");
0325 return 0;
0326 }
0327 rev = tmp & DRVMGR_TR_REVERSE;
0328 up = tmp & DRVMGR_TR_PATH;
0329
0330 src = strtoul(argv[4], NULL, 0);
0331 if (src == ULONG_MAX && errno == ERANGE) {
0332 puts(" Not a valid source address");
0333 return 0;
0334 }
0335
0336 rc = drvmgr_translate((struct drvmgr_dev *)obj, up | rev, (void *)src, &dst);
0337 if (rc == 0)
0338 printf(" Address %p could not be translated\n", (void *)src);
0339 else if (rc == 0xffffffff)
0340 printf(" %p => %p (no translation required)\n", (void *)src, dst);
0341 else
0342 printf(" %p => %p (map size 0x%x)\n", (void *)src, dst, rc);
0343
0344 return 0;
0345 }
0346
0347 static const char drvmgr_usage_str[] =
0348 " usage:\n"
0349 " drvmgr buses List bus specfic information on all buses\n"
0350 " drvmgr devs List general and driver specfic information\n"
0351 " about all devices\n"
0352 " drvmgr drvs List driver specfic information on all drivers\n"
0353 " drvmgr info [ID] List general and driver specfic information\n"
0354 " about all devices or one device, bus or driver\n"
0355 " drvmgr mem Dynamically memory usage\n"
0356 " drvmgr parent ID Short info about parent bus of a device\n"
0357 " drvmgr remove ID Remove a device or a bus\n"
0358 " drvmgr res ID List Resources of a device or bus\n"
0359 " drvmgr short [ID] Short info about all devices/buses or one\n"
0360 " device/bus\n"
0361 " drvmgr topo Show bus topology with all devices\n"
0362 " drvmgr tr ID OPT ADR Translate ADR down(0)/up(1) -streams (OPT bit 1) in\n"
0363 " std(0)/reverse(1) (OPT bit 0) direction for device\n"
0364 " drvmgr --help\n";
0365
0366 static void usage(void)
0367 {
0368 puts(drvmgr_usage_str);
0369 }
0370
0371 static int shell_drvmgr_usage(int argc, char *argv[])
0372 {
0373 usage();
0374 return 0;
0375 }
0376
0377 struct shell_drvmgr_modifier {
0378 char *name;
0379 int (*func)(int argc, char *argv[]);
0380 };
0381
0382 #define MODIFIER_NUM 12
0383 static struct shell_drvmgr_modifier shell_drvmgr_modifiers[MODIFIER_NUM] =
0384 {
0385 {"buses", shell_drvmgr_buses},
0386 {"devs", shell_drvmgr_devs},
0387 {"drvs", shell_drvmgr_drvs},
0388 {"info", shell_drvmgr_info},
0389 {"mem", shell_drvmgr_mem},
0390 {"parent", shell_drvmgr_parent},
0391 {"remove", shell_drvmgr_remove},
0392 {"res", shell_drvmgr_res},
0393 {"short", shell_drvmgr_short},
0394 {"topo", shell_drvmgr_topo},
0395 {"tr", shell_drvmgr_translate},
0396 {"--help", shell_drvmgr_usage},
0397 };
0398
0399 static struct shell_drvmgr_modifier *shell_drvmgr_find_modifier(char *name)
0400 {
0401 struct shell_drvmgr_modifier *mod;
0402 int i;
0403
0404 if (name == NULL)
0405 return NULL;
0406
0407 for (i=0, mod=&shell_drvmgr_modifiers[0]; i<MODIFIER_NUM; i++, mod++) {
0408 if (strcmp(name, mod->name) == 0)
0409 return mod;
0410 }
0411
0412 return NULL;
0413 }
0414
0415 static int rtems_shell_main_drvmgr(
0416 int argc,
0417 char *argv[]
0418 )
0419 {
0420 struct shell_drvmgr_modifier *mod;
0421 int rc;
0422
0423 if (argc < 2) {
0424 show_drvmgr_info();
0425 rc = 0;
0426 } else if ((mod=shell_drvmgr_find_modifier(argv[1])) != NULL) {
0427 rc = mod->func(argc, argv);
0428 } else {
0429 rc = -1;
0430 }
0431
0432 if (rc < 0) {
0433 printf(" invalid argument\n");
0434 usage();
0435 }
0436
0437 return rc;
0438 }
0439
0440 rtems_shell_cmd_t rtems_shell_DRVMGR_Command = {
0441 "drvmgr",
0442 drvmgr_usage_str,
0443 "system",
0444 rtems_shell_main_drvmgr,
0445 NULL,
0446 NULL
0447 };