mm_kmem.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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-14 WangXiaoyao the first version
  9. */
  10. #include <rtthread.h>
  11. #define DBG_TAG "mm.kmem"
  12. #define DBG_LVL DBG_INFO
  13. #include <rtdbg.h>
  14. #include "mm_aspace.h"
  15. #include "mm_private.h"
  16. #include <mmu.h>
  17. static void list_kmem(void)
  18. {
  19. rt_aspace_print_all(&rt_kernel_space);
  20. }
  21. MSH_CMD_EXPORT(list_kmem, List varea in kernel virtual memory space);
  22. void rt_kmem_list(void) __attribute__((alias("list_kmem")));
  23. static rt_ubase_t rt_pv_offset;
  24. const rt_ubase_t rt_kmem_pvoff(void)
  25. {
  26. return rt_pv_offset;
  27. }
  28. void rt_kmem_pvoff_set(rt_ubase_t pvoff)
  29. {
  30. rt_pv_offset = pvoff;
  31. }
  32. #define _KMEM_LO_OFF(addr) ((rt_ubase_t)(addr) & ARCH_PAGE_MASK)
  33. int rt_kmem_map_phy(void *va, void *pa, rt_size_t length, rt_size_t attr)
  34. {
  35. int err;
  36. size_t lo_off;
  37. lo_off = _KMEM_LO_OFF(pa);
  38. if (va == RT_NULL)
  39. {
  40. LOG_E("%s: va NULL is not a valid input", __func__);
  41. err = -RT_EINVAL;
  42. }
  43. else if (_KMEM_LO_OFF(pa) != _KMEM_LO_OFF(va))
  44. {
  45. LOG_E("%s: misaligned PA(%p) to VA(%p)", __func__, pa, va);
  46. err = -RT_EINVAL;
  47. }
  48. else
  49. {
  50. struct rt_mm_va_hint hint = {.flags = MMF_MAP_FIXED,
  51. .limit_range_size = rt_kernel_space.size,
  52. .limit_start = rt_kernel_space.start,
  53. .prefer = va,
  54. .map_size = RT_ALIGN(length + lo_off, ARCH_PAGE_SIZE)};
  55. err = rt_aspace_map_phy(&rt_kernel_space, &hint, attr, MM_PA_TO_OFF(pa), &va);
  56. if (err)
  57. {
  58. LOG_W("%s: map %p to %p (%p bytes) failed(err %d)", __func__, pa, va, length, err);
  59. }
  60. }
  61. return err;
  62. }
  63. void *rt_kmem_v2p(void *vaddr)
  64. {
  65. return rt_hw_mmu_v2p(&rt_kernel_space, vaddr);
  66. }
  67. void *rt_kmem_p2v(void *paddr)
  68. {
  69. char *rc;
  70. char *linear_va;
  71. char *linear_pa;
  72. if (paddr != ARCH_MAP_FAILED)
  73. {
  74. linear_va = (char *)paddr - PV_OFFSET;
  75. linear_pa = rt_kmem_v2p(linear_va);
  76. if (linear_pa != paddr)
  77. {
  78. rc = RT_NULL;
  79. }
  80. else
  81. {
  82. rc = linear_va;
  83. }
  84. }
  85. else
  86. {
  87. rc = RT_NULL;
  88. }
  89. return rc;
  90. }