aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys-utils/lscpu-api.h1
-rw-r--r--sys-utils/lscpu-cputype.c103
2 files changed, 104 insertions, 0 deletions
diff --git a/sys-utils/lscpu-api.h b/sys-utils/lscpu-api.h
index 30b324cbea..8aa1c2b11e 100644
--- a/sys-utils/lscpu-api.h
+++ b/sys-utils/lscpu-api.h
@@ -129,6 +129,7 @@ struct lscpu_cputype *lscpu_cputype_get_default(struct lscpu_cxt *cxt);
int lscpu_read_cpuinfo(struct lscpu_cxt *cxt);
int lscpu_read_architecture(struct lscpu_cxt *cxt);
int lscpu_read_cpulists(struct lscpu_cxt *cxt);
+int lscpu_read_extra(struct lscpu_cxt *cxt);
struct lscpu_cpu *lscpu_new_cpu(void);
void lscpu_ref_cpu(struct lscpu_cpu *cpu);
diff --git a/sys-utils/lscpu-cputype.c b/sys-utils/lscpu-cputype.c
index a829007d3e..d88b382523 100644
--- a/sys-utils/lscpu-cputype.c
+++ b/sys-utils/lscpu-cputype.c
@@ -33,6 +33,42 @@ static void context_init_paths(struct lscpu_cxt *cxt)
}
+/* Lookup a pattern and get the value for format "<pattern> : <key>"
+ */
+static int lookup(char *line, char *pattern, char **value)
+{
+ char *p, *v;
+ int len = strlen(pattern);
+
+ /* don't re-fill already found tags, first one wins */
+ if (!*line || *value)
+ return 0;
+ /* pattern */
+ if (strncmp(line, pattern, len))
+ return 0;
+ /* white spaces */
+ for (p = line + len; isspace(*p); p++);
+
+ /* separator */
+ if (*p != ':')
+ return 0;
+ /* white spaces */
+ for (++p; isspace(*p); p++);
+
+ /* value */
+ if (!*p)
+ return 0;
+ v = p;
+
+ /* end of value */
+ len = strlen(line) - 1;
+ for (p = line + len; isspace(*(p-1)); p--);
+ *p = '\0';
+
+ *value = xstrdup(v);
+ return 1;
+}
+
struct lscpu_cputype *lscpu_new_cputype(void)
{
struct lscpu_cputype *ct;
@@ -489,6 +525,72 @@ int lscpu_read_cpulists(struct lscpu_cxt *cxt)
return 0;
}
+#if defined(HAVE_LIBRTAS)
+# define PROCESSOR_MODULE_INFO 43
+static int strbe16toh(const char *buf, int offset)
+{
+ return (buf[offset] << 8) + buf[offset+1];
+}
+#endif
+
+/* some extra information for the default CPU type */
+int lscpu_read_extra(struct lscpu_cxt *cxt)
+{
+ FILE *f;
+ char buf[BUFSIZ];
+ struct lscpu_cputype *ct;
+
+ assert(cxt);
+ ct = lscpu_cputype_get_default(cxt);
+ if (!ct)
+ return -EINVAL;
+
+ /* get dispatching mode */
+ if (ul_path_read_s32(cxt->syscpu, &ct->dispatching, "dispatching") != 0)
+ ct->dispatching = -1;
+
+ /* get cpufreq boost mode */
+ if (ul_path_read_s32(cxt->syscpu, &ct->freqboost, "cpufreq/boost") != 0)
+ ct->freqboost = -1;
+
+ if ((f = ul_path_fopen(cxt->procfs, "r", "sysinfo"))) {
+ while (fgets(buf, sizeof(buf), f) != NULL) {
+ if (lookup(buf, "Type", &ct->machinetype))
+ break;
+ }
+ fclose(f);
+ }
+
+#if defined(HAVE_LIBRTAS)
+ /* Get PowerPC speficic info */
+ if (!cxt->noalive) {
+ int rc, len, ntypes;
+
+ ct->physsockets = ct->physchips = ct->physcoresperchip = 0;
+
+ rc = rtas_get_sysparm(PROCESSOR_MODULE_INFO, sizeof(buf), buf);
+ if (rc < 0)
+ goto nortas;
+
+ len = strbe16toh(buf, 0);
+ if (len < 8)
+ goto nortas;
+
+ ntypes = strbe16toh(buf, 2);
+ assert(ntypes <= 1);
+ if (!ntypes)
+ goto nortas;
+
+ desc->physsockets = strbe16toh(buf, 4);
+ desc->physchips = strbe16toh(buf, 6);
+ desc->physcoresperchip = strbe16toh(buf, 8);
+nortas:
+ }
+#endif
+ return 0;
+}
+
+
#ifdef TEST_PROGRAM_CPUTYPE
/* TODO: move to lscpu.c */
struct lscpu_cxt *lscpu_new_context(void)
@@ -545,6 +647,7 @@ int main(int argc, char **argv)
lscpu_read_cpuinfo(cxt);
lscpu_read_architecture(cxt);
lscpu_read_cpulists(cxt);
+ lscpu_read_extra(cxt);
lscpu_free_context(cxt);
return EXIT_SUCCESS;