After commita35707c3d8
("riscv: add memory-type errata for T-Head"), builds with LLVM's integrated assembler fail like: In file included from arch/riscv/kernel/asm-offsets.c:10: In file included from ./include/linux/mm.h:29: In file included from ./include/linux/pgtable.h:6: In file included from ./arch/riscv/include/asm/pgtable.h:114: ./arch/riscv/include/asm/pgtable-64.h:210:2: error: invalid input constraint '0' in asm ALT_THEAD_PMA(prot_val); ^ ./arch/riscv/include/asm/errata_list.h:88:4: note: expanded from macro 'ALT_THEAD_PMA' : "0"(_val), \ ^ This was reported upstream to LLVM where Jessica pointed out a couple of issues with the existing implementation of ALT_THEAD_PMA: * t3 is modified but not listed in the clobbers list. * "+r"(_val) marks _val as both an input and output of the asm but then "0"(_val) marks _val as an input matching constraint, which does not make much sense in this situation, as %1 is not actually used in the asm and matching constraints are designed to be used for different inputs that need to use the same register. Drop the matching contraint and shift all the operands by one, as %1 is unused, and mark t3 as clobbered. This resolves the build error and goes not cause any problems with GNU as. Fixes:a35707c3d8
("riscv: add memory-type errata for T-Head") Link: https://github.com/ClangBuiltLinux/linux/issues/1641 Link: https://github.com/llvm/llvm-project/issues/55514 Link: https://gcc.gnu.org/onlinedocs/gcc/Simple-Constraints.html Suggested-by: Jessica Clarke <jrtc27@jrtc27.com> Signed-off-by: Nathan Chancellor <nathan@kernel.org> Reviewed-by: Nick Desaulniers <ndesaulniers@google.com> Reviewed-by: Heiko Stuebner <heiko@sntech.de> Tested-by: Heiko Stuebner <heiko@sntech.de> Link: https://lore.kernel.org/r/20220518184529.454008-1-nathan@kernel.org Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
98 lines
2.7 KiB
C
98 lines
2.7 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright (C) 2021 Sifive.
|
|
*/
|
|
#ifndef ASM_ERRATA_LIST_H
|
|
#define ASM_ERRATA_LIST_H
|
|
|
|
#include <asm/alternative.h>
|
|
#include <asm/vendorid_list.h>
|
|
|
|
#ifdef CONFIG_ERRATA_SIFIVE
|
|
#define ERRATA_SIFIVE_CIP_453 0
|
|
#define ERRATA_SIFIVE_CIP_1200 1
|
|
#define ERRATA_SIFIVE_NUMBER 2
|
|
#endif
|
|
|
|
#ifdef CONFIG_ERRATA_THEAD
|
|
#define ERRATA_THEAD_PBMT 0
|
|
#define ERRATA_THEAD_NUMBER 1
|
|
#endif
|
|
|
|
#define CPUFEATURE_SVPBMT 0
|
|
#define CPUFEATURE_NUMBER 1
|
|
|
|
#ifdef __ASSEMBLY__
|
|
|
|
#define ALT_INSN_FAULT(x) \
|
|
ALTERNATIVE(__stringify(RISCV_PTR do_trap_insn_fault), \
|
|
__stringify(RISCV_PTR sifive_cip_453_insn_fault_trp), \
|
|
SIFIVE_VENDOR_ID, ERRATA_SIFIVE_CIP_453, \
|
|
CONFIG_ERRATA_SIFIVE_CIP_453)
|
|
|
|
#define ALT_PAGE_FAULT(x) \
|
|
ALTERNATIVE(__stringify(RISCV_PTR do_page_fault), \
|
|
__stringify(RISCV_PTR sifive_cip_453_page_fault_trp), \
|
|
SIFIVE_VENDOR_ID, ERRATA_SIFIVE_CIP_453, \
|
|
CONFIG_ERRATA_SIFIVE_CIP_453)
|
|
#else /* !__ASSEMBLY__ */
|
|
|
|
#define ALT_FLUSH_TLB_PAGE(x) \
|
|
asm(ALTERNATIVE("sfence.vma %0", "sfence.vma", SIFIVE_VENDOR_ID, \
|
|
ERRATA_SIFIVE_CIP_1200, CONFIG_ERRATA_SIFIVE_CIP_1200) \
|
|
: : "r" (addr) : "memory")
|
|
|
|
/*
|
|
* _val is marked as "will be overwritten", so need to set it to 0
|
|
* in the default case.
|
|
*/
|
|
#define ALT_SVPBMT_SHIFT 61
|
|
#define ALT_THEAD_PBMT_SHIFT 59
|
|
#define ALT_SVPBMT(_val, prot) \
|
|
asm(ALTERNATIVE_2("li %0, 0\t\nnop", \
|
|
"li %0, %1\t\nslli %0,%0,%3", 0, \
|
|
CPUFEATURE_SVPBMT, CONFIG_RISCV_ISA_SVPBMT, \
|
|
"li %0, %2\t\nslli %0,%0,%4", THEAD_VENDOR_ID, \
|
|
ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT) \
|
|
: "=r"(_val) \
|
|
: "I"(prot##_SVPBMT >> ALT_SVPBMT_SHIFT), \
|
|
"I"(prot##_THEAD >> ALT_THEAD_PBMT_SHIFT), \
|
|
"I"(ALT_SVPBMT_SHIFT), \
|
|
"I"(ALT_THEAD_PBMT_SHIFT))
|
|
|
|
#ifdef CONFIG_ERRATA_THEAD_PBMT
|
|
/*
|
|
* IO/NOCACHE memory types are handled together with svpbmt,
|
|
* so on T-Head chips, check if no other memory type is set,
|
|
* and set the non-0 PMA type if applicable.
|
|
*/
|
|
#define ALT_THEAD_PMA(_val) \
|
|
asm volatile(ALTERNATIVE( \
|
|
"nop\n\t" \
|
|
"nop\n\t" \
|
|
"nop\n\t" \
|
|
"nop\n\t" \
|
|
"nop\n\t" \
|
|
"nop\n\t" \
|
|
"nop", \
|
|
"li t3, %1\n\t" \
|
|
"slli t3, t3, %3\n\t" \
|
|
"and t3, %0, t3\n\t" \
|
|
"bne t3, zero, 2f\n\t" \
|
|
"li t3, %2\n\t" \
|
|
"slli t3, t3, %3\n\t" \
|
|
"or %0, %0, t3\n\t" \
|
|
"2:", THEAD_VENDOR_ID, \
|
|
ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT) \
|
|
: "+r"(_val) \
|
|
: "I"(_PAGE_MTMASK_THEAD >> ALT_THEAD_PBMT_SHIFT), \
|
|
"I"(_PAGE_PMA_THEAD >> ALT_THEAD_PBMT_SHIFT), \
|
|
"I"(ALT_THEAD_PBMT_SHIFT) \
|
|
: "t3")
|
|
#else
|
|
#define ALT_THEAD_PMA(_val)
|
|
#endif
|
|
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
#endif
|