Browse Source

!480 优化关中断时间
Merge pull request !480 from jesven/opt_disable_int

bernard 3 years ago
parent
commit
1fd211b7ec

+ 0 - 6
components/drivers/tty/console.c

@@ -211,7 +211,6 @@ static rt_size_t rt_console_write(struct rt_device *dev,
         const void       *buffer,
         rt_size_t         size)
 {
-    rt_base_t level = 0;
     rt_size_t len = 0;
     struct tty_struct *console = RT_NULL;
 
@@ -219,16 +218,13 @@ static rt_size_t rt_console_write(struct rt_device *dev,
     RT_ASSERT(console != RT_NULL);
     RT_ASSERT(console->init_flag == TTY_INIT_FLAG_INITED);
 
-    level = rt_hw_interrupt_disable();
     len = rt_device_write((struct rt_device *)console->driver, -1, buffer, size);
-    rt_hw_interrupt_enable(level);
 
     return len;
 }
 
 static rt_err_t  rt_console_control(rt_device_t dev, int cmd, void *args)
 {
-    rt_base_t level = 0;
     rt_size_t len = 0;
     struct tty_struct *console = RT_NULL;
 
@@ -236,9 +232,7 @@ static rt_err_t  rt_console_control(rt_device_t dev, int cmd, void *args)
     RT_ASSERT(console != RT_NULL);
     RT_ASSERT(console->init_flag == TTY_INIT_FLAG_INITED);
 
-    level = rt_hw_interrupt_disable();
     len = rt_device_control((struct rt_device *)console->driver, cmd, args);
-    rt_hw_interrupt_enable(level);
 
     return len;
 }

+ 1 - 19
components/drivers/tty/n_tty.c

@@ -701,11 +701,8 @@ static int do_output_char(unsigned char c, struct tty_struct *tty)
 static int process_output(unsigned char c, struct tty_struct *tty)
 {
     int retval = 0;
-    int level = 0;
 
-    level = rt_hw_interrupt_disable();
     retval = do_output_char(c, tty);
-    rt_hw_interrupt_enable(level);
     if (retval < 0)
     {
         return -1;
@@ -742,9 +739,6 @@ static ssize_t process_output_block(struct tty_struct *tty,
     int i = 0;
     ssize_t size = 0;
     const char *cp = RT_NULL;
-    int level = 0;
-
-    level = rt_hw_interrupt_disable();
 
     for (i = 0, cp = buf; i < nr; i++, cp++)
     {
@@ -803,7 +797,6 @@ static ssize_t process_output_block(struct tty_struct *tty,
     }
 break_out:
     size = rt_device_write((rt_device_t)tty, -1, buf, i);
-    rt_hw_interrupt_enable(level);
     return size;
 }
 
@@ -950,7 +943,6 @@ static void commit_echoes(struct tty_struct *tty)
     struct n_tty_data *ldata = tty->disc_data;
     size_t nr = 0, old = 0;
     size_t head = 0;
-    int level = 0;
 
     head = ldata->echo_head;
     ldata->echo_mark = head;
@@ -965,32 +957,27 @@ static void commit_echoes(struct tty_struct *tty)
         return;
     }
 
-    level = rt_hw_interrupt_disable();
     ldata->echo_commit = head;
     __process_echoes(tty);
-    rt_hw_interrupt_enable(level);
 }
 
 static void process_echoes(struct tty_struct *tty)
 {
     struct n_tty_data *ldata = tty->disc_data;
-    int level = 0;
+
     if (ldata->echo_mark == ldata->echo_tail)
     {
         return;
     }
 
-    level = rt_hw_interrupt_disable();
     ldata->echo_commit = ldata->echo_mark;
     __process_echoes(tty);
-    rt_hw_interrupt_enable(level);
 }
 
 /* NB: echo_mark and echo_head should be equivalent here */
 static void flush_echoes(struct tty_struct *tty)
 {
     struct n_tty_data *ldata = tty->disc_data;
-    int level = 0;
 
     if ((!L_ECHO(tty) && !L_ECHONL(tty)) ||
         ldata->echo_commit == ldata->echo_head)
@@ -998,10 +985,8 @@ static void flush_echoes(struct tty_struct *tty)
         return;
     }
 
-    level = rt_hw_interrupt_disable();
     ldata->echo_commit = ldata->echo_head;
     __process_echoes(tty);
-    rt_hw_interrupt_enable(level);
 }
 /**
  *  n_tty_set_termios   -   termios data changed
@@ -1965,12 +1950,9 @@ static int n_tty_write(struct dfs_fd *fd, const void *buf, size_t count)
         }
         else
         {
-            int level = 0;
             while (count > 0)
             {
-                level = rt_hw_interrupt_disable();
                 c = rt_device_write((rt_device_t)tty, -1, b, count);
-                rt_hw_interrupt_enable(level);
                 if (c < 0)
                 {
                     retval = c;

+ 4 - 6
components/lwp/ioremap.c

@@ -36,7 +36,6 @@ static void _iounmap_range(void *addr, size_t size)
 
 static void *_ioremap_type(void *paddr, size_t size, int type)
 {
-    rt_base_t level;
     void *v_addr = NULL;
     size_t attr;
 
@@ -52,7 +51,7 @@ static void *_ioremap_type(void *paddr, size_t size, int type)
         return v_addr;
     }
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     v_addr = rt_hw_mmu_map(&mmu_info, 0, paddr, size, attr);
     if (v_addr)
     {
@@ -63,7 +62,7 @@ static void *_ioremap_type(void *paddr, size_t size, int type)
             v_addr = NULL;
         }
     }
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
     return v_addr;
 }
 
@@ -84,10 +83,9 @@ void *rt_ioremap_cached(void *paddr, size_t size)
 
 void rt_iounmap(volatile void *vaddr)
 {
-    rt_base_t level;
     struct lwp_avl_struct *ma_avl_node;
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     ma_avl_node = lwp_map_find(k_map_area, (size_t)vaddr);
     if (ma_avl_node)
     {
@@ -96,7 +94,7 @@ void rt_iounmap(volatile void *vaddr)
         _iounmap_range((void *)ma->addr, ma->size);
         lwp_map_area_remove(&k_map_area, (size_t)vaddr);
     }
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
 }
 
 #else

+ 1 - 1
components/lwp/lwp.c

@@ -1021,8 +1021,8 @@ void lwp_cleanup(struct rt_thread *tid)
 
     lwp_tid_put(tid->tid);
     rt_list_remove(&tid->sibling);
-    lwp_ref_dec(lwp);
     rt_hw_interrupt_enable(level);
+    lwp_ref_dec(lwp);
 
     return;
 }

+ 34 - 31
components/lwp/lwp_pid.c

@@ -307,35 +307,33 @@ struct rt_lwp* lwp_new(void)
     rt_base_t level;
     struct rt_lwp* lwp = RT_NULL;
 
-    level = rt_hw_interrupt_disable();
-
-    pid = lwp_pid_get();
-    if (pid == 0)
-    {
-        LOG_E("pid slot fulled!\n");
-        goto out;
-    }
     lwp = (struct rt_lwp *)rt_malloc(sizeof(struct rt_lwp));
     if (lwp == RT_NULL)
     {
-        lwp_pid_put(pid);
-        LOG_E("no memory for lwp struct!\n");
-        goto out;
+        return lwp;
     }
     rt_memset(lwp, 0, sizeof(*lwp));
+    //lwp->tgroup_leader = RT_NULL;
     rt_list_init(&lwp->wait_list);
-    lwp->pid = pid;
     lwp->leader = 0;
     lwp->session = -1;
     lwp->tty = RT_NULL;
-    //lwp->tgroup_leader = RT_NULL;
-    lwp_pid_set_lwp(pid, lwp);
     rt_list_init(&lwp->t_grp);
     lwp_user_object_lock_init(lwp);
     lwp->address_search_head = RT_NULL;
     rt_wqueue_init(&lwp->wait_queue);
-
     lwp->ref = 1;
+
+    level = rt_hw_interrupt_disable();
+    pid = lwp_pid_get();
+    if (pid == 0)
+    {
+        rt_free(lwp);
+        LOG_E("pid slot fulled!\n");
+        goto out;
+    }
+    lwp->pid = pid;
+    lwp_pid_set_lwp(pid, lwp);
 out:
     rt_hw_interrupt_enable(level);
     return lwp;
@@ -353,8 +351,9 @@ void lwp_free(struct rt_lwp* lwp)
     LOG_D("lwp free: %p\n", lwp);
 
     level = rt_hw_interrupt_disable();
-
     lwp->finish = 1;
+    rt_hw_interrupt_enable(level);
+
     if (lwp->args != RT_NULL)
     {
 #ifndef ARCH_MM_MMU
@@ -410,6 +409,7 @@ void lwp_free(struct rt_lwp* lwp)
     lwp_unmap_user_space(lwp);
 #endif
 
+    level = rt_hw_interrupt_disable();
     /* for children */
     while (lwp->first_child)
     {
@@ -420,7 +420,9 @@ void lwp_free(struct rt_lwp* lwp)
         if (child->finish)
         {
             lwp_pid_put(lwp_to_pid(child));
+            rt_hw_interrupt_enable(level);
             rt_free(child);
+            level = rt_hw_interrupt_disable();
         }
         else
         {
@@ -429,6 +431,7 @@ void lwp_free(struct rt_lwp* lwp)
         }
     }
 
+    rt_hw_interrupt_enable(level);
     /* for parent */
     {
         struct termios *old_stdin_termios = get_old_termios();
@@ -437,6 +440,7 @@ void lwp_free(struct rt_lwp* lwp)
         {
             tcsetattr(1, 0, old_stdin_termios);
         }
+        level = rt_hw_interrupt_disable();
         if (lwp->tty != RT_NULL)
         {
             if (lwp->tty->foreground == lwp)
@@ -470,10 +474,9 @@ void lwp_free(struct rt_lwp* lwp)
             }
         }
         lwp_pid_put(lwp_to_pid(lwp));
+        rt_hw_interrupt_enable(level);
         rt_free(lwp);
     }
