From: Martin Storsjö Date: Thu, 22 Jan 2026 22:56:56 +0000 (+0200) Subject: lscpu: Implement options for dumping ARM implementer/model name tables X-Git-Tag: v2.43-devel~134^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=16724407c858f4d3e2d2497f758b678b644c0011;p=thirdparty%2Futil-linux.git lscpu: Implement options for dumping ARM implementer/model name tables This allows extracting the contents of the tables, which itself is uncopyrightable, for use in other projects with different code licenses. --- diff --git a/bash-completion/lscpu b/bash-completion/lscpu index eb07cf9f2..8d54df188 100644 --- a/bash-completion/lscpu +++ b/bash-completion/lscpu @@ -30,6 +30,8 @@ _lscpu_module() -*) OPTS_ALL="--all --annotate + --arm-id + --arm-model --online --bytes --caches diff --git a/sys-utils/lscpu-arm.c b/sys-utils/lscpu-arm.c index 591e12064..ed255a3c7 100644 --- a/sys-utils/lscpu-arm.c +++ b/sys-utils/lscpu-arm.c @@ -16,6 +16,7 @@ * - SMBIOS tables (if applicable) */ #include "lscpu.h" +#include struct id_part { const int id; @@ -492,3 +493,107 @@ void lscpu_decode_arm(struct lscpu_cxt *cxt) for (i = 0; i < cxt->ncputypes; i++) arm_decode(cxt, cxt->cputypes[i]); } + +static struct libscols_table *arm_mktable(struct lscpu_cxt *cxt, const char *tabname) +{ + struct libscols_table *tb; + + scols_init_debug(0); + + tb = scols_new_table(); + if (!tb) + err(EXIT_FAILURE, _("failed to allocate output table")); + if (cxt->json) { + scols_table_enable_json(tb, 1); + scols_table_set_name(tb, tabname); + } + if (cxt->raw) + scols_table_enable_raw(tb, 1); + + scols_table_new_column(tb, _("id"), 0, 0); + scols_table_new_column(tb, _("name"), 0, 0); + + return tb; +} + +/* + * [--arm-id] backend + */ +void lscpu_print_arm_implementers(struct lscpu_cxt *cxt) +{ + size_t i; + struct libscols_table *tb; + + tb = arm_mktable(cxt, "arm-implementers"); + + for (i = 0; hw_implementer[i].id != -1; i++) { + struct libscols_line *ln; + ln = scols_table_new_line(tb, NULL); + if (!ln) + err(EXIT_FAILURE, _("failed to allocate output line")); + scols_line_sprintf(ln, 0, "0x%02x", hw_implementer[i].id); + scols_line_set_data(ln, 1, hw_implementer[i].name); + } + + scols_print_table(tb); + scols_unref_table(tb); +} + +/* + * [--arm-id=] backend + */ +void lscpu_print_arm_models(struct lscpu_cxt *cxt, int implementer) +{ + size_t i; + struct libscols_table *tb; + const struct id_part *parts = NULL; + + for (i = 0; hw_implementer[i].id != -1; i++) { + if (hw_implementer[i].id == implementer) { + parts = hw_implementer[i].parts; + break; + } + } + if (!parts) + errx(EXIT_FAILURE, _("implementer not found")); + + tb = arm_mktable(cxt, "arm-models"); + + for (i = 0; parts[i].id != -1; i++) { + struct libscols_line *ln; + ln = scols_table_new_line(tb, NULL); + if (!ln) + err(EXIT_FAILURE, _("failed to allocate output line")); + scols_line_sprintf(ln, 0, "0x%03x", parts[i].id); + scols_line_set_data(ln, 1, parts[i].name); + } + + scols_print_table(tb); + scols_unref_table(tb); +} + +/* + * [--arm-id= --arm-model=] backend + */ +void lscpu_print_arm_model(struct lscpu_cxt *cxt __attribute__((__unused__)), int implementer, int model) +{ + size_t i; + const struct id_part *parts = NULL; + + for (i = 0; hw_implementer[i].id != -1; i++) { + if (hw_implementer[i].id == implementer) { + parts = hw_implementer[i].parts; + break; + } + } + if (!parts) + errx(EXIT_FAILURE, _("implementer not found")); + + for (i = 0; parts[i].id != -1; i++) { + if (parts[i].id == model) { + printf("%s\n", parts[i].name); + return; + } + } + errx(EXIT_FAILURE, _("model not found")); +} diff --git a/sys-utils/lscpu.1.adoc b/sys-utils/lscpu.1.adoc index bf95ce464..0636ef87c 100644 --- a/sys-utils/lscpu.1.adoc +++ b/sys-utils/lscpu.1.adoc @@ -108,6 +108,16 @@ Display physical IDs for all columns with topology elements (core, socket, etc.) + The CPU logical numbers are not affected by this option. +*--arm-id*[**=**_list_]:: +Print a list of the known ARM core implementers and their human readable names. ++ +If an argument is given, print a list of the individual core IDs and their +names, for the given implementer. + +*--arm-model* _id_:: +Print the name for this specific core model. This requires passing +*--arm-id=_id_* to indicate the implementer id as well. + include::man-common/annotate.adoc[] == ENVIRONMENT diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c index c0ac61bbf..4556aa6df 100644 --- a/sys-utils/lscpu.c +++ b/sys-utils/lscpu.c @@ -1216,6 +1216,8 @@ static void __attribute__((__noreturn__)) usage(void) fputs(_(" -y, --physical print physical instead of logical IDs\n"), out); fputs(_(" --hierarchic[=when] use subsections in summary (auto, never, always)\n"), out); fputs(_(" --output-all print all available columns for -e, -p or -C\n"), out); + fputs(_(" --arm-id[=] print the known ARM implementers and their names. If an id is given, print all the cores for that implementer.\n"), out); + fputs(_(" --arm-model print the name of the given ARM implementer and model. Requires --arm-id=.\n"), out); fputs(USAGE_SEPARATOR, out); fprintf(out, USAGE_LIST_COLUMNS_OPTION(25)); fprintf(out, USAGE_HELP_OPTIONS(25)); @@ -1258,11 +1260,15 @@ int main(int argc, char *argv[]) char *outarg = NULL; size_t i, ncolumns = 0; char *annotate_opt_arg = NULL; + unsigned int arm_id = 0xf00; /* Valid values are 0-0xff */ + unsigned int arm_model = 0xf000; /* Valid values are 0-0xfff */ enum { OPT_OUTPUT_ALL = CHAR_MAX + 1, OPT_HIERARCHIC, OPT_ANNOTATE, + OPT_ARM_ID, + OPT_ARM_MODEL, }; static const struct option longopts[] = { { "all", no_argument, NULL, 'a' }, @@ -1283,6 +1289,8 @@ int main(int argc, char *argv[]) { "output-all", no_argument, NULL, OPT_OUTPUT_ALL }, { "hierarchic", optional_argument, NULL, OPT_HIERARCHIC }, { "list-columns", no_argument, NULL, 'H' }, + { "arm-id", optional_argument, NULL, OPT_ARM_ID }, + { "arm-model", required_argument, NULL, OPT_ARM_MODEL }, { NULL, 0, NULL, 0 } }; @@ -1372,6 +1380,18 @@ int main(int argc, char *argv[]) } else hierarchic = 1; break; + case OPT_ARM_ID: + if (optarg) { + if (cxt->mode != LSCPU_OUTPUT_ARM_SINGLE_MODEL) + cxt->mode = LSCPU_OUTPUT_ARM_MODELS; + arm_id = str2unum_or_err(optarg, 0, _("failed to parse implementer id"), 0xFF); + } else + cxt->mode = LSCPU_OUTPUT_ARM_IMPLEMENTERS; + break; + case OPT_ARM_MODEL: + cxt->mode = LSCPU_OUTPUT_ARM_SINGLE_MODEL; + arm_model = str2unum_or_err(optarg, 0, _("failed to parse model id"), 0xFFF); + break; case 'H': collist = 1; break; @@ -1407,6 +1427,9 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } + if (cxt->mode == LSCPU_OUTPUT_ARM_SINGLE_MODEL && arm_id > 0xff) + errx(EXIT_FAILURE, _("--arm-model option needs to be used with --arm-id")); + if (argc != optind) { warnx(_("bad usage")); errtryhelp(EXIT_FAILURE); @@ -1532,6 +1555,15 @@ int main(int argc, char *argv[]) print_cpus_parsable(cxt, columns, ncolumns); break; + case LSCPU_OUTPUT_ARM_IMPLEMENTERS: + lscpu_print_arm_implementers(cxt); + break; + case LSCPU_OUTPUT_ARM_MODELS: + lscpu_print_arm_models(cxt, arm_id); + break; + case LSCPU_OUTPUT_ARM_SINGLE_MODEL: + lscpu_print_arm_model(cxt, arm_id, arm_model); + break; } lscpu_free_context(cxt); diff --git a/sys-utils/lscpu.h b/sys-utils/lscpu.h index 713ef04b1..0fae5d29e 100644 --- a/sys-utils/lscpu.h +++ b/sys-utils/lscpu.h @@ -212,7 +212,10 @@ enum { LSCPU_OUTPUT_SUMMARY = 0, /* default */ LSCPU_OUTPUT_CACHES, LSCPU_OUTPUT_PARSABLE, - LSCPU_OUTPUT_READABLE + LSCPU_OUTPUT_READABLE, + LSCPU_OUTPUT_ARM_IMPLEMENTERS, + LSCPU_OUTPUT_ARM_MODELS, + LSCPU_OUTPUT_ARM_SINGLE_MODEL, }; struct lscpu_cxt { @@ -324,6 +327,9 @@ struct lscpu_cpu *lscpu_cpus_loopup_by_type(struct lscpu_cxt *cxt, struct lscpu_ void lscpu_decode_arm(struct lscpu_cxt *cxt); void lscpu_format_isa_riscv(struct lscpu_cputype *ct); +void lscpu_print_arm_implementers(struct lscpu_cxt *cxt); +void lscpu_print_arm_models(struct lscpu_cxt *cxt, int implementer); +void lscpu_print_arm_model(struct lscpu_cxt *cxt, int implementer, int model); int lookup(char *line, char *pattern, char **value);