summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/arch/pvrformat.H135
-rw-r--r--src/kernel/cpuid.C48
-rw-r--r--src/kernel/cpumgr.C4
-rw-r--r--src/usr/intr/intrrp.C13
4 files changed, 175 insertions, 25 deletions
diff --git a/src/include/arch/pvrformat.H b/src/include/arch/pvrformat.H
new file mode 100644
index 000000000..7915891fe
--- /dev/null
+++ b/src/include/arch/pvrformat.H
@@ -0,0 +1,135 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/arch/pvrformat.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef _PVRFORMAT_H
+#define _PVRFORMAT_H
+
+/**
+ * @brief Format of Processor Version Register (PVR) for P9
+ */
+struct PVR_t
+{
+ union
+ {
+ // Layout of the PVR is (32-bit):
+ uint32_t word;
+
+ //Nimbus DD1.0
+ // 2 nibbles reserved.
+ // 2 nibbles chip family.
+ // = x'4E' - P9
+ // 1 nibble technology.
+ // 1 nibble major DD.
+ // 1 nibble reserved.
+ // 1 nibble minor DD.
+ struct
+ {
+ uint32_t dd1_reserved0:8; // 00:07 = unused
+ uint32_t dd1_chipFamily:8; // 08:15 = chip type
+ uint32_t dd1_tech:4; // 16:19 = technology
+ uint32_t dd1_majorDD:4; // 20:23 = Major DD
+ uint32_t dd1_reserved1:4; // 24:27 = unused
+ uint32_t dd1_minorDD:4; // 28:31 = Minor DD
+ } PACKED;
+
+
+ //Nimbus DD2+, Cumulus
+ // 2 nibbles reserved.
+ // 2 nibbles chip family.
+ // = x'4E' - P9
+ // 2 bits Simics indicator.
+ // 1 bit chip type.
+ // = x'0' - Nimbus
+ // = x'1' - Cumulus
+ // 1 bit SMT mode.
+ // = x'0' - 12 core (SMT8)
+ // = x'1' - 24 core (SMT4)
+ // 1 nibble major DD.
+ // 1 nibble reserved.
+ // 1 nibble minor DD.
+ struct
+ {
+ uint32_t reserved0:8; // 00:07 = unused
+ uint32_t chipFamily:8; // 08:15 = chip family
+ uint32_t simics:2; // 16:17 = Simics flag
+ uint32_t chipType:1; // 18 = chip type
+ uint32_t smt:1; // 19 = SMT mode
+ uint32_t majorDD:4; // 20:23 = Major DD
+ uint32_t reserved1:4; // 24:27 = unused
+ uint32_t minorDD:4; // 28:31 = Minor DD
+ } PACKED;
+ };
+
+ // Populate with a 32-bit data word
+ PVR_t(uint32_t i_word = 0) : word(i_word) {}
+
+ // Populate with a 64-bit data word
+ PVR_t(uint64_t i_word = 0)
+ : word(static_cast<uint32_t>(i_word & 0xFFFFFFFF)) {}
+
+ PVR_t operator= (uint32_t i_word)
+ {
+ word = i_word;
+ return word;
+ }
+
+ PVR_t operator= (uint64_t i_word)
+ {
+ word = static_cast<uint32_t>(i_word & 0xFFFFFFFF);
+ return word;
+ }
+
+ /**
+ * @brief Return Major.Minor DD level
+ * @return 8-bit DD level
+ */
+ inline uint8_t getDDLevel() {
+ return (majorDD << 4) | minorDD;
+ }
+
+ /**
+ * @brief A bunch of constants
+ */
+ enum
+ {
+ CHIP_DD_MASK = 0x00FF0F0F,
+ IS_NIMBUS_DD1 = 0x004E0100,
+
+ // Field: chipType
+ NIMBUS_CHIP = 0,
+ CUMULUS_CHIP = 1,
+
+ // Field: smt
+ SMT8_MODE = 0,
+ SMT4_MODE = 1,
+
+ // Field: chipFamily
+ P8_MURANO = 0x4B,
+ P8_NAPLES = 0x4C,
+ P8_VENICE = 0x4D,
+ P9_ALL = 0x4E,
+ };
+};
+
+#endif //_PVRFORMAT_H
diff --git a/src/kernel/cpuid.C b/src/kernel/cpuid.C
index 576c74043..f65612ae1 100644
--- a/src/kernel/cpuid.C
+++ b/src/kernel/cpuid.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2015 */
+/* Contributors Listed Below - COPYRIGHT 2011,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,37 +27,45 @@
*/
#include <kernel/cpuid.H>
+#include <arch/pvrformat.H>
namespace CpuID
{
ProcessorCoreType getCpuType()
{
- uint64_t l_pvr = getPVR();
+ PVR_t l_pvr( getPVR() );
- // Layout of the PVR is (32-bit):
- // 2 nibbles reserved.
- // 2 nibbles chip type.
- // 1 nibble technology.
- // 1 nibble major DD.
- // 1 nibble reserved.
- // 1 nibble minor DD.
-
- switch(l_pvr & 0xFFFF0000)
+ switch(l_pvr.chipFamily)
{
- case 0x004B0000:
+ case PVR_t::P8_MURANO:
return CORE_POWER8_MURANO;
- case 0x004C0000:
+ case PVR_t::P8_NAPLES:
return CORE_POWER8_NAPLES;
- case 0x004D0000:
+ case PVR_t::P8_VENICE:
return CORE_POWER8_VENICE;
- case 0x004E0000:
- return CORE_POWER9_NIMBUS;
+ case PVR_t::P9_ALL:
+ {
+ // Nimbus DD1.0 has a different PVR format
+ if( (l_pvr.word & PVR_t::CHIP_DD_MASK) == PVR_t::IS_NIMBUS_DD1)
+ {
+ return CORE_POWER9_NIMBUS;
+ }
+
+ switch(l_pvr.chipType)
+ {
+ case PVR_t::NIMBUS_CHIP:
+ return CORE_POWER9_NIMBUS;
+
+ case PVR_t::CUMULUS_CHIP:
+ return CORE_POWER9_CUMULUS;
- case 0x004F0000:
- return CORE_POWER9_CUMULUS;
+ default:
+ return CORE_UNKNOWN;
+ }
+ }
default:
return CORE_UNKNOWN;
@@ -66,8 +74,8 @@ namespace CpuID
uint8_t getCpuDD()
{
- uint64_t l_pvr = getPVR();
- return ((l_pvr & 0x0F00) >> 4) | (l_pvr & 0x000F);
+ PVR_t l_pvr( getPVR() );
+ return l_pvr.getDDLevel();
}
};
diff --git a/src/kernel/cpumgr.C b/src/kernel/cpumgr.C
index e6bf08dd9..f7cb25961 100644
--- a/src/kernel/cpumgr.C
+++ b/src/kernel/cpumgr.C
@@ -46,6 +46,7 @@
#include <kernel/kernel_reasoncodes.H>
#include <kernel/cpuid.H>
#include <kernel/doorbell.H>
+#include <arch/pvrformat.H>
cpu_t** CpuManager::cv_cpus[KERNEL_MAX_SUPPORTED_NODES];
bool CpuManager::cv_shutdown_requested = false;
@@ -472,6 +473,9 @@ size_t CpuManager::getThreadCount()
case CORE_UNKNOWN:
default:
+ PVR_t l_pvr( getPVR() );
+ printk("cputype=%d, pvr=%.8X\n",
+ CpuID::getCpuType(), l_pvr.word);
kassert(false);
break;
}
diff --git a/src/usr/intr/intrrp.C b/src/usr/intr/intrrp.C
index fe010ed11..85d8f54f1 100644
--- a/src/usr/intr/intrrp.C
+++ b/src/usr/intr/intrrp.C
@@ -51,6 +51,7 @@
#include <fsi/fsiif.H>
#include <arch/ppc.H>
#include <arch/pirformat.H>
+#include <arch/pvrformat.H>
#include <config.h>
#include <p9_misc_scom_addresses.H>
@@ -397,11 +398,13 @@ errlHndl_t IntrRp::resetIntUnit(intr_hdlr_t* i_proc)
TARGETING::Target* procTarget = i_proc->proc;
do {
-
- //TODO RTC 160361 - Replace attribute with EC check. Anything greater
- // DD20 should do the HW-based reset
- uint8_t l_doHwReset =
- iv_masterHdlr->proc->getAttr<TARGETING::ATTR_XIVE_HW_RESET>();
+ //Anything greater than DD10 should do the HW-based reset
+ bool l_doHwReset = true;
+ uint32_t l_pvr = mmio_pvr_read() & 0xFFFFFFFF;
+ if( (l_pvr & PVR_t::CHIP_DD_MASK) == PVR_t::IS_NIMBUS_DD1 )
+ {
+ l_doHwReset = false;
+ }
if (l_doHwReset)
{
OpenPOWER on IntegriCloud