Commit ef074d3f authored by Laurent Dufour's avatar Laurent Dufour Committed by Pavel Emelyanov

ppc64: introduce CPU feature checking operations

This patch introduces basic CPU feature checking for PowerPC.
Signed-off-by: 's avatarLaurent Dufour <ldufour@linux.vnet.ibm.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 406edb00
#undef LOG_PREFIX #undef LOG_PREFIX
#define LOG_PREFIX "cpu: " #define LOG_PREFIX "cpu: "
#include <sys/auxv.h>
#include <errno.h> #include <errno.h>
#include <asm/cputable.h>
#include "asm/types.h"
#include "asm/cpu.h"
#include "cr_options.h"
#include "proc_parse.h"
#include "util.h"
#include "log.h"
#include "cpu.h" #include "cpu.h"
bool cpu_has_feature(unsigned int feature) #include "protobuf.h"
{ #include "protobuf/cpuinfo.pb-c.h"
return false;
} static uint64_t hwcap[2];
#ifdef __LITTLE_ENDIAN__
#define CURRENT_ENDIANNESS CPUINFO_PPC64_ENTRY__ENDIANNESS__LITTLEENDIAN
#else
#define CURRENT_ENDIANNESS CPUINFO_PPC64_ENTRY__ENDIANESS__BIGENDIAN
#endif
int cpu_init(void) int cpu_init(void)
{ {
hwcap[0] = getauxval(AT_HWCAP);
hwcap[1] = getauxval(AT_HWCAP2);
if (!hwcap[0] || !hwcap[1]) {
pr_err("Can't read the hardware capabilities");
return -1;
}
return 0; return 0;
} }
int cpu_dump_cpuinfo(void) int cpu_dump_cpuinfo(void)
{ {
return 0; CpuinfoEntry cpu_info = CPUINFO_ENTRY__INIT;
CpuinfoPpc64Entry cpu_ppc64_info = CPUINFO_PPC64_ENTRY__INIT;
CpuinfoPpc64Entry *cpu_ppc64_info_ptr = &cpu_ppc64_info;
struct cr_img *img;
int ret = -1;
img = open_image(CR_FD_CPUINFO, O_DUMP);
if (!img)
return -1;
cpu_info.ppc64_entry = &cpu_ppc64_info_ptr;
cpu_info.n_ppc64_entry = 1;
cpu_ppc64_info.endian = CURRENT_ENDIANNESS;
cpu_ppc64_info.n_hwcap = 2;
cpu_ppc64_info.hwcap = hwcap;
ret = pb_write_one(img, &cpu_info, PB_CPUINFO);
close_image(img);
return ret;
} }
int cpu_validate_cpuinfo(void) int cpu_validate_cpuinfo(void)
{ {
return 0; CpuinfoEntry *cpu_info;
} CpuinfoPpc64Entry *cpu_ppc64_entry;
struct cr_img *img;
int ret = -1;
img = open_image(CR_FD_CPUINFO, O_RSTR);
if (!img)
return -1;
int cpu_dump_cpuinfo_single(void) if (pb_read_one(img, &cpu_info, PB_CPUINFO) < 0)
{ goto error;
return -ENOTSUP;
}
int cpu_validate_image_cpuinfo_single(void) if (cpu_info->n_ppc64_entry != 1) {
{ pr_err("No PPC64 related entry in image");
return -ENOTSUP; goto error;
}
cpu_ppc64_entry = cpu_info->ppc64_entry[0];
if (cpu_ppc64_entry->endian != CURRENT_ENDIANNESS) {
pr_err("Bad endianness");
goto error;
}
if (cpu_ppc64_entry->n_hwcap != 2) {
pr_err("Hardware capabilities information missing\n");
goto error;
}
#define CHECK_FEATURE(s,f) do { \
if ((cpu_ppc64_entry->hwcap[s] & f) && !(hwcap[s] & f)) { \
pr_err("CPU Feature %s required by image " \
"is not supported on host.\n", #f); \
goto error; \
} \
} while(0)
#define REQUIRE_FEATURE(s,f) do { \
if (!(cpu_ppc64_entry->hwcap[s] & f)) { \
pr_err("CPU Feature %s missing in image.\n", #f); \
goto error; \
} \
} while(0)
REQUIRE_FEATURE(0, PPC_FEATURE_64);
REQUIRE_FEATURE(0, PPC_FEATURE_HAS_FPU);
REQUIRE_FEATURE(0, PPC_FEATURE_HAS_MMU);
REQUIRE_FEATURE(0, PPC_FEATURE_HAS_VSX);
REQUIRE_FEATURE(1, PPC_FEATURE2_ARCH_2_07);
CHECK_FEATURE(0, PPC_FEATURE_TRUE_LE);
CHECK_FEATURE(1, PPC_FEATURE2_HTM);
CHECK_FEATURE(1, PPC_FEATURE2_DSCR);
CHECK_FEATURE(1, PPC_FEATURE2_EBB);
CHECK_FEATURE(1, PPC_FEATURE2_ISEL);
CHECK_FEATURE(1, PPC_FEATURE2_TAR);
CHECK_FEATURE(1, PPC_FEATURE2_VEC_CRYPTO);
ret = 0;
error:
close_image(img);
return ret;
} }
int cpuinfo_dump(void) int cpuinfo_dump(void)
{ {
return -ENOTSUP; if (cpu_init())
return -1;
if (cpu_dump_cpuinfo())
return -1;
return 0;
} }
int cpuinfo_check(void) int cpuinfo_check(void)
{ {
return -ENOTSUP; if (cpu_init())
return -1;
if (cpu_validate_cpuinfo())
return 1;
return 0;
} }
...@@ -15,6 +15,16 @@ message cpuinfo_x86_entry { ...@@ -15,6 +15,16 @@ message cpuinfo_x86_entry {
optional string model_id = 7; optional string model_id = 7;
} }
message cpuinfo_ppc64_entry {
enum endianness {
BIGENDIAN = 0;
LITTLEENDIAN = 1;
}
required endianness endian = 1;
repeated uint64 hwcap = 2;
}
message cpuinfo_entry { message cpuinfo_entry {
/* /*
* Usually on SMP system there should be same CPUs * Usually on SMP system there should be same CPUs
...@@ -22,4 +32,5 @@ message cpuinfo_entry { ...@@ -22,4 +32,5 @@ message cpuinfo_entry {
* various CPUs so @repeated used. * various CPUs so @repeated used.
*/ */
repeated cpuinfo_x86_entry x86_entry = 1; repeated cpuinfo_x86_entry x86_entry = 1;
repeated cpuinfo_ppc64_entry ppc64_entry = 2;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment