tlb.h 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-11-28 WangXiaoyao the first version
  9. */
  10. #ifndef __TLB_H__
  11. #define __TLB_H__
  12. #include <rtthread.h>
  13. #include <stddef.h>
  14. #include <stdint.h>
  15. #include "mm_aspace.h"
  16. #include "mmu.h"
  17. #define TLBI_ARG(addr, asid) \
  18. ({ \
  19. uintptr_t arg = (uintptr_t)(addr) >> 12; \
  20. arg &= (1ull << 44) - 1; \
  21. arg |= (uintptr_t)(asid) << 48; \
  22. (void *)arg; \
  23. })
  24. static inline void rt_hw_tlb_invalidate_all(void)
  25. {
  26. __asm__ volatile(
  27. // ensure updates to pte completed
  28. "dsb ishst\n"
  29. "tlbi vmalle1is\n"
  30. "dsb ish\n"
  31. // after tlb in new context, refresh inst
  32. "isb\n" ::
  33. : "memory");
  34. }
  35. static inline void rt_hw_tlb_invalidate_all_local(void)
  36. {
  37. __asm__ volatile(
  38. // ensure updates to pte completed
  39. "dsb nshst\n"
  40. "tlbi vmalle1is\n"
  41. "dsb nsh\n"
  42. // after tlb in new context, refresh inst
  43. "isb\n" ::
  44. : "memory");
  45. }
  46. static inline void rt_hw_tlb_invalidate_aspace(rt_aspace_t aspace)
  47. {
  48. rt_hw_tlb_invalidate_all();
  49. }
  50. static inline void rt_hw_tlb_invalidate_page(rt_aspace_t aspace, void *start)
  51. {
  52. start = TLBI_ARG(start, 0);
  53. __asm__ volatile(
  54. "dsb ishst\n"
  55. "tlbi vaae1is, %0\n"
  56. "dsb ish\n"
  57. "isb\n" ::"r"(start)
  58. : "memory");
  59. }
  60. static inline void rt_hw_tlb_invalidate_range(rt_aspace_t aspace, void *start,
  61. size_t size, size_t stride)
  62. {
  63. if (size <= ARCH_PAGE_SIZE)
  64. {
  65. rt_hw_tlb_invalidate_page(aspace, start);
  66. }
  67. else
  68. {
  69. rt_hw_tlb_invalidate_aspace(aspace);
  70. }
  71. }
  72. #endif /* __TLB_H__ */