Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 77b2555b52a894a2e39a42e43d993df875c46a6a 697 lines 17 kB view raw
1/* 2 * linux/arch/arm/lib/uaccess.S 3 * 4 * Copyright (C) 1995, 1996,1997,1998 Russell King 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * Routines to block copy data to/from user memory 11 * These are highly optimised both for the 4k page size 12 * and for various alignments. 13 */ 14#include <linux/linkage.h> 15#include <asm/assembler.h> 16#include <asm/errno.h> 17 18 .text 19 20#define PAGE_SHIFT 12 21 22/* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n) 23 * Purpose : copy a block to user memory from kernel memory 24 * Params : to - user memory 25 * : from - kernel memory 26 * : n - number of bytes to copy 27 * Returns : Number of bytes NOT copied. 28 */ 29 30.c2u_dest_not_aligned: 31 rsb ip, ip, #4 32 cmp ip, #2 33 ldrb r3, [r1], #1 34USER( strbt r3, [r0], #1) @ May fault 35 ldrgeb r3, [r1], #1 36USER( strgebt r3, [r0], #1) @ May fault 37 ldrgtb r3, [r1], #1 38USER( strgtbt r3, [r0], #1) @ May fault 39 sub r2, r2, ip 40 b .c2u_dest_aligned 41 42ENTRY(__arch_copy_to_user) 43 stmfd sp!, {r2, r4 - r7, lr} 44 cmp r2, #4 45 blt .c2u_not_enough 46 PLD( pld [r1, #0] ) 47 PLD( pld [r0, #0] ) 48 ands ip, r0, #3 49 bne .c2u_dest_not_aligned 50.c2u_dest_aligned: 51 52 ands ip, r1, #3 53 bne .c2u_src_not_aligned 54/* 55 * Seeing as there has to be at least 8 bytes to copy, we can 56 * copy one word, and force a user-mode page fault... 57 */ 58 59.c2u_0fupi: subs r2, r2, #4 60 addmi ip, r2, #4 61 bmi .c2u_0nowords 62 ldr r3, [r1], #4 63USER( strt r3, [r0], #4) @ May fault 64 mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction 65 rsb ip, ip, #0 66 movs ip, ip, lsr #32 - PAGE_SHIFT 67 beq .c2u_0fupi 68/* 69 * ip = max no. of bytes to copy before needing another "strt" insn 70 */ 71 cmp r2, ip 72 movlt ip, r2 73 sub r2, r2, ip 74 subs ip, ip, #32 75 blt .c2u_0rem8lp 76 PLD( pld [r1, #28] ) 77 PLD( pld [r0, #28] ) 78 PLD( subs ip, ip, #64 ) 79 PLD( blt .c2u_0cpynopld ) 80 PLD( pld [r1, #60] ) 81 PLD( pld [r0, #60] ) 82 83.c2u_0cpy8lp: 84 PLD( pld [r1, #92] ) 85 PLD( pld [r0, #92] ) 86.c2u_0cpynopld: ldmia r1!, {r3 - r6} 87 stmia r0!, {r3 - r6} @ Shouldnt fault 88 ldmia r1!, {r3 - r6} 89 subs ip, ip, #32 90 stmia r0!, {r3 - r6} @ Shouldnt fault 91 bpl .c2u_0cpy8lp 92 PLD( cmn ip, #64 ) 93 PLD( bge .c2u_0cpynopld ) 94 PLD( add ip, ip, #64 ) 95 96.c2u_0rem8lp: cmn ip, #16 97 ldmgeia r1!, {r3 - r6} 98 stmgeia r0!, {r3 - r6} @ Shouldnt fault 99 tst ip, #8 100 ldmneia r1!, {r3 - r4} 101 stmneia r0!, {r3 - r4} @ Shouldnt fault 102 tst ip, #4 103 ldrne r3, [r1], #4 104 strnet r3, [r0], #4 @ Shouldnt fault 105 ands ip, ip, #3 106 beq .c2u_0fupi 107.c2u_0nowords: teq ip, #0 108 beq .c2u_finished 109.c2u_nowords: cmp ip, #2 110 ldrb r3, [r1], #1 111USER( strbt r3, [r0], #1) @ May fault 112 ldrgeb r3, [r1], #1 113USER( strgebt r3, [r0], #1) @ May fault 114 ldrgtb r3, [r1], #1 115USER( strgtbt r3, [r0], #1) @ May fault 116 b .c2u_finished 117 118.c2u_not_enough: 119 movs ip, r2 120 bne .c2u_nowords 121.c2u_finished: mov r0, #0 122 LOADREGS(fd,sp!,{r2, r4 - r7, pc}) 123 124.c2u_src_not_aligned: 125 bic r1, r1, #3 126 ldr r7, [r1], #4 127 cmp ip, #2 128 bgt .c2u_3fupi 129 beq .c2u_2fupi 130.c2u_1fupi: subs r2, r2, #4 131 addmi ip, r2, #4 132 bmi .c2u_1nowords 133 mov r3, r7, pull #8 134 ldr r7, [r1], #4 135 orr r3, r3, r7, push #24 136USER( strt r3, [r0], #4) @ May fault 137 mov ip, r0, lsl #32 - PAGE_SHIFT 138 rsb ip, ip, #0 139 movs ip, ip, lsr #32 - PAGE_SHIFT 140 beq .c2u_1fupi 141 cmp r2, ip 142 movlt ip, r2 143 sub r2, r2, ip 144 subs ip, ip, #16 145 blt .c2u_1rem8lp 146 PLD( pld [r1, #12] ) 147 PLD( pld [r0, #12] ) 148 PLD( subs ip, ip, #32 ) 149 PLD( blt .c2u_1cpynopld ) 150 PLD( pld [r1, #28] ) 151 PLD( pld [r0, #28] ) 152 153.c2u_1cpy8lp: 154 PLD( pld [r1, #44] ) 155 PLD( pld [r0, #44] ) 156.c2u_1cpynopld: mov r3, r7, pull #8 157 ldmia r1!, {r4 - r7} 158 subs ip, ip, #16 159 orr r3, r3, r4, push #24 160 mov r4, r4, pull #8 161 orr r4, r4, r5, push #24 162 mov r5, r5, pull #8 163 orr r5, r5, r6, push #24 164 mov r6, r6, pull #8 165 orr r6, r6, r7, push #24 166 stmia r0!, {r3 - r6} @ Shouldnt fault 167 bpl .c2u_1cpy8lp 168 PLD( cmn ip, #32 ) 169 PLD( bge .c2u_1cpynopld ) 170 PLD( add ip, ip, #32 ) 171 172.c2u_1rem8lp: tst ip, #8 173 movne r3, r7, pull #8 174 ldmneia r1!, {r4, r7} 175 orrne r3, r3, r4, push #24 176 movne r4, r4, pull #8 177 orrne r4, r4, r7, push #24 178 stmneia r0!, {r3 - r4} @ Shouldnt fault 179 tst ip, #4 180 movne r3, r7, pull #8 181 ldrne r7, [r1], #4 182 orrne r3, r3, r7, push #24 183 strnet r3, [r0], #4 @ Shouldnt fault 184 ands ip, ip, #3 185 beq .c2u_1fupi 186.c2u_1nowords: mov r3, r7, get_byte_1 187 teq ip, #0 188 beq .c2u_finished 189 cmp ip, #2 190USER( strbt r3, [r0], #1) @ May fault 191 movge r3, r7, get_byte_2 192USER( strgebt r3, [r0], #1) @ May fault 193 movgt r3, r7, get_byte_3 194USER( strgtbt r3, [r0], #1) @ May fault 195 b .c2u_finished 196 197.c2u_2fupi: subs r2, r2, #4 198 addmi ip, r2, #4 199 bmi .c2u_2nowords 200 mov r3, r7, pull #16 201 ldr r7, [r1], #4 202 orr r3, r3, r7, push #16 203USER( strt r3, [r0], #4) @ May fault 204 mov ip, r0, lsl #32 - PAGE_SHIFT 205 rsb ip, ip, #0 206 movs ip, ip, lsr #32 - PAGE_SHIFT 207 beq .c2u_2fupi 208 cmp r2, ip 209 movlt ip, r2 210 sub r2, r2, ip 211 subs ip, ip, #16 212 blt .c2u_2rem8lp 213 PLD( pld [r1, #12] ) 214 PLD( pld [r0, #12] ) 215 PLD( subs ip, ip, #32 ) 216 PLD( blt .c2u_2cpynopld ) 217 PLD( pld [r1, #28] ) 218 PLD( pld [r0, #28] ) 219 220.c2u_2cpy8lp: 221 PLD( pld [r1, #44] ) 222 PLD( pld [r0, #44] ) 223.c2u_2cpynopld: mov r3, r7, pull #16 224 ldmia r1!, {r4 - r7} 225 subs ip, ip, #16 226 orr r3, r3, r4, push #16 227 mov r4, r4, pull #16 228 orr r4, r4, r5, push #16 229 mov r5, r5, pull #16 230 orr r5, r5, r6, push #16 231 mov r6, r6, pull #16 232 orr r6, r6, r7, push #16 233 stmia r0!, {r3 - r6} @ Shouldnt fault 234 bpl .c2u_2cpy8lp 235 PLD( cmn ip, #32 ) 236 PLD( bge .c2u_2cpynopld ) 237 PLD( add ip, ip, #32 ) 238 239.c2u_2rem8lp: tst ip, #8 240 movne r3, r7, pull #16 241 ldmneia r1!, {r4, r7} 242 orrne r3, r3, r4, push #16 243 movne r4, r4, pull #16 244 orrne r4, r4, r7, push #16 245 stmneia r0!, {r3 - r4} @ Shouldnt fault 246 tst ip, #4 247 movne r3, r7, pull #16 248 ldrne r7, [r1], #4 249 orrne r3, r3, r7, push #16 250 strnet r3, [r0], #4 @ Shouldnt fault 251 ands ip, ip, #3 252 beq .c2u_2fupi 253.c2u_2nowords: mov r3, r7, get_byte_2 254 teq ip, #0 255 beq .c2u_finished 256 cmp ip, #2 257USER( strbt r3, [r0], #1) @ May fault 258 movge r3, r7, get_byte_3 259USER( strgebt r3, [r0], #1) @ May fault 260 ldrgtb r3, [r1], #0 261USER( strgtbt r3, [r0], #1) @ May fault 262 b .c2u_finished 263 264.c2u_3fupi: subs r2, r2, #4 265 addmi ip, r2, #4 266 bmi .c2u_3nowords 267 mov r3, r7, pull #24 268 ldr r7, [r1], #4 269 orr r3, r3, r7, push #8 270USER( strt r3, [r0], #4) @ May fault 271 mov ip, r0, lsl #32 - PAGE_SHIFT 272 rsb ip, ip, #0 273 movs ip, ip, lsr #32 - PAGE_SHIFT 274 beq .c2u_3fupi 275 cmp r2, ip 276 movlt ip, r2 277 sub r2, r2, ip 278 subs ip, ip, #16 279 blt .c2u_3rem8lp 280 PLD( pld [r1, #12] ) 281 PLD( pld [r0, #12] ) 282 PLD( subs ip, ip, #32 ) 283 PLD( blt .c2u_3cpynopld ) 284 PLD( pld [r1, #28] ) 285 PLD( pld [r0, #28] ) 286 287.c2u_3cpy8lp: 288 PLD( pld [r1, #44] ) 289 PLD( pld [r0, #44] ) 290.c2u_3cpynopld: mov r3, r7, pull #24 291 ldmia r1!, {r4 - r7} 292 subs ip, ip, #16 293 orr r3, r3, r4, push #8 294 mov r4, r4, pull #24 295 orr r4, r4, r5, push #8 296 mov r5, r5, pull #24 297 orr r5, r5, r6, push #8 298 mov r6, r6, pull #24 299 orr r6, r6, r7, push #8 300 stmia r0!, {r3 - r6} @ Shouldnt fault 301 bpl .c2u_3cpy8lp 302 PLD( cmn ip, #32 ) 303 PLD( bge .c2u_3cpynopld ) 304 PLD( add ip, ip, #32 ) 305 306.c2u_3rem8lp: tst ip, #8 307 movne r3, r7, pull #24 308 ldmneia r1!, {r4, r7} 309 orrne r3, r3, r4, push #8 310 movne r4, r4, pull #24 311 orrne r4, r4, r7, push #8 312 stmneia r0!, {r3 - r4} @ Shouldnt fault 313 tst ip, #4 314 movne r3, r7, pull #24 315 ldrne r7, [r1], #4 316 orrne r3, r3, r7, push #8 317 strnet r3, [r0], #4 @ Shouldnt fault 318 ands ip, ip, #3 319 beq .c2u_3fupi 320.c2u_3nowords: mov r3, r7, get_byte_3 321 teq ip, #0 322 beq .c2u_finished 323 cmp ip, #2 324USER( strbt r3, [r0], #1) @ May fault 325 ldrgeb r3, [r1], #1 326USER( strgebt r3, [r0], #1) @ May fault 327 ldrgtb r3, [r1], #0 328USER( strgtbt r3, [r0], #1) @ May fault 329 b .c2u_finished 330 331 .section .fixup,"ax" 332 .align 0 3339001: LOADREGS(fd,sp!, {r0, r4 - r7, pc}) 334 .previous 335 336/* Prototype: unsigned long __arch_copy_from_user(void *to,const void *from,unsigned long n); 337 * Purpose : copy a block from user memory to kernel memory 338 * Params : to - kernel memory 339 * : from - user memory 340 * : n - number of bytes to copy 341 * Returns : Number of bytes NOT copied. 342 */ 343.cfu_dest_not_aligned: 344 rsb ip, ip, #4 345 cmp ip, #2 346USER( ldrbt r3, [r1], #1) @ May fault 347 strb r3, [r0], #1 348USER( ldrgebt r3, [r1], #1) @ May fault 349 strgeb r3, [r0], #1 350USER( ldrgtbt r3, [r1], #1) @ May fault 351 strgtb r3, [r0], #1 352 sub r2, r2, ip 353 b .cfu_dest_aligned 354 355ENTRY(__arch_copy_from_user) 356 stmfd sp!, {r0, r2, r4 - r7, lr} 357 cmp r2, #4 358 blt .cfu_not_enough 359 PLD( pld [r1, #0] ) 360 PLD( pld [r0, #0] ) 361 ands ip, r0, #3 362 bne .cfu_dest_not_aligned 363.cfu_dest_aligned: 364 ands ip, r1, #3 365 bne .cfu_src_not_aligned 366/* 367 * Seeing as there has to be at least 8 bytes to copy, we can 368 * copy one word, and force a user-mode page fault... 369 */ 370 371.cfu_0fupi: subs r2, r2, #4 372 addmi ip, r2, #4 373 bmi .cfu_0nowords 374USER( ldrt r3, [r1], #4) 375 str r3, [r0], #4 376 mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction 377 rsb ip, ip, #0 378 movs ip, ip, lsr #32 - PAGE_SHIFT 379 beq .cfu_0fupi 380/* 381 * ip = max no. of bytes to copy before needing another "strt" insn 382 */ 383 cmp r2, ip 384 movlt ip, r2 385 sub r2, r2, ip 386 subs ip, ip, #32 387 blt .cfu_0rem8lp 388 PLD( pld [r1, #28] ) 389 PLD( pld [r0, #28] ) 390 PLD( subs ip, ip, #64 ) 391 PLD( blt .cfu_0cpynopld ) 392 PLD( pld [r1, #60] ) 393 PLD( pld [r0, #60] ) 394 395.cfu_0cpy8lp: 396 PLD( pld [r1, #92] ) 397 PLD( pld [r0, #92] ) 398.cfu_0cpynopld: ldmia r1!, {r3 - r6} @ Shouldnt fault 399 stmia r0!, {r3 - r6} 400 ldmia r1!, {r3 - r6} @ Shouldnt fault 401 subs ip, ip, #32 402 stmia r0!, {r3 - r6} 403 bpl .cfu_0cpy8lp 404 PLD( cmn ip, #64 ) 405 PLD( bge .cfu_0cpynopld ) 406 PLD( add ip, ip, #64 ) 407 408.cfu_0rem8lp: cmn ip, #16 409 ldmgeia r1!, {r3 - r6} @ Shouldnt fault 410 stmgeia r0!, {r3 - r6} 411 tst ip, #8 412 ldmneia r1!, {r3 - r4} @ Shouldnt fault 413 stmneia r0!, {r3 - r4} 414 tst ip, #4 415 ldrnet r3, [r1], #4 @ Shouldnt fault 416 strne r3, [r0], #4 417 ands ip, ip, #3 418 beq .cfu_0fupi 419.cfu_0nowords: teq ip, #0 420 beq .cfu_finished 421.cfu_nowords: cmp ip, #2 422USER( ldrbt r3, [r1], #1) @ May fault 423 strb r3, [r0], #1 424USER( ldrgebt r3, [r1], #1) @ May fault 425 strgeb r3, [r0], #1 426USER( ldrgtbt r3, [r1], #1) @ May fault 427 strgtb r3, [r0], #1 428 b .cfu_finished 429 430.cfu_not_enough: 431 movs ip, r2 432 bne .cfu_nowords 433.cfu_finished: mov r0, #0 434 add sp, sp, #8 435 LOADREGS(fd,sp!,{r4 - r7, pc}) 436 437.cfu_src_not_aligned: 438 bic r1, r1, #3 439USER( ldrt r7, [r1], #4) @ May fault 440 cmp ip, #2 441 bgt .cfu_3fupi 442 beq .cfu_2fupi 443.cfu_1fupi: subs r2, r2, #4 444 addmi ip, r2, #4 445 bmi .cfu_1nowords 446 mov r3, r7, pull #8 447USER( ldrt r7, [r1], #4) @ May fault 448 orr r3, r3, r7, push #24 449 str r3, [r0], #4 450 mov ip, r1, lsl #32 - PAGE_SHIFT 451 rsb ip, ip, #0 452 movs ip, ip, lsr #32 - PAGE_SHIFT 453 beq .cfu_1fupi 454 cmp r2, ip 455 movlt ip, r2 456 sub r2, r2, ip 457 subs ip, ip, #16 458 blt .cfu_1rem8lp 459 PLD( pld [r1, #12] ) 460 PLD( pld [r0, #12] ) 461 PLD( subs ip, ip, #32 ) 462 PLD( blt .cfu_1cpynopld ) 463 PLD( pld [r1, #28] ) 464 PLD( pld [r0, #28] ) 465 466.cfu_1cpy8lp: 467 PLD( pld [r1, #44] ) 468 PLD( pld [r0, #44] ) 469.cfu_1cpynopld: mov r3, r7, pull #8 470 ldmia r1!, {r4 - r7} @ Shouldnt fault 471 subs ip, ip, #16 472 orr r3, r3, r4, push #24 473 mov r4, r4, pull #8 474 orr r4, r4, r5, push #24 475 mov r5, r5, pull #8 476 orr r5, r5, r6, push #24 477 mov r6, r6, pull #8 478 orr r6, r6, r7, push #24 479 stmia r0!, {r3 - r6} 480 bpl .cfu_1cpy8lp 481 PLD( cmn ip, #32 ) 482 PLD( bge .cfu_1cpynopld ) 483 PLD( add ip, ip, #32 ) 484 485.cfu_1rem8lp: tst ip, #8 486 movne r3, r7, pull #8 487 ldmneia r1!, {r4, r7} @ Shouldnt fault 488 orrne r3, r3, r4, push #24 489 movne r4, r4, pull #8 490 orrne r4, r4, r7, push #24 491 stmneia r0!, {r3 - r4} 492 tst ip, #4 493 movne r3, r7, pull #8 494USER( ldrnet r7, [r1], #4) @ May fault 495 orrne r3, r3, r7, push #24 496 strne r3, [r0], #4 497 ands ip, ip, #3 498 beq .cfu_1fupi 499.cfu_1nowords: mov r3, r7, get_byte_1 500 teq ip, #0 501 beq .cfu_finished 502 cmp ip, #2 503 strb r3, [r0], #1 504 movge r3, r7, get_byte_2 505 strgeb r3, [r0], #1 506 movgt r3, r7, get_byte_3 507 strgtb r3, [r0], #1 508 b .cfu_finished 509 510.cfu_2fupi: subs r2, r2, #4 511 addmi ip, r2, #4 512 bmi .cfu_2nowords 513 mov r3, r7, pull #16 514USER( ldrt r7, [r1], #4) @ May fault 515 orr r3, r3, r7, push #16 516 str r3, [r0], #4 517 mov ip, r1, lsl #32 - PAGE_SHIFT 518 rsb ip, ip, #0 519 movs ip, ip, lsr #32 - PAGE_SHIFT 520 beq .cfu_2fupi 521 cmp r2, ip 522 movlt ip, r2 523 sub r2, r2, ip 524 subs ip, ip, #16 525 blt .cfu_2rem8lp 526 PLD( pld [r1, #12] ) 527 PLD( pld [r0, #12] ) 528 PLD( subs ip, ip, #32 ) 529 PLD( blt .cfu_2cpynopld ) 530 PLD( pld [r1, #28] ) 531 PLD( pld [r0, #28] ) 532 533.cfu_2cpy8lp: 534 PLD( pld [r1, #44] ) 535 PLD( pld [r0, #44] ) 536.cfu_2cpynopld: mov r3, r7, pull #16 537 ldmia r1!, {r4 - r7} @ Shouldnt fault 538 subs ip, ip, #16 539 orr r3, r3, r4, push #16 540 mov r4, r4, pull #16 541 orr r4, r4, r5, push #16 542 mov r5, r5, pull #16 543 orr r5, r5, r6, push #16 544 mov r6, r6, pull #16 545 orr r6, r6, r7, push #16 546 stmia r0!, {r3 - r6} 547 bpl .cfu_2cpy8lp 548 PLD( cmn ip, #32 ) 549 PLD( bge .cfu_2cpynopld ) 550 PLD( add ip, ip, #32 ) 551 552.cfu_2rem8lp: tst ip, #8 553 movne r3, r7, pull #16 554 ldmneia r1!, {r4, r7} @ Shouldnt fault 555 orrne r3, r3, r4, push #16 556 movne r4, r4, pull #16 557 orrne r4, r4, r7, push #16 558 stmneia r0!, {r3 - r4} 559 tst ip, #4 560 movne r3, r7, pull #16 561USER( ldrnet r7, [r1], #4) @ May fault 562 orrne r3, r3, r7, push #16 563 strne r3, [r0], #4 564 ands ip, ip, #3 565 beq .cfu_2fupi 566.cfu_2nowords: mov r3, r7, get_byte_2 567 teq ip, #0 568 beq .cfu_finished 569 cmp ip, #2 570 strb r3, [r0], #1 571 movge r3, r7, get_byte_3 572 strgeb r3, [r0], #1 573USER( ldrgtbt r3, [r1], #0) @ May fault 574 strgtb r3, [r0], #1 575 b .cfu_finished 576 577.cfu_3fupi: subs r2, r2, #4 578 addmi ip, r2, #4 579 bmi .cfu_3nowords 580 mov r3, r7, pull #24 581USER( ldrt r7, [r1], #4) @ May fault 582 orr r3, r3, r7, push #8 583 str r3, [r0], #4 584 mov ip, r1, lsl #32 - PAGE_SHIFT 585 rsb ip, ip, #0 586 movs ip, ip, lsr #32 - PAGE_SHIFT 587 beq .cfu_3fupi 588 cmp r2, ip 589 movlt ip, r2 590 sub r2, r2, ip 591 subs ip, ip, #16 592 blt .cfu_3rem8lp 593 PLD( pld [r1, #12] ) 594 PLD( pld [r0, #12] ) 595 PLD( subs ip, ip, #32 ) 596 PLD( blt .cfu_3cpynopld ) 597 PLD( pld [r1, #28] ) 598 PLD( pld [r0, #28] ) 599 600.cfu_3cpy8lp: 601 PLD( pld [r1, #44] ) 602 PLD( pld [r0, #44] ) 603.cfu_3cpynopld: mov r3, r7, pull #24 604 ldmia r1!, {r4 - r7} @ Shouldnt fault 605 orr r3, r3, r4, push #8 606 mov r4, r4, pull #24 607 orr r4, r4, r5, push #8 608 mov r5, r5, pull #24 609 orr r5, r5, r6, push #8 610 mov r6, r6, pull #24 611 orr r6, r6, r7, push #8 612 stmia r0!, {r3 - r6} 613 subs ip, ip, #16 614 bpl .cfu_3cpy8lp 615 PLD( cmn ip, #32 ) 616 PLD( bge .cfu_3cpynopld ) 617 PLD( add ip, ip, #32 ) 618 619.cfu_3rem8lp: tst ip, #8 620 movne r3, r7, pull #24 621 ldmneia r1!, {r4, r7} @ Shouldnt fault 622 orrne r3, r3, r4, push #8 623 movne r4, r4, pull #24 624 orrne r4, r4, r7, push #8 625 stmneia r0!, {r3 - r4} 626 tst ip, #4 627 movne r3, r7, pull #24 628USER( ldrnet r7, [r1], #4) @ May fault 629 orrne r3, r3, r7, push #8 630 strne r3, [r0], #4 631 ands ip, ip, #3 632 beq .cfu_3fupi 633.cfu_3nowords: mov r3, r7, get_byte_3 634 teq ip, #0 635 beq .cfu_finished 636 cmp ip, #2 637 strb r3, [r0], #1 638USER( ldrgebt r3, [r1], #1) @ May fault 639 strgeb r3, [r0], #1 640USER( ldrgtbt r3, [r1], #1) @ May fault 641 strgtb r3, [r0], #1 642 b .cfu_finished 643 644 .section .fixup,"ax" 645 .align 0 646 /* 647 * We took an exception. r0 contains a pointer to 648 * the byte not copied. 649 */ 6509001: ldr r2, [sp], #4 @ void *to 651 sub r2, r0, r2 @ bytes copied 652 ldr r1, [sp], #4 @ unsigned long count 653 subs r4, r1, r2 @ bytes left to copy 654 movne r1, r4 655 blne __memzero 656 mov r0, r4 657 LOADREGS(fd,sp!, {r4 - r7, pc}) 658 .previous 659 660/* Prototype: int __arch_clear_user(void *addr, size_t sz) 661 * Purpose : clear some user memory 662 * Params : addr - user memory address to clear 663 * : sz - number of bytes to clear 664 * Returns : number of bytes NOT cleared 665 */ 666ENTRY(__arch_clear_user) 667 stmfd sp!, {r1, lr} 668 mov r2, #0 669 cmp r1, #4 670 blt 2f 671 ands ip, r0, #3 672 beq 1f 673 cmp ip, #2 674USER( strbt r2, [r0], #1) 675USER( strlebt r2, [r0], #1) 676USER( strltbt r2, [r0], #1) 677 rsb ip, ip, #4 678 sub r1, r1, ip @ 7 6 5 4 3 2 1 6791: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7 680USER( strplt r2, [r0], #4) 681USER( strplt r2, [r0], #4) 682 bpl 1b 683 adds r1, r1, #4 @ 3 2 1 0 -1 -2 -3 684USER( strplt r2, [r0], #4) 6852: tst r1, #2 @ 1x 1x 0x 0x 1x 1x 0x 686USER( strnebt r2, [r0], #1) 687USER( strnebt r2, [r0], #1) 688 tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1 689USER( strnebt r2, [r0], #1) 690 mov r0, #0 691 LOADREGS(fd,sp!, {r1, pc}) 692 693 .section .fixup,"ax" 694 .align 0 6959001: LOADREGS(fd,sp!, {r0, pc}) 696 .previous 697