-
-    rt_hw_interrupt_enable(level);
 }
 
 void lwp_ref_inc(struct rt_lwp *lwp)
@@ -488,32 +491,32 @@ void lwp_ref_inc(struct rt_lwp *lwp)
 void lwp_ref_dec(struct rt_lwp *lwp)
 {
     rt_base_t level;
-    int ref;
+    int ref = -1;
 
     level = rt_hw_interrupt_disable();
     if (lwp->ref)
     {
         lwp->ref--;
         ref = lwp->ref;
-        if (!ref)
-        {
-            struct rt_channel_msg msg;
+    }
+    rt_hw_interrupt_enable(level);
+    if (!ref)
+    {
+        struct rt_channel_msg msg;
 
-            if (lwp->debug)
-            {
-                memset(&msg, 0, sizeof msg);
-                rt_raw_channel_send(gdb_server_channel(), &msg);
-            }
+        if (lwp->debug)
+        {
+            memset(&msg, 0, sizeof msg);
+            rt_raw_channel_send(gdb_server_channel(), &msg);
+        }
 
 #ifndef ARCH_MM_MMU
 #ifdef RT_LWP_USING_SHM
-            lwp_shm_lwp_free(lwp);
+        lwp_shm_lwp_free(lwp);
 #endif /* RT_LWP_USING_SHM */
 #endif /* not defined ARCH_MM_MMU */
-            lwp_free(lwp);
-        }
+        lwp_free(lwp);
     }
-    rt_hw_interrupt_enable(level);
 }
 
 struct rt_lwp* lwp_from_pid(pid_t pid)

