#ifdef __BIG_ENDIAN__
#define sLd sld /* Shift towards low-numbered address. */
#define sHd srd /* Shift towards high-numbered address. */
#else
#define sLd srd /* Shift towards low-numbered address. */
#define sHd sld /* Shift towards high-numbered address. */
#endif
/* * These macros are used to generate exception table entries. * The exception handlers below use the original arguments * (stored on the stack) and the point where we're up to in * the destination buffer, i.e. the address of the first * unmodified byte. Generally r3 points into the destination * buffer, but the first unmodified byte is at a variable * offset from r3. In the code below, the symbol r3_offset * is set to indicate the current offset at each point in * the code. This offset is then used as a negative offset * from the exception handler code, and those instructions * before the exception handlers are addi instructions that * adjust r3 to point to the correct place.
*/
.macro lex /* exception handler for load */
100: EX_TABLE(100b, .Lld_exc - r3_offset)
.endm
.macro stex /* exception handler for store */
100: EX_TABLE(100b, .Lst_exc - r3_offset)
.endm
.align 7
_GLOBAL_TOC(__copy_tofrom_user)
#ifdef CONFIG_PPC_BOOK3S_64
BEGIN_FTR_SECTION
nop
FTR_SECTION_ELSE
b __copy_tofrom_user_power7
ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY)
#endif
_GLOBAL(__copy_tofrom_user_base) /* first check for a 4kB copy on a 4kB boundary */
cmpldi cr1,r5,16
cmpdi cr6,r5,4096
or r0,r3,r4
neg r6,r3 /* LS 3 bits = # bytes to 8-byte dest bdry */
andi. r0,r0,4095
std r3,-24(r1)
crand cr0*4+2,cr0*4+2,cr6*4+2
std r4,-16(r1)
std r5,-8(r1)
dcbt 0,r4
beq .Lcopy_page_4K
andi. r6,r6,7
PPC_MTOCRF(0x01,r5)
blt cr1,.Lshort_copy /* Below we want to nop out the bne if we're on a CPU that has the * CPU_FTR_UNALIGNED_LD_STD bit set and the CPU_FTR_CP_USE_DCBTZ bit * cleared. * At the time of writing the only CPU that has this combination of bits * set is Power6.
*/
test_feature = (SELFTEST_CASE == 1)
BEGIN_FTR_SECTION
nop
FTR_SECTION_ELSE
bne .Ldst_unaligned
ALT_FTR_SECTION_END(CPU_FTR_UNALIGNED_LD_STD | CPU_FTR_CP_USE_DCBTZ, \
CPU_FTR_UNALIGNED_LD_STD)
.Ldst_aligned:
addi r3,r3,-16
r3_offset = 16
test_feature = (SELFTEST_CASE == 0)
BEGIN_FTR_SECTION
andi. r0,r4,7
bne .Lsrc_unaligned
END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
blt cr1,.Ldo_tail /* if < 16 bytes to copy */
srdi r0,r5,5
cmpdi cr1,r0,0
lex; ld r7,0(r4)
lex; ld r6,8(r4)
addi r4,r4,16
mtctr r0
andi. r0,r5,0x10
beq 22f
addi r3,r3,16
r3_offset = 0
addi r4,r4,-16
mr r9,r7
mr r8,r6
beq cr1,72f
21:
lex; ld r7,16(r4)
lex; ld r6,24(r4)
addi r4,r4,32
stex; std r9,0(r3)
r3_offset = 8
stex; std r8,8(r3)
r3_offset = 16
22:
lex; ld r9,0(r4)
lex; ld r8,8(r4)
stex; std r7,16(r3)
r3_offset = 24
stex; std r6,24(r3)
addi r3,r3,32
r3_offset = 0
bdnz 21b
72:
stex; std r9,0(r3)
r3_offset = 8
stex; std r8,8(r3)
r3_offset = 16
andi. r5,r5,0xf
beq+ 3f
addi r4,r4,16
.Ldo_tail:
addi r3,r3,16
r3_offset = 0
bf cr7*4+0,246f
lex; ld r9,0(r4)
addi r4,r4,8
stex; std r9,0(r3)
addi r3,r3,8
246: bf cr7*4+1,1f
lex; lwz r9,0(r4)
addi r4,r4,4
stex; stw r9,0(r3)
addi r3,r3,4
1: bf cr7*4+2,2f
lex; lhz r9,0(r4)
addi r4,r4,2
stex; sth r9,0(r3)
addi r3,r3,2
2: bf cr7*4+3,3f
lex; lbz r9,0(r4)
stex; stb r9,0(r3)
3: li r3,0
blr
/* * exception handlers follow * we have to return the number of bytes not copied * for an exception on a load, we set the rest of the destination to 0 * Note that the number of bytes of instructions for adjusting r3 needs * to equal the amount of the adjustment, due to the trick of using * .Lld_exc - r3_offset as the handler address.
*/
.Lld_exc_r7:
add r3,r3,r7
b .Lld_exc
/* adjust by 24 */
addi r3,r3,8
nop /* adjust by 16 */
addi r3,r3,8
nop /* adjust by 8 */
addi r3,r3,8
nop
/* * Here we have had a fault on a load and r3 points to the first * unmodified byte of the destination. We use the original arguments * and r3 to work out how much wasn't copied. Since we load some * distance ahead of the stores, we continue copying byte-by-byte until * we hit the load fault again in order to copy as much as possible.
*/
.Lld_exc: ld r6,-24(r1) ld r4,-16(r1) ld r5,-8(r1)
subf r6,r6,r3
add r4,r4,r6
subf r5,r6,r5 /* #bytes left to go */
/* * first see if we can copy any more bytes before hitting another exception
*/
mtctr r5
r3_offset = 0
100: EX_TABLE(100b, .Ldone)
43: lbz r0,0(r4)
addi r4,r4,1
stex; stb r0,0(r3)
addi r3,r3,1
bdnz 43b
li r3,0 /* huh? all copied successfully this time? */
blr
/* * here we have trapped again, amount remaining is in ctr.
*/
.Ldone:
mfctr r3
blr
/* * exception handlers for stores: we need to work out how many bytes * weren't copied, and we may need to copy some more. * Note that the number of bytes of instructions for adjusting r3 needs * to equal the amount of the adjustment, due to the trick of using * .Lst_exc - r3_offset as the handler address.
*/
.Lst_exc_r7:
add r3,r3,r7
b .Lst_exc
/* adjust by 24 */
addi r3,r3,8
nop /* adjust by 16 */
addi r3,r3,8
nop /* adjust by 8 */
addi r3,r3,4 /* adjust by 4 */
addi r3,r3,4
.Lst_exc: ld r6,-24(r1) /* original destination pointer */ ld r4,-16(r1) /* original source pointer */ ld r5,-8(r1) /* original number of bytes */
add r7,r6,r5 /* * If the destination pointer isn't 8-byte aligned, * we may have got the exception as a result of a * store that overlapped a page boundary, so we may be * able to copy a few more bytes.
*/
17: andi. r0,r3,7
beq 19f
subf r8,r6,r3 /* #bytes copied */
100: EX_TABLE(100b,19f)
lbzx r0,r8,r4
100: EX_TABLE(100b,19f)
stb r0,0(r3)
addi r3,r3,1
cmpld r3,r7
blt 17b
19: subf r3,r3,r7 /* #bytes not copied in r3 */
blr
/* * on an exception, reset to the beginning and jump back into the * standard __copy_tofrom_user
*/
.Labort: ld r20,-120(1) ld r21,-112(1) ld r22,-104(1) ld r23,-96(1) ld r24,-88(1) ld r25,-80(1) ld r26,-72(1) ld r27,-64(1) ld r28,-56(1) ld r29,-48(1) ld r30,-40(1) ld r31,-32(1) ld r3,-24(r1) ld r4,-16(r1)
li r5,4096
b .Ldst_aligned
EXPORT_SYMBOL(__copy_tofrom_user)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.