MIPS: Add Kconfig variable for CPUs with unaligned load/store instructions

MIPSR6 CPUs do not support unaligned load/store instructions
(LWL, LWR, SWL, SWR and LDL, LDR, SDL, SDR for 64bit).

Currently the MIPS tree has some special cases to avoid these
instructions, and the code is testing for !CONFIG_CPU_MIPSR6.

This patch declares a new Kconfig variable:
CONFIG_CPU_HAS_LOAD_STORE_LR.
This variable indicates that the CPU supports these instructions.

Then, the patch does the following:
- Carefully selects this option on all CPUs except MIPSR6.
- Switches all the special cases to test for the new variable,
  and inverts the logic:
    '#ifndef CONFIG_CPU_MIPSR6' turns into
    '#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR'
    and vice-versa.

Also, when this variable is NOT selected (e.g. MIPSR6),
CONFIG_GENERIC_CSUM will default to 'y', to compile generic
C checksum code (instead of special assembly code that uses the
unsupported instructions).

This commit should not affect any existing CPU, and is required
for future Lexra CPU support, that misses these instructions too.

Signed-off-by: Yasha Cherikovsky <yasha.che3@gmail.com>
Signed-off-by: Paul Burton <paul.burton@mips.com>
Patchwork: https://patchwork.linux-mips.org/patch/20808/
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paul Burton <paul.burton@mips.com>
Cc: James Hogan <jhogan@kernel.org>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
This commit is contained in:
Yasha Cherikovsky 2018-09-26 14:16:15 +03:00 committed by Paul Burton
parent d9df9fb901
commit 932afdeec1
No known key found for this signature in database
GPG Key ID: 3EA79FACB57500DD
4 changed files with 67 additions and 37 deletions

View File

