aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys-utils/Makemodule.am1
-rw-r--r--sys-utils/lscpu-api.h41
-rw-r--r--sys-utils/lscpu-arm.c160
-rw-r--r--sys-utils/lscpu-cputype.c2
-rw-r--r--sys-utils/lscpu-virt.c41
-rw-r--r--sys-utils/lscpu.h1
6 files changed, 141 insertions, 105 deletions
diff --git a/sys-utils/Makemodule.am b/sys-utils/Makemodule.am
index 15379aa967..c0cdda728d 100644
--- a/sys-utils/Makemodule.am
+++ b/sys-utils/Makemodule.am
@@ -403,6 +403,7 @@ check_PROGRAMS += test_cputype
test_cputype_SOURCES = sys-utils/lscpu-cputype.c \
sys-utils/lscpu-cpu.c \
sys-utils/lscpu-virt.c \
+ sys-utils/lscpu-arm.c \
sys-utils/lscpu-api.h
test_cputype_CFLAGS = $(AM_CFLAGS) -DTEST_PROGRAM_CPUTYPE
test_cputype_LDADD = $(LDADD) libcommon.la
diff --git a/sys-utils/lscpu-api.h b/sys-utils/lscpu-api.h
index 9bbd18d243..1d979e787d 100644
--- a/sys-utils/lscpu-api.h
+++ b/sys-utils/lscpu-api.h
@@ -191,9 +191,50 @@ int lscpu_add_cpu(struct lscpu_cxt *cxt,
struct lscpu_cputype *ct);
int lscpu_cpus_apply_type(struct lscpu_cxt *cxt, struct lscpu_cputype *type);
+void lscpu_decode_arm(struct lscpu_cxt *cxt);
+
struct lscpu_cxt *lscpu_new_context(void);
void lscpu_free_context(struct lscpu_cxt *cxt);
int lookup(char *line, char *pattern, char **value);
+/*
+ * Firmware stuff
+ */
+#define _PATH_SYS_DMI_TYPE4 "/sys/firmware/dmi/entries/4-0/raw"
+#define _PATH_SYS_DMI "/sys/firmware/dmi/tables/DMI"
+
+struct lscpu_dmi_header
+{
+ uint8_t type;
+ uint8_t length;
+ uint16_t handle;
+ uint8_t *data;
+};
+
+static inline void to_dmi_header(struct lscpu_dmi_header *h, uint8_t *data)
+{
+ h->type = data[0];
+ h->length = data[1];
+ memcpy(&h->handle, data + 2, sizeof(h->handle));
+ h->data = data;
+}
+
+static inline char *dmi_string(const struct lscpu_dmi_header *dm, uint8_t s)
+{
+ char *bp = (char *)dm->data;
+
+ if (!s || !bp)
+ return NULL;
+
+ bp += dm->length;
+ while (s > 1 && *bp) {
+ bp += strlen(bp);
+ bp++;
+ s--;
+ }
+
+ return !*bp ? NULL : bp;
+}
+
#endif /* LSCPU_API_H */
diff --git a/sys-utils/lscpu-arm.c b/sys-utils/lscpu-arm.c
index 20c7291e56..de6a1537c3 100644
--- a/sys-utils/lscpu-arm.c
+++ b/sys-utils/lscpu-arm.c
@@ -24,14 +24,7 @@
* - Ancient wisdom
* - SMBIOS tables (if applicable)
*/
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "lscpu.h"
+#include "lscpu-api.h"
struct id_part {
const int id;
@@ -216,72 +209,102 @@ static const struct hw_impl hw_implementer[] = {
{ -1, unknown_part, "unknown" },
};
-static void __arm_cpu_decode(struct lscpu_desc *desc)
+static int parse_id(const char *str)
{
- int j, impl = 0;
- const struct id_part *parts = NULL;
- char *end;
+ int id;
+ char *end = NULL;
- if (desc->vendor && startswith(desc->vendor, "0x")) {
- errno = 0;
- impl = (int) strtol(desc->vendor, &end, 0);
- if (errno || desc->vendor == end)
- return;
- }
+ if (!str || strncmp(str, "0x",2) != 0)
+ return -EINVAL;
- /* model and modelname */
- if (impl && desc->model && startswith(desc->model, "0x")) {
- int part;
+ errno = 0;
+ id = (int) strtol(str, &end, 0);
+ if (errno || str == end)
+ return -EINVAL;
- errno = 0;
+ return id;
+}
- part = (int) strtol(desc->model, &end, 0);
- if (errno || desc->model == end)
- return;
+#define parse_implementer_id(_cxt) (parse_id((_cxt)->vendor))
+#define parse_model_id(_cxt) (parse_id((_cxt)->model))
+
+/*
+ * Use model and vendor IDs to decode to human readable names.
+ */
+static int arm_ids_decode(struct lscpu_cputype *ct)
+{
+ int impl, part, j;
+ const struct id_part *parts = NULL;
- for (j = 0; hw_implementer[j].id != -1; j++) {
- if (hw_implementer[j].id == impl) {
- parts = hw_implementer[j].parts;
- desc->vendor = (char *) hw_implementer[j].name;
- break;
- }
+ impl = parse_implementer_id(ct);
+ if (impl <= 0)
+ return -EINVAL; /* no ARM or missing ID */
+
+ /* decode vendor */
+ for (j = 0; hw_implementer[j].id != -1; j++) {
+ if (hw_implementer[j].id == impl) {
+ parts = hw_implementer[j].parts;
+ free(ct->vendor);
+ ct->vendor = xstrdup(hw_implementer[j].name);
+ break;
}
+ }
+
+ /* decode model */
+ if (!parts)
+ goto done;
- if (parts == NULL)
- return;
+ part = parse_model_id(ct);
+ if (part <= 0)
+ goto done;
- for (j = 0; parts[j].id != -1; j++) {
- if (parts[j].id == part) {
- desc->modelname = (char *) parts[j].name;
- break;
- }
+ for (j = 0; parts[j].id != -1; j++) {
+ if (parts[j].id == part) {
+ free(ct->modelname);
+ ct->modelname = xstrdup(parts[j].name);
+ break;
}
}
+done:
+ return 0;
+}
- /* Print out the rXpY string for ARM cores */
- if (impl == 0x41 && desc->revision && desc->stepping) {
- int revision, variant;
- char buf[8];
+/* use "rXpY" string as stepping */
+static int arm_decode_rXpY(struct lscpu_cputype *ct)
+{
+ int impl, revision, variant;
+ char *end = NULL;
+ char buf[8];
- errno = 0;
- revision = (int) strtol(desc->revision, &end, 10);
- if (errno || desc->revision == end)
- return;
+ impl = parse_implementer_id(ct);
- errno = 0;
- variant = (int) strtol(desc->stepping, &end, 0);
- if (errno || desc->stepping == end)
- return;
+ if (impl != 0x41 || !ct->revision || !ct->stepping)
+ return -EINVAL;
- snprintf(buf, sizeof(buf), "r%dp%d", variant, revision);
- desc->stepping = xstrdup(buf);
- }
+ errno = 0;
+ revision = (int) strtol(ct->revision, &end, 10);
+ if (errno || ct->revision == end)
+ return -EINVAL;
+
+ errno = 0;
+ variant = (int) strtol(ct->stepping, &end, 0);
+ if (errno || ct->stepping == end)
+ return -EINVAL;
+
+ snprintf(buf, sizeof(buf), "r%dp%d", variant, revision);
+ free(ct->stepping);
+ ct->stepping = xstrdup(buf);
+
+ return 0;
}
#define PROC_MFR_OFFSET 0x07
#define PROC_VERSION_OFFSET 0x10
-static int __arm_cpu_smbios(struct lscpu_desc *desc)
+/*
+ * Use firmware to get human readable names
+ */
+static int arm_smbios_decode(struct lscpu_cputype *ct)
{
uint8_t data[8192];
char buf[128], *str;
@@ -304,28 +327,37 @@ static int __arm_cpu_smbios(struct lscpu_desc *desc)
str = dmi_string(&h, data[PROC_MFR_OFFSET]);
if (str) {
xstrncpy(buf, str, 127);
- desc->vendor = xstrdup(buf);
+ ct->vendor = xstrdup(buf);
}
str = dmi_string(&h, data[PROC_VERSION_OFFSET]);
if (str) {
xstrncpy(buf, str, 127);
- desc->modelname = xstrdup(buf);
+ ct->modelname = xstrdup(buf);
}
return 0;
}
-void arm_cpu_decode(struct lscpu_desc *desc, struct lscpu_modifier *mod)
+static void arm_decode(struct lscpu_cxt *cxt, struct lscpu_cputype *ct)
{
int rc = -1;
- /* use SMBIOS Type 4 data if available,
- * else fall back to manual decoding using the tables above */
- if (mod->system == SYSTEM_LIVE &&
- access(_PATH_SYS_DMI_TYPE4, R_OK) == 0)
- rc = __arm_cpu_smbios(desc);
-
+ /* use SMBIOS Type 4 data if available, else fall back to manual
+ * decoding using the tables above
+ */
+ if (!cxt->noalive && access(_PATH_SYS_DMI_TYPE4, R_OK) == 0)
+ rc = arm_smbios_decode(ct);
if (rc)
- __arm_cpu_decode(desc);
+ arm_ids_decode(ct);
+
+ arm_decode_rXpY(ct);
+}
+
+void lscpu_decode_arm(struct lscpu_cxt *cxt)
+{
+ size_t i;
+
+ for (i = 0; i < cxt->ncputypes; i++)
+ arm_decode(cxt, cxt->cputypes[i]);
}
diff --git a/sys-utils/lscpu-cputype.c b/sys-utils/lscpu-cputype.c
index dfa539b6ea..632b5c4cfc 100644
--- a/sys-utils/lscpu-cputype.c
+++ b/sys-utils/lscpu-cputype.c
@@ -343,6 +343,7 @@ static int cpuinfo_parse_line( struct lscpu_cputype **ct,
break;
default:
/* set value as a string and cleanup */
+ fprintf(stderr, "str=%s\n", str);
strdup_to_offset(stru, pat->offset, v);
data = (char **) ((char *) stru + pat->offset);
rtrim_whitespace((unsigned char *) *data);
@@ -812,6 +813,7 @@ int main(int argc, char **argv)
lscpu_read_extra(cxt);
lscpu_read_vulnerabilities(cxt);
lscpu_read_numas(cxt);
+ lscpu_decode_arm(cxt);
cxt->virt = lscpu_read_virtualization(cxt);
diff --git a/sys-utils/lscpu-virt.c b/sys-utils/lscpu-virt.c
index 501e4f8ebb..56dc5c2ef0 100644
--- a/sys-utils/lscpu-virt.c
+++ b/sys-utils/lscpu-virt.c
@@ -9,8 +9,6 @@
#include "lscpu-api.h"
-#define _PATH_SYS_DMI "/sys/firmware/dmi/tables/DMI"
-
/* Xen Domain feature flag used for /sys/hypervisor/properties/features */
#define XENFEAT_supervisor_mode_kernel 3
#define XENFEAT_mmu_pt_update_preserve_ad 5
@@ -40,14 +38,6 @@ static const int hv_graphics_pci[] = {
#define WORD(x) (uint16_t)(*(const uint16_t *)(x))
#define DWORD(x) (uint32_t)(*(const uint32_t *)(x))
-struct dmi_header
-{
- uint8_t type;
- uint8_t length;
- uint16_t handle;
- uint8_t *data;
-};
-
static void *get_mem_chunk(size_t base, size_t len, const char *devmem)
{
void *p = NULL;
@@ -72,35 +62,6 @@ nothing:
return NULL;
}
-static void to_dmi_header(struct dmi_header *h, uint8_t *data)
-{
- h->type = data[0];
- h->length = data[1];
- memcpy(&h->handle, data + 2, sizeof(h->handle));
- h->data = data;
-}
-
-static char *dmi_string(const struct dmi_header *dm, uint8_t s)
-{
- char *bp = (char *)dm->data;
-
- if (s == 0)
- return NULL;
-
- bp += dm->length;
- while (s > 1 && *bp)
- {
- bp += strlen(bp);
- bp++;
- s--;
- }
-
- if (!*bp)
- return NULL;
-
- return bp;
-}
-
static int hypervisor_from_dmi_table(uint32_t base, uint16_t len,
uint16_t num, const char *devmem)
{
@@ -119,7 +80,7 @@ static int hypervisor_from_dmi_table(uint32_t base, uint16_t len,
/* 4 is the length of an SMBIOS structure header */
while (i < num && data + 4 <= buf + len) {
uint8_t *next;
- struct dmi_header h;
+ struct lscpu_dmi_header h;
to_dmi_header(&h, data);
diff --git a/sys-utils/lscpu.h b/sys-utils/lscpu.h
index 3de0abcce1..04de84fee1 100644
--- a/sys-utils/lscpu.h
+++ b/sys-utils/lscpu.h
@@ -212,7 +212,6 @@ extern int read_hypervisor_dmi(void);
extern void arm_cpu_decode(struct lscpu_desc *desc, struct lscpu_modifier *mod);
#define _PATH_SYS_DMI "/sys/firmware/dmi/tables/DMI"
-#define _PATH_SYS_DMI_TYPE4 "/sys/firmware/dmi/entries/4-0/raw"
struct lscpu_dmi_header
{