xref: /openbmc/u-boot/cmd/cpu.c (revision 9d466f2f)
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