summaryrefslogtreecommitdiff
path: root/components/mm
diff options
context:
space:
mode:
authorwangxiaoyao <[email protected]>2023-02-20 13:44:20 +0800
committerguo <[email protected]>2023-02-21 08:48:49 +0800
commit855aef9c9c59df12102d6ddfe43ef02c05171036 (patch)
treef055f1f3d0ca5d3812b4e565b00107cdbf3a901c /components/mm
parented58f6676d074ec9f66ea78e23d1e1657c9fef20 (diff)
[mm] distinguish NULL and MAP_FAILED
Diffstat (limited to 'components/mm')
-rw-r--r--components/mm/ioremap.c114
-rw-r--r--components/mm/ioremap.h31
-rw-r--r--components/mm/mm_aspace.c31
-rw-r--r--components/mm/mm_aspace.h16
4 files changed, 173 insertions, 19 deletions
diff --git a/components/mm/ioremap.c b/components/mm/ioremap.c
new file mode 100644
index 0000000000..a24672a9f2
--- /dev/null
+++ b/components/mm/ioremap.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-05-06 Jesven first version
+ */
+#include <rthw.h>
+#include <rtthread.h>
+
+#include <mmu.h>
+#include <mm_aspace.h>
+#include <ioremap.h>
+
+void *rt_ioremap_start;
+size_t rt_ioremap_size;
+
+#ifdef RT_USING_SMART
+
+#include <lwp_mm.h>
+#define DBG_TAG "mm.ioremap"
+#define DBG_LVL DBG_LOG
+#include <rtdbg.h>
+
+enum ioremap_type
+{
+ MM_AREA_TYPE_PHY,
+ MM_AREA_TYPE_PHY_CACHED
+};
+
+static void *_ioremap_type(void *paddr, size_t size, enum ioremap_type type)
+{
+ void *v_addr = NULL;
+ size_t attr;
+ size_t lo_off;
+ int err;
+
+ lo_off = (uintptr_t)paddr & ARCH_PAGE_MASK;
+
+ struct rt_mm_va_hint hint = {
+ .prefer = RT_NULL,
+ .map_size = RT_ALIGN(size + lo_off, ARCH_PAGE_SIZE),
+ .flags = 0,
+ .limit_start = rt_ioremap_start,
+ .limit_range_size = rt_ioremap_size,
+ };
+
+ switch (type)
+ {
+ case MM_AREA_TYPE_PHY:
+ attr = MMU_MAP_K_DEVICE;
+ break;
+ case MM_AREA_TYPE_PHY_CACHED:
+ attr = MMU_MAP_K_RWCB;
+ break;
+ default:
+ return v_addr;
+ }
+ err = rt_aspace_map_phy(&rt_kernel_space, &hint, attr, MM_PA_TO_OFF(paddr), &v_addr);
+
+ if (err)
+ {
+ LOG_W("IOREMAP 0x%lx failed", paddr);
+ v_addr = NULL;
+ }
+ else
+ {
+ v_addr = v_addr + lo_off;
+ }
+ return v_addr;
+}
+
+void *rt_ioremap(void *paddr, size_t size)
+{
+ return _ioremap_type(paddr, size, MM_AREA_TYPE_PHY);
+}
+
+void *rt_ioremap_nocache(void *paddr, size_t size)
+{
+ return _ioremap_type(paddr, size, MM_AREA_TYPE_PHY);
+}
+
+void *rt_ioremap_cached(void *paddr, size_t size)
+{
+ return _ioremap_type(paddr, size, MM_AREA_TYPE_PHY_CACHED);
+}
+
+void rt_iounmap(volatile void *vaddr)
+{
+ rt_aspace_unmap(&rt_kernel_space, (void *)vaddr, 1);
+}
+
+#else
+void *rt_ioremap(void *paddr, size_t size)
+{
+ return paddr;
+}
+
+void *rt_ioremap_nocache(void *paddr, size_t size)
+{
+ return paddr;
+}
+
+void *rt_ioremap_cached(void *paddr, size_t size)
+{
+ return paddr;
+}
+
+void rt_iounmap(volatile void *vaddr)
+{
+}
+#endif
diff --git a/components/mm/ioremap.h b/components/mm/ioremap.h
new file mode 100644
index 0000000000..2611b3a520
--- /dev/null
+++ b/components/mm/ioremap.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-05-06 Jesven first version
+ */
+#ifndef __IOREMAP_H__
+#define __IOREMAP_H__
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *rt_ioremap(void *paddr, size_t size);
+void *rt_ioremap_nocache(void *paddr, size_t size);
+void *rt_ioremap_cached (void *paddr, size_t size);
+void rt_iounmap(volatile void *addr);
+
+extern void *rt_ioremap_start;
+extern size_t rt_ioremap_size;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__LWP_IOREMAP_H__*/
diff --git a/components/mm/mm_aspace.c b/components/mm/mm_aspace.c
index 6a969074dc..aadf36e06b 100644
--- a/components/mm/mm_aspace.c
+++ b/components/mm/mm_aspace.c
@@ -204,10 +204,12 @@ static int _do_prefetch(rt_aspace_t aspace, rt_varea_t varea, void *start,
LOG_W("%s: MMU mapping failed for va %p to %p of %lx", __func__,
vaddr, store + PV_OFFSET, store_sz);
}
+ else
+ {
+ rt_hw_tlb_invalidate_range(aspace, vaddr, store_sz, ARCH_PAGE_SIZE);
+ }
vaddr += store_sz;
off += store_sz >> ARCH_PAGE_SHIFT;
-
- rt_hw_tlb_invalidate_range(aspace, vaddr, store_sz, ARCH_PAGE_SIZE);
}
else
{
@@ -235,7 +237,7 @@ int _varea_install(rt_aspace_t aspace, rt_varea_t varea, rt_mm_va_hint_t hint)
/* TODO try merge surrounding regions to optimize memory footprint */
- if (alloc_va != ARCH_MAP_FAILED)
+ if (alloc_va != RT_NULL)
{
varea->start = alloc_va;
_aspace_bst_insert(aspace, varea);
@@ -285,9 +287,10 @@ static int _mm_aspace_map(rt_aspace_t aspace, rt_varea_t varea, rt_size_t attr,
static inline int _not_in_range(void *start, rt_size_t length,
void *limit_start, rt_size_t limit_size)
{
- LOG_D("%s: [%p : %p] [%p : %p]", __func__, start, length, limit_start, limit_size);
+ if (start != RT_NULL)
+ LOG_D("%s: [%p : %p] [%p : %p]", __func__, start, length, limit_start, limit_size);
/* assuming (base + length) will not overflow except (0) */
- return start != ARCH_MAP_FAILED
+ return start != RT_NULL
? ((length > (0ul - (uintptr_t)start)) || start < limit_start ||
(length + (rt_size_t)(start - limit_start)) > limit_size)
: length > limit_size;
@@ -295,7 +298,7 @@ static inline int _not_in_range(void *start, rt_size_t length,
static inline int _not_align(void *start, rt_size_t length, rt_size_t mask)
{
- return (start != ARCH_MAP_FAILED) &&
+ return (start != RT_NULL) &&
(((uintptr_t)start & mask) || (length & mask));
}
@@ -438,7 +441,7 @@ int _mm_aspace_map_phy(rt_aspace_t aspace, rt_varea_t varea,
if (err == RT_EOK)
*ret_va = vaddr;
else
- *ret_va = ARCH_MAP_FAILED;
+ *ret_va = RT_NULL;
}
return err;
@@ -511,8 +514,7 @@ void _aspace_unmap(rt_aspace_t aspace, void *addr, rt_size_t length)
WR_UNLOCK(aspace);
rt_hw_mmu_unmap(aspace, varea->start, varea->size);
- rt_hw_tlb_invalidate_range(aspace, varea->start, varea->size,
- ARCH_PAGE_SIZE);
+ rt_hw_tlb_invalidate_range(aspace, varea->start, varea->size, ARCH_PAGE_SIZE);
rt_free(varea);
varea = _aspace_bst_search_overlap(aspace, range);
@@ -552,7 +554,7 @@ static inline void *_align(void *va, rt_ubase_t align_mask)
static void *_ascending_search(rt_varea_t varea, rt_size_t req_size,
rt_ubase_t align_mask, struct _mm_range limit)
{
- void *ret = ARCH_MAP_FAILED;
+ void *ret = RT_NULL;
while (varea && varea->start < limit.end)
{
void *candidate = varea->start + varea->size;
@@ -586,7 +588,7 @@ static void *_find_head_and_asc_search(rt_aspace_t aspace, rt_size_t req_size,
rt_ubase_t align_mask,
struct _mm_range limit)
{
- void *va = ARCH_MAP_FAILED;
+ void *va = RT_NULL;
rt_varea_t varea = _aspace_bst_search_exceed(aspace, limit.start);
if (varea)
@@ -638,7 +640,7 @@ static void *_find_free(rt_aspace_t aspace, void *prefer, rt_size_t req_size,
mm_flag_t flags)
{
rt_varea_t varea = NULL;
- void *va = ARCH_MAP_FAILED;
+ void *va = RT_NULL;
struct _mm_range limit = {limit_start, limit_start + limit_size - 1};
rt_ubase_t align_mask = ~0ul;
@@ -647,7 +649,7 @@ static void *_find_free(rt_aspace_t aspace, void *prefer, rt_size_t req_size,
align_mask = ~((1 << MMF_GET_ALIGN(flags)) - 1);
}
- if (prefer != ARCH_MAP_FAILED)
+ if (prefer != RT_NULL)
{
prefer = _align(prefer, align_mask);
struct _mm_range range = {prefer, prefer + req_size - 1};
@@ -659,11 +661,12 @@ static void *_find_free(rt_aspace_t aspace, void *prefer, rt_size_t req_size,
}
else if (flags & MMF_MAP_FIXED)
{
+ /* OVERLAP */
}
else
{
va = _ascending_search(varea, req_size, align_mask, limit);
- if (va == ARCH_MAP_FAILED)
+ if (va == RT_NULL)
{
limit.end = varea->start - 1;
va = _find_head_and_asc_search(aspace, req_size, align_mask,
diff --git a/components/mm/mm_aspace.h b/components/mm/mm_aspace.h
index 8687f9a093..79986efe52 100644
--- a/components/mm/mm_aspace.h
+++ b/components/mm/mm_aspace.h
@@ -30,11 +30,11 @@ typedef rt_spinlock_t mm_spinlock;
#define MM_PGTBL_UNLOCK(aspace) (rt_hw_spin_unlock(&((aspace)->pgtbl_lock)))
#else
-typedef rt_hw_spinlock_t mm_spinlock;
+typedef struct rt_spinlock mm_spinlock;
-#define MM_PGTBL_LOCK_INIT(aspace) (rt_hw_spin_lock_init(&((aspace)->pgtbl_lock)))
-#define MM_PGTBL_LOCK(aspace) (rt_hw_spin_lock(&((aspace)->pgtbl_lock)))
-#define MM_PGTBL_UNLOCK(aspace) (rt_hw_spin_unlock(&((aspace)->pgtbl_lock)))
+#define MM_PGTBL_LOCK_INIT(aspace) (rt_spin_lock_init(&((aspace)->pgtbl_lock)))
+#define MM_PGTBL_LOCK(aspace) (rt_spin_lock(&((aspace)->pgtbl_lock)))
+#define MM_PGTBL_UNLOCK(aspace) (rt_spin_unlock(&((aspace)->pgtbl_lock)))
#endif /* RT_USING_SMP */
@@ -108,6 +108,8 @@ enum rt_mmu_cntl
{
MMU_CNTL_NONCACHE,
MMU_CNTL_CACHE,
+ MMU_CNTL_READONLY,
+ MMU_CNTL_READWRITE,
MMU_CNTL_DUMMY_END,
};
@@ -135,7 +137,7 @@ void rt_aspace_detach(rt_aspace_t aspace);
/**
* @brief Memory Map on Virtual Address Space to Mappable Object
* *INFO There is no restriction to use NULL address(physical/virtual).
- * Vaddr passing in addr must be page aligned. If vaddr is MM_MAP_FAILED,
+ * Vaddr passing in addr must be page aligned. If vaddr is RT_NULL,
* a suitable address will be chose automatically.
*
* @param aspace target virtual address space
@@ -206,4 +208,8 @@ rt_ubase_t rt_kmem_pvoff(void);
void rt_kmem_pvoff_set(rt_ubase_t pvoff);
+int rt_kmem_map_phy(void *va, void *pa, rt_size_t length, rt_size_t attr);
+
+void *rt_kmem_v2p(void *vaddr);
+
#endif /* __MM_ASPACE_H__ */