This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi list,This is a proposal for a ld patch that implements a work-around to a STMicroelectronics hardware erratum.
* Description of the problem: The STM32L4x6xx family of microcontroller suffers from a memory controller ('FMC') limitation, described in the publicly available document: <www.st.com/st-web-ui/static/active/en/resource/technical/document/errata_sheet/DM00111498.pdf> See : "Read burst access of 9 words or more is not supported by FMC" for the full the description. In a few words, the multiple loads that are issued from the code (ldm, vldm) through the FMC may receive corrupt data when more than 9 words are involved. Access should be limited to chunks of 8 words. * Impact of the problem: The STM32L476 product is available to anybody worldwide either directly through ST or through the distributors. As there is no plan for a revision of that silicon and it will live for at least 10 years, in the end tens of millions of parts or even more are potentially affected. * Possible solutions to the problem: The compilation tools can be changed to limit their code generation to appropriate multiple load sizes, but this solution does not account for existing libraries and third-party software libraries that cannot be recompiled. An alternative solution is to create a specific treatment at the linker level to identify and divert the faulty instruction and divert it to a correct sequence. Thus it can deal with any pre-existing .o or .a contribution that may expose the issue and produce a fixed, final executable. * Purpose of the patch: The patch is disabled by default and has no observable impact. When it is enabled, it checks if the expected architecture is used and warns otherwise. It scans the code sections for faulty ldm and vldm instructions and when one is detected it creates a veneer that contains a fixed sequence and a branch back to the following instruction, and replaces the original instruction to a branch to that veneer. The veneer contents are emitted based on the original instruction details, depending on the instruction family (9 cases for ldm, 3 for vldm) and various other details (PC being or not being part of the set of restored registers, write-back of the base register, etc..) * Implementation: The implementation is strongly inspired by the so-called VFPV11 work-around, and works in a similar way with regard to the veneer management. The only specificities are the specific conditions detection, and the emitted code supported by quite a few instruction encoding helpers. A deviation with regard to VFPV11 is that the veneers are not created in a dedicated section (as it was for .vfp11_veneer), but in a .text.stm32l4xx_veneer that is naturally treated by the linker scripts. * Testing: - Unit tests have been written to cover the veneer emission code for all ldm and vldm sub-cases, the IT block logic detection, the detection of specific IT block issues, the detection of branch overflows when creating veneers; and are part of the proposed change. - No regression on ld test suite under arm-none-eabi and arm-linux-gnueabi configuration - Our standard QA has been run with a 4_9-2015q2-20150609 Linaro embedded compiler patched with this linker changes, in two variants: default linker settings and fix enabled, forcing the linker warnings to be turned into hard errors. Our QA contains various commercial tests suites, industrial benchmarks and proprietary ST applications. We have not observed behavioral changes with and without the fixes, nor detected the occurrence of unhandled sequences (IT blocks limitations), nor observed branch limitations. - Hardware testing has been done on as STM32L476 "Discovery kit". * Impact: - The code size increase has been measured to 1.5% geometric mean increase on our whole set of QA applications, with a peak at 3.2%. * Limitations: - The veneer sizes are dimensioned to the maximum sequence that might be generated from a given instruction class (4 words for ldm, 6 for vldm), but the actual sequence may be smaller. - Faulty ldm or vldm that are part of IT blocks are transformed if and only if they appear as the last instruction of the IT block, where the creation of a jump is the only legitimate place, otherwise the linker emits a warning and does nothing. - In ldmdb cases when the pc is involved in the restored register list, the memory access order is reversed compared to what it was originally. Changelogs: bfd/ChangeLog: 2015-09-17 Laurent Alfonsi <laurent.alfonsi@st.com> Christophe Monat <christophe.monat@st.com> * bfd-in2.h: Regenerate. * bfd-in.h (bfd_arm_stm32l4xx_fix): New enum. Specify how STM32L4XX instruction scanning should be done. (bfd_elf32_arm_set_stm32l4xx_fix) (bfd_elf32_arm_stm32l4xx_erratum_scan) (bfd_elf32_arm_stm32l4xx_fix_veneer_locations): Add prototypes. (bfd_elf32_arm_set_target_relocs): Add stm32l4xx fix type argument to prototype. * elf32-arm.c (STM32L4XX_ERRATUM_VENEER_SECTION_NAME) (STM32L4XX_ERRATUM_VENEER_ENTRY_NAME): Define macros. (elf32_stm32l4xx_erratum_type): New enum. (elf32_stm32l4xx_erratum_list): New struct. List of veneers or jumps to veneers. (_arm_elf_section_data): Add stm32l4xx_erratumcount, stm32l4xx_erratumlist. (elf32_arm_link_hash_table): Add stm32l4xx_erratum_glue_size, stm32l4xx_fix and num_stm32l4xx_fixes fields. (ctz): New function. (popcount): New function. (elf32_arm_link_hash_table_create): Initialize stm32l4xx_fix. (put_thumb2_insn): New function. (STM32L4XX_ERRATUM_LDM_VENEER_SIZE): Define. Size of a veneer for LDM instructions. (STM32L4XX_ERRATUM_VLDM_VENEER_SIZE): Define. Size of a veneer for VLDM instructions. (bfd_elf32_arm_allocate_interworking_sections): Initialise erratum glue section. (record_stm32l4xx_erratum_veneer) : New function. Create a single veneer, and its associated symbols. (bfd_elf32_arm_add_glue_sections_to_bfd): Add STM32L4XX erratum glue. (bfd_elf32_arm_set_stm32l4xx_fix): New function. Set the type of erratum workaround required. (bfd_elf32_arm_stm32l4xx_fix_veneer_locations): New function. Find out where veneers and branches to veneers have been placed in virtual memory after layout. (is_thumb2_ldmia): New function. (is_thumb2_ldmdb): Likewise. (is_thumb2_vldm ): Likewise. (stm32l4xx_need_create_replacing_stub): New function. Decide if a veneer must be emitted. (bfd_elf32_arm_stm32l4xx_erratum_scan): Scan the sections of an input BFD for potential erratum-triggering insns. Record results. (bfd_elf32_arm_set_target_relocs): Set stm32l4xx_fix field in global hash table. (elf32_arm_size_dynamic_sections): Collect glue information. (create_instruction_branch_absolute): New function. (create_instruction_ldmia): Likewise. (create_instruction_ldmdb): Likewise. (create_instruction_mov): Likewise. (create_instruction_sub): Likewise. (create_instruction_vldmia): Likewise. (create_instruction_vldmdb): Likewise. (create_instruction_udf_w): Likewise. (create_instruction_udf): Likewise. (push_thumb2_insn32): Likewise. (push_thumb2_insn16): Likewise. (stm32l4xx_fill_stub_udf): Likewise. (stm32l4xx_create_replacing_stub_ldmia): New function. Expands the replacing stub for ldmia instructions. (stm32l4xx_create_replacing_stub_ldmdb): Likewise for ldmdb. (stm32l4xx_create_replacing_stub_vldm): Likewise for vldm. (stm32l4xx_create_replacing_stub): New function. Dispatches the stub emission to the appropriate functions. (elf32_arm_write_section): Output veneers, and branches to veneers. ld/ChangeLog: 2015-09-17 Laurent Alfonsi <laurent.alfonsi@st.com> Christophe Monat <christophe.monat@st.com> * ld.texinfo: Description of the STM32L4xx erratum workaround. * emultempl/armelf.em (stm32l4xx_fix): New. (arm_elf_before_allocation): Choose the type of fix, scan for erratum. (gld${EMULATION_NAME}_finish): Fix veneer locations. (arm_elf_create_output_section_statements): Propagate stm32l4xx_fix value. (PARSE_AND_LIST_PROLOGUE): Define OPTION_STM32L4XX_FIX. (PARSE_AND_LIST_LONGOPTS): Add entry for handling --fix-stm32l4xx-629360. (PARSE_AND_LIST_OPTION): Add entry for helping on --fix-stm32l4xx-629360. (PARSE_AND_LIST_ARGS_CASES): Treat OPTION_STM32L4XX_FIX. ld/testsuite/ChangeLog: 2015-09-17 Laurent Alfonsi <laurent.alfonsi@st.com> Christophe Monat <christophe.monat@st.com> * ld-arm/arm-elf.exp (armelftests_common): Add STM32L4XX tests. * ld-arm/stm32l4xx-cannot-fix-far-ldm.d: New. * ld-arm/stm32l4xx-cannot-fix-far-ldm.s: Likewise. * ld-arm/stm32l4xx-cannot-fix-it-block.d: Likewise. * ld-arm/stm32l4xx-cannot-fix-it-block.s: Likewise. * ld-arm/stm32l4xx-fix-all.d: Likewise. * ld-arm/stm32l4xx-fix-all.s: Likewise. * ld-arm/stm32l4xx-fix-it-block.d: Likewise. * ld-arm/stm32l4xx-fix-it-block.s: Likewise. * ld-arm/stm32l4xx-fix-ldm.d: Likewise. * ld-arm/stm32l4xx-fix-ldm.s: Likewise. * ld-arm/stm32l4xx-fix-vldm.d: Likewise. * ld-arm/stm32l4xx-fix-vldm.s: Likewise. Patch attached, waiting for your review. --C
Attachment:
0001-Fix-for-STMicroelectronics-hardware-erratum-STM32L4X.patch
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |