mirror of https://gitee.com/openkylin/linux.git
MIPS: Netlogic: Add 32-bit support for XLP
Update asm/netlogic/haldefs.h to extend register access functions nlm_{read,write}_reg64() for 32-bit compilation. When compiled for 32-bit the functions will read 64 IO registers with interrupts disabled. Signed-off-by: Jayachandran C <jchandra@broadcom.com> Patchwork: http://patchwork.linux-mips.org/patch/5026/ Acked-by: John Crispin <blogic@openwrt.org>
This commit is contained in:
parent
3c0553e734
commit
1ad4af852b
|
@ -35,14 +35,13 @@
|
|||
#ifndef __NLM_HAL_HALDEFS_H__
|
||||
#define __NLM_HAL_HALDEFS_H__
|
||||
|
||||
#include <linux/irqflags.h> /* for local_irq_disable */
|
||||
|
||||
/*
|
||||
* This file contains platform specific memory mapped IO implementation
|
||||
* and will provide a way to read 32/64 bit memory mapped registers in
|
||||
* all ABIs
|
||||
*/
|
||||
#if !defined(CONFIG_64BIT) && defined(CONFIG_CPU_XLP)
|
||||
#error "o32 compile not supported on XLP yet"
|
||||
#endif
|
||||
/*
|
||||
* For o32 compilation, we have to disable interrupts and enable KX bit to
|
||||
* access 64 bit addresses or data.
|
||||
|
@ -87,13 +86,40 @@ nlm_write_reg(uint64_t base, uint32_t reg, uint32_t val)
|
|||
*addr = val;
|
||||
}
|
||||
|
||||
/*
|
||||
* For o32 compilation, we have to disable interrupts to access 64 bit
|
||||
* registers
|
||||
*
|
||||
* We need to disable interrupts because we save just the lower 32 bits of
|
||||
* registers in interrupt handling. So if we get hit by an interrupt while
|
||||
* using the upper 32 bits of a register, we lose.
|
||||
*/
|
||||
|
||||
static inline uint64_t
|
||||
nlm_read_reg64(uint64_t base, uint32_t reg)
|
||||
{
|
||||
uint64_t addr = base + (reg >> 1) * sizeof(uint64_t);
|
||||
volatile uint64_t *ptr = (volatile uint64_t *)(long)addr;
|
||||
uint64_t val;
|
||||
|
||||
return *ptr;
|
||||
if (sizeof(unsigned long) == 4) {
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
__asm__ __volatile__(
|
||||
".set push" "\n\t"
|
||||
".set mips64" "\n\t"
|
||||
"ld %L0, %1" "\n\t"
|
||||
"dsra32 %M0, %L0, 0" "\n\t"
|
||||
"sll %L0, %L0, 0" "\n\t"
|
||||
".set pop" "\n"
|
||||
: "=r" (val)
|
||||
: "m" (*ptr));
|
||||
local_irq_restore(flags);
|
||||
} else
|
||||
val = *ptr;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -102,7 +128,25 @@ nlm_write_reg64(uint64_t base, uint32_t reg, uint64_t val)
|
|||
uint64_t addr = base + (reg >> 1) * sizeof(uint64_t);
|
||||
volatile uint64_t *ptr = (volatile uint64_t *)(long)addr;
|
||||
|
||||
*ptr = val;
|
||||
if (sizeof(unsigned long) == 4) {
|
||||
unsigned long flags;
|
||||
uint64_t tmp;
|
||||
|
||||
local_irq_save(flags);
|
||||
__asm__ __volatile__(
|
||||
".set push" "\n\t"
|
||||
".set mips64" "\n\t"
|
||||
"dsll32 %L0, %L0, 0" "\n\t"
|
||||
"dsrl32 %L0, %L0, 0" "\n\t"
|
||||
"dsll32 %M0, %M0, 0" "\n\t"
|
||||
"or %L0, %L0, %M0" "\n\t"
|
||||
"sd %L0, %2" "\n\t"
|
||||
".set pop" "\n"
|
||||
: "=r" (tmp)
|
||||
: "0" (val), "m" (*ptr));
|
||||
local_irq_restore(flags);
|
||||
} else
|
||||
*ptr = val;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue