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