shaojinchun 4 лет назад
Родитель
Сommit
3959a82071

+ 35 - 3
components/finsh/msh.c

@@ -296,6 +296,12 @@ static int _msh_exec_cmd(char *cmd, rt_size_t length, int *retp)
     return 0;
 }
 
+#ifdef RT_USING_GDBSERVER
+pid_t exec(char*, int, int, char**);
+#else
+pid_t exec(char*, int, char**);
+#endif
+
 #if defined(RT_USING_LWP) && defined(RT_USING_DFS)
 static int _msh_exec_lwp(char *cmd, rt_size_t length)
 {
@@ -304,8 +310,9 @@ static int _msh_exec_lwp(char *cmd, rt_size_t length)
     char *argv[FINSH_ARG_MAX];
     int fd = -1;
     char *pg_name;
-
-    extern int exec(char*, int, char**);
+#ifdef RT_USING_GDBSERVER
+    int debug = 0;
+#endif
 
     /* find the size of first command */
     while ((cmd[cmd0_size] != ' ' && cmd[cmd0_size] != '\t') && cmd0_size < length)
@@ -313,6 +320,27 @@ static int _msh_exec_lwp(char *cmd, rt_size_t length)
     if (cmd0_size == 0)
         return -1;
 
+#ifdef RT_USING_GDBSERVER
+    if ((cmd0_size == sizeof "gdb" - 1) && (memcmp(cmd, "gdb", sizeof "gdb" - 1) == 0))
+    {
+        cmd += cmd0_size;
+        length -= cmd0_size;
+        while (*cmd  == ' ' || *cmd == '\t')
+        {
+            cmd++;
+            length--;
+        }
+
+        if (length == 0)
+        {
+            rt_kprintf("Usage: gdb FILE...\n");
+            return 0;
+        }
+
+        debug = 1;
+    }
+#endif
+
     /* split arguments */
     rt_memset(argv, 0x00, sizeof(argv));
     argc = msh_split(cmd, length, argv);
@@ -354,8 +382,12 @@ static int _msh_exec_lwp(char *cmd, rt_size_t length)
 
     /* found program */
     close(fd);
-    exec(pg_name, argc, argv);
 
+#ifdef RT_USING_GDBSERVER
+    exec(pg_name, debug, argc, argv);
+#else
+    exec(pg_name, argc, argv);
+#endif
     if (pg_name != argv[0])
         rt_free(pg_name);
 

+ 4 - 3
components/lwp/arch/aarch64/cortex-a/lwp_gcc.S

@@ -198,9 +198,10 @@ SVC_Handler:
     bl  lwp_user_setting_save
 
     ldp x8, x9, [sp, #(CONTEXT_OFFSET_X8)]
-    uxtb x0, w8
-    cmp x0, #0xfe
+    and x0, x8, #0xf000
+    cmp x0, #0xe000
     beq lwp_signal_quit
+    uxtb x0, w8
     bl lwp_get_sys_api
     cmp x0, xzr
     mov x30, x0
@@ -395,7 +396,7 @@ user_do_signal:
     eret
 
 lwp_sigreturn:
-    mov x8, #0xfe
+    mov x8, #0xe000
     svc #0
 
 lwp_thread_return:

+ 5 - 0
components/lwp/arch/arm/cortex-a/lwp_arch.h

@@ -38,6 +38,11 @@ rt_inline unsigned long ffz(unsigned long x)
     return __builtin_ffs(~x) - 1;
 }
 
+rt_inline void icache_invalid_all(void)
+{
+    asm volatile ("mcr p15, 0, r0, c7, c5, 0\ndsb\nisb":::"memory");//iciallu
+}
+
 #ifdef __cplusplus
 }
 #endif

+ 7 - 5
components/lwp/arch/arm/cortex-a/lwp_gcc.S

@@ -153,13 +153,15 @@ vector_swi:
     bl rt_thread_self
     bl lwp_user_setting_save
 
-    and r0, r7, #0xff
-    cmp r0, #0xfe
+    and r0, r7, #0xf000
+    cmp r0, #0xe000
     beq lwp_signal_quit
+
 #ifdef RT_USING_GDBSERVER