+ 16 - 25
components/lwp/lwp_shm.c

@@ -146,11 +146,10 @@ err:
 int lwp_shmget(size_t key, size_t size, int create)
 {
     int ret = 0;
-    rt_base_t level = 0;
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     ret = _lwp_shmget(key, size, create);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
     return ret;
 }
 
@@ -211,11 +210,10 @@ static int _lwp_shmrm(int id)
 int lwp_shmrm(int id)
 {
     int ret = 0;
-    rt_base_t level = 0;
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     ret = _lwp_shmrm(id);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
     return ret;
 }
 
@@ -257,15 +255,14 @@ static void *_lwp_shmat(int id, void *shm_vaddr)
 void *lwp_shmat(int id, void *shm_vaddr)
 {
     void *ret = RT_NULL;
-    rt_base_t level = 0;
 
     if (((size_t)shm_vaddr & ARCH_PAGE_MASK) != 0)
     {
         return RT_NULL;
     }
-    level= rt_hw_interrupt_disable();
+    rt_mm_lock();
     ret = _lwp_shmat(id, shm_vaddr);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
     return ret;
 }
 
@@ -303,11 +300,10 @@ static int _lwp_shm_ref_inc(struct rt_lwp *lwp, void *shm_vaddr)
 int lwp_shm_ref_inc(struct rt_lwp *lwp, void *shm_vaddr)
 {
     int ret = 0;
-    rt_base_t level = 0;
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     ret = _lwp_shm_ref_inc(lwp, shm_vaddr);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
 
     return ret;
 }
