Commit 61a6fccc authored by Huacai Chen's avatar Huacai Chen
Browse files

LoongArch: Add unaligned access support



Loongson-2 series (Loongson-2K500, Loongson-2K1000) don't support
unaligned access in hardware, while Loongson-3 series (Loongson-3A5000,
Loongson-3C5000) are configurable whether support unaligned access in
hardware. This patch add unaligned access emulation for those LoongArch
processors without hardware support.

Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
parent dbcd7f5f
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -433,8 +433,8 @@ ignore-unaligned-usertrap

On architectures where unaligned accesses cause traps, and where this
feature is supported (``CONFIG_SYSCTL_ARCH_UNALIGN_NO_WARN``;
currently, ``arc`` and ``ia64``), controls whether all unaligned traps
are logged.
currently, ``arc``, ``ia64`` and ``loongarch``), controls whether all
unaligned traps are logged.

= =============================================================
0 Log all unaligned accesses.
@@ -1457,8 +1457,8 @@ unaligned-trap

On architectures where unaligned accesses cause traps, and where this
feature is supported (``CONFIG_SYSCTL_ARCH_UNALIGN_ALLOW``; currently,
``arc`` and ``parisc``), controls whether unaligned traps are caught
and emulated (instead of failing).
``arc``, ``parisc`` and ``loongarch``), controls whether unaligned traps
are caught and emulated (instead of failing).

= ========================================================
0 Do not emulate unaligned accesses.
+2 −0
Original line number Diff line number Diff line
@@ -121,6 +121,8 @@ config LOONGARCH
	select RTC_LIB
	select SMP
	select SPARSE_IRQ
	select SYSCTL_ARCH_UNALIGN_ALLOW
	select SYSCTL_ARCH_UNALIGN_NO_WARN
	select SYSCTL_EXCEPTION_TRACE
	select SWIOTLB
	select TRACE_IRQFLAGS_SUPPORT
+14 −0
Original line number Diff line number Diff line
@@ -76,6 +76,10 @@ enum reg2i12_op {
	ldbu_op		= 0xa8,
	ldhu_op		= 0xa9,
	ldwu_op		= 0xaa,
	flds_op		= 0xac,
	fsts_op		= 0xad,
	fldd_op		= 0xae,
	fstd_op		= 0xaf,
};

enum reg2i14_op {
@@ -146,6 +150,10 @@ enum reg3_op {
	ldxbu_op	= 0x7040,
	ldxhu_op	= 0x7048,
	ldxwu_op	= 0x7050,
	fldxs_op	= 0x7060,
	fldxd_op	= 0x7068,
	fstxs_op	= 0x7070,
	fstxd_op	= 0x7078,
	amswapw_op	= 0x70c0,
	amswapd_op	= 0x70c1,
	amaddw_op	= 0x70c2,
@@ -566,4 +574,10 @@ static inline void emit_##NAME(union loongarch_instruction *insn, \

DEF_EMIT_REG3SA2_FORMAT(alsld, alsld_op)

struct pt_regs;

void emulate_load_store_insn(struct pt_regs *regs, void __user *addr, unsigned int *pc);
unsigned long unaligned_read(void __user *addr, void *value, unsigned long n, bool sign);
unsigned long unaligned_write(void __user *addr, unsigned long value, unsigned long n);

#endif /* _ASM_INST_H */
+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ struct thread_info {
#define INIT_THREAD_INFO(tsk)			\
{						\
	.task		= &tsk,			\
	.flags		= 0,			\
	.flags		= _TIF_FIXADE,		\
	.cpu		= 0,			\
	.preempt_count	= INIT_PREEMPT_COUNT,	\
}
+2 −1
Original line number Diff line number Diff line
@@ -7,7 +7,8 @@ extra-y := vmlinux.lds

obj-y		+= head.o cpu-probe.o cacheinfo.o env.o setup.o entry.o genex.o \
		   traps.o irq.o idle.o process.o dma.o mem.o io.o reset.o switch.o \
		   elf.o syscall.o signal.o time.o topology.o inst.o ptrace.o vdso.o
		   elf.o syscall.o signal.o time.o topology.o inst.o ptrace.o vdso.o \
		   unaligned.o

obj-$(CONFIG_ACPI)		+= acpi.o
obj-$(CONFIG_EFI) 		+= efi.o
Loading