ioremap.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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. #endif
  20. #define DBG_TAG "mm.ioremap"
  21. #define DBG_LVL DBG_LOG
  22. #include <rtdbg.h>
  23. enum ioremap_type
  24. {
  25. MM_AREA_TYPE_PHY,
  26. MM_AREA_TYPE_PHY_WT,
  27. MM_AREA_TYPE_PHY_CACHED
  28. };
  29. static void *_ioremap_type(void *paddr, size_t size, enum ioremap_type type)
  30. {
  31. char *v_addr = NULL;
  32. size_t attr;
  33. size_t lo_off;
  34. int err;
  35. lo_off = (rt_ubase_t)paddr & ARCH_PAGE_MASK;
  36. struct rt_mm_va_hint hint = {
  37. .prefer = RT_NULL,
  38. .map_size = RT_ALIGN(size + lo_off, ARCH_PAGE_SIZE),
  39. .flags = 0,
  40. .limit_start = rt_ioremap_start,
  41. .limit_range_size = rt_ioremap_size,
  42. };
  43. switch (type)
  44. {
  45. case MM_AREA_TYPE_PHY:
  46. attr = MMU_MAP_K_DEVICE;
  47. break;
  48. case MM_AREA_TYPE_PHY_WT:
  49. attr = MMU_MAP_K_RW;
  50. break;
  51. case MM_AREA_TYPE_PHY_CACHED:
  52. attr = MMU_MAP_K_RWCB;
  53. break;
  54. default:
  55. return v_addr;
  56. }
  57. err = rt_aspace_map_phy(&rt_kernel_space, &hint, attr, MM_PA_TO_OFF(paddr), (void **)&v_addr);
  58. if (err)
  59. {
  60. LOG_W("IOREMAP 0x%lx failed %d\n", paddr, err);
  61. v_addr = NULL;
  62. }
  63. else
  64. {
  65. v_addr = v_addr + lo_off;
  66. }
  67. return v_addr;
  68. }
  69. rt_weak void *rt_ioremap_early(void *paddr, size_t size)
  70. {
  71. if (!size)
  72. {
  73. return RT_NULL;
  74. }
  75. return paddr;
  76. }
  77. void *rt_ioremap(void *paddr, size_t size)
  78. {
  79. return _ioremap_type(paddr, size, MM_AREA_TYPE_PHY);
  80. }
  81. void *rt_ioremap_nocache(void *paddr, size_t size)
  82. {
  83. return _ioremap_type(paddr, size, MM_AREA_TYPE_PHY);
  84. }
  85. void *rt_ioremap_wt(void *paddr, size_t size)
  86. {
  87. return _ioremap_type(paddr, size, MM_AREA_TYPE_PHY_WT);
  88. }
  89. void *rt_ioremap_cached(void *paddr, size_t size)
  90. {
  91. return _ioremap_type(paddr, size, MM_AREA_TYPE_PHY_CACHED);
  92. }
  93. void rt_iounmap(volatile void *vaddr)
  94. {
  95. rt_aspace_unmap(&rt_kernel_space, (void *)vaddr);
  96. }