@@ -327,11 +323,10 @@ static int _lwp_shm_ref_dec(struct rt_lwp *lwp, void *shm_vaddr)
 int lwp_shm_ref_dec(struct rt_lwp *lwp, void *shm_vaddr)
 {
     int ret = 0;
-    rt_base_t level = 0;
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     ret = _lwp_shm_ref_dec(lwp, shm_vaddr);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
 
     return ret;
 }
@@ -359,11 +354,10 @@ int _lwp_shmdt(void *shm_vaddr)
 int lwp_shmdt(void *shm_vaddr)
 {
     int ret = 0;
-    rt_base_t level = 0;
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     ret = _lwp_shmdt(shm_vaddr);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
 
     return ret;
 }
@@ -389,11 +383,10 @@ void *_lwp_shminfo(int id)
 void *lwp_shminfo(int id)
 {
     void *vaddr = RT_NULL;
-    rt_base_t level = 0;
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     vaddr = _lwp_shminfo(id);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
     return vaddr;
 }
 
@@ -410,13 +403,11 @@ static int _shm_info(struct lwp_avl_struct* node_key, void *data)
 
 void list_shm(void)
 {
-    rt_base_t level = 0;
-
     rt_kprintf("   key        paddr      size       id\n");
     rt_kprintf("---------- ---------- ---------- --------\n");
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     lwp_avl_traversal(shm_tree_key, _shm_info, NULL);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
 }
 MSH_CMD_EXPORT(list_shm, show share memory info);
 #endif

+ 1 - 1
components/lwp/lwp_signal.c

@@ -552,7 +552,7 @@ int lwp_kill(pid_t pid, int sig)
     }
     level = rt_hw_interrupt_disable();
     lwp = lwp_from_pid(pid);
