kernel-ark/arch/sparc64/kernel/una_asm.S
David S. Miller ff171d8f66 [SPARC64]: Handle little-endian unaligned loads/stores correctly.
Because we use byte loads/stores to cons up the value
in and out of registers, we can't expect the ASI endianness
setting to take care of this for us.  So do it by hand.

This case is triggered by drivers/block/aoe/aoecmd.c in the
ataid_complete() function where it goes:

		/* word 100: number lba48 sectors */
		ssize = le64_to_cpup((__le64 *) &id[100<<1]);

This &id[100<<1] address is 4 byte, rather than 8 byte aligned,
thus triggering the unaligned exception.

Signed-off-by: David S. Miller <davem@davemloft.net>
2005-09-19 19:56:06 -07:00

154 lines
3.5 KiB
ArmAsm

/* una_asm.S: Kernel unaligned trap assembler helpers.
*
* Copyright (C) 1996,2005 David S. Miller (davem@davemloft.net)
* Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
*/
.text
kernel_unaligned_trap_fault:
call kernel_mna_trap_fault
nop
retl
nop
.size kern_unaligned_trap_fault, .-kern_unaligned_trap_fault
.globl __do_int_store
__do_int_store:
rd %asi, %o4
wr %o3, 0, %asi
mov %o2, %g3
cmp %o1, 2
be,pn %icc, 2f
cmp %o1, 4
be,pt %icc, 1f
srlx %g3, 24, %g2
srlx %g3, 56, %g1
srlx %g3, 48, %g7
4: stba %g1, [%o0] %asi
srlx %g3, 40, %g1
5: stba %g7, [%o0 + 1] %asi
srlx %g3, 32, %g7
6: stba %g1, [%o0 + 2] %asi
7: stba %g7, [%o0 + 3] %asi
srlx %g3, 16, %g1
8: stba %g2, [%o0 + 4] %asi
srlx %g3, 8, %g7
9: stba %g1, [%o0 + 5] %asi
10: stba %g7, [%o0 + 6] %asi
ba,pt %xcc, 0f
11: stba %g3, [%o0 + 7] %asi
1: srl %g3, 16, %g7
12: stba %g2, [%o0] %asi
srl %g3, 8, %g2
13: stba %g7, [%o0 + 1] %asi
14: stba %g2, [%o0 + 2] %asi
ba,pt %xcc, 0f
15: stba %g3, [%o0 + 3] %asi
2: srl %g3, 8, %g2
16: stba %g2, [%o0] %asi
17: stba %g3, [%o0 + 1] %asi
0:
wr %o4, 0x0, %asi
retl
nop
.size __do_int_store, .-__do_int_store
.section __ex_table
.word 4b, kernel_unaligned_trap_fault
.word 5b, kernel_unaligned_trap_fault
.word 6b, kernel_unaligned_trap_fault
.word 7b, kernel_unaligned_trap_fault
.word 8b, kernel_unaligned_trap_fault
.word 9b, kernel_unaligned_trap_fault
.word 10b, kernel_unaligned_trap_fault
.word 11b, kernel_unaligned_trap_fault
.word 12b, kernel_unaligned_trap_fault
.word 13b, kernel_unaligned_trap_fault
.word 14b, kernel_unaligned_trap_fault
.word 15b, kernel_unaligned_trap_fault
.word 16b, kernel_unaligned_trap_fault
.word 17b, kernel_unaligned_trap_fault
.previous
.globl do_int_load
do_int_load:
rd %asi, %o5
wr %o4, 0, %asi
cmp %o1, 8
bge,pn %icc, 9f
cmp %o1, 4
be,pt %icc, 6f
4: lduba [%o2] %asi, %g2
5: lduba [%o2 + 1] %asi, %g3
sll %g2, 8, %g2
brz,pt %o3, 3f
add %g2, %g3, %g2
sllx %g2, 48, %g2
srax %g2, 48, %g2
3: ba,pt %xcc, 0f
stx %g2, [%o0]
6: lduba [%o2 + 1] %asi, %g3
sll %g2, 24, %g2
7: lduba [%o2 + 2] %asi, %g7
sll %g3, 16, %g3
8: lduba [%o2 + 3] %asi, %g1
sll %g7, 8, %g7
or %g2, %g3, %g2
or %g7, %g1, %g7
or %g2, %g7, %g2
brnz,a,pt %o3, 3f
sra %g2, 0, %g2
3: ba,pt %xcc, 0f
stx %g2, [%o0]
9: lduba [%o2] %asi, %g2
10: lduba [%o2 + 1] %asi, %g3
sllx %g2, 56, %g2
11: lduba [%o2 + 2] %asi, %g7
sllx %g3, 48, %g3
12: lduba [%o2 + 3] %asi, %g1
sllx %g7, 40, %g7
sllx %g1, 32, %g1
or %g2, %g3, %g2
or %g7, %g1, %g7
13: lduba [%o2 + 4] %asi, %g3
or %g2, %g7, %g7
14: lduba [%o2 + 5] %asi, %g1
sllx %g3, 24, %g3
15: lduba [%o2 + 6] %asi, %g2
sllx %g1, 16, %g1
or %g7, %g3, %g7
16: lduba [%o2 + 7] %asi, %g3
sllx %g2, 8, %g2
or %g7, %g1, %g7
or %g2, %g3, %g2
or %g7, %g2, %g7
cmp %o1, 8
be,a,pt %icc, 0f
stx %g7, [%o0]
srlx %g7, 32, %g2
sra %g7, 0, %g7
stx %g2, [%o0]
stx %g7, [%o0 + 8]
0:
wr %o5, 0x0, %asi
retl
nop
.size __do_int_load, .-__do_int_load
.section __ex_table
.word 4b, kernel_unaligned_trap_fault
.word 5b, kernel_unaligned_trap_fault
.word 6b, kernel_unaligned_trap_fault
.word 7b, kernel_unaligned_trap_fault
.word 8b, kernel_unaligned_trap_fault
.word 9b, kernel_unaligned_trap_fault
.word 10b, kernel_unaligned_trap_fault
.word 11b, kernel_unaligned_trap_fault
.word 12b, kernel_unaligned_trap_fault
.word 13b, kernel_unaligned_trap_fault
.word 14b, kernel_unaligned_trap_fault
.word 15b, kernel_unaligned_trap_fault
.word 16b, kernel_unaligned_trap_fault
.previous