ioremap.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-05-06 Jesven first version
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include <mmu.h>
  13. #include <mm_aspace.h>
  14. #include <ioremap.h>
  15. void *rt_ioremap_start;
  16. size_t rt_ioremap_size;
  17. #ifdef RT_USING_SMART
  18. #include <lwp_mm.h>
  19. #define DBG_TAG "mm.ioremap"
  20. #define DBG_LVL DBG_LOG
  21. #include <rtdbg.h>
  22. enum ioremap_type
  23. {
  24. MM_AREA_TYPE_PHY,
  25. MM_AREA_TYPE_PHY_WT,
  26. MM_AREA_TYPE_PHY_CACHED
  27. };
  28. static void *_ioremap_type(void *paddr, size_t size, enum ioremap_type type)
  29. {
  30. char *v_addr = NULL;
  31. size_t attr;
  32. size_t lo_off;
  33. int err;
  34. lo_off = (rt_ubase_t)paddr & ARCH_PAGE_MASK;
  35. struct rt_mm_va_hint hint = {
  36. .prefer = RT_NULL,
  37. .map_size = RT_ALIGN(size + lo_off, ARCH_PAGE_SIZE),
  38. .flags = 0,
  39. .limit_start = rt_ioremap_start,
  40. .limit_range_size = rt_ioremap_size,
  41. };
  42. switch (type)
  43. {
  44. case MM_AREA_TYPE_PHY:
  45. attr = MMU_MAP_K_DEVICE;
  46. break;
  47. case MM_AREA_TYPE_PHY_WT:
  48. attr = MMU_MAP_K_RW;
  49. break;
  50. case MM_AREA_TYPE_PHY_CACHED:
  51. attr = MMU_MAP_K_RWCB;
  52. break;
  53. default:
  54. return v_addr;
  55. }
  56. err = rt_aspace_map_phy(&rt_kernel_space, &hint, attr, MM_PA_TO_OFF(paddr), (void **)&v_addr);
  57. if (err)
  58. {
  59. LOG_W("IOREMAP 0x%lx failed %d\n", paddr, err);
  60. v_addr = NULL;
  61. }
  62. else
  63. {
  64. v_addr = v_addr + lo_off;
  65. }
  66. return v_addr;
  67. }
  68. rt_weak void *rt_ioremap_early(void *paddr, size_t size)
  69. {
  70. if (!size)
  71. {
  72. return RT_NULL;
  73. }
  74. return paddr;
  75. }
  76. void *rt_ioremap(void *paddr, size_t size)
  77. {
  78. return _ioremap_type(paddr, size, MM_AREA_TYPE_PHY);
  79. }
  80. void *rt_ioremap_nocache(void *paddr, size_t size)
  81. {
  82. return _ioremap_type(paddr, size, MM_AREA_TYPE_PHY);
  83. }
  84. void *rt_ioremap_wt(void *paddr, size_t size)
  85. {
  86. return _ioremap_type(paddr, size, MM_AREA_TYPE_PHY_WT);
  87. }
  88. void *rt_ioremap_cached(void *paddr, size_t size)
  89. {
  90. return _ioremap_type(paddr, size, MM_AREA_TYPE_PHY_CACHED);
  91. }
  92. void rt_iounmap(volatile void *vaddr)
  93. {
  94. rt_aspace_unmap(&rt_kernel_space, (void *)vaddr);
  95. }
  96. #else
  97. void *rt_ioremap(void *paddr, size_t size)
  98. {
  99. return paddr;
  100. }
  101. void *rt_ioremap_nocache(void *paddr, size_t size)
  102. {
  103. return paddr;
  104. }
  105. void *rt_ioremap_cached(void *paddr, size_t size)
  106. {
  107. return paddr;
  108. }
  109. void rt_iounmap(volatile void *vaddr)
  110. {
  111. }
  112. #endif