usb_memcpy.h 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. * Copyright (c) 2024, sakumisu
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #ifndef USB_MEMCPY_H
  7. #define USB_MEMCPY_H
  8. #include <stdint.h>
  9. #include <stddef.h>
  10. #define ALIGN_UP_DWORD(x) ((uint32_t)(uintptr_t)(x) & (sizeof(uint32_t) - 1))
  11. static inline void dword2array(char *addr, uint32_t w)
  12. {
  13. addr[0] = w;
  14. addr[1] = w >> 8;
  15. addr[2] = w >> 16;
  16. addr[3] = w >> 24;
  17. }
  18. static inline void *usb_memcpy(void *s1, const void *s2, size_t n)
  19. {
  20. char *b1 = (char *)s1;
  21. const char *b2 = (const char *)s2;
  22. uint32_t *w1;
  23. const uint32_t *w2;
  24. if (ALIGN_UP_DWORD(b1) == ALIGN_UP_DWORD(b2)) {
  25. while (ALIGN_UP_DWORD(b1) != 0 && n > 0) {
  26. *b1++ = *b2++;
  27. --n;
  28. }
  29. w1 = (uint32_t *)b1;
  30. w2 = (const uint32_t *)b2;
  31. while (n >= 4 * sizeof(uint32_t)) {
  32. *w1++ = *w2++;
  33. *w1++ = *w2++;
  34. *w1++ = *w2++;
  35. *w1++ = *w2++;
  36. n -= 4 * sizeof(uint32_t);
  37. }
  38. while (n >= sizeof(uint32_t)) {
  39. *w1++ = *w2++;
  40. n -= sizeof(uint32_t);
  41. }
  42. b1 = (char *)w1;
  43. b2 = (const char *)w2;
  44. while (n--) {
  45. *b1++ = *b2++;
  46. }
  47. } else {
  48. while (n > 0 && ALIGN_UP_DWORD(b2) != 0) {
  49. *b1++ = *b2++;
  50. --n;
  51. }
  52. w2 = (const uint32_t *)b2;
  53. while (n >= 4 * sizeof(uint32_t)) {
  54. dword2array(b1, *w2++);
  55. b1 += sizeof(uint32_t);
  56. dword2array(b1, *w2++);
  57. b1 += sizeof(uint32_t);
  58. dword2array(b1, *w2++);
  59. b1 += sizeof(uint32_t);
  60. dword2array(b1, *w2++);
  61. b1 += sizeof(uint32_t);
  62. n -= 4 * sizeof(uint32_t);
  63. }
  64. while (n >= sizeof(uint32_t)) {
  65. dword2array(b1, *w2++);
  66. b1 += sizeof(uint32_t);
  67. n -= sizeof(uint32_t);
  68. }
  69. b2 = (const char *)w2;
  70. while (n--) {
  71. *b1++ = *b2++;
  72. }
  73. }
  74. return s1;
  75. }
  76. #ifndef CONFIG_USB_MEMCPY_DISABLE
  77. #define memcpy usb_memcpy
  78. #endif
  79. #endif