csumpartialcopyuser.S 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * linux/arch/arm/lib/csumpartialcopyuser.S
  3. *
  4. * Copyright (C) 1995-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. * 27/03/03 Ian Molton Clean up CONFIG_CPU
  11. *
  12. */
  13. #include <linux/linkage.h>
  14. #include <asm/assembler.h>
  15. #include <asm/errno.h>
  16. #include <asm/asm-offsets.h>
  17. .text
  18. .macro save_regs
  19. mov ip, sp
  20. stmfd sp!, {r1 - r2, r4 - r8, fp, ip, lr, pc}
  21. sub fp, ip, #4
  22. .endm
  23. .macro load_regs
  24. ldmfd sp, {r1, r2, r4-r8, fp, sp, pc}
  25. .endm
  26. .macro load1b, reg1
  27. 9999: ldrbt \reg1, [r0], $1
  28. .section __ex_table, "a"
  29. .align 3
  30. .long 9999b, 6001f
  31. .previous
  32. .endm
  33. .macro load2b, reg1, reg2
  34. 9999: ldrbt \reg1, [r0], $1
  35. 9998: ldrbt \reg2, [r0], $1
  36. .section __ex_table, "a"
  37. .long 9999b, 6001f
  38. .long 9998b, 6001f
  39. .previous
  40. .endm
  41. .macro load1l, reg1
  42. 9999: ldrt \reg1, [r0], $4
  43. .section __ex_table, "a"
  44. .align 3
  45. .long 9999b, 6001f
  46. .previous
  47. .endm
  48. .macro load2l, reg1, reg2
  49. 9999: ldrt \reg1, [r0], $4
  50. 9998: ldrt \reg2, [r0], $4
  51. .section __ex_table, "a"
  52. .long 9999b, 6001f
  53. .long 9998b, 6001f
  54. .previous
  55. .endm
  56. .macro load4l, reg1, reg2, reg3, reg4
  57. 9999: ldrt \reg1, [r0], $4
  58. 9998: ldrt \reg2, [r0], $4
  59. 9997: ldrt \reg3, [r0], $4
  60. 9996: ldrt \reg4, [r0], $4
  61. .section __ex_table, "a"
  62. .long 9999b, 6001f
  63. .long 9998b, 6001f
  64. .long 9997b, 6001f
  65. .long 9996b, 6001f
  66. .previous
  67. .endm
  68. /*
  69. * unsigned int
  70. * csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *err_ptr)
  71. * r0 = src, r1 = dst, r2 = len, r3 = sum, [sp] = *err_ptr
  72. * Returns : r0 = checksum, [[sp, #0], #0] = 0 or -EFAULT
  73. */
  74. #define FN_ENTRY ENTRY(csum_partial_copy_from_user)
  75. #include "csumpartialcopygeneric.S"
  76. /*
  77. * FIXME: minor buglet here
  78. * We don't return the checksum for the data present in the buffer. To do
  79. * so properly, we would have to add in whatever registers were loaded before
  80. * the fault, which, with the current asm above is not predictable.
  81. */
  82. .section .fixup,"ax"
  83. .align 4
  84. 6001: mov r4, #-EFAULT
  85. ldr r5, [fp, #4] @ *err_ptr
  86. str r4, [r5]
  87. ldmia sp, {r1, r2} @ retrieve dst, len
  88. add r2, r2, r1
  89. mov r0, #0 @ zero the buffer
  90. 6002: teq r2, r1
  91. strneb r0, [r1], #1
  92. bne 6002b
  93. load_regs
  94. .previous