Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/749032/?format=api
{ "id": 749032, "url": "http://patchwork.ozlabs.org/api/patches/749032/?format=api", "web_url": "http://patchwork.ozlabs.org/project/skiboot/patch/20170410140251.1438-1-npiggin@gmail.com/", "project": { "id": 44, "url": "http://patchwork.ozlabs.org/api/projects/44/?format=api", "name": "skiboot firmware development", "link_name": "skiboot", "list_id": "skiboot.lists.ozlabs.org", "list_email": "skiboot@lists.ozlabs.org", "web_url": "http://github.com/open-power/skiboot", "scm_url": "http://github.com/open-power/skiboot", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20170410140251.1438-1-npiggin@gmail.com>", "list_archive_url": null, "date": "2017-04-10T14:02:51", "name": "[RFC,v2] cpufeatures: add base and POWER8, POWER9 /cpus/cpufeatures dt", "commit_ref": null, "pull_url": null, "state": "changes-requested", "archived": false, "hash": "334fa3216b3674fabab20b3fb5f1574144969ed6", "submitter": { "id": 69518, "url": "http://patchwork.ozlabs.org/api/people/69518/?format=api", "name": "Nicholas Piggin", "email": "npiggin@gmail.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/skiboot/patch/20170410140251.1438-1-npiggin@gmail.com/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/749032/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/749032/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "skiboot@lists.ozlabs.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "skiboot@lists.ozlabs.org" ], "Received": [ "from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\t(using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3w1sN52963z9sNb\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 11 Apr 2017 00:03:17 +1000 (AEST)", "from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 3w1sN519xpzDqC2\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 11 Apr 2017 00:03:17 +1000 (AEST)", "from mail-pf0-x242.google.com (mail-pf0-x242.google.com\n\t[IPv6:2607:f8b0:400e:c00::242])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128\n\tbits)) (No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 3w1sMt2fHtzDq5j\n\tfor <skiboot@lists.ozlabs.org>; Tue, 11 Apr 2017 00:03:06 +1000 (AEST)", "by mail-pf0-x242.google.com with SMTP id a188so1008079pfa.2\n\tfor <skiboot@lists.ozlabs.org>; Mon, 10 Apr 2017 07:03:06 -0700 (PDT)", "from roar.au.ibm.com ([203.221.48.234])\n\tby smtp.gmail.com with ESMTPSA id\n\t189sm25096096pgd.30.2017.04.10.07.03.00\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tMon, 10 Apr 2017 07:03:02 -0700 (PDT)" ], "Authentication-Results": [ "ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"eZzLRhcD\"; dkim-atps=neutral", "lists.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"eZzLRhcD\"; dkim-atps=neutral", "lists.ozlabs.org; dkim=pass (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"eZzLRhcD\"; dkim-atps=neutral" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;\n\th=from:to:cc:subject:date:message-id;\n\tbh=Lm95GVGCf/CzLuXN0FygP99PCvHufBK7MYZGzQ/zrUU=;\n\tb=eZzLRhcDuBIKQQjbvBnMlAkms/H+8zIDkDzWHR7xFSdtYh/fuDTOqCOCu5LOU4YYal\n\t3/IK/C71TS51dQ9nHShyoC7HAFzf8sHz/aPM7/TepSQSr8tk6R/AKaG02dsB4qiAsFs6\n\tsrCLxIa0WdkRbKmTAOXhJC9Bhn8C1x+7B7qrzg1lYRt1/8Kq6KMaf7p1+5S3T+yVhyEH\n\tToG/JvEYSJ3MnFHRAEyHHf3lbYudMgtKoYSEwezA6srFBNcDd71PKqn8Tba01hYVXIbC\n\tEnIuhc4XBHQynsUBJ4uv+KBVMK+V9glrCjBxZaXaM8UHbxtFOyMbWNBzO0nDaAwoWFtT\n\txhHQ==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id;\n\tbh=Lm95GVGCf/CzLuXN0FygP99PCvHufBK7MYZGzQ/zrUU=;\n\tb=DeRZoOt3I3h0eqoS26dOi8Cae9t94GFlY/h9+bnT/eAeAwQKJ69CBPVnisE+m0mQox\n\ttSs1iwjPm2sTL4Pl9jO7U+OtXe0VMsZSBPLi50naJvaJAwQu8JGepH0JnUvX3qQm6CRt\n\t5Q3cHB7vKenKeD8HzQ0BCdPPx5/qKOVwvEzmHjhgHKdHuC8/yIfSaHNiMxLkWf6SpJgv\n\tmK7AbmvIn+lGxOPb9wXZRizp4IL1cPaPo6/Lvq7F8SsprpqOQotyJWz11r1jTTOD1s9J\n\tOOj5Xsf+DDs59RzNGmPAPrvIUIk9PeGqD5WPde5wNcA0o2rxy787WOBJqk8CXvQlZ3Zo\n\tXckQ==", "X-Gm-Message-State": "AFeK/H0LRDLfpCeteQYw7kHzX2d4Tdhft5XTrtB7Dl2LAcOa317zvILpakB27kTVhXPTvA==", "X-Received": "by 10.98.78.8 with SMTP id c8mr53924608pfb.155.1491832983610;\n\tMon, 10 Apr 2017 07:03:03 -0700 (PDT)", "From": "Nicholas Piggin <npiggin@gmail.com>", "To": "skiboot@lists.ozlabs.org", "Date": "Tue, 11 Apr 2017 00:02:51 +1000", "Message-Id": "<20170410140251.1438-1-npiggin@gmail.com>", "X-Mailer": "git-send-email 2.11.0", "Subject": "[Skiboot] [RFC][PATCH v2] cpufeatures: add base and POWER8,\n\tPOWER9 /cpus/cpufeatures dt", "X-BeenThere": "skiboot@lists.ozlabs.org", "X-Mailman-Version": "2.1.23", "Precedence": "list", "List-Id": "Mailing list for skiboot development <skiboot.lists.ozlabs.org>", "List-Unsubscribe": "<https://lists.ozlabs.org/options/skiboot>,\n\t<mailto:skiboot-request@lists.ozlabs.org?subject=unsubscribe>", "List-Archive": "<http://lists.ozlabs.org/pipermail/skiboot/>", "List-Post": "<mailto:skiboot@lists.ozlabs.org>", "List-Help": "<mailto:skiboot-request@lists.ozlabs.org?subject=help>", "List-Subscribe": "<https://lists.ozlabs.org/listinfo/skiboot>,\n\t<mailto:skiboot-request@lists.ozlabs.org?subject=subscribe>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "base64", "Errors-To": "skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org", "Sender": "\"Skiboot\"\n\t<skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org>" }, "content": "Add /cpus/cpufeatures device tree implementation for POWER8 and POWER9.\nThis is a new format for CPU feature and compatibility advertisement.\ncpufeatures aims to be an extensible format that provides granular\nfeatures in a human readable format, with privilege-level-aware\ncompatibility, and enabling forward compatible implementations for\nfeatures with known simple recipes to enable.\n\nI'm posting this out now because I've made some significant updates\nto the Linux patch which I'm aiming to have merged. The firmware side\ncan wait until afterwards, so this is not quite ready for merge. That\nsaid I have made some progress:\n\nSince last time:\n- Updated to ISA3.0B\n- Split out some more features after going through PAPR and ISA docs\n again.\n- Moved out of hdata and into its own file.\n- Started improving documentation of individual feature nodes. Is such\n documentation enough:\n /*\n * ISAv2.07 Book3S Chapter 5.7.9.1. Virtual Page Class Key Protecion\n * AMR, IAMR, AMOR, UAMOR, etc registers and MMU key bits.\n */\n ? Some features are slightly more difficult to document than others\n (e.g., \"smt\").\n \n- Still have not added dt binding documentation. I'm hesitant to\n duplicate the large document between trees, so perhaps we keep\n the canonical binding doc in skiboot and short doc + reference link\n in Linux? I'm open to ideas.\n- Asked but haven't got any more feedback about whether to split\n vector-crypto into different algorithms as Stewart suggested.\n\n---\n core/Makefile.inc | 2 +-\n core/cpufeatures.c | 784 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n core/device.c | 7 +\n core/init.c | 1 +\n hdata/cpu-common.c | 14 +-\n include/device.h | 1 +\n include/skiboot.h | 17 ++\n 7 files changed, 824 insertions(+), 2 deletions(-)\n create mode 100644 core/cpufeatures.c", "diff": "diff --git a/core/Makefile.inc b/core/Makefile.inc\nindex b09c30c0..7c247836 100644\n--- a/core/Makefile.inc\n+++ b/core/Makefile.inc\n@@ -8,7 +8,7 @@ CORE_OBJS += pci-opal.o fast-reboot.o device.o exceptions.o trace.o affinity.o\n CORE_OBJS += vpd.o hostservices.o platform.o nvram.o nvram-format.o hmi.o\n CORE_OBJS += console-log.o ipmi.o time-utils.o pel.o pool.o errorlog.o\n CORE_OBJS += timer.o i2c.o rtc.o flash.o sensor.o ipmi-opal.o\n-CORE_OBJS += flash-subpartition.o bitmap.o buddy.o pci-quirk.o\n+CORE_OBJS += flash-subpartition.o bitmap.o buddy.o pci-quirk.o cpufeatures.o\n \n ifeq ($(SKIBOOT_GCOV),1)\n CORE_OBJS += gcov-profiling.o\ndiff --git a/core/cpufeatures.c b/core/cpufeatures.c\nnew file mode 100644\nindex 00000000..2c47886b\n--- /dev/null\n+++ b/core/cpufeatures.c\n@@ -0,0 +1,784 @@\n+/* Copyright 2017 IBM Corp.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ * \thttp://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n+ * implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+#include <skiboot.h>\n+#include <cpu.h>\n+#include <ccan/str/str.h>\n+#include <device.h>\n+\n+/* Table to set up the /cpus/cpufeatures dt */\n+#define USABLE_PR\t\t(1U << 0)\n+#define USABLE_OS\t\t(1U << 1)\n+#define USABLE_HV\t\t(1U << 2)\n+\n+#define HV_SUPPORT_NONE\t\t0\n+#define HV_SUPPORT_CUSTOM\t1\n+#define HV_SUPPORT_HFSCR\t2\n+\n+#define OS_SUPPORT_NONE\t\t0\n+#define OS_SUPPORT_CUSTOM\t1\n+#define OS_SUPPORT_FSCR\t\t2\n+\n+#define CPU_P8_DD1\t\t(1U << CPUFEATURES_CPU_P8_DD1)\n+#define CPU_P8_DD2\t\t(1U << CPUFEATURES_CPU_P8_DD2)\n+#define CPU_P9_DD1\t\t(1U << CPUFEATURES_CPU_P9_DD1)\n+#define CPU_P9_DD2\t\t(1U << CPUFEATURES_CPU_P9_DD2)\n+\n+#define CPU_P8\t\t\t(CPU_P8_DD1|CPU_P8_DD2)\n+#define CPU_P9\t\t\t(CPU_P9_DD1|CPU_P9_DD2)\n+#define CPU_ALL\t\t\t(CPU_P8|CPU_P9)\n+\n+#define ISA_BASE\t\t0\n+#define ISA_V3\t\t\t3000\n+\n+struct cpu_feature {\n+\tconst char *name;\n+\tuint32_t cpus_supported;\n+\tuint32_t isa;\n+\tuint32_t usable_mask;\n+\tuint32_t hv_support;\n+\tuint32_t os_support;\n+\tuint32_t hfscr_bit_nr;\n+\tuint32_t fscr_bit_nr;\n+\tuint32_t hwcap_bit_nr;\n+\tconst char *dependencies_names; /* space-delimited names */\n+};\n+\n+/*\n+ * The base (or NULL) cpu feature set is the CPU features available\n+ * when no child nodes of the /cpus/features node exist. The base feature\n+ * set is POWER8 (ISAv2.07), less features that are listed explicitly.\n+ *\n+ * There will be a /cpus/features/isa property that specifies the currently\n+ * active ISA level. Those architected features without explicit nodes\n+ * will match the current ISA level. A greater ISA level will imply some\n+ * features are phased out.\n+ */\n+static const struct cpu_feature cpu_features_table[] = {\n+\t/*\n+\t * Big endian as in ISAv2.07, MSR_LE=0\n+\t */\n+\t{ \"big-endian\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * Little endian as in ISAv2.07, MSR_LE=1. When big and little endian\n+\t * are defined, there is an LPCR ILE bit and implementation specific\n+\t * way to switch HILE mode.\n+\t */\n+\t{ \"little-endian\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * MSR_HV=1 mode as in ISAv2.07 (i.e., hypervisor privileged\n+\t * instructions and registers).\n+\t */\n+\t{ \"hypervisor\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * Interrupt vectors and register modes as in ISAv2.07\n+\t * (e.g., AIL, ILE, HV, etc LPCR bits).\n+\t */\n+\t{ \"interrupt-facilities\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t{ \"smt\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, 14,\n+\tNULL, },\n+\n+\t/*\n+\t * PPR, RPR, PSPB registers, priority \"or\" instructions, as in\n+\t * ISAv2.07.\n+\t */\n+\t{ \"program-priority-register\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv2.07 Book3S Chapter 5.7.9.1. Virtual Page Class Key Protecion\n+\t * AMR, IAMR, AMOR, UAMOR, etc registers and MMU key bits.\n+\t */\n+\t{ \"virtual-page-class-key-protection\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv2.07 SAO storage control attribute\n+\t */\n+\t{ \"strong-access-ordering\",\n+\tCPU_ALL & ~CPU_P9_DD1,\n+\tISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv2.07 no-execute storage control attribute\n+\t */\n+\t{ \"no-execute\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * Cache inhibited attribute on large pages.\n+\t */\n+\t{ \"cache-inhibited-large-page\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv2.07 Book3S Chapter 8. Debug Facilities\n+\t * CIEA, CIABR, DEAW, MEte, trace interrupt, etc.\n+\t * Except CFAR, branch tracing.\n+\t */\n+\t{ \"debug-facilities\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv2.07 CFAR\n+\t */\n+\t{ \"come-from-address-register\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\t\"debug-facilities\", },\n+\n+\t/*\n+\t * ISAv2.07 Branch tracing (optional in ISA)\n+\t */\n+\t{ \"branch-tracing\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\t\"debug-facilities\", },\n+\n+\t/*\n+\t * ISAv2.07 FPU instructions and registers.\n+\t */\n+\t{ \"floating-point\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\tPPC_BITLSHIFT(63), -1, 27,\n+\tNULL, },\n+\n+\t/*\n+\t * VSX / VMX\n+\t * XXX: should vector-scalar be separate?\n+\t */\n+\t{ \"vector\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\tPPC_BITLSHIFT(62), -1, -1 /* 28 and 7 */,\n+\t\"floating-point\", },\n+\n+\t{ \"vector-crypto\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, 57,\n+\t\"vector\", },\n+\n+\t/* BCD */\n+\t{ \"decimal-integer\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/* DFP */\n+\t{ \"decimal-floating-point\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, 10,\n+\t\"floating-point\", },\n+\n+\t/* DSCR */\n+\t{ \"data-stream-control-register\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\tPPC_BITLSHIFT(61), -1, 61,\n+\tNULL, },\n+\n+\t/* BHRB */\n+\t{ \"branch-history-rolling-buffer\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\tPPC_BITLSHIFT(59), -1, -1,\n+\tNULL, },\n+\n+\t/* HTM */\n+\t{ \"transactional-memory\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\tPPC_BITLSHIFT(58), -1, 62,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv3 transactional memory which provides\n+\t * TEXASR bit 17, self-induced vs external footprint overflow\n+\t */\n+\t{ \"transactional-memory-v3\",\n+\tCPU_ALL,\n+\tISA_V3, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\t\"transactional-memory\", },\n+\n+\t/* EBB */\n+\t{ \"event-based-branch\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\tPPC_BITLSHIFT(56), PPC_BITLSHIFT(56), 60,\n+\tNULL, },\n+\n+\t/* TAR */\n+\t{ \"target-address-register\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\tPPC_BITLSHIFT(55), PPC_BITLSHIFT(55), 58,\n+\tNULL, },\n+\n+\t/* CTRL */\n+\t{ \"control-register\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv2.07 Book3S Chapter 11. Processor Control.\n+\t * msgsnd, msgsndp, doorbell, etc.\n+\t *\n+\t * ISAv3 is not compatible (different addressing, HFSCR required\n+\t * for msgsndp).\n+\t */\n+\t{ \"processor-control-facility\",\n+\tCPU_P8_DD2, /* P8 DD1 has no dbell */\n+\tISA_BASE, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv2.07 PURR, SPURR registers\n+\t */\n+\t{ \"processor-utilization-of-resources-register\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t{ \"coprocessor-icswx\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv2.07 hash based MMU and all instructions, registers,\n+\t * data structures, exceptions, etc.\n+\t */\n+\t{ \"mmu-hash\",\n+\tCPU_P8,\n+\tISA_BASE, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t{ \"machine-check-power8\",\n+\tCPU_P8,\n+\tISA_BASE, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t{ \"performance-monitor-power8\",\n+\tCPU_P8,\n+\tISA_BASE, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * POWER CPUs do not used this, and it's removed from ISAv3.\n+\t */\n+\t{ \"alignment-interrupt-dsisr\",\n+\t0,\n+\tISA_BASE, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv2.07 / POWER8 doze, nap, sleep, winkle instructions\n+\t * XXX: is Linux we using some BookIV specific implementation details\n+\t * in nap handling? We have no POWER8 specific key. How about for\n+\t * ISAv3 stop implementation?\n+\t */\n+\t{ \"idle-nap\",\n+\tCPU_P8,\n+\tISA_BASE, USABLE_HV,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv2.07 wait instruction\n+\t */\n+\t{ \"wait\",\n+\tCPU_P8,\n+\tISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t{ \"subcore\",\n+\tCPU_P8,\n+\tISA_BASE, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\t\"smt\", },\n+\n+\t/*\n+\t * ISAv3.0 radix based MMU\n+\t */\n+\t{ \"mmu-radix\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv3.0 hash based MMU, new hash pte format, PCTR, etc\n+\t */\n+\t{ \"mmu-hash-v3\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv3 wait instruction\n+\t */\n+\t{ \"wait-v3\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv3 stop idle instructions and registers\n+\t */\n+\t{ \"idle-stop\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t{ \"hypervisor-virtualization-interrupt\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * POWER9 MCE / machine check exception.\n+\t */\n+\t{ \"machine-check-power9\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * POWER9 PMU / performance monitor unit.\n+\t */\n+\t{ \"performance-monitor-power9\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_CUSTOM,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv3 scv/rfscv system call instructions and exceptions, fscr bit\n+\t * etc.\n+\t */\n+\t{ \"system-call-vectored\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_CUSTOM,\n+\t-1, PPC_BITLSHIFT(51), -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv3 Book3S Chapter 10. Processor Control.\n+\t * global msgsnd, msgsndp, msgsync, doorbell, etc.\n+\t */\n+\t{ \"processor-control-facility-v3\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_CUSTOM, OS_SUPPORT_NONE,\n+\tPPC_BITLSHIFT(53), -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv3 addpcis instruction\n+\t */\n+\t{ \"pc-relative-addressing\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv2.07 Book3S Chapter 7. Timer Facilities\n+\t * TB, VTB, DEC, HDEC, IC, etc registers and exceptions.\n+\t * Not including PURR or SPURR registers.\n+\t */\n+\t{ \"timer-facilities\",\n+\tCPU_ALL,\n+\tISA_BASE, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv3 Book3S Chapter 7. Timer Facilities\n+\t * Large decrementer and hypervisor decrementer\n+\t */\n+\t{ \"timer-facilities-v3\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\t\"timer-facilities\", },\n+\n+\t/*\n+\t * ISAv3 deliver a random number instruction (darn)\n+\t */\n+\t{ \"random-number-generator\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv3 fixed point instructions\n+\t * multiply-add, modulo, count trailing zeroes, cmprb, cmpeqb,\n+\t * extswsli, mfvsrld, mtvsrdd, mtvsrws, addex\n+\t */\n+\t{ \"fixed-point-v3\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv3 lightweight mffs\n+\t */\n+\t{ \"floating-point-v3\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\t\"floating-point\", },\n+\n+\t{ \"decimal-integer-v3\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\t\"decimal-integer\", },\n+\n+\t{ \"decimal-floating-point-v3\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\t\"decimal-floating-point\", },\n+\n+\t{ \"vector-v3\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\t\"vector\", },\n+\n+\t{ \"vector-binary128\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, 54,\n+\t\"vector-v3\", },\n+\n+\t{ \"vector-binary16\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\t\"vector-v3\", },\n+\n+\t/*\n+\t * ISAv3 branch instruction and register additions\n+\t * CA32, OV32, mcrxrx, setb\n+\t */\n+\t{ \"branch-v3\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv3\n+\t * external event based branch\n+\t */\n+\t{ \"event-based-branch-v3\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\t\"event-based-branch\", },\n+\n+\t{ \"atomic-memory-operations\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t{ \"copy-paste\",\n+\tCPU_P9,\n+\tISA_V3, USABLE_HV|USABLE_OS|USABLE_PR,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\tNULL, },\n+\n+\t/*\n+\t * ISAv3\n+\t * GSR SPR register\n+\t * ISAv3 includes this but POWER9 does not implement it.\n+\t */\n+\t{ \"group-start-register\",\n+\t0,\n+\tISA_V3, USABLE_HV|USABLE_OS,\n+\tHV_SUPPORT_NONE, OS_SUPPORT_NONE,\n+\t-1, -1, -1,\n+\tNULL, },\n+};\n+\n+static void add_cpu_feature_nodeps(struct dt_node *features, const struct cpu_feature *f)\n+{\n+\tstruct dt_node *feature;\n+\n+\tfeature = dt_new(features, f->name);\n+\tassert(feature);\n+\n+\tdt_add_property_cells(feature, \"isa\", f->isa);\n+\tdt_add_property_cells(feature, \"usable-mask\", f->usable_mask);\n+\n+\tif (f->usable_mask & USABLE_HV) {\n+\t\tif (f->hv_support != HV_SUPPORT_NONE) {\n+\t\t\tdt_add_property_cells(feature, \"hv-support\", f->hv_support);\n+\t\t\tif (f->hfscr_bit_nr != -1)\n+\t\t\t\tdt_add_property_cells(feature, \"hfscr-bit-nr\", f->hfscr_bit_nr);\n+\t\t} else {\n+\t\t\tassert(f->hfscr_bit_nr == -1);\n+\t\t}\n+\t}\n+\n+\tif (f->usable_mask & USABLE_OS) {\n+\t\tif (f->os_support != OS_SUPPORT_NONE) {\n+\t\t\tdt_add_property_cells(feature, \"os-support\", f->os_support);\n+\t\t\tif (f->fscr_bit_nr != -1)\n+\t\t\t\tdt_add_property_cells(feature, \"fscr-bit-nr\", f->fscr_bit_nr);\n+\t\t} else {\n+\t\t\tassert(f->fscr_bit_nr == -1);\n+\t\t}\n+\t}\n+\n+\tif (f->usable_mask & USABLE_PR) {\n+\t\tif (f->hwcap_bit_nr != -1)\n+\t\t\tdt_add_property_cells(feature, \"hwcap-bit-nr\", f->hwcap_bit_nr);\n+\t}\n+\n+\tif (f->dependencies_names)\n+\t\tdt_add_property(feature, \"dependencies\", NULL, 0);\n+}\n+\n+void add_cpufeatures(struct dt_node *cpus,\n+\t\tuint32_t cpu_feature_isa, uint32_t cpu_feature_cpu)\n+{\n+\tstruct dt_node *features;\n+\tstruct dt_node *feature;\n+\tint i;\n+\n+\tfeatures = dt_new(cpus, \"features\");\n+\tassert(features);\n+\n+\tdt_add_property_cells(features, \"isa\", cpu_feature_isa);\n+\n+\tdt_add_property_string(features, \"device_type\", \"cpu-features\");\n+\n+\tfor (i = 0; i < ARRAY_SIZE(cpu_features_table); i++) {\n+\t\tconst struct cpu_feature *f = &cpu_features_table[i];\n+\n+\t\tif (f->cpus_supported & cpu_feature_cpu)\n+\t\t\tadd_cpu_feature_nodeps(features, f);\n+\t}\n+\n+\t/* dependency construction pass */\n+\tdt_for_each_node(features, feature) {\n+\t\tconst struct cpu_feature *f;\n+\t\tconst char *deps_names;\n+\t\tstruct dt_property *deps;\n+\t\tint nr_deps;\n+\t\tint i;\n+\n+\t\t/* Find features with dependencies */\n+\n+\t\tdeps = __dt_find_property(feature, \"dependencies\");\n+\t\tif (!deps)\n+\t\t\tcontinue;\n+\n+\t\t/* Find the matching cpu table */\n+\t\tfor (i = 0; i < ARRAY_SIZE(cpu_features_table); i++) {\n+\t\t\tf = &cpu_features_table[i];\n+\t\t\tif (!strcmp(f->name, feature->name))\n+\t\t\t\tbreak;\n+\t\t}\n+\t\tassert(f->dependencies_names);\n+\n+\t\t/*\n+\t\t * Count number of depended features and allocate space\n+\t\t * for phandles in the property.\n+\t\t */\n+\t\tdeps_names = f->dependencies_names;\n+\t\tnr_deps = strcount(deps_names, \" \") + 1;\n+\t\tdt_resize_property(&deps, nr_deps * sizeof(u32));\n+\t\tdeps->len = nr_deps * sizeof(u32);\n+\n+\t\t/*\n+\t\t * For each one, find the depended feature then advance to\n+\t\t * next name.\n+\t\t */\n+\t\tfor (i = 0; i < nr_deps; i++) {\n+\t\t\tstruct dt_node *dep;\n+\n+\t\t\tdt_for_each_node(features, dep) {\n+\t\t\t\tif (strstarts(deps_names, dep->name))\n+\t\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\tdt_property_set_cell(deps, i, dep->phandle);\n+\n+\t\t\t/* Advance over the name + delimiter */\n+\t\t\tdeps_names += strlen(dep->name) + 1;\n+\t\t}\n+\t}\n+}\n+\n+void dt_add_cpufeatures(struct dt_node *root)\n+{\n+\tint version;\n+\tuint32_t cpu_feature_isa = 0;\n+\tuint32_t cpu_feature_cpu = 0;\n+\tstruct dt_node *cpus;\n+\n+\tversion = mfspr(SPR_PVR);\n+\tswitch(PVR_TYPE(version)) {\n+\tcase PVR_TYPE_P8:\n+\tcase PVR_TYPE_P8E:\n+\tcase PVR_TYPE_P8NVL:\n+\t\tcpu_feature_isa = CPUFEATURES_ISA_V2_07;\n+\t\tif (PVR_VERS_MAJ(version) == 1)\n+\t\t\tcpu_feature_cpu = CPUFEATURES_CPU_P8_DD1;\n+\t\telse\n+\t\t\tcpu_feature_cpu = CPUFEATURES_CPU_P8_DD2;\n+\t\tbreak;\n+\tcase PVR_TYPE_P9:\n+\t\tcpu_feature_isa = CPUFEATURES_ISA_V3;\n+\t\tif (PVR_VERS_MAJ(version) == 1)\n+\t\t\tcpu_feature_cpu = CPUFEATURES_CPU_P9_DD1;\n+\t\telse\n+\t\t\tcpu_feature_cpu = CPUFEATURES_CPU_P9_DD2;\n+\t\tbreak;\n+\t}\n+\n+\tcpus = dt_new_check(root, \"cpus\");\n+\n+\tadd_cpufeatures(cpus, cpu_feature_isa, cpu_feature_cpu);\n+}\n+\ndiff --git a/core/device.c b/core/device.c\nindex f3ee63fb..38a420eb 100644\n--- a/core/device.c\n+++ b/core/device.c\n@@ -598,6 +598,13 @@ u32 dt_property_get_cell(const struct dt_property *prop, u32 index)\n \treturn fdt32_to_cpu(((const u32 *)prop->prop)[index]);\n }\n \n+void dt_property_set_cell(struct dt_property *prop, u32 index, u32 val)\n+{\n+\tassert(prop->len >= (index+1)*sizeof(u32));\n+\t/* Always aligned, so this works. */\n+\t((u32 *)prop->prop)[index] = cpu_to_fdt32(val);\n+}\n+\n /* First child of this node. */\n struct dt_node *dt_first(const struct dt_node *root)\n {\ndiff --git a/core/init.c b/core/init.c\nindex 6b8137c8..08b70ea3 100644\n--- a/core/init.c\n+++ b/core/init.c\n@@ -789,6 +789,7 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt)\n \t\t\tabort();\n \t} else {\n \t\tdt_expand(fdt);\n+\t\tdt_add_cpufeatures(dt_root);\n \t}\n \n \t/* Now that we have a full devicetree, verify that we aren't on fire. */\ndiff --git a/hdata/cpu-common.c b/hdata/cpu-common.c\nindex c69c53a7..bd7c9729 100644\n--- a/hdata/cpu-common.c\n+++ b/hdata/cpu-common.c\n@@ -29,6 +29,8 @@ struct dt_node * add_core_common(struct dt_node *cpus,\n \tconst char *name;\n \tstruct dt_node *cpu;\n \tuint32_t version;\n+\tuint32_t cpu_feature_isa = 0;\n+\tuint32_t cpu_feature_cpu = 0;\n \tuint64_t freq;\n \tconst uint8_t pa_features_p7[] = {\n \t\t6, 0,\n@@ -94,20 +96,28 @@ struct dt_node * add_core_common(struct dt_node *cpus,\n \t\tpa_features_size = sizeof(pa_features_p7p);\n \t\ttlb_congruence = 128;\n \t\tbreak;\n-\tcase PVR_TYPE_P8E:\n \tcase PVR_TYPE_P8:\n+\tcase PVR_TYPE_P8E:\n \tcase PVR_TYPE_P8NVL:\n \t\tname = \"PowerPC,POWER8\";\n+\t\tcpu_feature_isa = CPUFEATURES_ISA_V2_07;\n+\t\tif (PVR_VERS_MAJ(version) == 1)\n+\t\t\tcpu_feature_cpu = CPUFEATURES_CPU_P8_DD1;\n+\t\telse\n+\t\t\tcpu_feature_cpu = CPUFEATURES_CPU_P8_DD2;\n \t\tpa_features = pa_features_p8;\n \t\tpa_features_size = sizeof(pa_features_p8);\n \t\ttlb_congruence = 512;\n \t\tbreak;\n \tcase PVR_TYPE_P9:\n \t\tname = \"PowerPC,POWER9\";\n+\t\tcpu_feature_isa = CPUFEATURES_ISA_V3;\n \t\tif (PVR_VERS_MAJ(version) == 1) {\n+\t\t\tcpu_feature_cpu = CPUFEATURES_CPU_P9_DD1;\n \t\t\tpa_features = pa_features_p9_dd1;\n \t\t\tpa_features_size = sizeof(pa_features_p9_dd1);\n \t\t} else {\n+\t\t\tcpu_feature_cpu = CPUFEATURES_CPU_P9_DD2;\n \t\t\tpa_features = pa_features_p9_dd2;\n \t\t\tpa_features_size = sizeof(pa_features_p9_dd2);\n \t\t}\n@@ -119,6 +129,8 @@ struct dt_node * add_core_common(struct dt_node *cpus,\n \t\tpa_features = NULL;\n \t}\n \n+\tadd_cpufeatures(cpus, cpu_feature_isa, cpu_feature_cpu);\n+\n \tcpu = dt_new_addr(cpus, name, int_server);\n \tassert(cpu);\n \tdt_add_property_string(cpu, \"device_type\", \"cpu\");\ndiff --git a/include/device.h b/include/device.h\nindex 5155daad..ca4dd0b0 100644\n--- a/include/device.h\n+++ b/include/device.h\n@@ -125,6 +125,7 @@ void dt_check_del_prop(struct dt_node *node, const char *name);\n /* Warning: moves *prop! */\n void dt_resize_property(struct dt_property **prop, size_t len);\n \n+void dt_property_set_cell(struct dt_property *prop, u32 index, u32 val);\n u32 dt_property_get_cell(const struct dt_property *prop, u32 index);\n \n /* First child of this node. */\ndiff --git a/include/skiboot.h b/include/skiboot.h\nindex 8bc767a4..27fcd1a6 100644\n--- a/include/skiboot.h\n+++ b/include/skiboot.h\n@@ -184,6 +184,23 @@ extern void start_kernel_secondary(uint64_t entry) __noreturn;\n /* Get description of machine from HDAT and create device-tree */\n extern int parse_hdat(bool is_opal);\n \n+struct dt_node;\n+\n+/* Add /cpus/cpufeatures node for boot environment that passes an fdt */\n+extern void dt_add_cpufeatures(struct dt_node *root);\n+\n+#define CPUFEATURES_ISA_V2_07\t2070\n+#define CPUFEATURES_ISA_V3\t3000\n+\n+#define CPUFEATURES_CPU_P8_DD1\t0\n+#define CPUFEATURES_CPU_P8_DD2\t1\n+#define CPUFEATURES_CPU_P9_DD1\t2\n+#define CPUFEATURES_CPU_P9_DD2\t3\n+\n+/* Add /cpus/cpufeatures node given the given ISA and CPU */\n+extern void add_cpufeatures(struct dt_node *cpus,\n+\t\tuint32_t cpu_feature_isa, uint32_t cpu_feature_cpu);\n+\n /* Root of device tree. */\n extern struct dt_node *dt_root;\n \n", "prefixes": [ "RFC", "v2" ] }