-    cmp r0, #0xff
+    cmp r0, #0xf000
     beq ret_from_user
 #endif
+    and r0, r7, #0xff
     bl lwp_get_sys_api
     cmp r0, #0           /* r0 = api */
     mov lr, r0
@@ -304,11 +306,11 @@ user_do_signal:
     movs pc, lr
 
 lwp_debugreturn:
-    mov r7, #0xff
+    mov r7, #0xf000
     svc #0
 
 lwp_sigreturn:
-    mov r7, #0xfe
+    mov r7, #0xe000
     svc #0
 
 lwp_thread_return:

+ 74 - 71
libcpu/arm/cortex-a/trap.c

@@ -35,83 +35,86 @@ static int check_debug_event(struct rt_hw_exp_stack *regs, uint32_t pc_adj)
 {
     uint32_t mode = regs->cpsr;
 
-    if ((mode & 0x1f) == 0x10)
+    if ((mode & 0x1f) == 0x10) /* is user mode */
     {
-        /*
+        struct rt_channel_msg msg;
+        gdb_thread_info thread_info;
         uint32_t ifsr, dfar, dfsr;
-        */
-        uint32_t ifsr, dfar;
         int ret;
 
-        asm volatile ("MRC p15, 0, %0, c5, c0, 1":"=r"(ifsr));
-        ifsr &= ((1UL << 10) | 0xfUL);
-        if (ifsr == 0x2UL)
+        if (pc_adj == 4) /* pabt */
         {
-            uint32_t dbgdscr;
-            struct rt_channel_msg msg;
-            gdb_thread_info thread_info;
-
-            regs->pc -= pc_adj;
-
-            asm volatile ("MRC p14, 0, %0, c0, c1, 0":"=r"(dbgdscr));
-            switch ((dbgdscr & (0xfUL << 2)))
+            /* check breakpoint event */
+            asm volatile ("MRC p15, 0, %0, c5, c0, 1":"=r"(ifsr));
+            ifsr &= ((1UL << 12) | 0x3fUL); /* status */
+            if (ifsr == 0x2UL)
             {
-                case (0x1UL << 2): //breadkpoint
-                case (0x3UL << 2): //bkpt
-                    do {
-                        struct rt_lwp *gdb_lwp = gdb_get_dbg_lwp();
-                        struct rt_lwp *lwp;
-
-                        if (!gdb_lwp)
-                        {
-                            break;
-                        }
-                        lwp = lwp_self();
-                        if (lwp == gdb_lwp)
-                        {
-                            break;
-                        }
-                        *(uint32_t*)regs->pc = lwp->bak_first_ins;
-                        rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void*)regs->pc, 4);
-                        icache_invalid_all();
-                        lwp->debug = 0;
-                        return 1;
-                    } while (0);
-
-                    thread_info.notify_type = GDB_NOTIFIY_BREAKPOINT;
-                    thread_info.abt_ins = *(uint32_t*)regs->pc;
-                    ret = 1;
-                    break;
-                case (0xaUL << 2): //watchpoint
-                    asm volatile ("MRC p15, 0, %0, c6, c0, 0":"=r"(dfar));
-                    thread_info.watch_addr = (void*)dfar;
-                    /*
-                    asm volatile ("MRC p15, 0, %0, c5, c0, 0":"=r"(dfsr));
-                    thread_info.rw = (1UL << ((dfsr >> 11) & 1UL));
-                    */
-                    thread_info.rw = (1UL << (((~*(uint32_t*)regs->pc) >> 20) & 1UL));
-                    thread_info.notify_type = GDB_NOTIFIY_WATCHPOINT;
-                    ret =  2;
-                    break;
-                default:
-                    return 0;
+                /* is breakpoint event */
+                regs->pc -= pc_adj;
+                do {
+                    struct rt_lwp *gdb_lwp = gdb_get_dbg_lwp();
+                    struct rt_lwp *lwp;
+
+                    if (!gdb_lwp)
+                    {
+                        break;
+                    }
+                    lwp = lwp_self();
+                    if (lwp == gdb_lwp)
+                    {
+                        break;
+                    }
+                    *(uint32_t *)regs->pc = lwp->bak_first_ins;
+                    rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)regs->pc, 4);
+                    icache_invalid_all();
+                    lwp->debug = 0;
+                    return 1;
+                } while (0);
+
+                thread_info.notify_type = GDB_NOTIFIY_BREAKPOINT;
+                thread_info.abt_ins = *(uint32_t *)regs->pc;
+                ret = 1;
             }