@ -1150,6 +1150,7 @@ config NO_IOPORT_MAP
config GENERIC_CSUM
bool
default y if !CPU_HAS_LOAD_STORE_LR
config GENERIC_ISA_DMA
bool
@ -1368,6 +1369,7 @@ config CPU_LOONGSON3
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_HUGEPAGES
select CPU_HAS_LOAD_STORE_LR
select WEAK_ORDERING
select WEAK_REORDERING_BEYOND_LLSC
select MIPS_PGD_C0_CONTEXT
@ -1444,6 +1446,7 @@ config CPU_MIPS32_R1
bool "MIPS32 Release 1"
depends on SYS_HAS_CPU_MIPS32_R1
select CPU_HAS_PREFETCH
select CPU_HAS_LOAD_STORE_LR
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
help
@ -1461,6 +1464,7 @@ config CPU_MIPS32_R2
bool "MIPS32 Release 2"
depends on SYS_HAS_CPU_MIPS32_R2
select CPU_HAS_PREFETCH
select CPU_HAS_LOAD_STORE_LR
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_MSA
@ -1479,7 +1483,6 @@ config CPU_MIPS32_R6
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_MSA
select GENERIC_CSUM
select HAVE_KVM
select MIPS_O32_FP64_SUPPORT
help
@ -1492,6 +1495,7 @@ config CPU_MIPS64_R1
bool "MIPS64 Release 1"
depends on SYS_HAS_CPU_MIPS64_R1
select CPU_HAS_PREFETCH
select CPU_HAS_LOAD_STORE_LR
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
@ -1511,6 +1515,7 @@ config CPU_MIPS64_R2
bool "MIPS64 Release 2"
depends on SYS_HAS_CPU_MIPS64_R2
select CPU_HAS_PREFETCH
select CPU_HAS_LOAD_STORE_LR
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
@ -1532,7 +1537,6 @@ config CPU_MIPS64_R6
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_MSA
select GENERIC_CSUM
select MIPS_O32_FP64_SUPPORT if 32BIT || MIPS32_O32
select HAVE_KVM
help
@ -1545,6 +1549,7 @@ config CPU_R3000
bool "R3000"
depends on SYS_HAS_CPU_R3000
select CPU_HAS_WB
select CPU_HAS_LOAD_STORE_LR
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
help
@ -1559,12 +1564,14 @@ config CPU_TX39XX
bool "R39XX"
depends on SYS_HAS_CPU_TX39XX
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_HAS_LOAD_STORE_LR
config CPU_VR41XX
bool "R41xx"
depends on SYS_HAS_CPU_VR41XX
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_HAS_LOAD_STORE_LR
help
The options selects support for the NEC VR4100 series of processors.
Only choose this option if you have one of these processors as a
@ -1576,6 +1583,7 @@ config CPU_R4300
depends on SYS_HAS_CPU_R4300
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_HAS_LOAD_STORE_LR
help
MIPS Technologies R4300-series processors.
@ -1585,6 +1593,7 @@ config CPU_R4X00
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HUGEPAGES
select CPU_HAS_LOAD_STORE_LR
help
MIPS Technologies R4000-series processors other than 4300, including
the R4000, R4400, R4600, and 4700.
@ -1593,6 +1602,7 @@ config CPU_TX49XX
bool "R49XX"
depends on SYS_HAS_CPU_TX49XX
select CPU_HAS_PREFETCH
select CPU_HAS_LOAD_STORE_LR
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HUGEPAGES
@ -1603,6 +1613,7 @@ config CPU_R5000
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HUGEPAGES
select CPU_HAS_LOAD_STORE_LR
help
MIPS Technologies R5000-series processors other than the Nevada.
@ -1612,6 +1623,7 @@ config CPU_R5432
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HUGEPAGES
select CPU_HAS_LOAD_STORE_LR
config CPU_R5500
bool "R5500"
@ -1619,6 +1631,7 @@ config CPU_R5500
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HUGEPAGES
select CPU_HAS_LOAD_STORE_LR
help
NEC VR5500 and VR5500A series processors implement 64-bit MIPS IV
instruction set.
@ -1629,6 +1642,7 @@ config CPU_NEVADA
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HUGEPAGES
select CPU_HAS_LOAD_STORE_LR
help
QED / PMC-Sierra RM52xx-series ("Nevada") processors.
@ -1636,6 +1650,7 @@ config CPU_R8000
bool "R8000"
depends on SYS_HAS_CPU_R8000
select CPU_HAS_PREFETCH
select CPU_HAS_LOAD_STORE_LR
select CPU_SUPPORTS_64BIT_KERNEL
help
MIPS Technologies R8000 processors. Note these processors are
@ -1645,6 +1660,7 @@ config CPU_R10000
bool "R10000"
depends on SYS_HAS_CPU_R10000
select CPU_HAS_PREFETCH
select CPU_HAS_LOAD_STORE_LR
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
@ -1656,6 +1672,7 @@ config CPU_RM7000
bool "RM7000"
depends on SYS_HAS_CPU_RM7000
select CPU_HAS_PREFETCH
select CPU_HAS_LOAD_STORE_LR
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
@ -1664,6 +1681,7 @@ config CPU_RM7000
config CPU_SB1
bool "SB1"
depends on SYS_HAS_CPU_SB1
select CPU_HAS_LOAD_STORE_LR
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
@ -1674,6 +1692,7 @@ config CPU_CAVIUM_OCTEON
bool "Cavium Octeon processor"
depends on SYS_HAS_CPU_CAVIUM_OCTEON
select CPU_HAS_PREFETCH
select CPU_HAS_LOAD_STORE_LR
select CPU_SUPPORTS_64BIT_KERNEL
select WEAK_ORDERING
select CPU_SUPPORTS_HIGHMEM
@ -1703,6 +1722,7 @@ config CPU_BMIPS
select WEAK_ORDERING
select CPU_SUPPORTS_HIGHMEM
select CPU_HAS_PREFETCH
select CPU_HAS_LOAD_STORE_LR
select CPU_SUPPORTS_CPUFREQ
select MIPS_EXTERNAL_TIMER
help
@ -1711,6 +1731,7 @@ config CPU_BMIPS
config CPU_XLR
bool "Netlogic XLR SoC"
depends on SYS_HAS_CPU_XLR
select CPU_HAS_LOAD_STORE_LR
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
@ -1729,6 +1750,7 @@ config CPU_XLP
select WEAK_ORDERING
select WEAK_REORDERING_BEYOND_LLSC
select CPU_HAS_PREFETCH
select CPU_HAS_LOAD_STORE_LR
select CPU_MIPSR2
select CPU_SUPPORTS_HUGEPAGES
select MIPS_ASID_BITS_VARIABLE
@ -1834,12 +1856,14 @@ config CPU_LOONGSON2
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_HUGEPAGES
select ARCH_HAS_PHYS_TO_DMA
select CPU_HAS_LOAD_STORE_LR
config CPU_LOONGSON1
bool
select CPU_MIPS32
select CPU_MIPSR1
select CPU_HAS_PREFETCH
select CPU_HAS_LOAD_STORE_LR
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_CPUFREQ
@ -2453,6 +2477,13 @@ config XKS01
config CPU_HAS_RIXI
bool
config CPU_HAS_LOAD_STORE_LR
bool
help
CPU has support for unaligned load and store instructions:
LWL, LWR, SWL, SWR (Load/store word left/right).
LDL, LDR, SDL, SDR (Load/store doubleword left/right, for 64bit systems).
#
# Vectored interrupt mode is an R2 feature
#