-    if (!lwp)
+    if (!lwp || lwp->finish)
     {
         rt_set_errno(ESRCH);
         goto out;

+ 13 - 19
components/lwp/lwp_user_mm.c

@@ -124,16 +124,15 @@ static void *_lwp_map_user(struct rt_lwp *lwp, void *map_va, size_t map_size, in
 
 int lwp_unmap_user(struct rt_lwp *lwp, void *va)
 {
-    rt_base_t level = 0;
     struct lwp_avl_struct *ma_avl_node = RT_NULL;
     struct rt_mm_area_struct *ma = RT_NULL;
     int pa_need_free = 0;
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     ma_avl_node = lwp_map_find(lwp->map_area, (size_t)va);
     if (!ma_avl_node)
     {
-        rt_hw_interrupt_enable(level);
+        rt_mm_unlock();
         return -1;
     }
     ma = (struct rt_mm_area_struct *)ma_avl_node->data;
@@ -145,7 +144,7 @@ int lwp_unmap_user(struct rt_lwp *lwp, void *va)
     }
     unmap_range(lwp, (void *)ma->addr, ma->size, pa_need_free);
     lwp_map_area_remove(&lwp->map_area, (size_t)va);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
     return 0;
 }
 
@@ -225,7 +224,6 @@ int lwp_unmap_user_type(struct rt_lwp *lwp, void *va)
 
 void *lwp_map_user(struct rt_lwp *lwp, void *map_va, size_t map_size, int text)
 {
-    rt_base_t level = 0;
     void *ret = RT_NULL;
     size_t offset = 0;
 
@@ -238,9 +236,9 @@ void *lwp_map_user(struct rt_lwp *lwp, void *map_va, size_t map_size, int text)
     map_size &= ~ARCH_PAGE_MASK;
     map_va = (void *)((size_t)map_va & ~ARCH_PAGE_MASK);
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     ret = _lwp_map_user(lwp, map_va, map_size, text);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
     if (ret)
     {
         ret = (void *)((char *)ret + offset);
@@ -283,7 +281,6 @@ static void *_lwp_map_user_type(struct rt_lwp *lwp, void *map_va, void *map_pa,
 
 void *lwp_map_user_type(struct rt_lwp *lwp, void *map_va, void *map_pa, size_t map_size, int cached, int type)
 {
-    rt_base_t level = 0;
     void *ret = RT_NULL;
     size_t offset = 0;
 
@@ -303,9 +300,9 @@ void *lwp_map_user_type(struct rt_lwp *lwp, void *map_va, void *map_pa, size_t m
     map_size &= ~ARCH_PAGE_MASK;
     map_pa = (void *)((size_t)map_pa & ~ARCH_PAGE_MASK);
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     ret = _lwp_map_user_type(lwp, map_va, map_pa, map_size, cached, type);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
     if (ret)
     {
         ret = (void *)((char *)ret + offset);
@@ -320,11 +317,10 @@ void *lwp_map_user_phy(struct rt_lwp *lwp, void *map_va, void *map_pa, size_t ma
 
 rt_base_t lwp_brk(void *addr)
 {
-    rt_base_t level = 0;
     rt_base_t ret = -1;
     struct rt_lwp *lwp = RT_NULL;
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     lwp = rt_thread_self()->lwp;
 
     if ((size_t)addr <= lwp->end_heap)
@@ -347,7 +343,7 @@ rt_base_t lwp_brk(void *addr)
             ret = lwp->end_heap;
         }
     }
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
     return ret;
 }
 
@@ -356,16 +352,15 @@ rt_base_t lwp_brk(void *addr)
 void* lwp_mmap2(void *addr, size_t length, int prot,
         int flags, int fd, off_t pgoffset)
 {
-    rt_base_t level = 0;
     void *ret = (void *)-1;
     struct rt_lwp *lwp = RT_NULL;
 
     if (fd == -1)
     {
         lwp = rt_thread_self()->lwp;
-        level = rt_hw_interrupt_disable();
+        rt_mm_lock();
         ret = lwp_map_user(lwp, addr, length, 0);
-        rt_hw_interrupt_enable(level);
+        rt_mm_unlock();
         if (ret)
         {
             if ((flags & MAP_ANONYMOUS) != 0)
@@ -383,14 +378,13 @@ void* lwp_mmap2(void *addr, size_t length, int prot,
 
 int lwp_munmap(void *addr)
 {
-    rt_base_t level = 0;
     int ret = 0;
     struct rt_lwp *lwp = RT_NULL;
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     lwp = rt_thread_self()->lwp;
     ret = lwp_unmap_user(lwp, addr);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
     return ret;
 }
 

+ 45 - 38
libcpu/aarch64/common/mmu.c

@@ -34,6 +34,34 @@
 #define MMU_TBL_PAGE_4k_LEVEL  3
 #define MMU_TBL_LEVEL_NR       4
 
+static rt_mutex_t mm_lock;
+
+void rt_mm_lock(void)
+{
+    if (rt_thread_self())
+    {
+        if (!mm_lock)
+        {
+            mm_lock = rt_mutex_create("mm_lock", RT_IPC_FLAG_FIFO);
+        }
+        if (mm_lock)
+        {
+            rt_mutex_take(mm_lock, RT_WAITING_FOREVER);
+        }
+    }
+}
+
+void rt_mm_unlock(void)
+{
+    if (rt_thread_self())
+    {
+        if (mm_lock)
+        {
+            rt_mutex_release(mm_lock);
+        }
+    }
+}
+
 void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void *v_addr);
 
 struct page_table
@@ -502,7 +530,6 @@ void rt_hw_mmu_setup(struct mem_desc *mdesc, int desc_nr)
  */
 int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void *v_address, size_t size, size_t *vtable, size_t pv_off)
 {
-    rt_base_t level;
     size_t va_s, va_e;
 
     if (!mmu_info || !vtable)
@@ -526,15 +553,11 @@ int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void *v_address, size_t size, size
         return -1;
     }
 
-    level = rt_hw_interrupt_disable();
-
     mmu_info->vtable = vtable;
     mmu_info->vstart = va_s;
     mmu_info->vend = va_e;
     mmu_info->pv_off = pv_off;
 
-    rt_hw_interrupt_enable(level);
-
     return 0;
 }
 
@@ -712,38 +735,22 @@ void *_rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void *p_addr, size_t s
     }
     if (vaddr)
     {
+        rt_enter_critical();
         ret = __rt_hw_mmu_map(mmu_info, (void *)vaddr, p_addr, pages, attr);
         if (ret == 0)
         {
             rt_hw_cpu_tlb_invalidate();
+            rt_exit_critical();
             return (void *)(vaddr + ((size_t)p_addr & ARCH_PAGE_MASK));
         }
+        rt_exit_critical();
     }
     return 0;
 }
 #else
 void *_rt_hw_mmu_map(rt_mmu_info *mmu_info, void* p_addr, size_t size, size_t attr)
 {
-    size_t pa_s, pa_e;
-    size_t vaddr;
-    int pages;
-    int ret;
-
-    pa_s = (size_t)p_addr;
-    pa_e = (size_t)p_addr + size - 1;
-    pa_s >>= ARCH_PAGE_SHIFT;
-    pa_e >>= ARCH_PAGE_SHIFT;
-    pages = pa_e - pa_s + 1;
-    vaddr = find_vaddr(mmu_info, pages);
-    if (vaddr) {
-        //TODO ret = __rt_hw_mmu_map(mmu_info, (void*)vaddr, p_addr, pages, attr);
-        if (ret == 0)
-        {
-            rt_hw_cpu_tlb_invalidate();
-            return (void*)(vaddr + ((size_t)p_addr & ARCH_PAGE_MASK));
-        }
-    }
-    return 0;
+    return p_addr;
 }
 #endif
 
@@ -819,12 +826,15 @@ void *_rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size
     }
     if (vaddr)
     {
+        rt_enter_critical();
         ret = __rt_hw_mmu_map_auto(mmu_info, (void *)vaddr, pages, attr);
         if (ret == 0)
         {
             rt_hw_cpu_tlb_invalidate();
+            rt_exit_critical();
             return (void *)((char *)vaddr + offset);
         }
+        rt_exit_critical();
     }
     return 0;
 }
@@ -839,39 +849,37 @@ void _rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void *v_addr, size_t size)
     va_s >>= ARCH_PAGE_SHIFT;
     va_e >>= ARCH_PAGE_SHIFT;
     pages = va_e - va_s + 1;
+    rt_enter_critical();
     __rt_hw_mmu_unmap(mmu_info, v_addr, pages);
     rt_hw_cpu_tlb_invalidate();
+    rt_exit_critical();
 }
 
 void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void *p_addr, size_t size, size_t attr)
 {
     void *ret;
-    rt_base_t level;
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     ret = _rt_hw_mmu_map(mmu_info, v_addr, p_addr, size, attr);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
     return ret;
 }
 
 void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr)
 {
     void *ret;
-    rt_base_t level;
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     ret = _rt_hw_mmu_map_auto(mmu_info, v_addr, size, attr);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
     return ret;
 }
 
 void rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void *v_addr, size_t size)
 {
-    rt_base_t level;
-
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     _rt_hw_mmu_unmap(mmu_info, v_addr, size);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
 }
 #endif
 