-            thread_info.thread = rt_thread_self();
-            thread_info.thread->regs = regs;
-            msg.u.d = (void*)&thread_info;
-            dmb();
-            thread_info.thread->debug_suspend = 1;
-            dsb();
-            rt_thread_suspend_witch_flag(thread_info.thread, RT_UNINTERRUPTIBLE);
-            rt_raw_channel_send(gdb_get_server_channel(), &msg);
-            rt_schedule();
-            while (thread_info.thread->debug_suspend)
+            else
+            {
+                return 0; /* not debug pabt */
+            }
+        }
+        else
+        {
+            /* watchpoing event */
+            asm volatile ("MRC p15, 0, %0, c5, c0, 0":"=r"(dfsr));
+            dfsr = (((dfsr & (1UL << 10)) >> 6) | (dfsr & 0xfUL)); /* status */
+            if (dfsr == 0x2UL)
+            {
+                /* is watchpoint event */
+                regs->pc -= pc_adj;
+                asm volatile ("MRC p15, 0, %0, c6, c0, 0":"=r"(dfar));
+                thread_info.watch_addr = (void *)dfar;
+                thread_info.rw = (1UL << (((~*(uint32_t *)regs->pc) >> 20) & 1UL));
+                thread_info.notify_type = GDB_NOTIFIY_WATCHPOINT;
+                ret =  2;
+            }
+            else
             {
-                rt_thread_suspend_witch_flag(thread_info.thread, RT_UNINTERRUPTIBLE);
-                rt_schedule();
+                return 0; /* not debug dabt */
             }
-            return ret;
         }
+        thread_info.thread = rt_thread_self();
+        thread_info.thread->regs = regs;
+        msg.u.d = (void *)&thread_info;
+        rt_hw_dmb();
+        thread_info.thread->debug_suspend = 1;
+        rt_hw_dsb();
+        rt_thread_suspend_with_flag(thread_info.thread, RT_UNINTERRUPTIBLE);
+        rt_raw_channel_send(gdb_get_server_channel(), &msg);
+        rt_schedule();
+        while (thread_info.thread->debug_suspend)
+        {
+            rt_thread_suspend_with_flag(thread_info.thread, RT_UNINTERRUPTIBLE);
+            rt_schedule();
+        }
+        return ret;
     }
     return 0;
 }
@@ -169,7 +172,7 @@ void rt_hw_show_register(struct rt_hw_exp_stack *regs)
         rt_kprintf("ttbr0:0x%08x\n", v);
         asm volatile ("MRC p15, 0, %0, c6, c0, 0":"=r"(v));
         rt_kprintf("dfar:0x%08x\n", v);
-        rt_kprintf("0x%08x -> 0x%08x\n", v, rt_hw_mmu_v2p(&mmu_info, (void*)v));
+        rt_kprintf("0x%08x -> 0x%08x\n", v, rt_hw_mmu_v2p(&mmu_info, (void *)v));
     }
 #endif
 }
@@ -196,18 +199,18 @@ void rt_hw_trap_undef(struct rt_hw_exp_stack *regs)
         {
             /* thumb mode */
             addr = regs->pc - 2;
-            ins = (uint32_t)*(uint16_t*)addr;
+            ins = (uint32_t)*(uint16_t *)addr;
             if ((ins & (3 << 11)) != 0)
             {
                 /* 32 bit ins */
                 ins <<= 16;
-                ins += *(uint16_t*)(addr + 2);
+                ins += *(uint16_t *)(addr + 2);
             }
         }
         else
         {
             addr = regs->pc - 4;
-            ins = *(uint32_t*)addr;
+            ins = *(uint32_t *)addr;
         }
         if ((ins & 0xe00) == 0xa00)
         {