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