Commit cd1e0737 authored by James Hogan's avatar James Hogan

MIPS: mipsregs.h: Add read const Cop0 macros

Some Cop0 registers are constant and have no side effects when read.
There is no need for the inline asm to read these to be marked
__volatile__, and doing so prevents them from being removed by the
compiler.

Add a few new accessor macros to handle these registers more efficiently
(especially for the sake of running in a guest where redundant access to
the register may trap to the hypervisor):
  __read_const_32bit_c0_register()
  __read_const_64bit_c0_register()
  __read_const_ulong_c0_register()
Signed-off-by: default avatarJames Hogan <jhogan@kernel.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Maciej W. Rozycki <macro@mips.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/17922/
parent ffe1f935
......@@ -1245,14 +1245,14 @@ do { \
* Macros to access the system control coprocessor
*/
#define __read_32bit_c0_register(source, sel) \
#define ___read_32bit_c0_register(source, sel, vol) \
({ unsigned int __res; \
if (sel == 0) \
__asm__ __volatile__( \
__asm__ vol( \
"mfc0\t%0, " #source "\n\t" \
: "=r" (__res)); \
else \
__asm__ __volatile__( \
__asm__ vol( \
".set\tmips32\n\t" \
"mfc0\t%0, " #source ", " #sel "\n\t" \
".set\tmips0\n\t" \
......@@ -1260,18 +1260,18 @@ do { \
__res; \
})
#define __read_64bit_c0_register(source, sel) \
#define ___read_64bit_c0_register(source, sel, vol) \
({ unsigned long long __res; \
if (sizeof(unsigned long) == 4) \
__res = __read_64bit_c0_split(source, sel); \
__res = __read_64bit_c0_split(source, sel, vol); \
else if (sel == 0) \
__asm__ __volatile__( \
__asm__ vol( \
".set\tmips3\n\t" \
"dmfc0\t%0, " #source "\n\t" \
".set\tmips0" \
: "=r" (__res)); \
else \
__asm__ __volatile__( \
__asm__ vol( \
".set\tmips64\n\t" \
"dmfc0\t%0, " #source ", " #sel "\n\t" \
".set\tmips0" \
......@@ -1279,6 +1279,18 @@ do { \
__res; \
})
#define __read_32bit_c0_register(source, sel) \
___read_32bit_c0_register(source, sel, __volatile__)
#define __read_const_32bit_c0_register(source, sel) \
___read_32bit_c0_register(source, sel,)
#define __read_64bit_c0_register(source, sel) \
___read_64bit_c0_register(source, sel, __volatile__)
#define __read_const_64bit_c0_register(source, sel) \
___read_64bit_c0_register(source, sel,)
#define __write_32bit_c0_register(register, sel, value) \
do { \
if (sel == 0) \
......@@ -1316,6 +1328,11 @@ do { \
(unsigned long) __read_32bit_c0_register(reg, sel) : \
(unsigned long) __read_64bit_c0_register(reg, sel))
#define __read_const_ulong_c0_register(reg, sel) \
((sizeof(unsigned long) == 4) ? \
(unsigned long) __read_const_32bit_c0_register(reg, sel) : \
(unsigned long) __read_const_64bit_c0_register(reg, sel))
#define __write_ulong_c0_register(reg, sel, val) \
do { \
if (sizeof(unsigned long) == 4) \
......@@ -1346,14 +1363,14 @@ do { \
* These versions are only needed for systems with more than 38 bits of
* physical address space running the 32-bit kernel. That's none atm :-)
*/
#define __read_64bit_c0_split(source, sel) \
#define __read_64bit_c0_split(source, sel, vol) \
({ \
unsigned long long __val; \
unsigned long __flags; \
\
local_irq_save(__flags); \
if (sel == 0) \
__asm__ __volatile__( \
__asm__ vol( \
".set\tmips64\n\t" \
"dmfc0\t%L0, " #source "\n\t" \
"dsra\t%M0, %L0, 32\n\t" \
......@@ -1361,7 +1378,7 @@ do { \
".set\tmips0" \
: "=r" (__val)); \
else \
__asm__ __volatile__( \
__asm__ vol( \
".set\tmips64\n\t" \
"dmfc0\t%L0, " #source ", " #sel "\n\t" \
"dsra\t%M0, %L0, 32\n\t" \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment