1 /* 2 * Copyright (c) 2015 Google, Inc 3 * Written by Simon Glass <sjg@chromium.org> 4 * Copyright (c) 2017 Álvaro Fernández Rojas <noltari@gmail.com> 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 9 #include <common.h> 10 #include <command.h> 11 #include <cpu.h> 12 #include <dm.h> 13 #include <errno.h> 14 15 static const char *cpu_feature_name[CPU_FEAT_COUNT] = { 16 "L1 cache", 17 "MMU", 18 "Microcode", 19 "Device ID", 20 }; 21 22 static int print_cpu_list(bool detail) 23 { 24 struct udevice *dev; 25 char buf[100]; 26 27 for (uclass_first_device(UCLASS_CPU, &dev); 28 dev; 29 uclass_next_device(&dev)) { 30 struct cpu_platdata *plat = dev_get_parent_platdata(dev); 31 struct cpu_info info; 32 bool first = true; 33 int ret, i; 34 35 ret = cpu_get_desc(dev, buf, sizeof(buf)); 36 printf("%3d: %-10s %s\n", dev->seq, dev->name, 37 ret ? "<no description>" : buf); 38 if (!detail) 39 continue; 40 ret = cpu_get_info(dev, &info); 41 if (ret) { 42 printf("\t(no detail available"); 43 if (ret != -ENOSYS) 44 printf(": err=%d", ret); 45 printf(")\n"); 46 continue; 47 } 48 printf("\tID = %d, freq = ", plat->cpu_id); 49 print_freq(info.cpu_freq, ""); 50 for (i = 0; i < CPU_FEAT_COUNT; i++) { 51 if (info.features & (1 << i)) { 52 printf("%s%s", first ? ": " : ", ", 53 cpu_feature_name[i]); 54 first = false; 55 } 56 } 57 printf("\n"); 58 if (info.features & (1 << CPU_FEAT_UCODE)) 59 printf("\tMicrocode version %#x\n", 60 plat->ucode_version); 61 if (info.features & (1 << CPU_FEAT_DEVICE_ID)) 62 printf("\tDevice ID %#lx\n", plat->device_id); 63 } 64 65 return 0; 66 } 67 68 static int do_cpu_list(cmd_tbl_t *cmdtp, int flag, int argc, 69 char *const argv[]) 70 { 71 if (print_cpu_list(false)) 72 return CMD_RET_FAILURE; 73 74 return 0; 75 } 76 77 static int do_cpu_detail(cmd_tbl_t *cmdtp, int flag, int argc, 78 char *const argv[]) 79 { 80 if (print_cpu_list(true)) 81 return CMD_RET_FAILURE; 82 83 return 0; 84 } 85 86 static cmd_tbl_t cmd_cpu_sub[] = { 87 U_BOOT_CMD_MKENT(list, 2, 1, do_cpu_list, "", ""), 88 U_BOOT_CMD_MKENT(detail, 4, 0, do_cpu_detail, "", ""), 89 }; 90 91 /* 92 * Process a cpu sub-command 93 */ 94 static int do_cpu(cmd_tbl_t *cmdtp, int flag, int argc, 95 char * const argv[]) 96 { 97 cmd_tbl_t *c = NULL; 98 99 /* Strip off leading 'cpu' command argument */ 100 argc--; 101 argv++; 102 103 if (argc) 104 c = find_cmd_tbl(argv[0], cmd_cpu_sub, 105 ARRAY_SIZE(cmd_cpu_sub)); 106 107 if (c) 108 return c->cmd(cmdtp, flag, argc, argv); 109 else 110 return CMD_RET_USAGE; 111 } 112 113 U_BOOT_CMD( 114 cpu, 2, 1, do_cpu, 115 "display information about CPUs", 116 "list - list available CPUs\n" 117 "cpu detail - show CPU detail" 118 ); 119