View File

@ -130,7 +130,7 @@ do { \
: "r" (addr), "i" (-EFAULT)); \
} while(0)
#ifndef CONFIG_CPU_MIPSR6
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
#define _LoadW(addr, value, res, type) \
do { \
__asm__ __volatile__ ( \
@ -151,8 +151,8 @@ do { \
: "r" (addr), "i" (-EFAULT)); \
} while(0)
#else
/* MIPSR6 has no lwl instruction */
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
/* For CPUs without lwl instruction */
#define _LoadW(addr, value, res, type) \
do { \
__asm__ __volatile__ ( \
@ -186,7 +186,7 @@ do { \
: "r" (addr), "i" (-EFAULT)); \
} while(0)
#endif /* CONFIG_CPU_MIPSR6 */
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
#define _LoadHWU(addr, value, res, type) \
do { \
@ -212,7 +212,7 @@ do { \
: "r" (addr), "i" (-EFAULT)); \
} while(0)
#ifndef CONFIG_CPU_MIPSR6
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
#define _LoadWU(addr, value, res, type) \
do { \
__asm__ __volatile__ ( \
@ -255,8 +255,8 @@ do { \
: "r" (addr), "i" (-EFAULT)); \
} while(0)
#else
/* MIPSR6 has not lwl and ldl instructions */
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
/* For CPUs without lwl and ldl instructions */
#define _LoadWU(addr, value, res, type) \
do { \
__asm__ __volatile__ ( \
@ -339,7 +339,7 @@ do { \
: "r" (addr), "i" (-EFAULT)); \
} while(0)
#endif /* CONFIG_CPU_MIPSR6 */
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
#define _StoreHW(addr, value, res, type) \
@ -365,7 +365,7 @@ do { \
: "r" (value), "r" (addr), "i" (-EFAULT));\
} while(0)
#ifndef CONFIG_CPU_MIPSR6
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
#define _StoreW(addr, value, res, type) \
do { \
__asm__ __volatile__ ( \
@ -406,8 +406,7 @@ do { \
: "r" (value), "r" (addr), "i" (-EFAULT)); \
} while(0)
#else
/* MIPSR6 has no swl and sdl instructions */
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
#define _StoreW(addr, value, res, type) \
do { \
__asm__ __volatile__ ( \
@ -483,7 +482,7 @@ do { \
: "memory"); \
} while(0)
#endif /* CONFIG_CPU_MIPSR6 */
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
#else /* __BIG_ENDIAN */
@ -509,7 +508,7 @@ do { \
: "r" (addr), "i" (-EFAULT)); \
} while(0)
#ifndef CONFIG_CPU_MIPSR6
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
#define _LoadW(addr, value, res, type) \
do { \
__asm__ __volatile__ ( \
@ -530,8 +529,8 @@ do { \
: "r" (addr), "i" (-EFAULT)); \
} while(0)
#else
/* MIPSR6 has no lwl instruction */
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
/* For CPUs without lwl instruction */
#define _LoadW(addr, value, res, type) \
do { \
__asm__ __volatile__ ( \
@ -565,7 +564,7 @@ do { \
: "r" (addr), "i" (-EFAULT)); \
} while(0)
#endif /* CONFIG_CPU_MIPSR6 */
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
#define _LoadHWU(addr, value, res, type) \
@ -592,7 +591,7 @@ do { \
: "r" (addr), "i" (-EFAULT)); \
} while(0)
#ifndef CONFIG_CPU_MIPSR6
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
#define _LoadWU(addr, value, res, type) \
do { \
__asm__ __volatile__ ( \
@ -635,8 +634,8 @@ do { \
: "r" (addr), "i" (-EFAULT)); \
} while(0)
#else
/* MIPSR6 has not lwl and ldl instructions */
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
/* For CPUs without lwl and ldl instructions */
#define _LoadWU(addr, value, res, type) \
do { \
__asm__ __volatile__ ( \
@ -718,7 +717,7 @@ do { \
: "=&r" (value), "=r" (res) \
: "r" (addr), "i" (-EFAULT)); \
} while(0)
#endif /* CONFIG_CPU_MIPSR6 */
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
#define _StoreHW(addr, value, res, type) \
do { \
@ -743,7 +742,7 @@ do { \
: "r" (value), "r" (addr), "i" (-EFAULT));\
} while(0)
#ifndef CONFIG_CPU_MIPSR6
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
#define _StoreW(addr, value, res, type) \
do { \
__asm__ __volatile__ ( \
@ -784,8 +783,8 @@ do { \
: "r" (value), "r" (addr), "i" (-EFAULT)); \
} while(0)
#else
/* MIPSR6 has no swl and sdl instructions */
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
/* For CPUs without swl and sdl instructions */
#define _StoreW(addr, value, res, type) \
do { \
__asm__ __volatile__ ( \
@ -861,7 +860,7 @@ do { \
: "memory"); \
} while(0)
#endif /* CONFIG_CPU_MIPSR6 */
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
#endif
#define LoadHWU(addr, value, res) _LoadHWU(addr, value, res, kernel)

View File

@ -297,7 +297,7 @@
and t0, src, ADDRMASK
PREFS( 0, 2*32(src) )
PREFD( 1, 2*32(dst) )
#ifndef CONFIG_CPU_MIPSR6
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
bnez t1, .Ldst_unaligned\@
nop
bnez t0, .Lsrc_unaligned_dst_aligned\@
@ -385,7 +385,7 @@
bne rem, len, 1b
.set noreorder
#ifndef CONFIG_CPU_MIPSR6
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
/*
* src and dst are aligned, need to copy rem bytes (rem < NBYTES)
* A loop would do only a byte at a time with possible branch
@ -487,7 +487,7 @@
bne len, rem, 1b
.set noreorder
#endif /* !CONFIG_CPU_MIPSR6 */
#endif /* CONFIG_CPU_HAS_LOAD_STORE_LR */
.Lcopy_bytes_checklen\@:
beqz len, .Ldone\@
nop
@ -516,7 +516,7 @@
jr ra
nop
#ifdef CONFIG_CPU_MIPSR6
#ifndef CONFIG_CPU_HAS_LOAD_STORE_LR
.Lcopy_unaligned_bytes\@:
1:
COPY_BYTE(0)
@ -530,7 +530,7 @@
ADD src, src, 8
b 1b
ADD dst, dst, 8
#endif /* CONFIG_CPU_MIPSR6 */
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
.if __memcpy == 1
END(memcpy)
.set __memcpy, 0

View File

@ -112,7 +112,7 @@
.set at
#endif
#ifndef CONFIG_CPU_MIPSR6
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
R10KCBARRIER(0(ra))
#ifdef __MIPSEB__
EX(LONG_S_L, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */
@ -122,7 +122,7 @@
PTR_SUBU a0, t0 /* long align ptr */
PTR_ADDU a2, t0 /* correct size */
#else /* CONFIG_CPU_MIPSR6 */
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
#define STORE_BYTE(N) \
EX(sb, a1, N(a0), .Lbyte_fixup\@); \
beqz t0, 0f; \
@ -145,7 +145,7 @@
ori a0, STORMASK
xori a0, STORMASK
PTR_ADDIU a0, STORSIZE
#endif /* CONFIG_CPU_MIPSR6 */
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
1: ori t1, a2, 0x3f /* # of full blocks */
xori t1, 0x3f
beqz t1, .Lmemset_partial\@ /* no block to fill */
@ -185,7 +185,7 @@
andi a2, STORMASK /* At most one long to go */
beqz a2, 1f
#ifndef CONFIG_CPU_MIPSR6
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
PTR_ADDU a0, a2 /* What's left */
R10KCBARRIER(0(ra))
#ifdef __MIPSEB__
@ -230,7 +230,7 @@
.hidden __memset
.endif
#ifdef CONFIG_CPU_MIPSR6
#ifndef CONFIG_CPU_HAS_LOAD_STORE_LR
.Lbyte_fixup\@:
/*
* unset_bytes = (#bytes - (#unaligned bytes)) - (-#unaligned bytes remaining + 1) + 1
@ -239,7 +239,7 @@
PTR_SUBU a2, t0
jr ra
PTR_ADDIU a2, 1
#endif /* CONFIG_CPU_MIPSR6 */
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
.Lfirst_fixup\@:
/* unset_bytes already in a2 */