From da7b394c300d19900c7fd4ee9a37718152536954 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Fri, 3 Jan 2020 18:25:15 +1100 Subject: [PATCH 01/15] ifcompiler: Fix stream operation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ifcompiler/initCompiler.C: In constructor ‘init::Parser::Parser(int, char**)’: ifcompiler/initCompiler.C:311:18: error: no match for ‘operator<<’ (operand types are ‘std::ostream’ {aka ‘std::basic_ostream’} and ‘std::ostringstream’ {aka ‘std::__cxx11::basic_ostringstream’}) 311 | cout << stats; | ~~~~ ^~ ~~~~~ | | | | | std::ostringstream {aka std::__cxx11::basic_ostringstream} | std::ostream {aka std::basic_ostream} Change-Id: I563b5008050b2ea2baa456226cc2afbdbd63805d Signed-off-by: Joel Stanley --- src/usr/hwpf/ifcompiler/initCompiler.C | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/usr/hwpf/ifcompiler/initCompiler.C b/src/usr/hwpf/ifcompiler/initCompiler.C index 0ea6dfb7df4..496d73087ff 100755 --- a/src/usr/hwpf/ifcompiler/initCompiler.C +++ b/src/usr/hwpf/ifcompiler/initCompiler.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2014 */ +/* Contributors Listed Below - COPYRIGHT 2011,2020 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -308,7 +308,7 @@ Parser::Parser(int narg, char ** argv) } else { - cout << stats; + cout << stats.rdbuf(); } } From 77192fcf704ca64571a0bcc5b905038149218914 Mon Sep 17 00:00:00 2001 From: Luis Fernandez Date: Thu, 21 Feb 2019 14:13:44 -0600 Subject: [PATCH 02/15] HB Improvements: Fix compiler warnings on modern compilers Resolve warnings when compiling with gcc 4.8. Compiled with GCC 7.3, no more compile errors/warnings; build ends with caught exception from linker. This commit compiles with GCC 8.2, no more error/warnings; except for a linking warning. Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/72271 (cherry picked from p9 branch) Signed-off-by: Joel Stanley Change-Id: Iff33e15367cea0b8693709941592a2275efac589 --- src/build/linker/linker.C | 39 ++++++++++++++++++--- src/include/usr/devicefw/driverif.H | 16 ++++++--- src/include/usr/targeting/common/target.H | 25 ++++++------- src/include/util/locked/list.H | 10 +++--- src/lib/utilmisc.C | 9 +++-- src/usr/devicefw/driverif.C | 18 +++++++++- src/usr/errl/errludlogregister.C | 18 ++++++++++ src/usr/targeting/common/xmltohb/xmltohb.pl | 12 +++++-- src/usr/testcore/rtloader/loader.H | 2 +- 9 files changed, 119 insertions(+), 30 deletions(-) diff --git a/src/build/linker/linker.C b/src/build/linker/linker.C index d6ac6f11903..3b47b15252b 100644 --- a/src/build/linker/linker.C +++ b/src/build/linker/linker.C @@ -269,6 +269,36 @@ inline void advance_to_page_align(FILE * i_f) } } +/** + * @brief Throw error if std::fread was performed incorrectly. + * @param[i] i_buffer: pointer to the first object in the array to be read + * @param[i] i_size: size of each object in i_buffer array, in bytes + * @param[i] i_count: number of the objects in i_buffer array to be read + * @param[i] i_stream: input-file pointer + */ +inline void fread_wrapper(void* i_buffer, const size_t i_size, + const size_t i_count, FILE* i_stream) +{ + + size_t n_values_read = fread(i_buffer,i_size,i_count,i_stream); + + if (i_count != n_values_read) + { + if (feof(i_stream)) + { + throw "End of file reached, file not read fully."; + } + else if (ferror(i_stream)) + { + throw "Error occurred while reading file."; + } + else + { + throw "Unknown read error."; + } + } +} + // // Global variables // @@ -597,7 +627,7 @@ bool Object::write_object() long int file_size = ftell(file); uint8_t * buffer = new uint8_t[file_size]; fseek(file,0,SEEK_SET); - fread(buffer,file_size,1,file); + fread_wrapper(buffer,file_size,1,file); fwrite(buffer,file_size,1,iv_output); delete [] buffer; fclose(file); @@ -795,7 +825,7 @@ bool Object::perform_local_relocations() char data[sizeof(uint64_t)]; fseek(iv_output, offset + i->address, SEEK_SET); - fread(data, sizeof(uint64_t), 1, iv_output); + fread_wrapper(data, sizeof(uint64_t), 1, iv_output); address = bfd_getb64(data); if ((address != i->addend) && (address != 0)) @@ -885,7 +915,8 @@ bool Object::perform_global_relocations() } fseek(j->iv_output, symbol_addr, SEEK_SET); - fread(data, sizeof(uint64_t), 3, j->iv_output); + fread_wrapper(data, sizeof(uint64_t), 3, + j->iv_output); fseek(iv_output, offset + i->address, SEEK_SET); fwrite(data, sizeof(uint64_t), 3, iv_output); @@ -996,7 +1027,7 @@ void ModuleTable::write_table(vector & i_objects) cout << "Updating base module table..." << endl; fseek(iv_output, module_table_offset, SEEK_SET); char mx_mod_ch = 0; - fread(&mx_mod_ch,sizeof(char),1,iv_output); + fread_wrapper(&mx_mod_ch,sizeof(char),1,iv_output); max_modules = (uint64_t)mx_mod_ch; // VFS_MODULE_MAX; ++i; } diff --git a/src/include/usr/devicefw/driverif.H b/src/include/usr/devicefw/driverif.H index a148725b5fd..76b6348e184 100644 --- a/src/include/usr/devicefw/driverif.H +++ b/src/include/usr/devicefw/driverif.H @@ -324,8 +324,12 @@ namespace DeviceFW void* io_buffer, size_t& io_buflen, AccType i_accessType, ...) { - return InvalidParameterType(); // Cause a compile fail if not one of - // the explicit template specializations. + // Cause a compile fail if not one of + // the explicit template specializations. + static_assert(sizeof(AccType) != sizeof(AccType), "Must use" + " an explicitly supported template specialization"); + errlHndl_t errl = nullptr; + return errl; } /** @@ -349,8 +353,12 @@ namespace DeviceFW void* io_buffer, size_t& io_buflen, AccType i_accessType, va_list i_args) { - return InvalidParameterType(); // Cause a compile fail if not one of - // the explicit template specializations. + // Cause a compile fail if not one of + // the explicit template specializations. + static_assert(sizeof(AccType) != sizeof(AccType), "Must use" + " an explicitly supported template specialization"); + errlHndl_t errl = nullptr; + return errl; } // --- Below are template specializations to aid in type-safety. --- diff --git a/src/include/usr/targeting/common/target.H b/src/include/usr/targeting/common/target.H index 1243deebe38..2e793d789be 100644 --- a/src/include/usr/targeting/common/target.H +++ b/src/include/usr/targeting/common/target.H @@ -611,8 +611,8 @@ bool Target::tryGetAttr(typename AttributeTraits::Type& o_attrValue) const template bool Target::trySetAttr(typename AttributeTraits::Type const& i_attrValue) { - if(AttributeTraits::writeable) { } - if(AttributeTraits::notHbMutex) { } + if(AttributeTraits::writeable == AttributeTraits::writeable) { } + if(AttributeTraits::notHbMutex == AttributeTraits::notHbMutex) { } return _trySetAttr(A,sizeof(i_attrValue),&i_attrValue); } @@ -641,18 +641,18 @@ void Target::setAttr(typename AttributeTraits::Type const& i_attrValue) template mutex_t* Target::getHbMutexAttr() const { - if(AttributeTraits::hbMutex) { } - if(AttributeTraits::readable) { } - if(AttributeTraits::writeable) { } + if(AttributeTraits::hbMutex == AttributeTraits::hbMutex) { } + if(AttributeTraits::readable == AttributeTraits::readable) { } + if(AttributeTraits::writeable == AttributeTraits::writeable) { } return _getHbMutexAttr(A); } template util::Mutex* Target::getFspMutexAttr() const { - if(AttributeTraits::fspMutex) { } - if(AttributeTraits::readable) { } - if(AttributeTraits::writeable) { } + if(AttributeTraits::fspMutex == AttributeTraits::fspMutex) { } + if(AttributeTraits::readable == AttributeTraits::readable) { } + if(AttributeTraits::writeable == AttributeTraits::writeable) { } return _getFspMutexAttr(A); } @@ -660,9 +660,9 @@ template bool Target::tryGetHbMutexAttr( mutex_t*& o_pMutex) const { - if(AttributeTraits::hbMutex) { } - if(AttributeTraits::readable) { } - if(AttributeTraits::writeable) { } + if(AttributeTraits::hbMutex == AttributeTraits::hbMutex) { } + if(AttributeTraits::readable == AttributeTraits::readable) { } + if(AttributeTraits::writeable == AttributeTraits::writeable) { } return _tryGetHbMutexAttr(A,o_pMutex); } @@ -672,7 +672,8 @@ const char* Target::getAttrAsString() const // Note: the compiler optimizes the following check (which fails // at compile time if the attribute does not have a string // conversion) away - if(AttributeTraits::hasStringConversion) { } + if(AttributeTraits::hasStringConversion == + AttributeTraits::hasStringConversion) { } typename AttributeTraits::Type l_attrValue; bool l_read = tryGetAttr(l_attrValue); if (unlikely(!l_read)) diff --git a/src/include/util/locked/list.H b/src/include/util/locked/list.H index 6708b383b4e..31bbd713f1b 100644 --- a/src/include/util/locked/list.H +++ b/src/include/util/locked/list.H @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2010,2014 */ +/* Contributors Listed Below - COPYRIGHT 2010,2019 */ +/* [+] 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. */ @@ -42,9 +44,9 @@ namespace Util void insert(_T*); void erase(_T* node); - void erase(_K& key); + _T* erase(_K& key); - _T* find(_K& key) const; + _T* find(_K& key) const; bool empty(); _T* begin(); @@ -156,7 +158,7 @@ namespace Util } template - void List<_T,_K,locked,_S>::erase(_K& key) + _T* List<_T,_K,locked,_S>::erase(_K& key) { __lock(); diff --git a/src/lib/utilmisc.C b/src/lib/utilmisc.C index d1145845405..c19b8851a1d 100644 --- a/src/lib/utilmisc.C +++ b/src/lib/utilmisc.C @@ -29,14 +29,19 @@ namespace Util { bool isSimics() __attribute__((alias("__isSimicsRunning"))); -extern "C" void __isSimicsRunning() NEVER_INLINE; +extern "C" bool __isSimicsRunning() NEVER_INLINE; -void __isSimicsRunning() +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wreturn-type" + +bool __isSimicsRunning() { asm volatile("li 3, 0"); MAGIC_INSTRUCTION(MAGIC_SIMICS_CHECK); } +#pragma GCC diagnostic pop + bool isSimicsRunning() { static bool simics = isSimics(); diff --git a/src/usr/devicefw/driverif.C b/src/usr/devicefw/driverif.C index acd2a5a1d75..9f7c6899568 100644 --- a/src/usr/devicefw/driverif.C +++ b/src/usr/devicefw/driverif.C @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2011,2014 */ +/* Contributors Listed Below - COPYRIGHT 2011,2019 */ +/* [+] 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. */ @@ -31,6 +33,16 @@ namespace DeviceFW { + +// This extension will silence warnings relating to the mis-match of argument +// types used in the various aliases created in this document. + +// The following flag is only available in GCC 8 +#if __GNUC__ >= 8 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wattribute-alias" +#endif + /** @brief Wrapper function to call singleton instance for registerRoute. * * This is defined as an extern "C" function so that it can be aliased @@ -199,4 +211,8 @@ namespace DeviceFW AccessType_DriverOnly i_accessType, va_list i_args) __attribute__((alias("DeviceFW_deviceOpValist"))); +#if __GNUC__ >= 8 +#pragma GCC diagnostic pop +#endif + }; diff --git a/src/usr/errl/errludlogregister.C b/src/usr/errl/errludlogregister.C index 77e385dbbe8..34cbbf5463f 100644 --- a/src/usr/errl/errludlogregister.C +++ b/src/usr/errl/errludlogregister.C @@ -39,6 +39,7 @@ namespace ERRORLOG { using namespace TARGETING; +using namespace DeviceFW; extern TARG_TD_t g_trac_errl; @@ -277,6 +278,16 @@ void ErrlUserDetailsLogRegister::copyRegisterData( * * This function will call the readRegister() function to log and do the read. */ + +// This extension will silence warnings relating to the mis-match of argument +// types used in the various aliases created in this document. + +// The following flag is only available in GCC 8 +#if __GNUC__ >= 8 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wattribute-alias" +#endif + template <> void ErrlUserDetailsLogRegister::addData<>( DeviceFW::AccessType i_accessType, ...) @@ -289,6 +300,9 @@ __attribute__((alias("_ZN8ERRORLOG26ErrlUserDetailsLogRegister9__addDataEhz"))); void ErrlUserDetailsLogRegister::__addData( uint8_t i_accessType, ...) { + static_assert(LAST_DRIVER_ACCESS_TYPE <= UINT8_MAX, + "Logic violation, LAST_DRIVER_ACCESS_TYPE is greater than UINT8_MAX."); + TRACDCOMP(g_trac_errl, "LogRegister::addData: type %x", i_accessType); @@ -316,6 +330,10 @@ void ErrlUserDetailsLogRegister::addDataBuffer<>( DeviceFW::AccessType_DriverOnly i_accessType, ...) __attribute__((alias("_ZN8ERRORLOG26ErrlUserDetailsLogRegister15__addDataBufferEPvmhz"))); +#if __GNUC__ >= 8 +#pragma GCC diagnostic pop +#endif // ignoring -Wattribute-alias in GCC 8 + void ErrlUserDetailsLogRegister::__addDataBuffer( void *i_dataBuf, size_t i_dataSize, uint8_t i_accessType, ...) diff --git a/src/usr/targeting/common/xmltohb/xmltohb.pl b/src/usr/targeting/common/xmltohb/xmltohb.pl index 5bcaf503aa2..16cffb970af 100755 --- a/src/usr/targeting/common/xmltohb/xmltohb.pl +++ b/src/usr/targeting/common/xmltohb/xmltohb.pl @@ -1451,9 +1451,17 @@ sub writeStringHeaderFileHeader { const char* attrToString( typename AttributeTraits::Type const& i_attrValue) { - // Default behavior is to fail the compile if caller attempt to print an + // Default behavior is to fail the compile if caller attempts to print an // unsupported string - return InvalidAttributeForStringification(); + #ifdef __HOSTBOOT_MODULE + static_assert(A != A, \"Must use an explicitly supported template \" + \"specialization\"); + #else + char mustUseTemplateSpecialization[A != A ? 1 : -1]; + #endif + + const char* retVal = NULL; + return retVal; } VERBATIM diff --git a/src/usr/testcore/rtloader/loader.H b/src/usr/testcore/rtloader/loader.H index 53a0c0fa168..1d5f56e47a9 100644 --- a/src/usr/testcore/rtloader/loader.H +++ b/src/usr/testcore/rtloader/loader.H @@ -469,7 +469,7 @@ class RuntimeLoaderTest : public CxxTest::TestSuite //fix the offset for the TEST section so that the testcases //don't collide - i_offset = (PNOR::TEST) ? (i_offset+ + i_offset = (l_id==PNOR::TEST) ? (i_offset+ ((PNOR::pnorTestSec_rt_readwrite_offset*9)/8)):i_offset; uint32_t l_flashAddr = l_info.flashAddr + i_offset; From d8f7b87ad056e45833e83101c582748b9d626742 Mon Sep 17 00:00:00 2001 From: Andrew Geissler Date: Thu, 30 Jun 2016 15:58:38 -0500 Subject: [PATCH 03/15] Remove legacy binutils workaround in tracehash Change-Id: I52e002a2f7085baa5b6b5d536e5aa95a5fab2c0d RTC: 123492 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/26507 Tested-by: Jenkins Server Tested-by: FSP CI Jenkins Reviewed-by: Christian R. Geddes Reviewed-by: William G. Hoffa Reviewed-by: Matthew A. Ploetz Signed-off-by: Joel Stanley --- src/build/trace/tracehash.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/build/trace/tracehash.c b/src/build/trace/tracehash.c index d28920fe784..076d3e1e1ff 100644 --- a/src/build/trace/tracehash.c +++ b/src/build/trace/tracehash.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2015 */ +/* Contributors Listed Below - COPYRIGHT 2013,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -471,14 +471,7 @@ void create_sections(bfd* inFile, asection* s, void* param) // for this section to point to the group // symbol // Binutils 2.24 BFD requires an offset of 176 - // Binutils 2.22 BFD requires an offset of 168 - // So we're just going to key off a define that's only in 2.24 - // TODO RTC 123492 -#ifdef bfd_find_nearest_line_discriminator uint32_t offset = 176; -#else - uint32_t offset = 168; -#endif void *ptr_sym_offset = s->used_by_bfd + offset; asymbol **tsym = (asymbol **)ptr_sym_offset; *tsym = gsym; From 8ed7d6d04d727f6641362f33f7e0e4347d85694d Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 22 Mar 2017 11:48:21 -0500 Subject: [PATCH 04/15] Fix Tracehash Buffer Overflow Change-Id: Id8c8be0ef1d5e9f3ca377c4a89715c9c46d17a38 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/38304 Reviewed-by: Prachi Gupta Tested-by: Jenkins Server Reviewed-by: Elizabeth K. Liner Tested-by: FSP CI Jenkins Tested-by: Jenkins OP Build CI Reviewed-by: Matthew A. Ploetz Signed-off-by: Joel Stanley --- src/build/trace/tracehash.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/build/trace/tracehash.c b/src/build/trace/tracehash.c index 076d3e1e1ff..26607898efe 100644 --- a/src/build/trace/tracehash.c +++ b/src/build/trace/tracehash.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2016 */ +/* Contributors Listed Below - COPYRIGHT 2013,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -665,7 +665,10 @@ char* create_format_string(const char* string) size_t r_pos = 0; // Current position in result string. // Iterate through source string looking for format tags. - for(size_t pos = 0; pos < length; pos++) + // length - 2 was used because "length" already includes the 0 terminal byte + // and we want to make sure we have at least one char beyond the "%" + // that way we have two which should deal with most cases + for(size_t pos = 0; pos < (length-2); pos++) { // Skip if not %. if (string[pos] != '%') continue; @@ -882,7 +885,7 @@ void parse_traceinfo(bfd* inFile, asection* s) static const char filesep[] = ": "; size_t len_begin = replace_pos - (char*)&contents[pos]; - size_t len_end = strlen(&contents[pos]) - + size_t len_end = strlen(&contents[pos + len_begin]) - strlen(TRACEPP_REPLACE_WITH_FILENAME); size_t length = len_begin + strlen(filename) + len_end + strlen(filesep) + 1; From be52281138bc5326a96dce6c024c54df0b09a0cb Mon Sep 17 00:00:00 2001 From: Brian Silver Date: Wed, 5 Nov 2014 14:16:36 -0600 Subject: [PATCH 05/15] Changes for Habanero bringup, uart delay and centaur/vddr Change-Id: I381732be6facd25fb27bbd1f8ac0d75eb5b4980e --- src/usr/console/uart.C | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/usr/console/uart.C b/src/usr/console/uart.C index aa85df50b09..c267d6040f3 100644 --- a/src/usr/console/uart.C +++ b/src/usr/console/uart.C @@ -117,7 +117,7 @@ namespace CONSOLE // Wait for transmit FIFO to have space. { const uint64_t DELAY_NS = 100; - const uint64_t DELAY_LOOPS = 10000; + const uint64_t DELAY_LOOPS = 100000000; uint8_t data = 0; uint64_t loops = 0; From 8abcd70c9a92724dce3cb4415bdfa3a4f1fb346f Mon Sep 17 00:00:00 2001 From: Andrew Geissler Date: Mon, 16 Feb 2015 13:43:51 -0600 Subject: [PATCH 06/15] GCC 4.9: Make compiler use ELFv1 ABI. GCC4.9 defaults to ELFv2 ABI support but we do not have all of the needed tools to suppor this. Change-Id: Iacf49c46b1fb25776ba60d6506ccadff7b46bf60 RTC: 123430 --- src/build/mkrules/cflags.env.mk | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/build/mkrules/cflags.env.mk b/src/build/mkrules/cflags.env.mk index c805999a558..c90ee0fe1da 100644 --- a/src/build/mkrules/cflags.env.mk +++ b/src/build/mkrules/cflags.env.mk @@ -36,10 +36,12 @@ CFLAGS += -D__HOSTBOOT_MODULE=$(MODULE) endif COMMONFLAGS += $(OPT_LEVEL) -nostdlib +# TODO RTC: 123994 - ELFv2 ABI support (-mabi=elfv1) CFLAGS += $(COMMONFLAGS) -mcpu=power7 -nostdinc -g -mno-vsx -mno-altivec\ -Wall -Werror -mtraceback=no -pipe \ - -ffunction-sections -fdata-sections -ffreestanding -mbig-endian -ASMFLAGS += $(COMMONFLAGS) -mcpu=power7 -mbig-endian + -ffunction-sections -fdata-sections -ffreestanding -mbig-endian \ + -mabi=elfv1 +ASMFLAGS += $(COMMONFLAGS) -mcpu=power7 -mbig-endian -mabi=elfv1 CXXFLAGS += $(CFLAGS) -nostdinc++ -fno-rtti -fno-exceptions -Wall \ -fuse-cxa-atexit LDFLAGS += --nostdlib --sort-common -EB $(COMMONFLAGS) From 8349962a57245fa9d21a7c0302bb4e985e7016a0 Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Thu, 25 Aug 2016 20:22:30 +1000 Subject: [PATCH 07/15] Default to std=gnu++03 Seeing as no C++ dialect was previously selected, GCC < 6 defaulted to GNU++98 as the standard C++ mode. However... it seems that C++03 is a better match for HostBoot code (confirmed by Patrick Williams in https://github.com/open-power/hostboot/pull/62#discussion_r76830612 ) Change-Id: I6661b5b61319c85c2a90926beb6e2662e96dcf06 Signed-off-by: Stewart Smith --- src/build/mkrules/cflags.env.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/build/mkrules/cflags.env.mk b/src/build/mkrules/cflags.env.mk index c90ee0fe1da..971c11b9ad8 100644 --- a/src/build/mkrules/cflags.env.mk +++ b/src/build/mkrules/cflags.env.mk @@ -43,7 +43,7 @@ CFLAGS += $(COMMONFLAGS) -mcpu=power7 -nostdinc -g -mno-vsx -mno-altivec\ -mabi=elfv1 ASMFLAGS += $(COMMONFLAGS) -mcpu=power7 -mbig-endian -mabi=elfv1 CXXFLAGS += $(CFLAGS) -nostdinc++ -fno-rtti -fno-exceptions -Wall \ - -fuse-cxa-atexit + -fuse-cxa-atexit -std=gnu++03 LDFLAGS += --nostdlib --sort-common -EB $(COMMONFLAGS) INCFLAGS = $(addprefix -I, $(INCDIR) ) From 5e6d9e43ab4957c097eca9a20aefae19581f98c8 Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Thu, 25 Aug 2016 19:22:00 +1000 Subject: [PATCH 08/15] fix build error: return-statement with a value, in function returning 'void' Change-Id: I9dc8b698fec95488e209cbc40b928769a26b6de6 Signed-off-by: Stewart Smith --- src/include/usr/devicefw/driverif.H | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/usr/devicefw/driverif.H b/src/include/usr/devicefw/driverif.H index 76b6348e184..cea9e955734 100644 --- a/src/include/usr/devicefw/driverif.H +++ b/src/include/usr/devicefw/driverif.H @@ -266,7 +266,7 @@ namespace DeviceFW TargType i_targetType, deviceOp_t i_regRoute) { - return InvalidParameterType(); // Cause a compile fail if not one of + InvalidParameterType(); // Cause a compile fail if not one of // the explicit template specializations. } From e1cfbc76b28b8b3f9099d9a3ce8d8796d97c89e2 Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Thu, 25 Aug 2016 19:27:04 +1000 Subject: [PATCH 09/15] error: dereferencing type-punned pointer will break strict-aliasing rules Change-Id: I63accd3e881c941736ece4b4498c2c9d06ff8761 Signed-off-by: Stewart Smith --- src/include/usr/hwpf/hwp/mvpd_accessors/getMBvpdAttr.H | 7 +++++++ .../hwpf/hwp/mvpd_accessors/getMBvpdMemoryDataVersion.H | 1 - .../hwpf/hwp/mvpd_accessors/getMBvpdMemoryDataVersion.C | 6 +++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/include/usr/hwpf/hwp/mvpd_accessors/getMBvpdAttr.H b/src/include/usr/hwpf/hwp/mvpd_accessors/getMBvpdAttr.H index e5af2c9e134..7edf2bfa0bc 100755 --- a/src/include/usr/hwpf/hwp/mvpd_accessors/getMBvpdAttr.H +++ b/src/include/usr/hwpf/hwp/mvpd_accessors/getMBvpdAttr.H @@ -227,6 +227,13 @@ namespace getAttrData uint8_t iv_systemType; uint8_t iv_systemType_ext; uint8_t iv_dataVersion; + public: + MBvpdVMKeyword() : iv_version(0),iv_systemType(0), + iv_systemType_ext(0),iv_dataVersion(0) {}; + operator uint32_t() const { + return iv_version << 24 | iv_systemType << 16 | + iv_systemType_ext << 8 | iv_dataVersion; + } }; // Attribute definition struct MBvpdAttrDef diff --git a/src/include/usr/hwpf/hwp/mvpd_accessors/getMBvpdMemoryDataVersion.H b/src/include/usr/hwpf/hwp/mvpd_accessors/getMBvpdMemoryDataVersion.H index f172508cb5e..85460b2107c 100644 --- a/src/include/usr/hwpf/hwp/mvpd_accessors/getMBvpdMemoryDataVersion.H +++ b/src/include/usr/hwpf/hwp/mvpd_accessors/getMBvpdMemoryDataVersion.H @@ -33,7 +33,6 @@ #define _HWP_GETMBVPDMEMDATAVERSION_ #include -#define VM_KEYWORD_DEFAULT_VALUE 0x00000000 // function pointer typedef definition for HWP call support typedef fapi::ReturnCode (*getMBvpdMemoryDataVersion_FP_t) diff --git a/src/usr/hwpf/hwp/mvpd_accessors/getMBvpdMemoryDataVersion.C b/src/usr/hwpf/hwp/mvpd_accessors/getMBvpdMemoryDataVersion.C index 2f83fa234d2..ef6451588a8 100644 --- a/src/usr/hwpf/hwp/mvpd_accessors/getMBvpdMemoryDataVersion.C +++ b/src/usr/hwpf/hwp/mvpd_accessors/getMBvpdMemoryDataVersion.C @@ -50,7 +50,7 @@ fapi::ReturnCode getMBvpdMemoryDataVersion( fapi::ReturnCode l_fapirc; DimmType l_dimmType = ISDIMM; fapi::MBvpdRecord l_record = fapi::MBVPD_RECORD_SPDX; - uint32_t l_vpdMemoryDataVersion = VM_KEYWORD_DEFAULT_VALUE; + MBvpdVMKeyword l_vpdMemoryDataVersion; uint32_t l_bufSize = sizeof(l_vpdMemoryDataVersion); FAPI_DBG("getMBvpdMemoryDataVersion: entry "); @@ -140,8 +140,8 @@ fapi::ReturnCode getMBvpdMemoryDataVersion( } // Check if the format byte in the value returned is in between valid range - if (( ((MBvpdVMKeyword *)(&l_vpdMemoryDataVersion))->iv_version > VM_SUPPORTED_HIGH_VER )|| - ( ((MBvpdVMKeyword *)(&l_vpdMemoryDataVersion))->iv_version == VM_NOT_SUPPORTED )) + if ((l_vpdMemoryDataVersion.iv_version > VM_SUPPORTED_HIGH_VER )|| + (l_vpdMemoryDataVersion.iv_version == VM_NOT_SUPPORTED )) { FAPI_ERR("getMBvpdMemoryDataVersion:" " keyword data returned is invalid : %d ", From 9ef3a94ca5571a1e58aa035613a71c26aa95042c Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Thu, 25 Aug 2016 19:33:42 +1000 Subject: [PATCH 10/15] Change cv_forcedMemPeriodic to uint8_t as bool is invalid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC6 throws the following error: operand type ‘bool*’ is incompatible with argument 1 of ‘__sync_fetch_and_and’ GCC documents that bool is invalid for __sync builtins over at: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html#g_t_005f_005fsync-Builtins " GCC allows any scalar type that is 1, 2, 4 or 8 bytes in size other than the C type _Bool or the C++ type bool" Change-Id: Iab6415348cb19f590921d8ccc5349867fa57a42d Signed-off-by: Stewart Smith --- src/include/kernel/cpumgr.H | 2 +- src/kernel/cpumgr.C | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/include/kernel/cpumgr.H b/src/include/kernel/cpumgr.H index 68f8972784a..6e9b697b837 100644 --- a/src/include/kernel/cpumgr.H +++ b/src/include/kernel/cpumgr.H @@ -215,7 +215,7 @@ class CpuManager */ static uint64_t cv_cpuSeq; - static bool cv_forcedMemPeriodic; //!< force free / coalesce. + static uint8_t cv_forcedMemPeriodic; //!< force free / coalesce. // If a shutdown of all CPUs is requested static bool cv_shutdown_requested; diff --git a/src/kernel/cpumgr.C b/src/kernel/cpumgr.C index b59fa702534..a963336a0b1 100644 --- a/src/kernel/cpumgr.C +++ b/src/kernel/cpumgr.C @@ -50,7 +50,7 @@ cpu_t** CpuManager::cv_cpus[KERNEL_MAX_SUPPORTED_NODES]; bool CpuManager::cv_shutdown_requested = false; uint64_t CpuManager::cv_shutdown_status = 0; size_t CpuManager::cv_cpuSeq = 0; -bool CpuManager::cv_forcedMemPeriodic = false; +uint8_t CpuManager::cv_forcedMemPeriodic = 0; InteractiveDebug CpuManager::cv_interactive_debug; CpuManager::CpuManager() : iv_lastStartTimebase(0) @@ -361,7 +361,7 @@ void CpuManager::executePeriodics(cpu_t * i_cpu) } bool forceMemoryPeriodic = __sync_fetch_and_and(&cv_forcedMemPeriodic, - false); + 0); ++(i_cpu->periodic_count); if((0 == (i_cpu->periodic_count % CPU_PERIODIC_CHECK_MEMORY)) || @@ -461,7 +461,7 @@ size_t CpuManager::getThreadCount() void CpuManager::forceMemoryPeriodic() { - cv_forcedMemPeriodic = true; + cv_forcedMemPeriodic = 1; } From f044df6c7e963365a2f27dec6218e23ed54a7a3b Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Thu, 25 Aug 2016 20:13:11 +1000 Subject: [PATCH 11/15] =?UTF-8?q?error:=20the=20compiler=20can=20assume=20?= =?UTF-8?q?that=20the=20address=20of=20=E2=80=98r=E2=80=99=20will=20never?= =?UTF-8?q?=20be=20NULL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PRDF_ASSERT( &r != NULL ); Change-Id: I2d60075f9e2232512efe45a5c6aa5563f3a565f5 Signed-off-by: Stewart Smith --- src/usr/diag/prdf/common/framework/register/prdfErrorRegister.C | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/usr/diag/prdf/common/framework/register/prdfErrorRegister.C b/src/usr/diag/prdf/common/framework/register/prdfErrorRegister.C index 9ee1358eb3b..ef7279b9deb 100755 --- a/src/usr/diag/prdf/common/framework/register/prdfErrorRegister.C +++ b/src/usr/diag/prdf/common/framework/register/prdfErrorRegister.C @@ -120,8 +120,6 @@ ErrorRegister::ErrorRegister( SCAN_COMM_REGISTER_CLASS & r, ResolutionMap & rm, ErrorRegisterType(), scr(r), scr_rc(SUCCESS), rMap(rm), xNoErrorOnZeroScr(false), xScrId(scrId) { - PRDF_ASSERT( &r != NULL ); - PRDF_ASSERT( &rm != NULL ); } /*---------------------------------------------------------------------*/ From ddb623a5dddf44165f9fb7817a91e6b6a2ab7bb4 Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Thu, 25 Aug 2016 20:07:58 +1000 Subject: [PATCH 12/15] Fix compiler can assume address will never be NULL error with GCC6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So, it turns out that relying on the address of something passed by reference being able to be NULL isn't exactly a good idea, or remotely obvious code. So, instead, do the sane thing and pass a pointer and check it. ../../../../src/usr/diag/prdf/common/framework/register/prdfOperatorRegister.H: In constructor ‘PRDF::AttnTypeRegister::AttnTypeRegister(PRDF::SCAN_COMM_REGISTE R_CLASS&, PRDF::SCAN_COMM_REGISTER_CLASS&, PRDF::SCAN_COMM_REGISTER_CLASS&, PRDF ::SCAN_COMM_REGISTER_CLASS&)’: ../../../../src/usr/diag/prdf/common/framework/register/prdfOperatorRegister.H:4 42:21: error: the compiler can assume that the address of ‘i_check’ will never b e NULL [-Werror=address] iv_check( NULL == &i_check ? &cv_null : &i_check), ~~^~~~~~~~~~~ ../../../../src/usr/diag/prdf/common/framework/register/prdfOperatorRegister.H:4 43:21: error: the compiler can assume that the address of ‘i_recov’ will never b e NULL [-Werror=address] iv_recov( NULL == &i_recov ? &cv_null : &i_recov), ~~^~~~~~~~~~~ ../../../../src/usr/diag/prdf/common/framework/register/prdfOperatorRegister.H:4 44:22: error: the compiler can assume that the address of ‘i_special’ will never be NULL [-Werror=address] iv_special(NULL == &i_special ? &cv_null : &i_special), ~~^~~~~~~~~~~~~ ../../../../src/usr/diag/prdf/common/framework/register/prdfOperatorRegister.H:4 45:22: error: the compiler can assume that the address of ‘i_proccs’ will never be NULL [-Werror=address] iv_proccs( NULL == &i_proccs ? &cv_null : &i_proccs), ~~^~~~~~~~~~~~ Change-Id: Iecd8636da67aac24f64f73fd82b1f7ccbfced900 Signed-off-by: Stewart Smith --- .../framework/register/prdfOperatorRegister.H | 16 ++++++++-------- .../common/framework/register/prdfScanFacility.C | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/usr/diag/prdf/common/framework/register/prdfOperatorRegister.H b/src/usr/diag/prdf/common/framework/register/prdfOperatorRegister.H index b0513e48378..a26a76e05ec 100755 --- a/src/usr/diag/prdf/common/framework/register/prdfOperatorRegister.H +++ b/src/usr/diag/prdf/common/framework/register/prdfOperatorRegister.H @@ -434,15 +434,15 @@ class AttnTypeRegister : public SCAN_COMM_REGISTER_CLASS iv_bs = &iv_iBS; } - AttnTypeRegister( SCAN_COMM_REGISTER_CLASS & i_check, - SCAN_COMM_REGISTER_CLASS & i_recov, - SCAN_COMM_REGISTER_CLASS & i_special, - SCAN_COMM_REGISTER_CLASS & i_proccs ) : + AttnTypeRegister( SCAN_COMM_REGISTER_CLASS *i_check, + SCAN_COMM_REGISTER_CLASS *i_recov, + SCAN_COMM_REGISTER_CLASS *i_special, + SCAN_COMM_REGISTER_CLASS *i_proccs ) : SCAN_COMM_REGISTER_CLASS( ), - iv_check( NULL == &i_check ? &cv_null : &i_check), - iv_recov( NULL == &i_recov ? &cv_null : &i_recov), - iv_special(NULL == &i_special ? &cv_null : &i_special), - iv_proccs( NULL == &i_proccs ? &cv_null : &i_proccs), + iv_check( NULL == i_check ? &cv_null : i_check), + iv_recov( NULL == i_recov ? &cv_null : i_recov), + iv_special(NULL == i_special ? &cv_null : i_special), + iv_proccs( NULL == i_proccs ? &cv_null : i_proccs), iv_iBS(0) // will fully initialize this inside ctor. { uint32_t l_length = 1024; diff --git a/src/usr/diag/prdf/common/framework/register/prdfScanFacility.C b/src/usr/diag/prdf/common/framework/register/prdfScanFacility.C index 5ab5ba718ba..1af0e307e0b 100755 --- a/src/usr/diag/prdf/common/framework/register/prdfScanFacility.C +++ b/src/usr/diag/prdf/common/framework/register/prdfScanFacility.C @@ -168,7 +168,7 @@ SCAN_COMM_REGISTER_CLASS & ScanFacility::GetAttnTypeRegister( SCAN_COMM_REGISTER_CLASS * i_special, SCAN_COMM_REGISTER_CLASS * i_proccs ) { - AttnTypeRegister r(*i_check, *i_recov, *i_special, *i_proccs); + AttnTypeRegister r(i_check, i_recov, i_special, i_proccs); return iv_attnRegFw.get(r); } From ac29c7bedd65e680322f30d08a4f0aa15af7dfd5 Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Wed, 31 Aug 2016 13:07:17 +1000 Subject: [PATCH 13/15] =?UTF-8?q?error:=20in=20C++98=20=E2=80=98l=5FvmVers?= =?UTF-8?q?ionBuf=E2=80=99=20must=20be=20initialized=20by=20constructor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix GCC6 thrown error Change-Id: I9aa508843f54c99ebb59822c39590811423ad0b1 Signed-off-by: Stewart Smith --- src/usr/hwpf/hwp/mvpd_accessors/getMBvpdAttr.C | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/usr/hwpf/hwp/mvpd_accessors/getMBvpdAttr.C b/src/usr/hwpf/hwp/mvpd_accessors/getMBvpdAttr.C index 3739c757134..a4685ad04cb 100755 --- a/src/usr/hwpf/hwp/mvpd_accessors/getMBvpdAttr.C +++ b/src/usr/hwpf/hwp/mvpd_accessors/getMBvpdAttr.C @@ -392,7 +392,7 @@ fapi::ReturnCode getVersion (const fapi::Target & i_mbaTarget, fapi::Target l_mbTarget; fapi::MBvpdKeyword l_keyword = fapi::MBVPD_KEYWORD_VM; // try VM first fapi::MBvpdRecord l_record = fapi::MBVPD_RECORD_SPDX; // default to SPDX - MBvpdVMKeyword l_vmVersionBuf={}; + MBvpdVMKeyword l_vmVersionBuf; uint32_t l_version = 0; uint32_t l_vmBufSize = sizeof(MBvpdVMKeyword); // VM keyword is of 4 bytes. uint16_t l_versionBuf = 0; From 66bc621373898f44e030d3459c6a1e5b4f7fce2b Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Thu, 3 Nov 2016 14:36:19 +1100 Subject: [PATCH 14/15] Use -std=gnu++03 for host g++ invocations Seeing as the ancient GCC on RHEL6 doesn't actually support -std=gnu++03 we have to go through some hoops to detect it (we use the same magic Make as we use in skiboot to do the same) Change-Id: I338560ae2ebdac842c8055c07519d542564c3923 Signed-off-by: Stewart Smith --- src/usr/hwpf/makefile | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/usr/hwpf/makefile b/src/usr/hwpf/makefile index 8d0bb723fc0..ee8cf13d7f3 100644 --- a/src/usr/hwpf/makefile +++ b/src/usr/hwpf/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2011,2015 +# Contributors Listed Below - COPYRIGHT 2011,2016 # [+] International Business Machines Corp. # # @@ -402,18 +402,26 @@ $(call GENTARGET, ${IF_CMP_FLEX_TARGET}) : \ $(C2) " FLEX $(notdir $<)" $(C1)flex -o$@ $^ +try = $(shell set -e; if ($(1)) >/dev/null 2>&1; \ + then echo "$(2)"; \ + else echo "$(3)"; fi ) + +try-cflag = $(call try,$(1) $(2) -x c -c /dev/null -o /dev/null,$(2)) +HOSTCFLAGS:=-O3 +HOSTCFLAGS+=$(call try-cflag,$(HOST_PREFIX)g++,-std=gnu++03) + $(GENDIR)/$(IF_CMP_SUBDIR)/%.host.o: \ ifcompiler/%.C $(IF_COMPILER_H_FILES) \ $(GENDIR)/$(IF_CMP_YACC_H_TARGET) $(C2) " CXX $(notdir $<)" - $(C1)$(CCACHE) $(HOST_PREFIX)g++ -O3 $< -I ifcompiler -I $(GENDIR) \ + $(C1)$(CCACHE) $(HOST_PREFIX)g++ $(HOSTCFLAGS) $< -I ifcompiler -I $(GENDIR) \ -I $(GENDIR)/$(IF_CMP_SUBDIR) \ -I $(ROOTPATH)/src/include/usr/hwpf/hwp -c -o $@ $(GENDIR)/$(IF_CMP_YACC_C_TARGET:.c=.host.o): \ $(GENDIR)/$(IF_CMP_YACC_C_TARGET) $(IF_COMPILER_H_FILES) $(C2) " CXX $(notdir $<)" - $(C1)$(CCACHE) $(HOST_PREFIX)g++ -O3 $< -I ifcompiler -I $(GENDIR) \ + $(C1)$(CCACHE) $(HOST_PREFIX)g++ $(HOSTCFLAGS) $< -I ifcompiler -I $(GENDIR) \ -I $(GENDIR)/$(IF_CMP_SUBDIR) \ -I $(ROOTPATH)/src/include/usr/hwpf/hwp -c -o $@ @@ -421,7 +429,7 @@ $(GENDIR)/$(IF_CMP_FLEX_TARGET:.c=.host.o): \ $(GENDIR)/$(IF_CMP_FLEX_TARGET) $(IF_COMPILER_H_FILES) \ $(GENDIR)/$(IF_CMP_YACC_H_TARGET) $(C2) " CXX $(notdir $<)" - $(C1)$(CCACHE) $(HOST_PREFIX)g++ -O3 -DHOSTBOOT_COMPILE $< -I ifcompiler -I $(GENDIR) \ + $(C1)$(CCACHE) $(HOST_PREFIX)g++ $(HOSTCFLAGS) -DHOSTBOOT_COMPILE $< -I ifcompiler -I $(GENDIR) \ -I $(GENDIR)/$(IF_CMP_SUBDIR) \ -I $(ROOTPATH)/src/include/usr/hwpf/hwp -c -o $@ From 5b77bf654cfa9b155e7d68369e0e5256d3e97a36 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Tue, 27 Jun 2017 18:00:09 +0930 Subject: [PATCH 15/15] kernel: Update assembly for modern binutils From Linux 80f23935cadb ("powerpc: Convert cmp to cmpd in idle enter sequence"): PowerPC's "cmp" instruction has four operands. Normally people write "cmpw" or "cmpd" for the second cmp operand 0 or 1. But, frequently people forget, and write "cmp" with just three operands. With older binutils this is silently accepted as if this was "cmpw", while often "cmpd" is wanted. With newer binutils GAS will complain about this for 64-bit code. For 32-bit code it still silently assumes "cmpw" is what is meant. The first two instances are dealing with SPRs, which are 32-bit, so cmpw is correct. It is not clear what to do in the third use of cmp, but given old toolchains have generated cmpw lets assume that we should maintain the behaviour. Change-Id: Iee5dd5903dcd7ac4028bab0176e08ce3db23b2d5 Signed-off-by: Joel Stanley --- src/kernel/shutdown.S | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/kernel/shutdown.S b/src/kernel/shutdown.S index 629645b26c8..cad5c66b813 100644 --- a/src/kernel/shutdown.S +++ b/src/kernel/shutdown.S @@ -5,7 +5,9 @@ # # OpenPOWER HostBoot Project # -# COPYRIGHT International Business Machines Corp. 2012,2014 +# Contributors Listed Below - COPYRIGHT 2012,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. @@ -92,7 +94,7 @@ kernel_shutdown_ea0_1_mode: ;// as it was the one that updated the cpu_count & lowest_pir ;// barrier - 1 wait for all nodes to report mfspr r10, PIR - cmp cr0, r10, r7 + cmpw cr0, r10, r7 bne+ 2f ;// inside KERNEL_BARRIER below ;// Perform barrier - 1 @@ -131,7 +133,7 @@ kernel_shutdown_ea0_1_mode: addi r8, r8, 8 ;// Check for PIR == r7. mfspr r10, PIR - cmp cr0, r10, r7 + cmpw cr0, r10, r7 beq 3f ;// Increment thread count. 1: @@ -164,7 +166,7 @@ kernel_shutdown_ea0_1_mode: 1: or 1,1,1 ld r11, 0(r8) - cmp cr0, r3, r11 + cmpw cr0, r3, r11 bne+ 1b isync ;// All other threads have left, so wait a little bit...