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