From fe9e99cf507792d2f92e19bc449e5589245cb92e Mon Sep 17 00:00:00 2001 From: Christopher Riedl Date: Wed, 12 Oct 2016 16:04:26 -0500 Subject: P9 DD1 Doorbell-write Workaround -- fixed mask for clearing the multicast config bits -- missing header include -- applied fixes suggested by Michael Floyd and made some other improvements -- attempting to fix copyright block "missing" automated build fail... -- added disabling of EE around polling loops (infinite polling bounded by WDT Change-Id: I210f306f7df3c975ebebe7ef4457a08272250346 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/31108 Tested-by: Jenkins Server Reviewed-by: RAHUL BATRA Reviewed-by: Gregory S. Still --- .../p9/procedures/ppe_closed/lib/hcodelibfiles.mk | 4 +- .../procedures/ppe_closed/lib/p9_dd1_doorbell_wr.c | 125 +++++++++++++++++++++ .../procedures/ppe_closed/lib/p9_dd1_doorbell_wr.h | 42 +++++++ 3 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 import/chips/p9/procedures/ppe_closed/lib/p9_dd1_doorbell_wr.c create mode 100644 import/chips/p9/procedures/ppe_closed/lib/p9_dd1_doorbell_wr.h diff --git a/import/chips/p9/procedures/ppe_closed/lib/hcodelibfiles.mk b/import/chips/p9/procedures/ppe_closed/lib/hcodelibfiles.mk index 41b11a5d..30c2d01d 100644 --- a/import/chips/p9/procedures/ppe_closed/lib/hcodelibfiles.mk +++ b/import/chips/p9/procedures/ppe_closed/lib/hcodelibfiles.mk @@ -42,8 +42,8 @@ ########################################################################## HCODE_C_SOURCES = \ - p9_hcd_block_copy.c - + p9_hcd_block_copy.c \ + p9_dd1_doorbell_wr.c HCODE_S_SOURCES = diff --git a/import/chips/p9/procedures/ppe_closed/lib/p9_dd1_doorbell_wr.c b/import/chips/p9/procedures/ppe_closed/lib/p9_dd1_doorbell_wr.c new file mode 100644 index 00000000..936da2ba --- /dev/null +++ b/import/chips/p9/procedures/ppe_closed/lib/p9_dd1_doorbell_wr.c @@ -0,0 +1,125 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/chips/p9/procedures/ppe_closed/lib/p9_dd1_doorbell_wr.c $ */ +/* */ +/* OpenPOWER HCODE Project */ +/* */ +/* COPYRIGHT 2016,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 */ + +#include "p9_dd1_doorbell_wr.h" + +#include "stdint.h" +#include "ppe42_msr.h" +#include "ppe42_scom.h" +#include "gpehw_common.h" + +#define PCB_MC_READ_OR 0x40000000ul +#define PCB_MC_READ_AND 0x48000000ul +#define PCB_MC_WRITE 0x68000000ul + +/// Note: External and timer interrupts are disabled during the "polling" +// portions of the code to allow for timeouts using the WDT. +// MSR[EE] == 0 will disable the WDT callback and therefore cause +// a halt/error condition if the polling takes "too long". + +void p9_dd1_db_unicast_wr(uint32_t addr, uint64_t data) +{ + uint64_t rdata; + + // Clear the DB register + wrteei(0); + + do + { + GPE_PUTSCOM(addr, 0ull); + GPE_GETSCOM(addr, rdata); + } + while((rdata >> 32) != 0); + + wrteei(1); + + // TODO Does it make sense to open up for interrupts here, since the two + // polling loops are right after each other anyways? + + // Write data to the DB register + wrteei(0); + + do + { + GPE_PUTSCOM(addr, data); + GPE_GETSCOM(addr, rdata); + } + while((rdata >> 32) == 0); + + wrteei(1); +} + +void p9_dd1_db_multicast_wr(uint32_t addr, uint64_t data, uint32_t coreMask) +{ + uint64_t rdata; + + // Clear out the multicast access type + addr &= ~(0x38000000ul); + + // Clear the DB register + wrteei(0); + + do + { + GPE_PUTSCOM(addr | PCB_MC_WRITE, 0ull); + GPE_GETSCOM(addr | PCB_MC_READ_OR, rdata); + } + while((rdata >> 32) != 0); + + wrteei(1); + + // Write data to the DB register + GPE_PUTSCOM(addr | PCB_MC_WRITE, data); + GPE_GETSCOM(addr | PCB_MC_READ_AND, rdata); + + // One of the slaves (or multiple) did not return the correct data... + // ... figure out which one(s) and write the DB data again to that + // (those) slave(s) + if((rdata >> 32) == 0) + { + uint32_t core = 0; + + for(; core < 24; ++core) + { + if(coreMask & (0x80000000ul >> core)) + { + // Replace the multicast config bits with the slave address + uint32_t unicastAddr = ((addr & ~(0xff000000ul)) | + ((core + 0x20ul) << 24)); + GPE_GETSCOM(unicastAddr, rdata); + // Only resend the write if needed (do not want duplicate DBs) + wrteei(0); + + while((rdata >> 32) == 0) + { + GPE_PUTSCOM(unicastAddr, data); + GPE_GETSCOM(unicastAddr, rdata); + } + + wrteei(1); + } + } + } +} diff --git a/import/chips/p9/procedures/ppe_closed/lib/p9_dd1_doorbell_wr.h b/import/chips/p9/procedures/ppe_closed/lib/p9_dd1_doorbell_wr.h new file mode 100644 index 00000000..03ec64ac --- /dev/null +++ b/import/chips/p9/procedures/ppe_closed/lib/p9_dd1_doorbell_wr.h @@ -0,0 +1,42 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/chips/p9/procedures/ppe_closed/lib/p9_dd1_doorbell_wr.h $ */ +/* */ +/* OpenPOWER HCODE Project */ +/* */ +/* COPYRIGHT 2016,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 _P9_DD1_DOORBELL_WR_H_ +#define _P9_DD1_DOORBELL_WR_H_ + +#include "stdint.h" + +void p9_dd1_db_unicast_wr (uint32_t addr, uint64_t data); + +// +/// @brief Provides a function to repeatedly attempt writes to multicast DB +/// registers as a workaround for DD1-HW issue. +/// @param addr The address (valid for multicast!) to write to. +/// @param data The data to write. +/// @param coreMask Bits 0:23 specify which of the CPPMs are present in the +/// multicast group specified in the address. +/// If all cores are active, then coreMask = 0xffffff00 +void p9_dd1_db_multicast_wr(uint32_t addr, uint64_t data, uint32_t coreMask); + +#endif // _P9_DD1_DOORBELL_WR_H_ -- cgit v1.2.3