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