@@ -927,11 +935,10 @@ void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void *v_addr)
 void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void *v_addr)
 {
     void *ret;
-    rt_base_t level;
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     ret = _rt_hw_mmu_v2p(mmu_info, v_addr);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
     return ret;
 }
 

+ 2 - 0
libcpu/aarch64/common/mmu.h

@@ -132,5 +132,7 @@ void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void* p_addr, size_t size, size_t att
 
 void rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t size);
 void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr);
+void rt_mm_lock(void);
+void rt_mm_unlock(void);
 
 #endif

+ 47 - 19
libcpu/arm/cortex-a/mmu.c

@@ -19,6 +19,34 @@
 #include "page.h"
 #endif
 
+static rt_mutex_t mm_lock;
+
+void rt_mm_lock(void)
+{
+    if (rt_thread_self())
+    {
+        if (!mm_lock)
+        {
+            mm_lock = rt_mutex_create("mm_lock", RT_IPC_FLAG_FIFO);
+        }
+        if (mm_lock)
+        {
+            rt_mutex_take(mm_lock, RT_WAITING_FOREVER);
+        }
+    }
+}
+
+void rt_mm_unlock(void)
+{
+    if (rt_thread_self())
+    {
+        if (mm_lock)
+        {
+            rt_mutex_release(mm_lock);
+        }
+    }
+}
+
 /* dump 2nd level page table */
 void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb)
 {
@@ -195,7 +223,6 @@ void rt_hw_cpu_dcache_clean(void *addr, int size);
 int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void* v_address, size_t size, size_t *vtable, size_t pv_off)
 {
     size_t l1_off, va_s, va_e;
-    rt_base_t level;
 
     if (!mmu_info || !vtable)
     {
@@ -218,15 +245,12 @@ int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void* v_address, size_t size, size
         return -1;
     }
 
-    level = rt_hw_interrupt_disable();
-
     for (l1_off = va_s; l1_off <= va_e; l1_off++)
     {
         size_t v = vtable[l1_off];
 
         if (v & ARCH_MMU_USED_MASK)
         {
-            rt_hw_interrupt_enable(level);
             return -1;
         }
     }
@@ -236,8 +260,6 @@ int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void* v_address, size_t size, size
     mmu_info->vend = va_e;
     mmu_info->pv_off = pv_off;
 
-    rt_hw_interrupt_enable(level);
-
     return 0;
 }
 
@@ -591,12 +613,15 @@ void *_rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void* p_addr, size_t s
         vaddr = find_vaddr(mmu_info, pages);
     }
     if (vaddr) {
+        rt_enter_critical();
         ret = __rt_hw_mmu_map(mmu_info, (void*)vaddr, p_addr, pages, attr);
         if (ret == 0)
         {
             rt_hw_cpu_tlb_invalidate();
+            rt_exit_critical();
             return (void*)(vaddr + ((size_t)p_addr & ARCH_PAGE_MASK));
         }
+        rt_exit_critical();
     }
     return 0;
 }
@@ -615,12 +640,15 @@ void *_rt_hw_mmu_map(rt_mmu_info *mmu_info, void* p_addr, size_t size, size_t at
     pages = pa_e - pa_s + 1;
     vaddr = find_vaddr(mmu_info, pages);
     if (vaddr) {
+        rt_enter_critical();
         ret = __rt_hw_mmu_map(mmu_info, (void*)vaddr, p_addr, pages, attr);
         if (ret == 0)
         {
             rt_hw_cpu_tlb_invalidate();
+            rt_exit_critical();
             return (void*)(vaddr + ((size_t)p_addr & ARCH_PAGE_MASK));
         }
+        rt_exit_critical();
     }
     return 0;
 }
@@ -728,12 +756,15 @@ void *_rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size
         vaddr = find_vaddr(mmu_info, pages);
     }
     if (vaddr) {
+        rt_enter_critical();
         ret = __rt_hw_mmu_map_auto(mmu_info, (void*)vaddr, pages, attr);
         if (ret == 0)
         {
             rt_hw_cpu_tlb_invalidate();
+            rt_exit_critical();
             return (void*)((char*)vaddr + offset);
         }
+        rt_exit_critical();
     }
     return 0;
 }
@@ -749,41 +780,39 @@ void _rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t size)
     va_s >>= ARCH_PAGE_SHIFT;
     va_e >>= ARCH_PAGE_SHIFT;
     pages = va_e - va_s + 1;
+    rt_enter_critical();
     __rt_hw_mmu_unmap(mmu_info, v_addr, pages);
     rt_hw_cpu_tlb_invalidate();
+    rt_exit_critical();
 }
 
 #ifdef RT_USING_USERSPACE
 void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void* p_addr, size_t size, size_t attr)
 {
     void *ret;
-    rt_base_t level;
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     ret = _rt_hw_mmu_map(mmu_info, v_addr, p_addr, size, attr);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
     return ret;
 }
 
 void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr)
 {
     void *ret;
-    rt_base_t level;
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     ret = _rt_hw_mmu_map_auto(mmu_info, v_addr, size, attr);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
     return ret;
 }
 #endif
 
 void rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t size)
 {
-    rt_base_t level;
-
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     _rt_hw_mmu_unmap(mmu_info, v_addr, size);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
 }
 
 void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr)
@@ -842,11 +871,10 @@ void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr)
 void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr)
 {
     void *ret;
-    rt_base_t level;
 
-    level = rt_hw_interrupt_disable();
+    rt_mm_lock();
     ret = _rt_hw_mmu_v2p(mmu_info, v_addr);
-    rt_hw_interrupt_enable(level);
+    rt_mm_unlock();
     return ret;
 }
 

+ 3 - 0
libcpu/arm/cortex-a/mmu.h

@@ -108,4 +108,7 @@ void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void* p_addr, size_t size, size_t att
 void rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t size);
 void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr);
 
+void rt_mm_lock(void);
+void rt_mm_unlock(void);
+
 #endif