Bläddra i källkod

Merge branch 'master' of https://github.com/RT-Thread/rt-thread

tyustli 6 år sedan
förälder
incheckning
8327200072
70 ändrade filer med 2441 tillägg och 3034 borttagningar
  1. 8 0
      bsp/es32f0334/.config
  2. 1 0
      bsp/es32f0334/README.md
  3. 24 1
      bsp/es32f0334/drivers/Kconfig
  4. 4 0
      bsp/es32f0334/drivers/SConscript
  5. 250 0
      bsp/es32f0334/drivers/drv_hwtimer.c
  6. 16 0
      bsp/es32f0334/drivers/drv_hwtimer.h
  7. 3 0
      bsp/es32f0334/rtconfig.h
  8. 8 0
      bsp/es32f0654/.config
  9. 5 2
      bsp/es32f0654/README.md
  10. 32 4
      bsp/es32f0654/drivers/Kconfig
  11. 4 0
      bsp/es32f0654/drivers/SConscript
  12. 252 0
      bsp/es32f0654/drivers/drv_hwtimer.c
  13. 16 0
      bsp/es32f0654/drivers/drv_hwtimer.h
  14. 2 6
      bsp/es32f0654/drivers/drv_pwm.c
  15. 3 0
      bsp/es32f0654/rtconfig.h
  16. 358 0
      bsp/imx6ul/.config
  17. 14 5
      bsp/imx6ul/drivers/board.c
  18. 1 3
      bsp/imx6ul/platform/SConscript
  19. 0 243
      bsp/imx6ul/platform/cpu/gic.c
  20. 0 285
      bsp/imx6ul/platform/cpu/mmu.c
  21. 0 157
      bsp/imx6ul/platform/cpu/mmu.h
  22. 96 0
      bsp/imx6ul/platform/cpu/platform.h
  23. 0 183
      bsp/imx6ul/platform/include/gic.h
  24. 0 101
      bsp/imx6ul/platform/include/interrupt.h
  25. 1 1
      bsp/imx6ul/rtconfig.py
  26. 1 0
      bsp/qemu-vexpress-a9/.config
  27. 13 0
      bsp/qemu-vexpress-a9/Makefile
  28. 2 2
      bsp/qemu-vexpress-a9/SConstruct
  29. 0 17
      bsp/qemu-vexpress-a9/cpu/SConscript
  30. 0 64
      bsp/qemu-vexpress-a9/cpu/armv7.h
  31. 0 198
      bsp/qemu-vexpress-a9/cpu/context_gcc.S
  32. 0 12
      bsp/qemu-vexpress-a9/cpu/cp15.h
  33. 0 140
      bsp/qemu-vexpress-a9/cpu/cp15_gcc.S
  34. 0 83
      bsp/qemu-vexpress-a9/cpu/cpuport.c
  35. 0 108
      bsp/qemu-vexpress-a9/cpu/interrupt.c
  36. 0 25
      bsp/qemu-vexpress-a9/cpu/interrupt.h
  37. 0 207
      bsp/qemu-vexpress-a9/cpu/mmu.c
  38. 0 12
      bsp/qemu-vexpress-a9/cpu/pmu.c
  39. 0 151
      bsp/qemu-vexpress-a9/cpu/pmu.h
  40. 0 71
      bsp/qemu-vexpress-a9/cpu/stack.c
  41. 0 447
      bsp/qemu-vexpress-a9/cpu/start_gcc.S
  42. 0 190
      bsp/qemu-vexpress-a9/cpu/trap.c
  43. 0 65
      bsp/qemu-vexpress-a9/cpu/vector_gcc.S
  44. 9 0
      bsp/qemu-vexpress-a9/drivers/board.c
  45. 13 0
      bsp/qemu-vexpress-a9/platform/SConscript
  46. 37 0
      bsp/qemu-vexpress-a9/platform/cpu/platform.h
  47. 149 0
      bsp/qemu-vexpress-a9/rtconfig.h
  48. 3 2
      bsp/qemu-vexpress-a9/rtconfig.py
  49. 8 26
      bsp/stm32/libraries/HAL_Drivers/drv_common.c
  50. 1 1
      components/lwp/SConscript
  51. 70 0
      components/lwp/arch/arm/cortex-a/lwp_gcc.S
  52. 92 0
      libcpu/arm/cortex-a/context_gcc.S
  53. 4 0
      libcpu/arm/cortex-a/cp15.h
  54. 14 1
      libcpu/arm/cortex-a/cp15_gcc.S
  55. 59 9
      libcpu/arm/cortex-a/cpu.c
  56. 14 12
      libcpu/arm/cortex-a/gic.c
  57. 9 7
      libcpu/arm/cortex-a/gic.h
  58. 47 72
      libcpu/arm/cortex-a/interrupt.c
  59. 32 0
      libcpu/arm/cortex-a/interrupt.h
  60. 14 35
      libcpu/arm/cortex-a/mmu.c
  61. 48 0
      libcpu/arm/cortex-a/mmu.h
  62. 5 1
      libcpu/arm/cortex-a/stack.c
  63. 99 13
      libcpu/arm/cortex-a/start_gcc.S
  64. 36 34
      libcpu/arm/cortex-a/trap.c
  65. 0 14
      libcpu/mips/xburst/SConscript.1
  66. 29 23
      src/kservice.c
  67. 7 1
      tools/building.py
  68. 299 0
      tools/eclipse.py
  69. 107 0
      tools/makefile.py
  70. 122 0
      tools/rtthread.mk

+ 8 - 0
bsp/es32f0334/.config

@@ -344,6 +344,14 @@ CONFIG_BSP_USING_UART1=y
 # CONFIG_BSP_USING_PWM2 is not set
 # CONFIG_BSP_USING_PWM3 is not set
 
+#
+# HWtimer Drivers
+#
+# CONFIG_BSP_USING_HWTIMER0 is not set
+# CONFIG_BSP_USING_HWTIMER1 is not set
+# CONFIG_BSP_USING_HWTIMER2 is not set
+# CONFIG_BSP_USING_HWTIMER3 is not set
+
 #
 # Onboard Peripheral Drivers
 #

+ 1 - 0
bsp/es32f0334/README.md

@@ -42,6 +42,7 @@ ES-PDS-ES32F0334-V1.1
 | SPI               |     支持     | SPI0/1                               |
 | I2C               |     支持     | I2C0/1                               |
 | PWM               |     支持     | PWM0/1/2/3                           |
+| TIMER             |     支持     | TIMER0/1/2/3                         |
 
 更多详细信息请咨询[上海东软载波微电子技术支持](http://www.essemi.com/)
 

+ 24 - 1
bsp/es32f0334/drivers/Kconfig

@@ -63,8 +63,31 @@ menu "Hardware Drivers Config"
             config BSP_USING_PWM3
                 bool "Using PWM3 PC06/PC07"
                 select RT_USING_PWM
-                default n  
+                default n
+        endmenu
+
+        menu "HWtimer Drivers"
+            config BSP_USING_HWTIMER0
+                bool "Using timer0"
+                select RT_USING_HWTIMER
+                default n
+
+            config BSP_USING_HWTIMER1
+                bool "Using timer1"
+                select RT_USING_HWTIMER
+                default n
+
+            config BSP_USING_HWTIMER2
+                bool "Using timer2"
+                select RT_USING_HWTIMER
+                default n
+
+            config BSP_USING_HWTIMER3
+                bool "Using timer3"
+                select RT_USING_HWTIMER
+                default n
         endmenu
+
     endmenu
 
     menu "Onboard Peripheral Drivers"

+ 4 - 0
bsp/es32f0334/drivers/SConscript

@@ -31,6 +31,10 @@ if GetDepend('BSP_USING_SPI_FLASH'):
 if GetDepend('BSP_USING_PWM0') or GetDepend('BSP_USING_PWM1') or GetDepend('BSP_USING_PWM2') or GetDepend('BSP_USING_PWM3'):
     src += ['drv_pwm.c']
 
+# add hwtimer driver code
+if GetDepend('BSP_USING_HWTIMER0') or GetDepend('BSP_USING_HWTIMER1') or GetDepend('BSP_USING_HWTIMER2') or GetDepend('BSP_USING_HWTIMER3'):
+    src += ['drv_hwtimer.c']
+
 CPPPATH = [cwd]
 group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
 

+ 250 - 0
bsp/es32f0334/drivers/drv_hwtimer.c

@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-3-19      wangyq       the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <drv_hwtimer.h>
+#include <board.h>
+#include <ald_cmu.h>
+#include <ald_timer.h>
+
+#ifdef RT_USING_HWTIMER
+
+struct es32f0_hwtimer_dev
+{
+    rt_hwtimer_t parent;
+    timer_handle_t *hwtimer_periph;
+    IRQn_Type IRQn;
+};
+
+#ifdef BSP_USING_HWTIMER0
+static struct es32f0_hwtimer_dev hwtimer0;
+
+void BS16T0_Handler(void)
+{
+    timer_clear_flag_status(hwtimer0.hwtimer_periph, TIMER_FLAG_UPDATE);
+    rt_device_hwtimer_isr(&hwtimer0.parent);
+
+    if (HWTIMER_MODE_ONESHOT == hwtimer0.parent.mode)
+    {
+        timer_base_stop(hwtimer0.hwtimer_periph);
+    }
+}
+#endif
+
+#ifdef BSP_USING_HWTIMER1
+static struct es32f0_hwtimer_dev hwtimer1;
+
+void BS16T1_UART2_Handler(void)
+{
+    if (timer_get_it_status(hwtimer1.hwtimer_periph, TIMER_IT_UPDATE) &&
+            timer_get_flag_status(hwtimer1.hwtimer_periph, TIMER_FLAG_UPDATE))
+    {
+        timer_clear_flag_status(hwtimer1.hwtimer_periph, TIMER_FLAG_UPDATE);
+        rt_device_hwtimer_isr(&hwtimer1.parent);
+
+        if (HWTIMER_MODE_ONESHOT == hwtimer1.parent.mode)
+        {
+            timer_base_stop(hwtimer1.hwtimer_periph);
+        }
+    }
+}
+#endif
+
+#ifdef BSP_USING_HWTIMER2
+static struct es32f0_hwtimer_dev hwtimer2;
+
+void BS16T2_UART3_Handler(void)
+{
+    if (timer_get_it_status(hwtimer2.hwtimer_periph, TIMER_IT_UPDATE) &&
+            timer_get_flag_status(hwtimer2.hwtimer_periph, TIMER_FLAG_UPDATE))
+    {
+        timer_clear_flag_status(hwtimer2.hwtimer_periph, TIMER_FLAG_UPDATE);
+        rt_device_hwtimer_isr(&hwtimer2.parent);
+
+        if (HWTIMER_MODE_ONESHOT == hwtimer2.parent.mode)
+        {
+            timer_base_stop(hwtimer2.hwtimer_periph);
+        }
+    }
+}
+#endif
+
+#ifdef BSP_USING_HWTIMER3
+static struct es32f0_hwtimer_dev hwtimer3;
+/* can not use when DAC0 Handler is enabled */
+void BS16T3_DAC0_Handler(void)
+{
+    /* if BS16T3 it */
+    if (timer_get_it_status(hwtimer3.hwtimer_periph, TIMER_IT_UPDATE) &&
+            timer_get_flag_status(hwtimer3.hwtimer_periph, TIMER_FLAG_UPDATE))
+    {
+        timer_clear_flag_status(hwtimer3.hwtimer_periph, TIMER_FLAG_UPDATE);
+        rt_device_hwtimer_isr(&hwtimer3.parent);
+
+        if (HWTIMER_MODE_ONESHOT == hwtimer3.parent.mode)
+        {
+            timer_base_stop(hwtimer3.hwtimer_periph);
+        }
+    }
+}
+#endif
+
+static struct rt_hwtimer_info es32f0_hwtimer_info =
+{
+    48000000, /* maximum count frequency */
+    1,        /* minimum count frequency */
+    65535,    /* counter maximum value */
+    HWTIMER_CNTMODE_UP
+};
+
+static void es32f0_hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state)
+{
+    struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
+
+    RT_ASSERT(hwtimer != RT_NULL);
+
+    if (1 == state)
+    {
+        timer_base_init(hwtimer->hwtimer_periph);
+        timer_interrupt_config(hwtimer->hwtimer_periph, TIMER_IT_UPDATE, ENABLE);
+        NVIC_EnableIRQ(hwtimer->IRQn);
+    }
+    hwtimer->parent.freq = cmu_get_pclk1_clock();
+    es32f0_hwtimer_info.maxfreq = cmu_get_pclk1_clock();
+    es32f0_hwtimer_info.minfreq = cmu_get_pclk1_clock();
+}
+
+static rt_err_t es32f0_hwtimer_start(rt_hwtimer_t *timer,
+                                     rt_uint32_t cnt,
+                                     rt_hwtimer_mode_t mode)
+{
+    struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
+
+    RT_ASSERT(hwtimer != RT_NULL);
+
+    WRITE_REG(hwtimer->hwtimer_periph->perh->AR, cnt);
+    timer_base_start(hwtimer->hwtimer_periph);
+
+    return RT_EOK;
+}
+
+static void es32f0_hwtimer_stop(rt_hwtimer_t *timer)
+{
+    struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
+
+    RT_ASSERT(hwtimer != RT_NULL);
+
+    timer_base_stop(hwtimer->hwtimer_periph);
+}
+
+static rt_uint32_t es32f0_hwtimer_count_get(rt_hwtimer_t *timer)
+{
+    struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
+    uint32_t hwtimer_count = 0;
+
+    RT_ASSERT(hwtimer != RT_NULL);
+
+    hwtimer_count = READ_REG(hwtimer->hwtimer_periph->perh->COUNT);
+
+    return hwtimer_count;
+}
+
+static rt_err_t es32f0_hwtimer_control(rt_hwtimer_t *timer,
+                                       rt_uint32_t cmd,
+                                       void *args)
+{
+    rt_err_t ret = RT_EOK;
+    rt_uint32_t freq = 0;
+    struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
+
+    RT_ASSERT(hwtimer != RT_NULL);
+
+    switch (cmd)
+    {
+    case HWTIMER_CTRL_FREQ_SET:
+        freq = *(rt_uint32_t *)args;
+        if (freq != cmu_get_pclk1_clock())
+        {
+            ret = -RT_ERROR;
+        }
+        break;
+
+    case HWTIMER_CTRL_STOP:
+        timer_base_stop(hwtimer->hwtimer_periph);
+        break;
+
+    default:
+        ret = RT_EINVAL;
+        break;
+    }
+
+    return ret;
+}
+
+static struct rt_hwtimer_ops es32f0_hwtimer_ops =
+{
+    es32f0_hwtimer_init,
+    es32f0_hwtimer_start,
+    es32f0_hwtimer_stop,
+    es32f0_hwtimer_count_get,
+    es32f0_hwtimer_control
+};
+
+int rt_hw_hwtimer_init(void)
+{
+    rt_err_t ret = RT_EOK;
+
+#ifdef BSP_USING_HWTIMER0
+    static timer_handle_t _hwtimer_periph0;
+    _hwtimer_periph0.perh = BS16T0;
+    hwtimer0.IRQn = BS16T0_IRQn;
+    hwtimer0.hwtimer_periph = &_hwtimer_periph0;
+    hwtimer0.parent.info = &es32f0_hwtimer_info;
+    hwtimer0.parent.ops = &es32f0_hwtimer_ops;
+    ret = rt_device_hwtimer_register(&hwtimer0.parent, "timer0", &hwtimer0);
+#endif
+
+#ifdef BSP_USING_HWTIMER1
+    static timer_handle_t _hwtimer_periph1;
+    _hwtimer_periph1.perh = BS16T1;
+    hwtimer1.IRQn = BS16T1_UART2_IRQn;
+    hwtimer1.hwtimer_periph = &_hwtimer_periph1;
+    hwtimer1.parent.info = &es32f0_hwtimer_info;
+    hwtimer1.parent.ops = &es32f0_hwtimer_ops;
+    ret = rt_device_hwtimer_register(&hwtimer1.parent, "timer1", &hwtimer1);
+#endif
+
+#ifdef BSP_USING_HWTIMER2
+    static timer_handle_t _hwtimer_periph2;
+    _hwtimer_periph2.perh = BS16T2;
+    hwtimer2.IRQn = BS16T2_UART3_IRQn;
+    hwtimer2.hwtimer_periph = &_hwtimer_periph2;
+    hwtimer2.parent.info = &es32f0_hwtimer_info;
+    hwtimer2.parent.ops = &es32f0_hwtimer_ops;
+    ret = rt_device_hwtimer_register(&hwtimer2.parent, "timer2", &hwtimer2);
+#endif
+
+#ifdef BSP_USING_HWTIMER3
+    static timer_handle_t _hwtimer_periph3;
+    _hwtimer_periph3.perh = BS16T3;
+    hwtimer3.IRQn = BS16T3_DAC0_IRQn;
+    hwtimer3.hwtimer_periph = &_hwtimer_periph3;
+    hwtimer3.parent.info = &es32f0_hwtimer_info;
+    hwtimer3.parent.ops = &es32f0_hwtimer_ops;
+    ret = rt_device_hwtimer_register(&hwtimer3.parent, "timer3", &hwtimer3);
+#endif
+
+    return ret;
+}
+INIT_BOARD_EXPORT(rt_hw_hwtimer_init);
+
+#endif

+ 16 - 0
bsp/es32f0334/drivers/drv_hwtimer.h

@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-3-19      wangyq       the first version
+ */
+
+#ifndef DRV_HWTIMER_H__
+#define DRV_HWTIMER_H__
+
+int rt_hw_hwtimer_init(void);
+
+#endif

+ 3 - 0
bsp/es32f0334/rtconfig.h

@@ -172,6 +172,9 @@
 /* PWM Drivers */
 
 
+/* HWtimer Drivers */
+
+
 /* Onboard Peripheral Drivers */
 
 

+ 8 - 0
bsp/es32f0654/.config

@@ -346,6 +346,14 @@ CONFIG_BSP_USING_UART2=y
 # CONFIG_BSP_USING_PWM2 is not set
 # CONFIG_BSP_USING_PWM3 is not set
 
+#
+# HWtimer Drivers
+#
+# CONFIG_BSP_USING_HWTIMER0 is not set
+# CONFIG_BSP_USING_HWTIMER1 is not set
+# CONFIG_BSP_USING_HWTIMER2 is not set
+# CONFIG_BSP_USING_HWTIMER3 is not set
+
 #
 # Onboard Peripheral Drivers
 #

+ 5 - 2
bsp/es32f0654/README.md

@@ -35,14 +35,17 @@ ES-PDS-ES32F0654-V1.1
 | **板载外设**      | **支持情况** | **备注**                             |
 | :---------------- | :----------: | :------------------------------------|
 | SPI FLASH         |     支持     | SPI0                                 |
-
 | **片上外设**      | **支持情况** | **备注**                             |
-| :---------------- | :----------: | :------------------------------------|
 | GPIO              |     支持     | 54 GPIOs                             |
 | UART              |     支持     | UART0/1/2/3                          |
 | SPI               |     支持     | SPI0/1                               |
 | I2C               |     支持     | I2C0/1                               |
 | PWM               |     支持     | PWM0/1/2/3                           |
+| TIMER             |     支持     | TIMER0/1/2/3                         |
+
+### 1.2  注意事项
+
+- 本BSP中,UART2和TIMER1不能同时使用,UART3和TIMER2不能同时使用
 
 更多详细信息请咨询[上海东软载波微电子技术支持](http://www.essemi.com/)
 

+ 32 - 4
bsp/es32f0654/drivers/Kconfig

@@ -16,16 +16,18 @@ menu "Hardware Drivers Config"
                 bool "Enable UART1 PC10/PC11(T/R)"
                 select RT_USING_SERIAL
                 default n
-        
+
             config BSP_USING_UART2
                 bool "Enable UART2 PC12/PD02(T/R)"
                 select RT_USING_SERIAL
                 default y
+                depends on !BSP_USING_HWTIMER1
 
             config BSP_USING_UART3
                 bool "Enable UART3 PC04/PC05(T/R)"
                 select RT_USING_SERIAL
                 default n
+                depends on !BSP_USING_HWTIMER2
         endmenu
 
         menu "SPI Drivers"
@@ -47,6 +49,7 @@ menu "Hardware Drivers Config"
                 bool "Enable I2C0 BUS PB08/PB09(SCL/SDA)"
                 select RT_USING_I2C
                 default n
+
             config BSP_USING_I2C1
                 bool "Enable I2C1 BUS PB10/PB11(SCL/SDA)"
                 select RT_USING_I2C
@@ -62,18 +65,43 @@ menu "Hardware Drivers Config"
             config BSP_USING_PWM1
                 bool "Using PWM1 PB06/PB07/PB08/PB09"
                 select RT_USING_PWM
-                default n  
+                default n
 
             config BSP_USING_PWM2
                 bool "Using PWM2 PA00/PA01"
                 select RT_USING_PWM
-                default n  
+                default n
 
             config BSP_USING_PWM3
                 bool "Using PWM3 PC06/PC07"
                 select RT_USING_PWM
-                default n  
+                default n
         endmenu
+
+        menu "HWtimer Drivers"
+            config BSP_USING_HWTIMER0
+                bool "Using timer0"
+                select RT_USING_HWTIMER
+                default n
+
+            config BSP_USING_HWTIMER1
+                bool "Using timer1"
+                select RT_USING_HWTIMER
+                default n
+                depends on !BSP_USING_UART2
+
+            config BSP_USING_HWTIMER2
+                bool "Using timer2"
+                select RT_USING_HWTIMER
+                default n
+                depends on !BSP_USING_UART3
+
+            config BSP_USING_HWTIMER3
+                bool "Using timer3"
+                select RT_USING_HWTIMER
+                default n
+        endmenu
+
     endmenu
 
     menu "Onboard Peripheral Drivers"

+ 4 - 0
bsp/es32f0654/drivers/SConscript

@@ -31,6 +31,10 @@ if GetDepend('BSP_USING_SPI_FLASH'):
 if GetDepend('BSP_USING_PWM0') or GetDepend('BSP_USING_PWM1') or GetDepend('BSP_USING_PWM2') or GetDepend('BSP_USING_PWM3'):
     src += ['drv_pwm.c']
 
+# add hwtimer driver code
+if GetDepend('BSP_USING_HWTIMER0') or GetDepend('BSP_USING_HWTIMER1') or GetDepend('BSP_USING_HWTIMER2') or GetDepend('BSP_USING_HWTIMER3'):
+    src += ['drv_hwtimer.c']
+
 CPPPATH = [cwd]
 group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
 

+ 252 - 0
bsp/es32f0654/drivers/drv_hwtimer.c

@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-3-19      wangyq       the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <drv_hwtimer.h>
+#include <board.h>
+#include <ald_cmu.h>
+#include <ald_timer.h>
+
+#ifdef RT_USING_HWTIMER
+
+struct es32f0_hwtimer_dev
+{
+    rt_hwtimer_t parent;
+    timer_handle_t *hwtimer_periph;
+    IRQn_Type IRQn;
+};
+
+#ifdef BSP_USING_HWTIMER0
+static struct es32f0_hwtimer_dev hwtimer0;
+
+void BS16T0_Handler(void)
+{
+    timer_clear_flag_status(hwtimer0.hwtimer_periph, TIMER_FLAG_UPDATE);
+    rt_device_hwtimer_isr(&hwtimer0.parent);
+
+    if (HWTIMER_MODE_ONESHOT == hwtimer0.parent.mode)
+    {
+        timer_base_stop(hwtimer0.hwtimer_periph);
+    }
+}
+#endif
+
+#ifdef BSP_USING_HWTIMER1
+static struct es32f0_hwtimer_dev hwtimer1;
+/* can not use when UART2 Handler is enabled */
+void BS16T1_UART2_Handler(void)
+{
+    /* if BS16T1 it */
+    if (timer_get_it_status(hwtimer1.hwtimer_periph, TIMER_IT_UPDATE) &&
+            timer_get_flag_status(hwtimer1.hwtimer_periph, TIMER_FLAG_UPDATE))
+    {
+        timer_clear_flag_status(hwtimer1.hwtimer_periph, TIMER_FLAG_UPDATE);
+        rt_device_hwtimer_isr(&hwtimer1.parent);
+
+        if (HWTIMER_MODE_ONESHOT == hwtimer1.parent.mode)
+        {
+            timer_base_stop(hwtimer1.hwtimer_periph);
+        }
+    }
+}
+#endif
+
+#ifdef BSP_USING_HWTIMER2
+static struct es32f0_hwtimer_dev hwtimer2;
+/* can not use when UART3 Handler is enabled */
+void BS16T2_UART3_Handler(void)
+{
+    /* if BS16T2 it */
+    if (timer_get_it_status(hwtimer2.hwtimer_periph, TIMER_IT_UPDATE) &&
+            timer_get_flag_status(hwtimer2.hwtimer_periph, TIMER_FLAG_UPDATE))
+    {
+        timer_clear_flag_status(hwtimer2.hwtimer_periph, TIMER_FLAG_UPDATE);
+        rt_device_hwtimer_isr(&hwtimer2.parent);
+
+        if (HWTIMER_MODE_ONESHOT == hwtimer2.parent.mode)
+        {
+            timer_base_stop(hwtimer2.hwtimer_periph);
+        }
+    }
+}
+#endif
+
+#ifdef BSP_USING_HWTIMER3
+static struct es32f0_hwtimer_dev hwtimer3;
+/* can not use when DAC0 Handler is enabled */
+void BS16T3_DAC0_Handler(void)
+{
+    /* if BS16T3 it */
+    if (timer_get_it_status(hwtimer3.hwtimer_periph, TIMER_IT_UPDATE) &&
+            timer_get_flag_status(hwtimer3.hwtimer_periph, TIMER_FLAG_UPDATE))
+    {
+        timer_clear_flag_status(hwtimer3.hwtimer_periph, TIMER_FLAG_UPDATE);
+        rt_device_hwtimer_isr(&hwtimer3.parent);
+
+        if (HWTIMER_MODE_ONESHOT == hwtimer3.parent.mode)
+        {
+            timer_base_stop(hwtimer3.hwtimer_periph);
+        }
+    }
+}
+#endif
+
+static struct rt_hwtimer_info es32f0_hwtimer_info =
+{
+    48000000, /* maximum count frequency */
+    1,        /* minimum count frequency */
+    65535,    /* counter maximum value */
+    HWTIMER_CNTMODE_UP
+};
+
+static void es32f0_hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state)
+{
+    struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
+
+    RT_ASSERT(hwtimer != RT_NULL);
+
+    if (1 == state)
+    {
+        timer_base_init(hwtimer->hwtimer_periph);
+        timer_interrupt_config(hwtimer->hwtimer_periph, TIMER_IT_UPDATE, ENABLE);
+        NVIC_EnableIRQ(hwtimer->IRQn);
+    }
+    hwtimer->parent.freq = cmu_get_pclk1_clock();
+    es32f0_hwtimer_info.maxfreq = cmu_get_pclk1_clock();
+    es32f0_hwtimer_info.minfreq = cmu_get_pclk1_clock();
+}
+
+static rt_err_t es32f0_hwtimer_start(rt_hwtimer_t *timer,
+                                     rt_uint32_t cnt,
+                                     rt_hwtimer_mode_t mode)
+{
+    struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
+
+    RT_ASSERT(hwtimer != RT_NULL);
+
+    WRITE_REG(hwtimer->hwtimer_periph->perh->AR, cnt);
+    timer_base_start(hwtimer->hwtimer_periph);
+
+    return RT_EOK;
+}
+
+static void es32f0_hwtimer_stop(rt_hwtimer_t *timer)
+{
+    struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
+
+    RT_ASSERT(hwtimer != RT_NULL);
+
+    timer_base_stop(hwtimer->hwtimer_periph);
+}
+
+static rt_uint32_t es32f0_hwtimer_count_get(rt_hwtimer_t *timer)
+{
+    struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
+    uint32_t hwtimer_count = 0;
+
+    RT_ASSERT(hwtimer != RT_NULL);
+
+    hwtimer_count = READ_REG(hwtimer->hwtimer_periph->perh->COUNT);
+
+    return hwtimer_count;
+}
+
+static rt_err_t es32f0_hwtimer_control(rt_hwtimer_t *timer,
+                                       rt_uint32_t cmd,
+                                       void *args)
+{
+    rt_err_t ret = RT_EOK;
+    rt_uint32_t freq = 0;
+    struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
+
+    RT_ASSERT(hwtimer != RT_NULL);
+
+    switch (cmd)
+    {
+    case HWTIMER_CTRL_FREQ_SET:
+        freq = *(rt_uint32_t *)args;
+        if (freq != cmu_get_pclk1_clock())
+        {
+            ret = -RT_ERROR;
+        }
+        break;
+
+    case HWTIMER_CTRL_STOP:
+        timer_base_stop(hwtimer->hwtimer_periph);
+        break;
+
+    default:
+        ret = RT_EINVAL;
+        break;
+    }
+
+    return ret;
+}
+
+static struct rt_hwtimer_ops es32f0_hwtimer_ops =
+{
+    es32f0_hwtimer_init,
+    es32f0_hwtimer_start,
+    es32f0_hwtimer_stop,
+    es32f0_hwtimer_count_get,
+    es32f0_hwtimer_control
+};
+
+int rt_hw_hwtimer_init(void)
+{
+    rt_err_t ret = RT_EOK;
+
+#ifdef BSP_USING_HWTIMER0
+    static timer_handle_t _hwtimer_periph0;
+    _hwtimer_periph0.perh = BS16T0;
+    hwtimer0.IRQn = BS16T0_IRQn;
+    hwtimer0.hwtimer_periph = &_hwtimer_periph0;
+    hwtimer0.parent.info = &es32f0_hwtimer_info;
+    hwtimer0.parent.ops = &es32f0_hwtimer_ops;
+    ret = rt_device_hwtimer_register(&hwtimer0.parent, "timer0", &hwtimer0);
+#endif
+
+#ifdef BSP_USING_HWTIMER1
+    static timer_handle_t _hwtimer_periph1;
+    _hwtimer_periph1.perh = BS16T1;
+    hwtimer1.IRQn = BS16T1_UART2_IRQn;
+    hwtimer1.hwtimer_periph = &_hwtimer_periph1;
+    hwtimer1.parent.info = &es32f0_hwtimer_info;
+    hwtimer1.parent.ops = &es32f0_hwtimer_ops;
+    ret = rt_device_hwtimer_register(&hwtimer1.parent, "timer1", &hwtimer1);
+#endif
+
+#ifdef BSP_USING_HWTIMER2
+    static timer_handle_t _hwtimer_periph2;
+    _hwtimer_periph2.perh = BS16T2;
+    hwtimer2.IRQn = BS16T2_UART3_IRQn;
+    hwtimer2.hwtimer_periph = &_hwtimer_periph2;
+    hwtimer2.parent.info = &es32f0_hwtimer_info;
+    hwtimer2.parent.ops = &es32f0_hwtimer_ops;
+    ret = rt_device_hwtimer_register(&hwtimer2.parent, "timer2", &hwtimer2);
+#endif
+
+#ifdef BSP_USING_HWTIMER3
+    static timer_handle_t _hwtimer_periph3;
+    _hwtimer_periph3.perh = BS16T3;
+    hwtimer3.IRQn = BS16T3_DAC0_IRQn;
+    hwtimer3.hwtimer_periph = &_hwtimer_periph3;
+    hwtimer3.parent.info = &es32f0_hwtimer_info;
+    hwtimer3.parent.ops = &es32f0_hwtimer_ops;
+    ret = rt_device_hwtimer_register(&hwtimer3.parent, "timer3", &hwtimer3);
+#endif
+
+    return ret;
+}
+INIT_BOARD_EXPORT(rt_hw_hwtimer_init);
+
+#endif

+ 16 - 0
bsp/es32f0654/drivers/drv_hwtimer.h

@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-3-19      wangyq       the first version
+ */
+
+#ifndef DRV_HWTIMER_H__
+#define DRV_HWTIMER_H__
+
+int rt_hw_hwtimer_init(void);
+
+#endif

+ 2 - 6
bsp/es32f0654/drivers/drv_pwm.c

@@ -19,7 +19,7 @@
 static void pwm_set_freq(timer_handle_t *timer_initstruct, uint32_t ns)
 {
     uint64_t _arr = (uint64_t)cmu_get_pclk1_clock() * ns / 1000000000 /
-                    (timer_initstruct->init.prescaler + 1) - 1;
+                    (timer_initstruct->init.prescaler + 1);
 
     WRITE_REG(timer_initstruct->perh->AR, (uint32_t)_arr);
     timer_initstruct->init.period   = (uint32_t)_arr;
@@ -28,7 +28,7 @@ static void pwm_set_freq(timer_handle_t *timer_initstruct, uint32_t ns)
 static void pwm_set_duty(timer_handle_t *timer_initstruct, timer_channel_t ch, uint32_t ns)
 {
     uint64_t tmp = (uint64_t)cmu_get_pclk1_clock() * ns / 1000000000 /
-                   (timer_initstruct->init.prescaler + 1) - 1;
+                   (timer_initstruct->init.prescaler + 1);
 
     if (ch == TIMER_CHANNEL_1)
         WRITE_REG(timer_initstruct->perh->CCVAL1, (uint32_t)tmp);
@@ -38,10 +38,6 @@ static void pwm_set_duty(timer_handle_t *timer_initstruct, timer_channel_t ch, u
         WRITE_REG(timer_initstruct->perh->CCVAL3, (uint32_t)tmp);
     else if (ch == TIMER_CHANNEL_4)
         WRITE_REG(timer_initstruct->perh->CCVAL4, (uint32_t)tmp);
-    else
-    {
-        ;/* do nothing */
-    }
 }
 
 static rt_err_t es32f0_pwm_control(struct rt_device_pwm *device, int cmd, void *arg)

+ 3 - 0
bsp/es32f0654/rtconfig.h

@@ -172,6 +172,9 @@
 /* PWM Drivers */
 
 
+/* HWtimer Drivers */
+
+
 /* Onboard Peripheral Drivers */
 
 

+ 358 - 0
bsp/imx6ul/.config

@@ -0,0 +1,358 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# RT-Thread Configuration
+#
+CONFIG_BOARD_IMX6UL=y
+
+#
+# RT-Thread Kernel
+#
+CONFIG_RT_NAME_MAX=8
+# CONFIG_RT_USING_SMP is not set
+CONFIG_RT_ALIGN_SIZE=4
+# CONFIG_RT_THREAD_PRIORITY_8 is not set
+CONFIG_RT_THREAD_PRIORITY_32=y
+# CONFIG_RT_THREAD_PRIORITY_256 is not set
+CONFIG_RT_THREAD_PRIORITY_MAX=32
+CONFIG_RT_TICK_PER_SECOND=100
+CONFIG_RT_USING_OVERFLOW_CHECK=y
+CONFIG_RT_USING_HOOK=y
+CONFIG_RT_USING_IDLE_HOOK=y
+CONFIG_RT_IDEL_HOOK_LIST_SIZE=4
+CONFIG_IDLE_THREAD_STACK_SIZE=256
+# CONFIG_RT_USING_TIMER_SOFT is not set
+CONFIG_RT_DEBUG=y
+# CONFIG_RT_DEBUG_INIT_CONFIG is not set
+# CONFIG_RT_DEBUG_THREAD_CONFIG is not set
+# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set
+# CONFIG_RT_DEBUG_IPC_CONFIG is not set
+# CONFIG_RT_DEBUG_TIMER_CONFIG is not set
+# CONFIG_RT_DEBUG_IRQ_CONFIG is not set
+# CONFIG_RT_DEBUG_MEM_CONFIG is not set
+# CONFIG_RT_DEBUG_SLAB_CONFIG is not set
+# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set
+# CONFIG_RT_DEBUG_MODULE_CONFIG is not set
+
+#
+# Inter-Thread communication
+#
+CONFIG_RT_USING_SEMAPHORE=y
+CONFIG_RT_USING_MUTEX=y
+CONFIG_RT_USING_EVENT=y
+CONFIG_RT_USING_MAILBOX=y
+CONFIG_RT_USING_MESSAGEQUEUE=y
+# CONFIG_RT_USING_SIGNALS is not set
+
+#
+# Memory Management
+#
+CONFIG_RT_USING_MEMPOOL=y
+# CONFIG_RT_USING_MEMHEAP is not set
+# CONFIG_RT_USING_NOHEAP is not set
+CONFIG_RT_USING_SMALL_MEM=y
+# CONFIG_RT_USING_SLAB is not set
+# CONFIG_RT_USING_MEMTRACE is not set
+CONFIG_RT_USING_HEAP=y
+
+#
+# Kernel Device Object
+#
+CONFIG_RT_USING_DEVICE=y
+# CONFIG_RT_USING_DEVICE_OPS is not set
+# CONFIG_RT_USING_INTERRUPT_INFO is not set
+CONFIG_RT_USING_CONSOLE=y
+CONFIG_RT_CONSOLEBUF_SIZE=128
+CONFIG_RT_CONSOLE_DEVICE_NAME="uart"
+CONFIG_RT_VER_NUM=0x40001
+CONFIG_ARCH_ARM=y
+CONFIG_ARCH_ARM_CORTEX_A=y
+CONFIG_ARCH_ARM_CORTEX_A7=y
+# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
+
+#
+# RT-Thread Components
+#
+CONFIG_RT_USING_COMPONENTS_INIT=y
+CONFIG_RT_USING_USER_MAIN=y
+CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048
+CONFIG_RT_MAIN_THREAD_PRIORITY=10
+
+#
+# C++ features
+#
+# CONFIG_RT_USING_CPLUSPLUS is not set
+
+#
+# Command shell
+#
+CONFIG_RT_USING_FINSH=y
+CONFIG_FINSH_THREAD_NAME="tshell"
+CONFIG_FINSH_USING_HISTORY=y
+CONFIG_FINSH_HISTORY_LINES=5
+CONFIG_FINSH_USING_SYMTAB=y
+CONFIG_FINSH_USING_DESCRIPTION=y
+# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
+CONFIG_FINSH_THREAD_PRIORITY=20
+CONFIG_FINSH_THREAD_STACK_SIZE=4096
+CONFIG_FINSH_CMD_SIZE=80
+# CONFIG_FINSH_USING_AUTH is not set
+CONFIG_FINSH_USING_MSH=y
+CONFIG_FINSH_USING_MSH_DEFAULT=y
+# CONFIG_FINSH_USING_MSH_ONLY is not set
+CONFIG_FINSH_ARG_MAX=10
+
+#
+# Device virtual file system
+#
+CONFIG_RT_USING_DFS=y
+CONFIG_DFS_USING_WORKDIR=y
+CONFIG_DFS_FILESYSTEMS_MAX=2
+CONFIG_DFS_FILESYSTEM_TYPES_MAX=2
+CONFIG_DFS_FD_MAX=16
+# CONFIG_RT_USING_DFS_MNTTABLE is not set
+# CONFIG_RT_USING_DFS_ELMFAT is not set
+CONFIG_RT_USING_DFS_DEVFS=y
+# CONFIG_RT_USING_DFS_ROMFS is not set
+# CONFIG_RT_USING_DFS_RAMFS is not set
+# CONFIG_RT_USING_DFS_UFFS is not set
+# CONFIG_RT_USING_DFS_JFFS2 is not set
+
+#
+# Device Drivers
+#
+CONFIG_RT_USING_DEVICE_IPC=y
+CONFIG_RT_PIPE_BUFSZ=512
+CONFIG_RT_USING_SERIAL=y
+CONFIG_RT_SERIAL_USING_DMA=y
+CONFIG_RT_SERIAL_RB_BUFSZ=64
+# CONFIG_RT_USING_CAN is not set
+# CONFIG_RT_USING_HWTIMER is not set
+# CONFIG_RT_USING_CPUTIME is not set
+# CONFIG_RT_USING_I2C is not set
+CONFIG_RT_USING_PIN=y
+# CONFIG_RT_USING_ADC is not set
+# CONFIG_RT_USING_PWM is not set
+# CONFIG_RT_USING_MTD_NOR is not set
+# CONFIG_RT_USING_MTD_NAND is not set
+# CONFIG_RT_USING_MTD is not set
+# CONFIG_RT_USING_PM is not set
+# CONFIG_RT_USING_RTC is not set
+# CONFIG_RT_USING_SDIO is not set
+# CONFIG_RT_USING_SPI is not set
+# CONFIG_RT_USING_WDT is not set
+# CONFIG_RT_USING_AUDIO is not set
+# CONFIG_RT_USING_SENSOR is not set
+
+#
+# Using WiFi
+#
+# CONFIG_RT_USING_WIFI is not set
+
+#
+# Using USB
+#
+# CONFIG_RT_USING_USB_HOST is not set
+# CONFIG_RT_USING_USB_DEVICE is not set
+
+#
+# POSIX layer and C standard library
+#
+CONFIG_RT_USING_LIBC=y
+# CONFIG_RT_USING_PTHREADS is not set
+CONFIG_RT_USING_POSIX=y
+# CONFIG_RT_USING_POSIX_MMAP is not set
+# CONFIG_RT_USING_POSIX_TERMIOS is not set
+# CONFIG_RT_USING_POSIX_AIO is not set
+# CONFIG_RT_USING_MODULE is not set
+
+#
+# Network
+#
+
+#
+# Socket abstraction layer
+#
+# CONFIG_RT_USING_SAL is not set
+
+#
+# light weight TCP/IP stack
+#
+# CONFIG_RT_USING_LWIP is not set
+
+#
+# Modbus master and slave stack
+#
+# CONFIG_RT_USING_MODBUS is not set
+
+#
+# AT commands
+#
+# CONFIG_RT_USING_AT is not set
+
+#
+# VBUS(Virtual Software BUS)
+#
+# CONFIG_RT_USING_VBUS is not set
+
+#
+# Utilities
+#
+# CONFIG_RT_USING_LOGTRACE is not set
+# CONFIG_RT_USING_RYM is not set
+# CONFIG_RT_USING_ULOG is not set
+# CONFIG_RT_USING_UTEST is not set
+# CONFIG_RT_USING_LWP is not set
+
+#
+# RT-Thread online packages
+#
+
+#
+# IoT - internet of things
+#
+# CONFIG_PKG_USING_PAHOMQTT is not set
+# CONFIG_PKG_USING_WEBCLIENT is not set
+# CONFIG_PKG_USING_WEBNET is not set
+# CONFIG_PKG_USING_MONGOOSE is not set
+# CONFIG_PKG_USING_WEBTERMINAL is not set
+# CONFIG_PKG_USING_CJSON is not set
+# CONFIG_PKG_USING_JSMN is not set
+# CONFIG_PKG_USING_LIBMODBUS is not set
+# CONFIG_PKG_USING_LJSON is not set
+# CONFIG_PKG_USING_EZXML is not set
+# CONFIG_PKG_USING_NANOPB is not set
+
+#
+# Wi-Fi
+#
+
+#
+# Marvell WiFi
+#
+# CONFIG_PKG_USING_WLANMARVELL is not set
+
+#
+# Wiced WiFi
+#
+# CONFIG_PKG_USING_WLAN_WICED is not set
+# CONFIG_PKG_USING_RW007 is not set
+# CONFIG_PKG_USING_COAP is not set
+# CONFIG_PKG_USING_NOPOLL is not set
+# CONFIG_PKG_USING_NETUTILS is not set
+# CONFIG_PKG_USING_AT_DEVICE is not set
+# CONFIG_PKG_USING_WIZNET is not set
+
+#
+# IoT Cloud
+#
+# CONFIG_PKG_USING_ONENET is not set
+# CONFIG_PKG_USING_GAGENT_CLOUD is not set
+# CONFIG_PKG_USING_ALI_IOTKIT is not set
+# CONFIG_PKG_USING_AZURE is not set
+# CONFIG_PKG_USING_TENCENT_IOTKIT is not set
+# CONFIG_PKG_USING_NIMBLE is not set
+# CONFIG_PKG_USING_OTA_DOWNLOADER is not set
+
+#
+# security packages
+#
+# CONFIG_PKG_USING_MBEDTLS is not set
+# CONFIG_PKG_USING_libsodium is not set
+# CONFIG_PKG_USING_TINYCRYPT is not set
+
+#
+# language packages
+#
+# CONFIG_PKG_USING_LUA is not set
+# CONFIG_PKG_USING_JERRYSCRIPT is not set
+# CONFIG_PKG_USING_MICROPYTHON is not set
+
+#
+# multimedia packages
+#
+# CONFIG_PKG_USING_OPENMV is not set
+# CONFIG_PKG_USING_MUPDF is not set
+
+#
+# tools packages
+#
+# CONFIG_PKG_USING_CMBACKTRACE is not set
+# CONFIG_PKG_USING_EASYFLASH is not set
+# CONFIG_PKG_USING_EASYLOGGER is not set
+# CONFIG_PKG_USING_SYSTEMVIEW is not set
+# CONFIG_PKG_USING_RDB is not set
+# CONFIG_PKG_USING_QRCODE is not set
+# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
+# CONFIG_PKG_USING_ADBD is not set
+
+#
+# system packages
+#
+# CONFIG_PKG_USING_GUIENGINE is not set
+# CONFIG_PKG_USING_PERSIMMON is not set
+# CONFIG_PKG_USING_CAIRO is not set
+# CONFIG_PKG_USING_PIXMAN is not set
+# CONFIG_PKG_USING_LWEXT4 is not set
+# CONFIG_PKG_USING_PARTITION is not set
+# CONFIG_PKG_USING_FAL is not set
+# CONFIG_PKG_USING_SQLITE is not set
+# CONFIG_PKG_USING_RTI is not set
+# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
+# CONFIG_PKG_USING_CMSIS is not set
+# CONFIG_PKG_USING_DFS_YAFFS is not set
+# CONFIG_PKG_USING_LITTLEFS is not set
+
+#
+# peripheral libraries and drivers
+#
+
+#
+# sensors drivers
+#
+# CONFIG_PKG_USING_LSM6DSL is not set
+# CONFIG_PKG_USING_LPS22HB is not set
+# CONFIG_PKG_USING_HTS221 is not set
+# CONFIG_PKG_USING_LSM303AGR is not set
+# CONFIG_PKG_USING_BME280 is not set
+# CONFIG_PKG_USING_BMA400 is not set
+# CONFIG_PKG_USING_BMI160_BMX160 is not set
+# CONFIG_PKG_USING_SPL0601 is not set
+# CONFIG_PKG_USING_REALTEK_AMEBA is not set
+# CONFIG_PKG_USING_SHT2X is not set
+# CONFIG_PKG_USING_AHT10 is not set
+# CONFIG_PKG_USING_AP3216C is not set
+# CONFIG_PKG_USING_STM32_SDIO is not set
+# CONFIG_PKG_USING_ICM20608 is not set
+# CONFIG_PKG_USING_U8G2 is not set
+# CONFIG_PKG_USING_BUTTON is not set
+# CONFIG_PKG_USING_MPU6XXX is not set
+# CONFIG_PKG_USING_PCF8574 is not set
+# CONFIG_PKG_USING_SX12XX is not set
+# CONFIG_PKG_USING_KENDRYTE_SDK is not set
+
+#
+# miscellaneous packages
+#
+# CONFIG_PKG_USING_LIBCSV is not set
+# CONFIG_PKG_USING_OPTPARSE is not set
+# CONFIG_PKG_USING_FASTLZ is not set
+# CONFIG_PKG_USING_MINILZO is not set
+# CONFIG_PKG_USING_QUICKLZ is not set
+# CONFIG_PKG_USING_MULTIBUTTON is not set
+# CONFIG_PKG_USING_CANFESTIVAL is not set
+# CONFIG_PKG_USING_ZLIB is not set
+# CONFIG_PKG_USING_DSTR is not set
+# CONFIG_PKG_USING_TINYFRAME is not set
+# CONFIG_PKG_USING_KENDRYTE_DEMO is not set
+
+#
+# samples: kernel and components samples
+#
+# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
+# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
+# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
+# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
+# CONFIG_PKG_USING_HELLO is not set
+# CONFIG_PKG_USING_VI is not set
+# CONFIG_RT_USING_UART0 is not set
+CONFIG_RT_USING_UART1=y

+ 14 - 5
bsp/imx6ul/drivers/board.c

@@ -20,6 +20,15 @@
 #include <epit.h>
 #include <cortex_a.h>
 
+#include <mmu.h>
+
+struct mem_desc platform_mem_desc[] = {
+    {0x00000000, 0x80000000, 0x00000000, DEVICE_MEM},
+    {0x80000000, 0xFFF00000, 0x80000000, NORMAL_MEM}
+};
+
+const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]);
+
 static void rt_hw_timer_isr(int vector, void *param)
 {
     rt_tick_increase();
@@ -32,17 +41,17 @@ int rt_hw_timer_init(void)
 
     // Make sure the timer is off.
     HW_ARMGLOBALTIMER_CONTROL.B.TIMER_ENABLE = 0;
-    
+
     HW_ARMGLOBALTIMER_CONTROL.B.FCR0 =1;
-    
+
     HW_ARMGLOBALTIMER_CONTROL.B.FCR1 =0;
-    
+
     HW_ARMGLOBALTIMER_CONTROL.B.DBG_ENABLE =0;
-    
+
     // Clear counter.
     HW_ARMGLOBALTIMER_COUNTER_HI_WR(0);
     HW_ARMGLOBALTIMER_COUNTER_LO_WR(0);
-    
+
     // Now turn on the timer.
     HW_ARMGLOBALTIMER_CONTROL.B.TIMER_ENABLE = 1;
 

+ 1 - 3
bsp/imx6ul/platform/SConscript

@@ -8,14 +8,12 @@ drivers/imx_timer.c
 drivers/imx_i2c.c
 drivers/imx_uart.c
 cpu/armv7_cache.c
-cpu/gic.c
 cpu/ccm_pll2.c
-cpu/mmu.c
 cpu/cortex_a_gcc.S
 ''')
 
 CPPPATH = [ cwd + '/cpu',
-cwd + '/include', 
+cwd + '/include',
 cwd + '/include/mx6ul',
 cwd + '/include/mx6ul/registers'
 ]

+ 0 - 243
bsp/imx6ul/platform/cpu/gic.c

@@ -1,243 +0,0 @@
-/*
- * Copyright (c) 2012, Freescale Semiconductor, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * o Redistributions of source code must retain the above copyright notice, this list
- *   of conditions and the following disclaimer.
- *
- * o Redistributions in binary form must reproduce the above copyright notice, this
- *   list of conditions and the following disclaimer in the documentation and/or
- *   other materials provided with the distribution.
- *
- * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived from this
- *   software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include <assert.h>
-#include "gic.h"
-#include "gic_registers.h"
-#include "cortex_a.h"
-
-////////////////////////////////////////////////////////////////////////////////
-// Prototypes
-////////////////////////////////////////////////////////////////////////////////
-
-static inline gicd_t * gic_get_gicd(void);
-static inline gicc_t * gic_get_gicc(void);
-static inline uint32_t irq_get_register_offset(uint32_t irqID);
-static inline uint32_t irq_get_bit_offset(uint32_t irqID);
-static inline uint32_t irq_get_bit_mask(uint32_t irqID);
-
-////////////////////////////////////////////////////////////////////////////////
-// Code
-////////////////////////////////////////////////////////////////////////////////
-
-static inline gicd_t * gic_get_gicd(void)
-{
-    uint32_t base = get_arm_private_peripheral_base() + kGICDBaseOffset;
-    return (gicd_t *)base;
-}
-
-static inline gicc_t * gic_get_gicc(void)
-{
-    uint32_t base = get_arm_private_peripheral_base() + kGICCBaseOffset;
-    return (gicc_t *)base;
-}
-
-static inline uint32_t irq_get_register_offset(uint32_t irqID)
-{
-    return irqID / 32;
-}
-
-static inline uint32_t irq_get_bit_offset(uint32_t irqID)
-{
-    return irqID & 0x1f;
-}
-
-static inline uint32_t irq_get_bit_mask(uint32_t irqID)
-{
-    return 1 << irq_get_bit_offset(irqID);    
-}
-
-void gic_enable(bool enableIt)
-{
-    gicd_t * gicd = gic_get_gicd();
-    
-    if (enableIt)
-    {
-        // Enable both secure and non-secure.
-        gicd->CTLR |= kBM_GICD_CTLR_EnableGrp0 | kBM_GICD_CTLR_EnableGrp1;
-    }
-    else
-    {
-        // Clear the enable bits.
-        gicd->CTLR &= ~(kBM_GICD_CTLR_EnableGrp0 | kBM_GICD_CTLR_EnableGrp1);
-    }
-}
-
-void gic_set_irq_security(uint32_t irqID, bool isSecure)
-{
-    gicd_t * gicd = gic_get_gicd();
-    
-    uint32_t reg = irq_get_register_offset(irqID);
-    uint32_t mask = irq_get_bit_mask(irqID);
-    
-    uint32_t value = gicd->IGROUPRn[reg];
-    if (!isSecure)
-    {
-        value &= ~mask;
-    }
-    else
-    {
-        value |= mask;
-    }
-    gicd->IGROUPRn[reg] = value;
-}
-
-void gic_enable_irq(uint32_t irqID, bool isEnabled)
-{
-    gicd_t * gicd = gic_get_gicd();
-    
-    uint32_t reg = irq_get_register_offset(irqID);
-    uint32_t mask = irq_get_bit_mask(irqID);
-    
-    // Select set-enable or clear-enable register based on enable flag.
-    if (isEnabled)
-    {
-        gicd->ISENABLERn[reg] = mask;
-    }
-    else
-    {
-        gicd->ICENABLERn[reg] = mask;
-    }
-}
-
-void gic_set_irq_priority(uint32_t ID, uint32_t priority)
-{
-    gicd_t * gicd = gic_get_gicd();
-    
-    // Update the priority register. The priority registers are byte accessible, and the register
-    // struct has the priority registers as a byte array, so we can just index directly by the
-    // interrupt ID.
-    gicd->IPRIORITYRn[ID] = priority & 0xff;
-}
-
-void gic_set_cpu_target(uint32_t irqID, unsigned cpuNumber, bool enableIt)
-{
-    // Make sure the CPU number is valid.
-    assert(cpuNumber <= 7);
-    
-    gicd_t * gicd = gic_get_gicd();
-    uint8_t cpuMask = 1 << cpuNumber;
-    
-    // Like the priority registers, the target registers are byte accessible, and the register
-    // struct has the them as a byte array, so we can just index directly by the
-    // interrupt ID.
-    if (enableIt)
-    {
-        gicd->ITARGETSRn[irqID] |= (cpuMask & 0xff);
-    }
-    else
-    {
-        gicd->ITARGETSRn[irqID] &= ~(cpuMask & 0xff);
-    }
-}
-
-void gic_send_sgi(uint32_t irqID, uint32_t target_list, uint32_t filter_list)
-{
-    gicd_t * gicd = gic_get_gicd();
-    
-    gicd->SGIR = (filter_list << kBP_GICD_SGIR_TargetListFilter)
-                    | (target_list << kBP_GICD_SGIR_CPUTargetList)
-                    | (irqID & 0xf);
-}
-
-void gic_cpu_enable(bool enableIt)
-{
-    gicc_t * gicc = gic_get_gicc();
-    
-    if (enableIt)
-    {
-        gicc->CTLR |= kBM_GICC_CTLR_EnableS | kBM_GICC_CTLR_EnableNS;
-    }
-    else
-    {
-        gicc->CTLR &= ~(kBM_GICC_CTLR_EnableS | kBM_GICC_CTLR_EnableNS);
-    }
-}
-
-void gic_set_cpu_priority_mask(uint32_t priority)
-{
-    gicc_t * gicc = gic_get_gicc();
-    gicc->PMR = priority & 0xff;    
-}
-
-uint32_t gic_read_irq_ack(void)
-{
-    gicc_t * gicc = gic_get_gicc();
-    return gicc->IAR;
-}
-
-void gic_write_end_of_irq(uint32_t irqID)
-{
-    gicc_t * gicc = gic_get_gicc();
-    gicc->EOIR = irqID;
-}
-
-void gic_init(void)
-{
-    gicd_t * gicd = gic_get_gicd();
-
-    // First disable the distributor.
-    gic_enable(false);
-    
-    // Clear all pending interrupts.
-    int i;
-    for (i = 0; i < 32; ++i)
-    {
-        gicd->ICPENDRn[i] = 0xffffffff;
-    }
-    
-    // Set all interrupts to secure.
-    for (i = 0; i < 8; ++i)
-    {
-        gicd->IGROUPRn[i] = 0;
-    }
-
-    // Init the GIC CPU interface.
-    gic_init_cpu();
-    
-    // Now enable the distributor.
-    gic_enable(true);
-}
-
-void gic_init_cpu(void)
-{
-    // Init the GIC CPU interface.
-    gic_set_cpu_priority_mask(0xff);
-
-    // Disable preemption.
-    gicc_t * gicc = gic_get_gicc();
-    gicc->BPR = 7;
-
-    // Enable signaling the CPU.
-    gic_cpu_enable(true);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// EOF
-////////////////////////////////////////////////////////////////////////////////

+ 0 - 285
bsp/imx6ul/platform/cpu/mmu.c

@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 2008-2012, Freescale Semiconductor, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * o Redistributions of source code must retain the above copyright notice, this list
- *   of conditions and the following disclaimer.
- *
- * o Redistributions in binary form must reproduce the above copyright notice, this
- *   list of conditions and the following disclaimer in the documentation and/or
- *   other materials provided with the distribution.
- *
- * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived from this
- *   software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*!
- * @file  mmu.c
- * @brief System memory arangement.
- */
-#include "cortex_a.h"
-#include "mmu.h"
-#include "arm_cp_registers.h"
-
-////////////////////////////////////////////////////////////////////////////////
-// Definitions
-////////////////////////////////////////////////////////////////////////////////
-
-//! @brief Size in bytes of the first-level page table.
-#define MMU_L1_PAGE_TABLE_SIZE (16 * 1024)
-
-//! @brief First-level 1MB section descriptor entry.
-typedef union mmu_l1_section {
-    uint32_t u;
-    struct {
-        uint32_t id:2;  //!< ID
-        uint32_t b:1;   //!< Bufferable
-        uint32_t c:1;   //!< Cacheable
-        uint32_t xn:1;  //!< Execute-not
-        uint32_t domain:4;  //!< Domain
-        uint32_t _impl_defined:1;   //!< Implementation defined, should be zero.
-        uint32_t ap1_0:2;  //!< Access permissions AP[1:0]
-        uint32_t tex:3; //!< TEX remap
-        uint32_t ap2:1; //!< Access permissions AP[2] 
-        uint32_t s:1;   //!< Shareable
-        uint32_t ng:1;  //!< Not-global
-        uint32_t _zero:1;   //!< Should be zero.
-        uint32_t ns:1;  //!< Non-secure
-        uint32_t address:12;   //!< Physical base address
-    };
-} mmu_l1_section_t;
-
-enum {
-    kMMU_L1_Section_ID = 2,  //!< ID value for a 1MB section first-level entry.
-    kMMU_L1_Section_Address_Shift = 20  //!< Bit offset of the physical base address field.
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// Externs
-////////////////////////////////////////////////////////////////////////////////
-
-extern char __l1_page_table_start;
-
-////////////////////////////////////////////////////////////////////////////////
-// Code
-////////////////////////////////////////////////////////////////////////////////
-
-void mmu_enable()
-{
-    // invalidate all tlb 
-    arm_unified_tlb_invalidate();
-
-    // read SCTLR 
-    uint32_t sctlr;
-    _ARM_MRC(15, 0, sctlr, 1, 0, 0);
-    
-    // set MMU enable bit 
-    sctlr |= BM_SCTLR_M;
-
-    // write modified SCTLR
-    _ARM_MCR(15, 0, sctlr, 1, 0, 0);
-}
-
-void mmu_disable()
-{
-    // read current SCTLR 
-    uint32_t sctlr;
-    _ARM_MRC(15, 0, sctlr, 1, 0, 0);
-    
-    // clear MMU enable bit 
-    sctlr &=~ BM_SCTLR_M;
-
-    // write modified SCTLR
-    _ARM_MCR(15, 0, sctlr, 1, 0, 0);
-}
-
-void mmu_init()
-{
-    // Get the L1 page table base address.
-    uint32_t * table = (uint32_t *)&__l1_page_table_start;
-    uint32_t share_attr = kShareable;
-
-    // write table address to TTBR0
-    _ARM_MCR(15, 0, table, 2, 0, 0);
-
-    // set Client mode for all Domains
-    uint32_t dacr = 0x55555555; 
-    _ARM_MCR(15, 0, dacr, 3, 0, 0); // MCR p15, 0, <Rd>, c3, c0, 0 ; Write DACR
-
-    // Clear the L1 table.
-    bzero(table, MMU_L1_PAGE_TABLE_SIZE);
-    
-    // Create default mappings.
-    mmu_map_l1_range(0x00000000, 0x00000000, 0x00900000, kStronglyOrdered, kShareable, kRWAccess); // ROM and peripherals
-    mmu_map_l1_range(0x00900000, 0x00900000, 0x00100000, kStronglyOrdered, kShareable, kRWAccess); // OCRAM
-    mmu_map_l1_range(0x00a00000, 0x00a00000, 0x0f600000, kStronglyOrdered, kShareable, kRWAccess); // More peripherals
-   
-    // Check whether SMP is enabled. If it is not, then we don't want to make SDRAM shareable.
-    uint32_t actlr = 0x0;
-    _ARM_MRC(15, 0, actlr, 1, 0, 1);
-    if (actlr & BM_ACTLR_SMP)
-    {
-        share_attr = kShareable;
-    }
-    else
-    {
-        share_attr = kNonshareable;
-    }
-
-#if defined(CHIP_MX6DQ) || defined(CHIP_MX6SDL)
-    mmu_map_l1_range(0x10000000, 0x10000000, 0x80000000, kOuterInner_WB_WA, share_attr, kRWAccess); // 2GB DDR
-#elif defined(CHIP_MX6SL) || defined(CHIP_MX6UL)
-    mmu_map_l1_range(0x80000000, 0x80000000, 0x40000000, kOuterInner_WB_WA, share_attr, kRWAccess); // 1GB DDR
-#else
-#error Unknown chip type!
-#endif
-}
-
-void mmu_map_l1_range(uint32_t pa, uint32_t va, uint32_t length, mmu_memory_type_t memoryType, mmu_shareability_t isShareable, mmu_access_t access)
-{
-    register mmu_l1_section_t entry;
-    entry.u = 0;
-    
-    // Set constant attributes.
-    entry.id = kMMU_L1_Section_ID;
-    entry.xn = 0; // Allow execution
-    entry.domain = 0; // Domain 0
-    entry.ng = 0; // Global
-    entry.ns = 0; // Secure
-    
-    // Set attributes based on the selected memory type.
-    switch (memoryType)
-    {
-        case kStronglyOrdered:
-            entry.c = 0;
-            entry.b = 0;
-            entry.tex = 0;
-            entry.s = 1; // Ignored
-            break;
-        case kDevice:
-            if (isShareable)
-            {
-                entry.c = 0;
-                entry.b = 1;
-                entry.tex = 0;
-                entry.s = 1; // Ignored
-            }
-            else
-            {
-                entry.c = 0;
-                entry.b = 0;
-                entry.tex = 2;
-                entry.s = 0; // Ignored
-            }
-            break;
-        case kOuterInner_WB_WA:
-            entry.c = 1;
-            entry.b = 1;
-            entry.tex = 1;
-            entry.s = isShareable;
-            break;
-        case kOuterInner_WT:
-            entry.c = 1;
-            entry.b = 0;
-            entry.tex = 0;
-            entry.s = isShareable;
-            break;
-        case kNoncacheable:
-            entry.c = 0;
-            entry.b = 0;
-            entry.tex = 1;
-            entry.s = isShareable;
-            break;
-    }
-    
-    // Set attributes from specified access mode.
-    switch (access)
-    {
-        case kNoAccess:
-            entry.ap2 = 0;
-            entry.ap1_0 = 0;
-            break;
-        case kROAccess:
-            entry.ap2 = 1;
-            entry.ap1_0 = 3;
-            break;
-        case kRWAccess:
-            entry.ap2 = 0;
-            entry.ap1_0 = 3;
-            break;
-    }
-    
-    // Get the L1 page table base address.
-    uint32_t * table = (uint32_t *)&__l1_page_table_start;
-    
-    // Convert addresses to 12-bit bases.
-    uint32_t vbase = va >> kMMU_L1_Section_Address_Shift;
-    uint32_t pbase = pa >> kMMU_L1_Section_Address_Shift;
-    uint32_t entries = length >> kMMU_L1_Section_Address_Shift;
-
-    // Fill in L1 page table entries.
-    for (; entries > 0; ++pbase, ++vbase, --entries)
-    {
-        entry.address = pbase;
-        table[vbase] = entry.u;
-    }
-    
-    // Invalidate TLB
-    arm_unified_tlb_invalidate();
-}
-
-bool mmu_virtual_to_physical(uint32_t virtualAddress, uint32_t * physicalAddress)
-{
-    uint32_t pa = 0;
-    
-    // VA to PA translation with privileged read permission check  
-    _ARM_MCR(15, 0, virtualAddress & 0xfffffc00, 7, 8, 0);
-    
-    // Read PA register 
-    _ARM_MRC(15, 0, pa, 7, 4, 0);
-    
-    // First bit of returned value is Result of conversion (0 is successful translation) 
-    if (pa & 1)
-    {
-        // We can try write permission also 
-        // VA to PA translation with privileged write permission check  
-        _ARM_MCR(15, 0, virtualAddress & 0xfffffc00, 7, 8, 1);
-        
-        // Read PA register 
-        _ARM_MRC(15, 0, pa, 7, 4, 0);
-        
-        // First bit of returned value is Result of conversion (0 is successful translation) 
-        if (pa & 1)
-        {
-            return false;
-        }
-    }
-    
-    if (physicalAddress)
-    {
-        // complete address returning base + offset
-        pa = (pa & 0xfffff000) | (virtualAddress & 0x00000fff);
-        *physicalAddress = pa;
-    }
-    
-    return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// EOF
-////////////////////////////////////////////////////////////////////////////////

+ 0 - 157
bsp/imx6ul/platform/cpu/mmu.h

@@ -1,157 +0,0 @@
-/*
- * Copyright (c) 2008-2012, Freescale Semiconductor, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * o Redistributions of source code must retain the above copyright notice, this list
- *   of conditions and the following disclaimer.
- *
- * o Redistributions in binary form must reproduce the above copyright notice, this
- *   list of conditions and the following disclaimer in the documentation and/or
- *   other materials provided with the distribution.
- *
- * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived from this
- *   software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-//! @addtogroup diag_mmu
-//! @{
-
-/*!
- * @file  mmu.h
- * @brief System memory arrangement.
- */
-
-#ifndef _MMU_H_
-#define _MMU_H_
-
-#include "sdk.h"
-
-////////////////////////////////////////////////////////////////////////////////
-// Definitions
-////////////////////////////////////////////////////////////////////////////////
-
-//! @brief Memory region attributes.
-typedef enum _mmu_memory_type
-{
-    kStronglyOrdered,
-    kDevice,
-    kOuterInner_WB_WA,
-    kOuterInner_WT,
-    kNoncacheable,
-} mmu_memory_type_t;
-
-//! @brief Memory region shareability options.
-typedef enum _mmu_shareability
-{
-    kShareable = 1,
-    kNonshareable = 0
-} mmu_shareability_t;
-
-//! @brief Access permissions for a memory region.
-typedef enum _mmu_access
-{
-    kNoAccess,
-    kROAccess,
-    kRWAccess
-} mmu_access_t;
-
-////////////////////////////////////////////////////////////////////////////////
-// Prototypes
-////////////////////////////////////////////////////////////////////////////////
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-/*!
- * @brief Enable the MMU.
- *
- * The L1 page tables and MMU settings must have already been configured by
- * calling mmu_init() before the MMU is enabled.
- */
-void mmu_enable();
-
-/*!
- * @brief Disable the MMU.
- */
-void mmu_disable();
-
-/*!
- * @brief Set up the default first-level page table.
- *
- * Initializes the L1 page table with the following regions:
- *  - 0x00000000...0x00900000 : ROM and peripherals, strongly-ordered
- *  - 0x00900000...0x00a00000 : OCRAM, strongly-ordered
- *  - For MX6DQ or MX6SDL: 0x10000000...0x90000000 : DDR, normal, outer inner, write-back, write-allocate
- *  - For MX6SL: 0x80000000...0xc0000000 : DDR, normal, outer inner, write-back, write-allocate
- *
- * If the CPU is participating in SMP, then the DDR regions are made shareable. Otherwise they
- * are marked as non-shareable.
- *
- * The TTBR0 register is set to the base of the L1 table.
- *
- * All memory domains are configured to allow client access. However, note that only domain 0 is
- * used by mmu_map_l1_range().
- */
-void mmu_init();
-
-/*!
- * @brief Maps a range of memory in the first-level page table.
- *
- * Entries in the first-level page table are filled in for the range of virtual addresses
- * starting at @a va and continuing for @a length bytes. These virtual addreses are mapped
- * to the physical addresses starting at @a pa and continuing for @a length bytes. All table
- * entries for the range of mapped memory have the same attributes, which are selected with
- * the @a memoryType, @a isShareable, and @a access parameters.
- *
- * @param pa The base physical address of the range to which the virtual address will be mapped.
- * @param va The base virtual address of the range.
- * @param length The size of the range to be mapped, in bytes. This value must be divisible by 1MB.
- * @param memoryType The type of the memory region. This controls caching, buffering, ordering of
- *      memory accesses, and other attributes of the region.
- * @param isShareable The shareability of the physical memory. Ignored for strongly-ordered memory.
- * @param access Access permissions.
- */
-void mmu_map_l1_range(uint32_t pa, uint32_t va, uint32_t length, mmu_memory_type_t memoryType, mmu_shareability_t isShareable, mmu_access_t access);
-
-/*!
- * @brief Convert virtual address to physical.
- *
- * First attempts a priviledged read translation for the current security mode. If that fails,
- * a priviledged write translation, also for the current security mode, is attempted. If this
- * second attempt at translation fails, then false will be returned.
- *
- * @param virtualAddress Virtual address to convert to a physical address.
- * @param[out] physicalAddress This parameter is filled in with the physical address corresponding
- *      to the virtual address passed in @a virtualAddress.
- * @retval true The address returned through @a physicalAddress is valid.
- * @retval false The conversion failed for some reason.
- */
-bool mmu_virtual_to_physical(uint32_t virtualAddress, uint32_t * physicalAddress);
-
-#if defined(__cplusplus)
-}
-#endif
-
-//! @}
-
-#endif // _MMU_H_
-////////////////////////////////////////////////////////////////////////////////
-// EOF
-////////////////////////////////////////////////////////////////////////////////
-

+ 96 - 0
bsp/imx6ul/platform/cpu/platform.h

@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-03-22     quanzhao     first version
+ */
+#ifndef __PLATFORM_H__
+#define __PLATFORM_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+
+/* SOC-relative definitions */
+//#include "realview.h"
+#include "gic_registers.h"
+#include "irq_numbers.h"
+
+/* the maximum number of gic */
+# define ARM_GIC_MAX_NR 1
+
+/* the maximum number of interrupts */
+#define ARM_GIC_NR_IRQS IMX_INTERRUPT_COUNT
+
+/* the maximum entries of the interrupt table */
+#define MAX_HANDLERS IMX_INTERRUPT_COUNT
+
+/* the basic constants needed by gic */
+rt_inline rt_uint32_t platform_get_gic_dist_base(void)
+{
+    rt_uint32_t gic_base;
+    asm volatile ("mrc p15, 4, %0, c15, c0, 0" : "=r"(gic_base));
+    return gic_base + kGICDBaseOffset;
+}
+
+rt_inline rt_uint32_t platform_get_gic_cpu_base(void)
+{
+    rt_uint32_t gic_base;
+    asm volatile ("mrc p15, 4, %0, c15, c0, 0" : "=r"(gic_base));
+    return gic_base + kGICCBaseOffset;
+}
+
+#define GIC_IRQ_START   0
+
+#define GIC_ACK_INTID_MASK              0x000003ff
+
+/* the definition needed by gic.c */
+#define __REG32(x)  (*((volatile unsigned int *)(x)))
+
+/* keep compatible with platform SDK */
+typedef enum {
+    CPU_0,
+    CPU_1,
+    CPU_2,
+    CPU_3,
+} cpuid_e;
+
+enum _gicd_sgi_filter
+{
+    //! Forward the interrupt to the CPU interfaces specified in the @a target_list parameter.
+    kGicSgiFilter_UseTargetList = 0,
+
+    //! Forward the interrupt to all CPU interfaces except that of the processor that requested
+    //! the interrupt.
+    kGicSgiFilter_AllOtherCPUs = 1,
+
+    //! Forward the interrupt only to the CPU interface of the processor that requested the
+    //! interrupt.
+    kGicSgiFilter_OnlyThisCPU = 2
+};
+
+typedef void (*irq_hdlr_t) (void);
+
+extern void rt_hw_interrupt_mask(int vector);
+extern void rt_hw_interrupt_umask(int vector);
+extern rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
+    void *param, const char *name);
+
+rt_inline void register_interrupt_routine(uint32_t irq_id, irq_hdlr_t isr)
+{
+    rt_hw_interrupt_install(irq_id, (rt_isr_handler_t)isr, NULL, "unknown");
+}
+
+rt_inline void enable_interrupt(uint32_t irq_id, uint32_t cpu_id, uint32_t priority)
+{
+    rt_hw_interrupt_umask(irq_id);
+}
+
+rt_inline void disable_interrupt(uint32_t irq_id, uint32_t cpu_id)
+{
+    rt_hw_interrupt_mask(irq_id);
+}
+
+#endif  /* __PLATFORM_H__ */

+ 0 - 183
bsp/imx6ul/platform/include/gic.h

@@ -1,183 +0,0 @@
-/*
- * Copyright (c) 2011-2012, Freescale Semiconductor, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * o Redistributions of source code must retain the above copyright notice, this list
- *   of conditions and the following disclaimer.
- *
- * o Redistributions in binary form must reproduce the above copyright notice, this
- *   list of conditions and the following disclaimer in the documentation and/or
- *   other materials provided with the distribution.
- *
- * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived from this
- *   software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef __GIC_H__
-#define __GIC_H__
-
-#include "sdk_types.h"
-
-//! @addtogroup gic
-//! @{
-
-////////////////////////////////////////////////////////////////////////////////
-// Definitions
-////////////////////////////////////////////////////////////////////////////////
-
-//! @brief Options for sending a software generated interrupt.
-//!
-//! These options are used for the @a filter_list parameter of the gic_send_sgi()
-//! function. They control how to select which CPUs that the interrupt is
-//! sent to.
-enum _gicd_sgi_filter
-{
-    //! Forward the interrupt to the CPU interfaces specified in the @a target_list parameter.
-    kGicSgiFilter_UseTargetList = 0,
-    
-    //! Forward the interrupt to all CPU interfaces except that of the processor that requested
-    //! the interrupt.
-    kGicSgiFilter_AllOtherCPUs = 1,
-    
-    //! Forward the interrupt only to the CPU interface of the processor that requested the
-    //! interrupt.
-    kGicSgiFilter_OnlyThisCPU = 2
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// API
-////////////////////////////////////////////////////////////////////////////////
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-//! @name Initialization
-//@{
-//! @brief Init interrupt handling.
-//!
-//! This function is intended to be called only by the primary CPU init code, so it will
-//! only be called once during system bootup.
-//!
-//! Also inits the current CPU. You don't need to call gic_init_cpu() separately.
-//!
-//! @post The interrupt distributor and the current CPU interface are enabled. All interrupts
-//!     that were pending are cleared, and all interrupts are made secure (group 0).
-void gic_init(void);
-
-//! @brief Init the current CPU's GIC interface.
-//!
-//! @post Enables the CPU interface and sets the priority mask to 255. Interrupt preemption
-//!     is disabled by setting the Binary Point to a value of 7.
-void gic_init_cpu(void);
-//@}
-
-//! @name GIC Interrupt Distributor Functions
-//@{
-//! @brief Enable or disable the GIC Distributor.
-//!
-//! Enables or disables the GIC distributor passing both secure (group 0) and non-secure
-//! (group 1) interrupts to the CPU interfaces.
-//!
-//! @param enableIt Pass true to enable or false to disable.
-void gic_enable(bool enableIt);
-
-//! @brief Set the security mode for an interrupt.
-//!
-//! @param irqID The interrupt number.
-//! @param isSecure Whether the interrupt is taken to secure mode.
-void gic_set_irq_security(uint32_t irqID, bool isSecure);
-
-//! @brief Enable or disable an interrupt.
-//!
-//! @param irqID The number of the interrupt to control.
-//! @param isEnabled Pass true to enable or false to disable.
-void gic_enable_irq(uint32_t irqID, bool isEnabled);
-
-//! @brief Set whether a CPU will receive a particular interrupt.
-//!
-//! @param irqID The interrupt number.
-//! @param cpuNumber The CPU number. The first CPU core is 0.
-//! @param enableIt Whether to send the interrupt to the specified CPU. Pass true to enable
-//!     or false to disable.
-void gic_set_cpu_target(uint32_t irqID, unsigned cpuNumber, bool enableIt);
-
-//! @brief Set an interrupt's priority.
-//!
-//! @param irq_id The interrupt number.
-//! @param priority The priority for the interrupt. In the range of 0 through 0xff, with
-//!     0 being the highest priority.
-void gic_set_irq_priority(uint32_t irq_id, uint32_t priority);
-
-//! @brief Send a software generated interrupt to a specific CPU.
-//!
-//! @param irq_id The interrupt number to send.
-//! @param target_list Each bit indicates a CPU to which the interrupt will be forwarded.
-//!     Bit 0 is CPU 0, bit 1 is CPU 1, and so on. If the value is 0, then the interrupt
-//!     will not be forwarded to any CPUs. This parameter is only used if @a filter_list
-//!     is set to #kGicSgiFilter_UseTargetList.
-//! @param filter_list One of the enums of the #_gicd_sgi_filter enumeration. The selected
-//!     option determines which CPUs the interrupt will be sent to. If the value
-//!     is #kGicSgiFilter_UseTargetList, then the @a target_list parameter is used.
-void gic_send_sgi(uint32_t irq_id, uint32_t target_list, uint32_t filter_list);
-//@}
-
-//! @name GIC CPU Interface Functions
-//@{
-//! @brief Enable or disable the interface to the GIC for the current CPU.
-//!
-//! @param enableIt Pass true to enable or false to disable.
-void gic_cpu_enable(bool enableIt);
-
-//! @brief Set the mask of which interrupt priorities the CPU will receive.
-//!
-//! @param priority The lowest priority that will be passed to the current CPU. Pass 0xff to
-//!     allow all priority interrupts to signal the CPU.
-void gic_set_cpu_priority_mask(uint32_t priority);
-
-//! @brief Acknowledge starting of interrupt handling and get the interrupt number.
-//!
-//! Normally, this function is called at the beginning of the IRQ handler. It tells the GIC
-//! that you are starting to handle an interupt, and returns the number of the interrupt you
-//! need to handle. After the interrupt is handled, you should call gic_write_end_of_irq()
-//! to signal that the interrupt is completely handled.
-//!
-//! In some cases, a spurious interrupt might happen. One possibility is if another CPU handles
-//! the interrupt. When a spurious interrupt occurs, the end of the interrupt should be indicated
-//! but nothing else.
-//!
-//! @return The number for the highest priority interrupt available for the calling CPU. If
-//!     the return value is 1022 or 1023, a spurious interrupt has occurred.
-uint32_t gic_read_irq_ack(void);
-
-//! @brief Signal the end of handling an interrupt.
-//!
-//! @param irq_id The number of the interrupt for which handling has finished.
-void gic_write_end_of_irq(uint32_t irq_id);
-//@}
-
-
-#if defined(__cplusplus)
-}
-#endif
-
-//! @}
-
-#endif // __GIC_H__
-////////////////////////////////////////////////////////////////////////////////
-// EOF
-////////////////////////////////////////////////////////////////////////////////

+ 0 - 101
bsp/imx6ul/platform/include/interrupt.h

@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2009-2012, Freescale Semiconductor, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * o Redistributions of source code must retain the above copyright notice, this list
- *   of conditions and the following disclaimer.
- *
- * o Redistributions in binary form must reproduce the above copyright notice, this
- *   list of conditions and the following disclaimer in the documentation and/or
- *   other materials provided with the distribution.
- *
- * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived from this
- *   software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef __INTERRUPT_H__
-#define __INTERRUPT_H__
-
-#include "sdk_types.h"
-#include "irq_numbers.h"
-
-//! @addtogroup diag_interrupt
-//! @{
-
-/*!
- * @file interrupt.h
- * @brief Interface for the interrupt manager.
- */
-
-////////////////////////////////////////////////////////////////////////////////
-// Definitions
-////////////////////////////////////////////////////////////////////////////////
-
-//! @brief
-typedef enum {
-    CPU_0,
-    CPU_1,
-    CPU_2,
-    CPU_3,
-} cpuid_e;
-
-//! @brief Interrupt service routine.
-typedef void (*irq_hdlr_t) (void);
-
-////////////////////////////////////////////////////////////////////////////////
-// API
-////////////////////////////////////////////////////////////////////////////////
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-//! @brief Enable an interrupt.
-//!
-//! Sets the interrupt priority and makes it non-secure. Then the interrupt is
-//! enabled on the CPU specified by @a cpu_id.
-//!
-//! @param irq_id The interrupt number to enable.
-//! @param cpu_id The index of the CPU for which the interrupt will be enabled.
-//! @param priority The interrupt priority, from 0-255. Lower numbers have higher priority.
-void enable_interrupt(uint32_t irq_id, uint32_t cpu_id, uint32_t priority);
-
-//! @brief Disable an interrupt on the specified CPU.
-//!
-//! @param irq_id The interrupt number to disabled.
-//! @param cpu_id The index of the CPU for which the interrupt will be disabled.
-void disable_interrupt(uint32_t irq_id, uint32_t cpu_id);
-
-//! @brief Set the interrupt service routine for the specified interrupt.
-//!
-//! @param irq_id The interrupt number.
-//! @param isr Function that will be called to handle the interrupt.
-void register_interrupt_routine(uint32_t irq_id, irq_hdlr_t isr);
-
-//! @brief Interrupt handler that simply prints a message.
-void default_interrupt_routine(void);
-
-#if defined(__cplusplus)
-}
-#endif
-
-//! @}
-
-#endif
-////////////////////////////////////////////////////////////////////////////////
-// EOF
-////////////////////////////////////////////////////////////////////////////////

+ 1 - 1
bsp/imx6ul/rtconfig.py

@@ -10,7 +10,7 @@ if os.getenv('RTT_CC'):
 
 # only support GNU GCC compiler.
 PLATFORM  = 'gcc'
-EXEC_PATH = '/opt/gcc-arm-none-eabi-4_8-2014q1_gri/bin'
+EXEC_PATH = '/usr/bin'
 
 if os.getenv('RTT_EXEC_PATH'):
     EXEC_PATH = os.getenv('RTT_EXEC_PATH')

+ 1 - 0
bsp/qemu-vexpress-a9/.config

@@ -322,6 +322,7 @@ CONFIG_RT_USING_LWP=y
 # CONFIG_PKG_USING_WEBTERMINAL is not set
 # CONFIG_PKG_USING_CJSON is not set
 # CONFIG_PKG_USING_JSMN is not set
+# CONFIG_PKG_USING_LIBMODBUS is not set
 # CONFIG_PKG_USING_LJSON is not set
 # CONFIG_PKG_USING_EZXML is not set
 # CONFIG_PKG_USING_NANOPB is not set

+ 13 - 0
bsp/qemu-vexpress-a9/Makefile

@@ -0,0 +1,13 @@
+phony := all
+all:
+
+include config.mk
+
+ifneq ($(MAKE_LIB),1)
+TARGET := rtthread.elf
+include src.mk
+endif
+
+$(if $(strip $(RTT_ROOT)),,$(error RTT_ROOT not defined))
+
+include $(RTT_ROOT)/tools/rtthread.mk

+ 2 - 2
bsp/qemu-vexpress-a9/SConstruct

@@ -5,7 +5,7 @@ import rtconfig
 if os.getenv('RTT_ROOT'):
     RTT_ROOT = os.getenv('RTT_ROOT')
 else:
-    RTT_ROOT = os.path.normpath(os.getcwd() + '/../..')
+    RTT_ROOT = os.path.join(os.getcwd(), '..', '..')
 
 sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
 from building import *
@@ -25,7 +25,7 @@ Export('RTT_ROOT')
 Export('rtconfig')
 
 # prepare building environment
-objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=True)
+objs = PrepareBuilding(env, RTT_ROOT)
 
 # make a building
 DoBuilding(TARGET, objs)

+ 0 - 17
bsp/qemu-vexpress-a9/cpu/SConscript

@@ -1,17 +0,0 @@
-Import('rtconfig')
-from building import *
-
-cwd     = GetCurrentDir()
-src	= Glob('*.c')
-CPPPATH = [cwd]
-
-if rtconfig.PLATFORM == 'iar':
-        src += Glob('*_iar.S')
-elif rtconfig.PLATFORM == 'gcc':
-        src += Glob('*_gcc.S')
-elif rtconfig.PLATFORM == 'armcc':
-        src += Glob('*_rvds.S')
-
-group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
-
-Return('group')

+ 0 - 64
bsp/qemu-vexpress-a9/cpu/armv7.h

@@ -1,64 +0,0 @@
-#ifndef __ARMV7_H__
-#define __ARMV7_H__
-
-/* the exception stack without VFP registers */
-struct rt_hw_exp_stack
-{
-	unsigned long r0;
-	unsigned long r1;
-	unsigned long r2;
-	unsigned long r3;
-	unsigned long r4;
-	unsigned long r5;
-	unsigned long r6;
-	unsigned long r7;
-	unsigned long r8;
-	unsigned long r9;
-	unsigned long r10;
-	unsigned long fp;
-	unsigned long ip;
-	unsigned long sp;
-	unsigned long lr;
-	unsigned long pc;
-	unsigned long cpsr;
-};
-
-struct rt_hw_stack
-{
-	unsigned long cpsr;
-	unsigned long r0;
-	unsigned long r1;
-	unsigned long r2;
-	unsigned long r3;
-	unsigned long r4;
-	unsigned long r5;
-	unsigned long r6;
-	unsigned long r7;
-	unsigned long r8;
-	unsigned long r9;
-	unsigned long r10;
-	unsigned long fp;
-	unsigned long ip;
-	unsigned long lr;
-	unsigned long pc;
-};
-
-#define USERMODE    0x10
-#define FIQMODE     0x11
-#define IRQMODE     0x12
-#define SVCMODE     0x13
-#define MONITORMODE 0x16
-#define ABORTMODE   0x17
-#define HYPMODE     0x1b
-#define UNDEFMODE   0x1b
-#define MODEMASK    0x1f
-#define NOINT       0xc0
-
-#define T_Bit       (1<<5)
-#define F_Bit       (1<<6)
-#define I_Bit       (1<<7)
-#define A_Bit       (1<<8)
-#define E_Bit       (1<<9)
-#define J_Bit       (1<<24)
-
-#endif

+ 0 - 198
bsp/qemu-vexpress-a9/cpu/context_gcc.S

@@ -1,198 +0,0 @@
-/*
- * File      : context.S
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2013, RT-Thread Development Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Change Logs:
- * Date           Author       Notes
- * 2013-07-05     Bernard      the first version
- * 2018-11-22     Jesven       in the smp version, using macro to
- *                             define rt_hw_interrupt_enable and rt_hw_interrupt_disable
- *                             rt_hw_context_switch_interrupt switches to the new thread directly
- */
-
-#include "rtconfig.h"
-.section .text, "ax"
-
-#ifdef RT_USING_SMP
-#define rt_hw_interrupt_disable rt_hw_local_irq_disable
-#define rt_hw_interrupt_enable  rt_hw_local_irq_enable
-#endif
-
-/*
- * rt_base_t rt_hw_interrupt_disable();
- */
-.globl rt_hw_interrupt_disable
-rt_hw_interrupt_disable:
-    mrs r0, cpsr
-    cpsid i
-    bx  lr
-
-/*
- * void rt_hw_interrupt_enable(rt_base_t level);
- */
-.globl rt_hw_interrupt_enable
-rt_hw_interrupt_enable:
-    msr cpsr, r0
-    bx  lr
-
-/*
- * void rt_hw_context_switch_to(rt_uint32 to);
- * r0 --> to
- */
-.globl rt_hw_context_switch_to
-rt_hw_context_switch_to:
-    ldr sp, [r0]            @ get new task stack pointer
-
-#ifdef RT_USING_SMP
-    mov     r0, r1
-    bl      rt_cpus_lock_status_restore
-#endif /*RT_USING_SMP*/
-
-#ifdef RT_USING_LWP
-    ldmfd sp, {r13, r14}^   @ pop usr_sp usr_lr
-    add sp, #8
-#endif
-
-    ldmfd sp!, {r4}         @ pop new task spsr
-    msr spsr_cxsf, r4
-
-    ldmfd sp!, {r0-r12, lr, pc}^   @ pop new task r0-r12, lr & pc
-
-.section .bss.share.isr
-_guest_switch_lvl:
-    .word 0
-
-.section .text.isr, "ax"
-/*
- * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
- * r0 --> from
- * r1 --> to
- */
-.globl rt_hw_context_switch
-rt_hw_context_switch:
-    stmfd   sp!, {lr}       @ push pc (lr should be pushed in place of PC)
-    stmfd   sp!, {r0-r12, lr}   @ push lr & register file
-
-    mrs r4, cpsr
-    tst lr, #0x01
-    orrne r4, r4, #0x20     @ it's thumb code
-
-    stmfd sp!, {r4}         @ push cpsr
-
-#ifdef RT_USING_LWP
-    stmfd sp, {r13, r14}^   @ push usr_sp usr_lr
-    sub sp, #8
-#endif
-
-    str sp, [r0]            @ store sp in preempted tasks TCB
-    ldr sp, [r1]            @ get new task stack pointer
-
-#ifdef RT_USING_SMP
-    mov     r0, r2
-    bl      rt_cpus_lock_status_restore
-#endif /*RT_USING_SMP*/
-
-#ifdef RT_USING_LWP
-    ldmfd sp, {r13, r14}^   @ pop usr_sp usr_lr
-    add sp, #8
-#endif
-
-    ldmfd sp!, {r4}         @ pop new task cpsr to spsr
-    msr spsr_cxsf, r4
-    ldmfd sp!, {r0-r12, lr, pc}^  @ pop new task r0-r12, lr & pc, copy spsr to cpsr
-
-/*
- * void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to);
- */
-.equ Mode_USR,        0x10
-.equ Mode_FIQ,        0x11
-.equ Mode_IRQ,        0x12
-.equ Mode_SVC,        0x13
-.equ Mode_ABT,        0x17
-.equ Mode_UND,        0x1B
-.equ Mode_SYS,        0x1F
-
-.equ I_Bit,           0x80            @ when I bit is set, IRQ is disabled
-.equ F_Bit,           0x40            @ when F bit is set, FIQ is disabled
-
-.globl rt_thread_switch_interrupt_flag
-.globl rt_interrupt_from_thread
-.globl rt_interrupt_to_thread
-.globl rt_hw_context_switch_interrupt
-rt_hw_context_switch_interrupt:
-#ifdef RT_USING_SMP
-    /* r0 :irq_mod context
-     * r1 :addr of from_thread's sp
-     * r2 :addr of to_thread's sp
-     * r3 :to_thread's tcb
-     */
-
-    @ r0 point to {r0-r3} in stack
-    push    {r1 - r3}
-    mov     r1, r0
-    add     r0, r0, #4*4
-    ldmfd   r0!, {r4-r12,lr}@ reload saved registers
-    mrs     r3,  spsr       @ get cpsr of interrupt thread
-    sub     r2,  lr, #4     @ save old task's pc to r2
-    msr     cpsr_c, #I_Bit|F_Bit|Mode_SVC
-
-    stmfd   sp!, {r2}       @ push old task's pc
-    stmfd   sp!, {r4-r12,lr}@ push old task's lr,r12-r4
-    ldmfd   r1,  {r4-r7}    @ restore r0-r3 of the interrupt thread
-    stmfd   sp!, {r4-r7}    @ push old task's r0-r3
-    stmfd   sp!, {r3}       @ push old task's cpsr
-
-#ifdef RT_USING_LWP
-    stmfd sp, {r13,r14}^    @push usr_sp usr_lr
-    sub sp, #8
-#endif
-
-    msr     cpsr_c, #I_Bit|F_Bit|Mode_IRQ
-    pop     {r1 - r3}
-    mov     sp, r0
-    msr     cpsr_c, #I_Bit|F_Bit|Mode_SVC
-    str     sp, [r1]
-
-    ldr     sp, [r2]
-    mov     r0, r3
-    bl      rt_cpus_lock_status_restore
-
-#ifdef RT_USING_LWP
-    ldmfd sp, {r13,r14}^  @pop usr_sp usr_lr
-    add sp, #8
-#endif
-
-    ldmfd   sp!, {r4}       @ pop new task's cpsr to spsr
-    msr     spsr_cxsf, r4
-
-    ldmfd   sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
-
-#else /*RT_USING_SMP*/
-    ldr r2, =rt_thread_switch_interrupt_flag
-    ldr r3, [r2]
-    cmp r3, #1
-    beq _reswitch
-    ldr ip, =rt_interrupt_from_thread   @ set rt_interrupt_from_thread
-    mov r3, #1              @ set rt_thread_switch_interrupt_flag to 1
-    str r0, [ip]
-    str r3, [r2]
-_reswitch:
-    ldr r2, =rt_interrupt_to_thread     @ set rt_interrupt_to_thread
-    str r1, [r2]
-    bx  lr
-#endif /*RT_USING_SMP*/

+ 0 - 12
bsp/qemu-vexpress-a9/cpu/cp15.h

@@ -1,12 +0,0 @@
-#ifndef __CP15_H__
-#define __CP15_H__
-
-unsigned long rt_cpu_get_smp_id(void);
-
-void rt_cpu_mmu_disable(void);
-void rt_cpu_mmu_enable(void);
-void rt_cpu_tlb_set(volatile unsigned long*);
-
-void rt_cpu_vector_set_base(unsigned int addr);
-
-#endif

+ 0 - 140
bsp/qemu-vexpress-a9/cpu/cp15_gcc.S

@@ -1,140 +0,0 @@
-/*
- * File      : cp15_gcc.S
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2013, RT-Thread Development Team
- * http://www.rt-thread.org
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Change Logs:
- * Date           Author       Notes
- * 2013-07-05     Bernard      the first version
- */
-
-.globl rt_cpu_get_smp_id
-rt_cpu_get_smp_id:
-    mrc     p15, #0, r0, c0, c0, #5
-    bx      lr
-
-.globl rt_cpu_vector_set_base
-rt_cpu_vector_set_base:
-    mcr     p15, #0, r0, c12, c0, #0
-    dsb
-    bx      lr
-
-.globl rt_hw_cpu_dcache_enable
-rt_hw_cpu_dcache_enable:
-    mrc     p15, #0, r0, c1, c0, #0
-    orr     r0,  r0, #0x00000004
-    mcr     p15, #0, r0, c1, c0, #0
-    bx      lr
-
-.globl rt_hw_cpu_icache_enable
-rt_hw_cpu_icache_enable:
-    mrc     p15, #0, r0, c1, c0, #0
-    orr     r0,  r0, #0x00001000
-    mcr     p15, #0, r0, c1, c0, #0
-    bx      lr
-
-_FLD_MAX_WAY:
-   .word  0x3ff
-_FLD_MAX_IDX:
-   .word  0x7ff
-
-.globl rt_cpu_dcache_clean_flush
-rt_cpu_dcache_clean_flush:
-    push    {r4-r11}
-    dmb
-    mrc     p15, #1, r0, c0, c0, #1  @ read clid register
-    ands    r3, r0, #0x7000000       @ get level of coherency
-    mov     r3, r3, lsr #23
-    beq     finished
-    mov     r10, #0
-loop1:
-    add     r2, r10, r10, lsr #1
-    mov     r1, r0, lsr r2
-    and     r1, r1, #7
-    cmp     r1, #2
-    blt     skip
-    mcr     p15, #2, r10, c0, c0, #0
-    isb
-    mrc     p15, #1, r1, c0, c0, #0
-    and     r2, r1, #7
-    add     r2, r2, #4
-    ldr     r4, _FLD_MAX_WAY
-    ands    r4, r4, r1, lsr #3
-    clz     r5, r4
-    ldr     r7, _FLD_MAX_IDX
-    ands    r7, r7, r1, lsr #13
-loop2:
-    mov     r9, r4
-loop3:
-    orr     r11, r10, r9, lsl r5
-    orr     r11, r11, r7, lsl r2
-    mcr     p15, #0, r11, c7, c14, #2
-    subs    r9, r9, #1
-    bge     loop3
-    subs    r7, r7, #1
-    bge     loop2
-skip:
-    add     r10, r10, #2
-    cmp     r3, r10
-    bgt     loop1
-
-finished:
-    dsb
-    isb
-    pop     {r4-r11}
-    bx      lr
-
-.globl rt_hw_cpu_dcache_disable
-rt_hw_cpu_dcache_disable:
-    push    {r4-r11, lr}
-    bl      rt_cpu_dcache_clean_flush
-    mrc     p15, #0, r0, c1, c0, #0
-    bic     r0,  r0, #0x00000004
-    mcr     p15, #0, r0, c1, c0, #0
-    pop     {r4-r11, lr}
-    bx      lr
-
-.globl rt_hw_cpu_icache_disable
-rt_hw_cpu_icache_disable:
-    mrc     p15, #0, r0, c1, c0, #0
-    bic     r0,  r0, #0x00001000
-    mcr     p15, #0, r0, c1, c0, #0
-    bx      lr
-
-.globl rt_cpu_mmu_disable
-rt_cpu_mmu_disable:
-    mcr     p15, #0, r0, c8, c7, #0    @ invalidate tlb
-    mrc     p15, #0, r0, c1, c0, #0
-    bic     r0, r0, #1
-    mcr     p15, #0, r0, c1, c0, #0    @ clear mmu bit
-    dsb
-    bx      lr
-
-.globl rt_cpu_mmu_enable
-rt_cpu_mmu_enable:
-    mrc     p15, #0, r0, c1, c0, #0
-    orr     r0, r0, #0x001
-    mcr     p15, #0, r0, c1, c0, #0    @ set mmu enable bit
-    dsb
-    bx      lr
-
-.globl rt_cpu_tlb_set
-rt_cpu_tlb_set:
-    mcr     p15, #0, r0, c2, c0, #0
-    dmb
-    bx      lr

+ 0 - 83
bsp/qemu-vexpress-a9/cpu/cpuport.c

@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- * 2011-09-15     Bernard      first version
- * 2018-11-22     Jesven       add rt_hw_cpu_id()
- */
-
-#include <rthw.h>
-#include <rtthread.h>
-#include <board.h>
-
-#ifdef RT_USING_SMP
-int rt_hw_cpu_id(void)
-{
-    int cpu_id;
-    __asm__ volatile (
-            "mrc p15, 0, %0, c0, c0, 5"
-            :"=r"(cpu_id)
-            );
-    cpu_id &= 0xf;
-    return cpu_id;
-};
-
-void rt_hw_spin_lock(rt_hw_spinlock_t *lock)
-{
-    unsigned long tmp;
-    unsigned long newval;
-    rt_hw_spinlock_t lockval;
-
-    __asm__ __volatile__(
-            "pld [%0]"
-            ::"r"(&lock->slock)
-            );
-
-    __asm__ __volatile__(
-            "1: ldrex   %0, [%3]\n"
-            "   add %1, %0, %4\n"
-            "   strex   %2, %1, [%3]\n"
-            "   teq %2, #0\n"
-            "   bne 1b"
-            : "=&r" (lockval), "=&r" (newval), "=&r" (tmp)
-            : "r" (&lock->slock), "I" (1 << 16)
-            : "cc");
-
-    while (lockval.tickets.next != lockval.tickets.owner) {
-        __asm__ __volatile__("wfe":::"memory");
-        lockval.tickets.owner = *(volatile unsigned short *)(&lock->tickets.owner);
-    }
-
-    __asm__ volatile ("dmb":::"memory");
-}
-
-void rt_hw_spin_unlock(rt_hw_spinlock_t *lock)
-{
-    __asm__ volatile ("dmb":::"memory");
-    lock->tickets.owner++;
-    __asm__ volatile ("dsb ishst\nsev":::"memory");
-}
-#endif /*RT_USING_SMP*/
-
-/**
- * @addtogroup ARM CPU
- */
-/*@{*/
-
-/** shutdown CPU */
-void rt_hw_cpu_shutdown()
-{
-    rt_uint32_t level;
-    rt_kprintf("shutdown...\n");
-
-    level = rt_hw_interrupt_disable();
-    while (level)
-    {
-        RT_ASSERT(0);
-    }
-}
-
-/*@}*/

+ 0 - 108
bsp/qemu-vexpress-a9/cpu/interrupt.c

@@ -1,108 +0,0 @@
-/*
- * File      : interrupt.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2013-2014, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2013-07-06     Bernard      first version
- * 2018-11-22     Jesven       add smp support
- */
-
-#include <rthw.h>
-#include <rtthread.h>
-#include "realview.h"
-#include "gic.h"
-
-#define MAX_HANDLERS                NR_IRQS_PBA8
-
-/* exception and interrupt handler table */
-struct rt_irq_desc isr_table[MAX_HANDLERS];
-
-#ifndef RT_USING_SMP
-/* Those varibles will be accessed in ISR, so we need to share them. */
-rt_uint32_t rt_interrupt_from_thread        = 0;
-rt_uint32_t rt_interrupt_to_thread          = 0;
-rt_uint32_t rt_thread_switch_interrupt_flag = 0;
-#endif
-
-const unsigned int VECTOR_BASE = 0x00;
-extern void rt_cpu_vector_set_base(unsigned int addr);
-extern int system_vectors;
-
-void rt_hw_vector_init(void)
-{
-    rt_cpu_vector_set_base((unsigned int)&system_vectors);
-}
-
-/**
- * This function will initialize hardware interrupt
- */
-void rt_hw_interrupt_init(void)
-{
-    rt_uint32_t gic_cpu_base;
-    rt_uint32_t gic_dist_base;
-
-    /* initialize vector table */
-    rt_hw_vector_init();
-
-    /* initialize exceptions table */
-    rt_memset(isr_table, 0x00, sizeof(isr_table));
-
-    /* initialize ARM GIC */
-    gic_dist_base = REALVIEW_GIC_DIST_BASE;
-    gic_cpu_base = REALVIEW_GIC_CPU_BASE;
-
-    arm_gic_dist_init(0, gic_dist_base, 0);
-    arm_gic_cpu_init(0, gic_cpu_base);
-}
-
-/**
- * This function will mask a interrupt.
- * @param vector the interrupt number
- */
-void rt_hw_interrupt_mask(int vector)
-{
-    arm_gic_mask(0, vector);
-}
-
-/**
- * This function will un-mask a interrupt.
- * @param vector the interrupt number
- */
-void rt_hw_interrupt_umask(int vector)
-{
-    arm_gic_umask(0, vector);
-}
-
-/**
- * This function will install a interrupt service routine to a interrupt.
- * @param vector the interrupt number
- * @param new_handler the interrupt service routine to be installed
- * @param old_handler the old interrupt service routine
- */
-rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
-        void *param, const char *name)
-{
-    rt_isr_handler_t old_handler = RT_NULL;
-
-    if (vector < MAX_HANDLERS)
-    {
-        old_handler = isr_table[vector].handler;
-
-        if (handler != RT_NULL)
-        {
-#ifdef RT_USING_INTERRUPT_INFO
-            rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX);
-#endif /* RT_USING_INTERRUPT_INFO */
-            isr_table[vector].handler = handler;
-            isr_table[vector].param = param;
-        }
-    }
-
-    return old_handler;
-}

+ 0 - 25
bsp/qemu-vexpress-a9/cpu/interrupt.h

@@ -1,25 +0,0 @@
-/*
- * File      : interrupt.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2011, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2013-07-06     Bernard      first version
- */
-
-#ifndef __INTERRUPT_H__
-#define __INTERRUPT_H__
-
-#define INT_IRQ     0x00
-#define INT_FIQ     0x01
-
-void rt_hw_interrupt_control(int vector, int priority, int route);
-
-void rt_hw_interrupt_init(void);
-
-#endif

+ 0 - 207
bsp/qemu-vexpress-a9/cpu/mmu.c

@@ -1,207 +0,0 @@
-/*
- * File      : mmu.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2012-01-10     bernard      porting to AM1808
- */
-
-#include <rtthread.h>
-#include <rthw.h>
-#include <board.h>
-
-#include "cp15.h"
-
-#define DESC_SEC       (0x2)
-#define CB             (3<<2)  //cache_on, write_back
-#define CNB            (2<<2)  //cache_on, write_through
-#define NCB            (1<<2)  //cache_off,WR_BUF on
-#define NCNB           (0<<2)  //cache_off,WR_BUF off
-#define AP_RW          (3<<10) //supervisor=RW, user=RW
-#define AP_RO          (2<<10) //supervisor=RW, user=RO
-#define XN             (1<<4)  // eXecute Never
-
-#define DOMAIN_FAULT   (0x0)
-#define DOMAIN_CHK     (0x1)
-#define DOMAIN_NOTCHK  (0x3)
-#define DOMAIN0        (0x0<<5)
-#define DOMAIN1        (0x1<<5)
-
-#define DOMAIN0_ATTR   (DOMAIN_CHK<<0)
-#define DOMAIN1_ATTR   (DOMAIN_FAULT<<2)
-
-/* Read/Write, cache, write back */
-#define RW_CB          (AP_RW|DOMAIN0|CB|DESC_SEC)
-/* Read/Write, cache, write through */
-#define RW_CNB         (AP_RW|DOMAIN0|CNB|DESC_SEC)
-/* Read/Write without cache and write buffer */
-#define RW_NCNB        (AP_RW|DOMAIN0|NCNB|DESC_SEC)
-/* Read/Write without cache and write buffer, no execute */
-#define RW_NCNBXN      (AP_RW|DOMAIN0|NCNB|DESC_SEC|XN)
-/* Read/Write without cache and write buffer */
-#define RW_FAULT       (AP_RW|DOMAIN1|NCNB|DESC_SEC)
-
-/* dump 2nd level page table */
-void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb)
-{
-    int i;
-    int fcnt = 0;
-
-    for (i = 0; i < 256; i++)
-    {
-        rt_uint32_t pte2 = ptb[i];
-        if ((pte2 & 0x3) == 0)
-        {
-            if (fcnt == 0)
-                rt_kprintf("    ");
-            rt_kprintf("%04x: ", i);
-            fcnt++;
-            if (fcnt == 16)
-            {
-                rt_kprintf("fault\n");
-                fcnt = 0;
-            }
-            continue;
-        }
-        if (fcnt != 0)
-        {
-            rt_kprintf("fault\n");
-            fcnt = 0;
-        }
-
-        rt_kprintf("    %04x: %x: ", i, pte2);
-        if ((pte2 & 0x3) == 0x1)
-        {
-            rt_kprintf("L,ap:%x,xn:%d,texcb:%02x\n",
-                       ((pte2 >> 7) | (pte2 >> 4))& 0xf,
-                       (pte2 >> 15) & 0x1,
-                       ((pte2 >> 10) | (pte2 >> 2)) & 0x1f);
-        }
-        else
-        {
-            rt_kprintf("S,ap:%x,xn:%d,texcb:%02x\n",
-                       ((pte2 >> 7) | (pte2 >> 4))& 0xf, pte2 & 0x1,
-                       ((pte2 >> 4) | (pte2 >> 2)) & 0x1f);
-        }
-    }
-}
-
-void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb)
-{
-    int i;
-    int fcnt = 0;
-
-    rt_kprintf("page table@%p\n", ptb);
-    for (i = 0; i < 1024*4; i++)
-    {
-        rt_uint32_t pte1 = ptb[i];
-        if ((pte1 & 0x3) == 0)
-        {
-            rt_kprintf("%03x: ", i);
-            fcnt++;
-            if (fcnt == 16)
-            {
-                rt_kprintf("fault\n");
-                fcnt = 0;
-            }
-            continue;
-        }
-        if (fcnt != 0)
-        {
-            rt_kprintf("fault\n");
-            fcnt = 0;
-        }
-
-        rt_kprintf("%03x: %08x: ", i, pte1);
-        if ((pte1 & 0x3) == 0x3)
-        {
-            rt_kprintf("LPAE\n");
-        }
-        else if ((pte1 & 0x3) == 0x1)
-        {
-            rt_kprintf("pte,ns:%d,domain:%d\n",
-                       (pte1 >> 3) & 0x1, (pte1 >> 5) & 0xf);
-            /*
-             *rt_hw_cpu_dump_page_table_2nd((void*)((pte1 & 0xfffffc000)
-             *                               - 0x80000000 + 0xC0000000));
-             */
-        }
-        else if (pte1 & (1 << 18))
-        {
-            rt_kprintf("super section,ns:%d,ap:%x,xn:%d,texcb:%02x\n",
-                       (pte1 >> 19) & 0x1,
-                       ((pte1 >> 13) | (pte1 >> 10))& 0xf,
-                       (pte1 >> 4) & 0x1,
-                       ((pte1 >> 10) | (pte1 >> 2)) & 0x1f);
-        }
-        else
-        {
-            rt_kprintf("section,ns:%d,ap:%x,"
-                       "xn:%d,texcb:%02x,domain:%d\n",
-                       (pte1 >> 19) & 0x1,
-                       ((pte1 >> 13) | (pte1 >> 10))& 0xf,
-                       (pte1 >> 4) & 0x1,
-                       (((pte1 & (0x7 << 12)) >> 10) |
-                        ((pte1 &        0x0c) >>  2)) & 0x1f,
-                       (pte1 >> 5) & 0xf);
-        }
-    }
-}
-
-/* level1 page table, each entry for 1MB memory. */
-volatile static unsigned long MMUTable[4*1024] __attribute__((aligned(16*1024)));
-void rt_hw_mmu_setmtt(rt_uint32_t vaddrStart,
-                      rt_uint32_t vaddrEnd,
-                      rt_uint32_t paddrStart,
-                      rt_uint32_t attr)
-{
-    volatile rt_uint32_t *pTT;
-    volatile int i, nSec;
-    pTT  = (rt_uint32_t *)MMUTable + (vaddrStart >> 20);
-    nSec = (vaddrEnd >> 20) - (vaddrStart >> 20);
-    for(i = 0; i <= nSec; i++)
-    {
-        *pTT = attr | (((paddrStart >> 20) + i) << 20);
-        pTT++;
-    }
-}
-
-unsigned long rt_hw_set_domain_register(unsigned long domain_val)
-{
-    unsigned long old_domain;
-
-    asm volatile ("mrc p15, 0, %0, c3, c0\n" : "=r" (old_domain));
-    asm volatile ("mcr p15, 0, %0, c3, c0\n" : :"r" (domain_val) : "memory");
-
-    return old_domain;
-}
-
-void rt_hw_mmu_init(void)
-{
-    rt_hw_cpu_dcache_disable();
-    rt_hw_cpu_icache_disable();
-    rt_cpu_mmu_disable();
-
-    /* set page table */
-    /* 4G 1:1 memory */
-    rt_hw_mmu_setmtt(0, 0xffffffff-1, 0, RW_CB);
-    /* IO memory region */
-    rt_hw_mmu_setmtt(0x44000000, 0x80000000-1, 0x44000000, RW_NCNBXN);
-
-    /*rt_hw_cpu_dump_page_table(MMUTable);*/
-    rt_hw_set_domain_register(0x55555555);
-
-    rt_cpu_tlb_set(MMUTable);
-
-    rt_cpu_mmu_enable();
-
-    rt_hw_cpu_icache_enable();
-    rt_hw_cpu_dcache_enable();
-}
-

+ 0 - 12
bsp/qemu-vexpress-a9/cpu/pmu.c

@@ -1,12 +0,0 @@
-#include <rtthread.h>
-#include "pmu.h"
-
-void rt_hw_pmu_dump_feature(void)
-{
-    unsigned long reg;
-
-    reg = rt_hw_pmu_get_control();
-    rt_kprintf("ARM PMU Implementor: %c, ID code: %02x, %d counters\n",
-               reg >> 24, (reg >> 16) & 0xff, (reg >> 11) & 0x1f);
-    RT_ASSERT(ARM_PMU_CNTER_NR == ((reg >> 11) & 0x1f));
-}

+ 0 - 151
bsp/qemu-vexpress-a9/cpu/pmu.h

@@ -1,151 +0,0 @@
-#ifndef __PMU_H__
-#define __PMU_H__
-
-#include "board.h"
-
-/* Number of counters */
-#define ARM_PMU_CNTER_NR 4
-
-enum rt_hw_pmu_event_type {
-    ARM_PMU_EVENT_PMNC_SW_INCR      = 0x00,
-    ARM_PMU_EVENT_L1_ICACHE_REFILL  = 0x01,
-    ARM_PMU_EVENT_ITLB_REFILL       = 0x02,
-    ARM_PMU_EVENT_L1_DCACHE_REFILL  = 0x03,
-    ARM_PMU_EVENT_L1_DCACHE_ACCESS  = 0x04,
-    ARM_PMU_EVENT_DTLB_REFILL       = 0x05,
-    ARM_PMU_EVENT_MEM_READ          = 0x06,
-    ARM_PMU_EVENT_MEM_WRITE         = 0x07,
-    ARM_PMU_EVENT_INSTR_EXECUTED    = 0x08,
-    ARM_PMU_EVENT_EXC_TAKEN         = 0x09,
-    ARM_PMU_EVENT_EXC_EXECUTED      = 0x0A,
-    ARM_PMU_EVENT_CID_WRITE         = 0x0B,
-};
-
-/* Enable bit */
-#define ARM_PMU_PMCR_E   (0x01 << 0)
-/* Event counter reset */
-#define ARM_PMU_PMCR_P   (0x01 << 1)
-/* Cycle counter reset */
-#define ARM_PMU_PMCR_C   (0x01 << 2)
-/* Cycle counter divider */
-#define ARM_PMU_PMCR_D   (0x01 << 3)
-
-#ifdef __GNUC__
-rt_inline void rt_hw_pmu_enable_cnt(int divide64)
-{
-    unsigned long pmcr;
-    unsigned long pmcntenset;
-
-    asm volatile ("mrc p15, 0, %0, c9, c12, 0" : "=r"(pmcr));
-    pmcr |= ARM_PMU_PMCR_E | ARM_PMU_PMCR_P | ARM_PMU_PMCR_C;
-    if (divide64)
-        pmcr |= ARM_PMU_PMCR_D;
-    else
-        pmcr &= ~ARM_PMU_PMCR_D;
-    asm volatile ("mcr p15, 0, %0, c9, c12, 0" :: "r"(pmcr));
-
-    /* enable all the counters */
-    pmcntenset = ~0;
-    asm volatile ("mcr p15, 0, %0, c9, c12, 1" :: "r"(pmcntenset));
-    /* clear overflows(just in case) */
-    asm volatile ("mcr p15, 0, %0, c9, c12, 3" :: "r"(pmcntenset));
-}
-
-rt_inline unsigned long rt_hw_pmu_get_control(void)
-{
-    unsigned long pmcr;
-    asm ("mrc p15, 0, %0, c9, c12, 0" : "=r"(pmcr));
-    return pmcr;
-}
-
-rt_inline unsigned long rt_hw_pmu_get_ceid(void)
-{
-    unsigned long reg;
-    /* only PMCEID0 is supported, PMCEID1 is RAZ. */
-    asm ("mrc p15, 0, %0, c9, c12, 6" : "=r"(reg));
-    return reg;
-}
-
-rt_inline unsigned long rt_hw_pmu_get_cnten(void)
-{
-    unsigned long pmcnt;
-    asm ("mrc p15, 0, %0, c9, c12, 1" : "=r"(pmcnt));
-    return pmcnt;
-}
-
-rt_inline void rt_hw_pmu_reset_cycle(void)
-{
-    unsigned long pmcr;
-
-    asm volatile ("mrc p15, 0, %0, c9, c12, 0" : "=r"(pmcr));
-    pmcr |= ARM_PMU_PMCR_C;
-    asm volatile ("mcr p15, 0, %0, c9, c12, 0" :: "r"(pmcr));
-    asm volatile ("isb");
-}
-
-rt_inline void rt_hw_pmu_reset_event(void)
-{
-    unsigned long pmcr;
-
-    asm volatile ("mrc p15, 0, %0, c9, c12, 0" : "=r"(pmcr));
-    pmcr |= ARM_PMU_PMCR_P;
-    asm volatile ("mcr p15, 0, %0, c9, c12, 0" :: "r"(pmcr));
-    asm volatile ("isb");
-}
-
-rt_inline unsigned long rt_hw_pmu_get_cycle(void)
-{
-    unsigned long cyc;
-    asm volatile ("isb");
-    asm volatile ("mrc  p15, 0, %0, c9, c13, 0" : "=r"(cyc));
-    return cyc;
-}
-
-rt_inline void rt_hw_pmu_select_counter(int idx)
-{
-    RT_ASSERT(idx < ARM_PMU_CNTER_NR);
-
-    asm volatile ("mcr p15, 0, %0, c9, c12, 5" : : "r"(idx));
-    /* Linux add an isb here, don't know why here. */
-    asm volatile ("isb");
-}
-
-rt_inline void rt_hw_pmu_select_event(int idx,
-                                      enum rt_hw_pmu_event_type eve)
-{
-    RT_ASSERT(idx < ARM_PMU_CNTER_NR);
-
-    rt_hw_pmu_select_counter(idx);
-    asm volatile ("mcr p15, 0, %0, c9, c13, 1" : : "r"(eve));
-}
-
-rt_inline unsigned long rt_hw_pmu_read_counter(int idx)
-{
-    unsigned long reg;
-
-    rt_hw_pmu_select_counter(idx);
-    asm volatile ("isb");
-    asm volatile ("mrc p15, 0, %0, c9, c13, 2" : "=r"(reg));
-    return reg;
-}
-
-rt_inline unsigned long rt_hw_pmu_get_ovsr(void)
-{
-    unsigned long reg;
-    asm volatile ("isb");
-    asm ("mrc  p15, 0, %0, c9, c12, 3" : "=r"(reg));
-    return reg;
-}
-
-rt_inline void rt_hw_pmu_clear_ovsr(unsigned long reg)
-{
-    asm ("mcr  p15, 0, %0, c9, c12, 3" : : "r"(reg));
-    asm volatile ("isb");
-}
-
-#endif
-
-void rt_hw_pmu_dump_feature(void);
-
-#endif /* end of include guard: __PMU_H__ */
-

+ 0 - 71
bsp/qemu-vexpress-a9/cpu/stack.c

@@ -1,71 +0,0 @@
-/*
- * File      : stack.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2011, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2011-09-23     Bernard      the first version
- * 2011-10-05     Bernard      add thumb mode
- */
-#include <rtthread.h>
-#include <board.h>
-
-/**
- * @addtogroup AM33xx
- */
-/*@{*/
-
-/**
- * This function will initialize thread stack
- *
- * @param tentry the entry of thread
- * @param parameter the parameter of entry 
- * @param stack_addr the beginning stack address
- * @param texit the function will be called when thread exit
- *
- * @return stack address
- */
-rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
-        rt_uint8_t *stack_addr, void *texit)
-{
-    rt_uint32_t *stk;
-
-    stack_addr += sizeof(rt_uint32_t);
-    stack_addr  = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8);
-    stk 	 = (rt_uint32_t*)stack_addr;
-    *(--stk) = (rt_uint32_t)tentry;			/* entry point */
-    *(--stk) = (rt_uint32_t)texit;			/* lr */
-    *(--stk) = 0;							/* r12 */
-    *(--stk) = 0;							/* r11 */
-    *(--stk) = 0;							/* r10 */
-    *(--stk) = 0;							/* r9 */
-    *(--stk) = 0;							/* r8 */
-    *(--stk) = 0;							/* r7 */
-    *(--stk) = 0;							/* r6 */
-    *(--stk) = 0;							/* r5 */
-    *(--stk) = 0;							/* r4 */
-    *(--stk) = 0;							/* r3 */
-    *(--stk) = 0;							/* r2 */
-    *(--stk) = 0;							/* r1 */
-    *(--stk) = (rt_uint32_t)parameter;		/* r0 : argument */
-    /* cpsr */
-    if ((rt_uint32_t)tentry & 0x01)
-        *(--stk) = SVCMODE | 0x20;			/* thumb mode */
-    else
-        *(--stk) = SVCMODE;					/* arm mode   */
-
-#ifdef RT_USING_LWP
-    *(--stk) = 0;		/* user lr */
-    *(--stk) = 0;		/* user sp*/
-#endif
-
-    /* return task's current stack address */
-    return (rt_uint8_t *)stk;
-}
-
-/*@}*/

+ 0 - 447
bsp/qemu-vexpress-a9/cpu/start_gcc.S

@@ -1,447 +0,0 @@
-/*
- * File      : start_gcc.S
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2013-2014, RT-Thread Development Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Change Logs:
- * Date           Author       Notes
- * 2013-07-05     Bernard      the first version
- * 2018-11-22     Jesven       in the interrupt context, use rt_scheduler_do_irq_switch checks
- *                             and switches to a new thread
- */
-
-#include "rtconfig.h"
-
-.equ Mode_USR,        0x10
-.equ Mode_FIQ,        0x11
-.equ Mode_IRQ,        0x12
-.equ Mode_SVC,        0x13
-.equ Mode_ABT,        0x17
-.equ Mode_UND,        0x1B
-.equ Mode_SYS,        0x1F
-
-.equ I_Bit,           0x80            @ when I bit is set, IRQ is disabled
-.equ F_Bit,           0x40            @ when F bit is set, FIQ is disabled
-
-.equ UND_Stack_Size,     0x00000000
-.equ SVC_Stack_Size,     0x00000400
-.equ ABT_Stack_Size,     0x00000000
-.equ RT_FIQ_STACK_PGSZ,  0x00000000
-.equ RT_IRQ_STACK_PGSZ,  0x00000800
-.equ USR_Stack_Size,     0x00000400
-
-#define ISR_Stack_Size  (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
-                 RT_FIQ_STACK_PGSZ + RT_IRQ_STACK_PGSZ)
-
-.section .data.share.isr
-/* stack */
-.globl stack_start
-.globl stack_top
-
-stack_start:
-.rept ISR_Stack_Size
-.byte 0
-.endr
-stack_top:
-
-.text
-/* reset entry */
-.globl _reset
-_reset:
-    /* set the cpu to SVC32 mode and disable interrupt */
-    mrs     r0, cpsr
-    bic     r0, r0, #0x1f
-    orr     r0, r0, #0x13
-    msr     cpsr_c, r0
-
-    mrc p15, 0, r1, c1, c0, 1
-    mov r0, #(1<<6)
-    orr r1, r0
-    mcr p15, 0, r1, c1, c0, 1 //enable smp
-
-    ldr lr, =after_enable_mmu
-    ldr r0, =mtbl
-    b enable_mmu
-
-after_enable_mmu:
-
-    /* setup stack */
-    bl      stack_setup
-
-    /* clear .bss */
-    mov     r0,#0                   /* get a zero                       */
-    ldr     r1,=__bss_start         /* bss start                        */
-    ldr     r2,=__bss_end           /* bss end                          */
-
-bss_loop:
-    cmp     r1,r2                   /* check if data to clear           */
-    strlo   r0,[r1],#4              /* clear 4 bytes                    */
-    blo     bss_loop                /* loop until done                  */
-
-    /* call C++ constructors of global objects                          */
-    ldr     r0, =__ctors_start__
-    ldr     r1, =__ctors_end__
-
-ctor_loop:
-    cmp     r0, r1
-    beq     ctor_end
-    ldr     r2, [r0], #4
-    stmfd   sp!, {r0-r1}
-    mov     lr, pc
-    bx      r2
-    ldmfd   sp!, {r0-r1}
-    b       ctor_loop
-ctor_end:
-
-    /* start RT-Thread Kernel */
-    bl      flush_cache_all
-    ldr     pc, _rtthread_startup
-_rtthread_startup:
-    .word rtthread_startup
-
-stack_setup:
-    ldr     r0, =stack_top
-
-    @  Set the startup stack for svc
-    mov     sp, r0
-
-    @  Enter Undefined Instruction Mode and set its Stack Pointer
-    msr     cpsr_c, #Mode_UND|I_Bit|F_Bit
-    mov     sp, r0
-    sub     r0, r0, #UND_Stack_Size
-
-    @  Enter Abort Mode and set its Stack Pointer
-    msr     cpsr_c, #Mode_ABT|I_Bit|F_Bit
-    mov     sp, r0
-    sub     r0, r0, #ABT_Stack_Size
-
-    @  Enter FIQ Mode and set its Stack Pointer
-    msr     cpsr_c, #Mode_FIQ|I_Bit|F_Bit
-    mov     sp, r0
-    sub     r0, r0, #RT_FIQ_STACK_PGSZ
-
-    @  Enter IRQ Mode and set its Stack Pointer
-    msr     cpsr_c, #Mode_IRQ|I_Bit|F_Bit
-    mov     sp, r0
-    sub     r0, r0, #RT_IRQ_STACK_PGSZ
-
-    /* come back to SVC mode */
-    msr     cpsr_c, #Mode_SVC|I_Bit|F_Bit
-    bx      lr
-
-    .global enable_mmu
-enable_mmu:
-    orr r0, #0x18
-    mcr p15, 0, r0, c2, c0, 0 @ttbr0
-
-    mov r0, #(1 << 5)         @PD1=1
-    mcr p15, 0, r0, c2, c0, 2 @ttbcr
-
-    mov r0, #1
-    mcr p15, 0, r0, c3, c0, 0 @dacr
-
-    mov r0, #0
-    mcr p15, 0, r0, c8, c7, 0
-    mcr p15, 0, r0, c7, c5, 0 @iciallu
-    mcr p15, 0, r0, c7, c5, 6 @bpiall
-
-    mrc p15, 0, r0, c1, c0, 0
-    orr r0, #(1 | 4)
-    orr r0, #(1 << 12)
-    mcr p15, 0, r0, c1, c0, 0
-    dsb
-    isb
-    mov pc, lr
-
-.global flush_cache_all
-flush_cache_all:
-    stmfd   sp!, {r0-r12, lr}
-    bl  v7_flush_dcache_all
-    mov r0, #0
-    mcr p15, 0, r0, c7, c5, 0       @ I+BTB cache invalidate
-    dsb
-    isb
-    ldmfd   sp!, {r0-r12, lr}
-    mov pc, lr
-
-    v7_flush_dcache_all:
-    dmb                 @ ensure ordering with previous memory accesses
-    mrc p15, 1, r0, c0, c0, 1       @ read clidr
-    ands    r3, r0, #0x7000000      @ extract loc from clidr
-    mov r3, r3, lsr #23         @ left align loc bit field
-    beq finished            @ if loc is 0, then no need to clean
-    mov r10, #0             @ start clean at cache level 0
-loop1:
-    add r2, r10, r10, lsr #1        @ work out 3x current cache level
-    mov r1, r0, lsr r2          @ extract cache type bits from clidr
-    and r1, r1, #7          @ mask of the bits for current cache only
-    cmp r1, #2              @ see what cache we have at this level
-    blt skip                @ skip if no cache, or just i-cache
-    mcr p15, 2, r10, c0, c0, 0      @ select current cache level in cssr
-    isb                 @ isb to sych the new cssr&csidr
-    mrc p15, 1, r1, c0, c0, 0       @ read the new csidr
-    and r2, r1, #7          @ extract the length of the cache lines
-    add r2, r2, #4          @ add 4 (line length offset)
-    ldr r4, =0x3ff
-    ands    r4, r4, r1, lsr #3      @ find maximum number on the way size
-    clz r5, r4              @ find bit position of way size increment
-    ldr r7, =0x7fff
-    ands    r7, r7, r1, lsr #13     @ extract max number of the index size
-loop2:
-    mov r9, r4              @ create working copy of max way size
-loop3:
-    orr r11, r10, r9, lsl r5        @ factor way and cache number into r11
-    orr r11, r11, r7, lsl r2        @ factor index number into r11
-    mcr p15, 0, r11, c7, c14, 2     @ clean & invalidate by set/way
-    subs    r9, r9, #1          @ decrement the way
-    bge loop3
-    subs    r7, r7, #1          @ decrement the index
-    bge loop2
-skip:
-    add r10, r10, #2            @ increment cache number
-    cmp r3, r10
-    bgt loop1
-finished:
-    mov r10, #0             @ swith back to cache level 0
-    mcr p15, 2, r10, c0, c0, 0      @ select current cache level in cssr
-    dsb
-    isb
-    mov pc, lr
-
-/* exception handlers: undef, swi, padt, dabt, resv, irq, fiq          */
-.section .text.isr, "ax"
-    .align  5
-.globl vector_fiq
-vector_fiq:
-    stmfd   sp!,{r0-r7,lr}
-    bl      rt_hw_trap_fiq
-    ldmfd   sp!,{r0-r7,lr}
-    subs    pc, lr, #4
-
-.globl      rt_interrupt_enter
-.globl      rt_interrupt_leave
-.globl      rt_thread_switch_interrupt_flag
-.globl      rt_interrupt_from_thread
-.globl      rt_interrupt_to_thread
-
-    .align  5
-.globl vector_irq
-vector_irq:
-#ifdef RT_USING_SMP
-    clrex
-#endif
-    stmfd   sp!, {r0-r12,lr}
-
-    bl      rt_interrupt_enter
-    bl      rt_hw_trap_irq
-    bl      rt_interrupt_leave
-
-#ifdef RT_USING_SMP
-    mov     r0, sp
-    bl      rt_scheduler_do_irq_switch
-
-    ldmfd   sp!, {r0-r12,lr}
-    subs    pc,  lr, #4
-#else
-    @ if rt_thread_switch_interrupt_flag set, jump to
-    @ rt_hw_context_switch_interrupt_do and don't return
-    ldr     r0, =rt_thread_switch_interrupt_flag
-    ldr     r1, [r0]
-    cmp     r1, #1
-    beq     rt_hw_context_switch_interrupt_do
-
-    ldmfd   sp!, {r0-r12,lr}
-    subs    pc,  lr, #4
-
-rt_hw_context_switch_interrupt_do:
-    mov     r1,  #0         @ clear flag
-    str     r1,  [r0]
-
-    mov     r1, sp          @ r1 point to {r0-r3} in stack
-    add     sp, sp, #4*4
-    ldmfd   sp!, {r4-r12,lr}@ reload saved registers
-    mrs     r0,  spsr       @ get cpsr of interrupt thread
-    sub     r2,  lr, #4     @ save old task's pc to r2
-
-    @ Switch to SVC mode with no interrupt. If the usr mode guest is
-    @ interrupted, this will just switch to the stack of kernel space.
-    @ save the registers in kernel space won't trigger data abort.
-    msr     cpsr_c, #I_Bit|F_Bit|Mode_SVC
-
-    stmfd   sp!, {r2}       @ push old task's pc
-    stmfd   sp!, {r4-r12,lr}@ push old task's lr,r12-r4
-    ldmfd   r1,  {r1-r4}    @ restore r0-r3 of the interrupt thread
-    stmfd   sp!, {r1-r4}    @ push old task's r0-r3
-    stmfd   sp!, {r0}       @ push old task's cpsr
-
-#ifdef RT_USING_LWP
-    stmfd sp, {r13, r14}^  @push usr_sp, usr_lr
-    sub sp, #8
-#endif
-
-    ldr     r4,  =rt_interrupt_from_thread
-    ldr     r5,  [r4]
-    str     sp,  [r5]       @ store sp in preempted tasks's TCB
-
-    ldr     r6,  =rt_interrupt_to_thread
-    ldr     r6,  [r6]
-    ldr     sp,  [r6]       @ get new task's stack pointer
-
-#ifdef RT_USING_LWP
-    ldmfd sp, {r13, r14}^  @pop usr_sp, usr_lr
-    add sp, #8
-#endif
-
-    ldmfd   sp!, {r4}       @ pop new task's cpsr to spsr
-    msr     spsr_cxsf, r4
-
-    ldmfd   sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
-
-#endif
-
-.macro push_svc_reg
-    sub     sp, sp, #17 * 4         @/* Sizeof(struct rt_hw_exp_stack)  */
-    stmia   sp, {r0 - r12}          @/* Calling r0-r12                  */
-    mov     r0, sp
-    mrs     r6, spsr                @/* Save CPSR                       */
-    str     lr, [r0, #15*4]         @/* Push PC                         */
-    str     r6, [r0, #16*4]         @/* Push CPSR                       */
-    cps     #Mode_SVC
-    str     sp, [r0, #13*4]         @/* Save calling SP                 */
-    str     lr, [r0, #14*4]         @/* Save calling PC                 */
-.endm
-
-    .align  5
-    .globl  vector_swi
-.weak SVC_Handler
-SVC_Handler:
-vector_swi:
-    push_svc_reg
-    bl      rt_hw_trap_swi
-    b       .
-
-    .align  5
-    .globl  vector_undef
-vector_undef:
-    push_svc_reg
-    bl      rt_hw_trap_undef
-    b       .
-
-    .align  5
-    .globl  vector_pabt
-vector_pabt:
-    push_svc_reg
-    bl      rt_hw_trap_pabt
-    b       .
-
-    .align  5
-    .globl  vector_dabt
-vector_dabt:
-    push_svc_reg
-    bl      rt_hw_trap_dabt
-    b       .
-
-    .align  5
-    .globl  vector_resv
-vector_resv:
-    push_svc_reg
-    bl      rt_hw_trap_resv
-    b       .
-
-#ifdef RT_USING_SMP
-.global set_secondary_cpu_boot_address
-set_secondary_cpu_boot_address:
-    ldr r0, =secondary_cpu_start
-
-    mvn r1, #0 //0xffffffff
-    ldr r2, =0x10000034
-    str r1, [r2]
-    str r0, [r2, #-4]
-    mov pc, lr
-
-.global secondary_cpu_start
-secondary_cpu_start:
-    mrc p15, 0, r1, c1, c0, 1
-    mov r0, #(1<<6)
-    orr r1, r0
-    mcr p15, 0, r1, c1, c0, 1 //enable smp
-
-    ldr r0, =mtbl
-    ldr lr, =1f
-
-    b enable_mmu
-1:
-    mrc p15, 0, r0, c1, c0, 0
-    bic r0, #(1<<13)
-    mcr p15, 0, r0, c1, c0, 0
-
-    cps #Mode_IRQ
-    ldr sp, =irq_stack_2_limit
-
-    cps #Mode_FIQ
-    ldr sp, =irq_stack_2_limit
-
-    cps #Mode_SVC
-    ldr sp, =svc_stack_2_limit
-
-    b secondary_cpu_c_start
-#endif
-
-.bss
-.align 2   //align to  2~2=4
-svc_stack_2:
-    .space (1 << 10)
-svc_stack_2_limit:
-
-irq_stack_2:
-    .space (1 << 10)
-irq_stack_2_limit:
-
-.data
-#define DEVICE_MEM  0x10c06
-#define NORMAL_MEM  0x11c0e
-.align 14
-mtbl:
-
-    //vaddr: 0x00000000
-    .rept 0x100
-    .word 0x0
-    .endr
-
-    //vaddr: 0x10000000
-    .equ mmu_tbl_map_paddr, 0x10000000
-    .rept 0x400
-    .word mmu_tbl_map_paddr | DEVICE_MEM
-    .equ mmu_tbl_map_paddr, mmu_tbl_map_paddr + 0x100000
-    .endr
-
-    //vaddr: 0x50000000
-    .rept 0x100
-    .word 0x0
-    .endr
-
-    //vaddr: 0x60000000
-    .equ mmu_tbl_map_paddr, 0x60000000
-    .rept 0x800
-    .word mmu_tbl_map_paddr | NORMAL_MEM
-    .equ mmu_tbl_map_paddr, mmu_tbl_map_paddr + 0x100000
-    .endr
-
-    //vaddr: 0xe0000000
-    .rept 0x200
-    .word 0x0
-    .endr

+ 0 - 190
bsp/qemu-vexpress-a9/cpu/trap.c

@@ -1,190 +0,0 @@
-/*
- * File      : trap.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2013, RT-Thread Develop Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2013-07-20     Bernard      first version
- */
-
-#include <rtthread.h>
-#include <rthw.h>
-#include <board.h>
-
-#include "armv7.h"
-
-#include "gic.h"
-
-#ifdef RT_USING_FINSH
-extern long list_thread(void);
-#endif
-
-/**
- * this function will show registers of CPU
- *
- * @param regs the registers point
- */
-void rt_hw_show_register(struct rt_hw_exp_stack *regs)
-{
-    rt_kprintf("Execption:\n");
-    rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
-    rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
-    rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
-    rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
-    rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
-    rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
-}
-
-/**
- * When comes across an instruction which it cannot handle,
- * it takes the undefined instruction trap.
- *
- * @param regs system registers
- *
- * @note never invoke this function in application
- */
-void rt_hw_trap_undef(struct rt_hw_exp_stack *regs)
-{
-    rt_kprintf("undefined instruction:\n");
-    rt_hw_show_register(regs);
-#ifdef RT_USING_FINSH
-    list_thread();
-#endif
-    rt_hw_cpu_shutdown();
-}
-
-/**
- * The software interrupt instruction (SWI) is used for entering
- * Supervisor mode, usually to request a particular supervisor
- * function.
- *
- * @param regs system registers
- *
- * @note never invoke this function in application
- */
-void rt_hw_trap_swi(struct rt_hw_exp_stack *regs)
-{
-    rt_kprintf("software interrupt:\n");
-    rt_hw_show_register(regs);
-#ifdef RT_USING_FINSH
-    list_thread();
-#endif
-    rt_hw_cpu_shutdown();
-}
-
-/**
- * An abort indicates that the current memory access cannot be completed,
- * which occurs during an instruction prefetch.
- *
- * @param regs system registers
- *
- * @note never invoke this function in application
- */
-void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs)
-{
-    rt_kprintf("prefetch abort:\n");
-    rt_hw_show_register(regs);
-#ifdef RT_USING_FINSH
-    list_thread();
-#endif
-    rt_hw_cpu_shutdown();
-}
-
-/**
- * An abort indicates that the current memory access cannot be completed,
- * which occurs during a data access.
- *
- * @param regs system registers
- *
- * @note never invoke this function in application
- */
-void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs)
-{
-    rt_kprintf("data abort:");
-    rt_hw_show_register(regs);
-#ifdef RT_USING_FINSH
-    list_thread();
-#endif
-    rt_hw_cpu_shutdown();
-}
-
-/**
- * Normally, system will never reach here
- *
- * @param regs system registers
- *
- * @note never invoke this function in application
- */
-void rt_hw_trap_resv(struct rt_hw_exp_stack *regs)
-{
-    rt_kprintf("reserved trap:\n");
-    rt_hw_show_register(regs);
-#ifdef RT_USING_FINSH
-    list_thread();
-#endif
-    rt_hw_cpu_shutdown();
-}
-
-#define GIC_ACK_INTID_MASK              0x000003ff
-
-void rt_hw_trap_irq(void)
-{
-    void *param;
-    unsigned long ir;
-    unsigned long fullir;
-    rt_isr_handler_t isr_func;
-    extern struct rt_irq_desc isr_table[];
-
-    fullir = arm_gic_get_active_irq(0);
-    ir = fullir & GIC_ACK_INTID_MASK;
-
-    if (ir == 1023)
-    {
-        /* Spurious interrupt */
-        return;
-    }
-
-    /* get interrupt service routine */
-    isr_func = isr_table[ir].handler;
-#ifdef RT_USING_INTERRUPT_INFO
-    isr_table[ir].counter++;
-#endif
-    if (isr_func)
-    {
-        /* Interrupt for myself. */
-        param = isr_table[ir].param;
-        /* turn to interrupt service routine */
-        isr_func(ir, param);
-    }
-
-    /* end of interrupt */
-    arm_gic_ack(0, fullir);
-}
-
-void rt_hw_trap_fiq(void)
-{
-    void *param;
-    unsigned long ir;
-    unsigned long fullir;
-    rt_isr_handler_t isr_func;
-    extern struct rt_irq_desc isr_table[];
-
-    fullir = arm_gic_get_active_irq(0);
-    ir = fullir & GIC_ACK_INTID_MASK;
-
-    /* get interrupt service routine */
-    isr_func = isr_table[ir].handler;
-    param = isr_table[ir].param;
-
-    /* turn to interrupt service routine */
-    isr_func(ir, param);
-
-    /* end of interrupt */
-    arm_gic_ack(0, fullir);
-}
-

+ 0 - 65
bsp/qemu-vexpress-a9/cpu/vector_gcc.S

@@ -1,65 +0,0 @@
-/*
- * File      : vector_gcc.S
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2013, RT-Thread Development Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Change Logs:
- * Date           Author       Notes
- * 2013-07-05     Bernard      the first version
- */
-
-.section .vectors, "ax"
-.code 32
-
-.globl system_vectors
-system_vectors:
-    ldr pc, _vector_reset
-    ldr pc, _vector_undef
-    ldr pc, _vector_swi
-    ldr pc, _vector_pabt
-    ldr pc, _vector_dabt
-    ldr pc, _vector_resv
-    ldr pc, _vector_irq
-    ldr pc, _vector_fiq
-
-.globl _reset
-.globl vector_undef
-.globl vector_swi
-.globl vector_pabt
-.globl vector_dabt
-.globl vector_resv
-.globl vector_irq
-.globl vector_fiq
-
-_vector_reset:
-    .word _reset
-_vector_undef:
-    .word vector_undef
-_vector_swi:
-    .word SVC_Handler
-_vector_pabt:
-    .word vector_pabt
-_vector_dabt:
-    .word vector_dabt
-_vector_resv:
-    .word vector_resv
-_vector_irq:
-    .word vector_irq
-_vector_fiq:
-    .word vector_fiq
-
-.balignl    16,0xdeadbeef

+ 9 - 0
bsp/qemu-vexpress-a9/drivers/board.c

@@ -17,6 +17,15 @@
 #include "board.h"
 #include "drv_timer.h"
 
+#include <mmu.h>
+
+struct mem_desc platform_mem_desc[] = {
+    {0x10000000, 0x50000000, 0x10000000, DEVICE_MEM},
+    {0x60000000, 0xe0000000, 0x60000000, NORMAL_MEM}
+};
+
+const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]);
+
 #define SYS_CTRL                        __REG32(REALVIEW_SCTL_BASE)
 
 extern void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler);

+ 13 - 0
bsp/qemu-vexpress-a9/platform/SConscript

@@ -0,0 +1,13 @@
+from building import *
+
+cwd = GetCurrentDir()
+src = Split('''
+''')
+
+CPPPATH = [ cwd + '/cpu',
+cwd + '/include',
+]
+
+group = DefineGroup('Platform', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 37 - 0
bsp/qemu-vexpress-a9/platform/cpu/platform.h

@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-03-22     quanzhao     first version
+ */
+
+#ifndef __PLATFORM_H__
+#define __PLATFORM_H__
+
+/* for 'rt_inline' */
+#include <rtdef.h>
+/* SOC-relative definitions */
+#include "realview.h"
+
+/* the maximum entries of the exception table */
+#define MAX_HANDLERS    NR_IRQS_PBA8
+
+/* the basic constants and interfaces needed by gic */
+rt_inline rt_uint32_t platform_get_gic_dist_base(void)
+{
+    return REALVIEW_GIC_DIST_BASE;
+}
+
+rt_inline rt_uint32_t platform_get_gic_cpu_base(void)
+{
+    return REALVIEW_GIC_CPU_BASE;
+}
+
+#define GIC_IRQ_START   0
+
+#define GIC_ACK_INTID_MASK  0x000003ff
+
+#endif  /* __PLATFORM_H__ */

+ 149 - 0
bsp/qemu-vexpress-a9/rtconfig.h

@@ -10,7 +10,9 @@
 #define RT_USING_SMP
 #define RT_CPUS_NR 2
 #define RT_ALIGN_SIZE 4
+/* RT_THREAD_PRIORITY_8 is not set */
 #define RT_THREAD_PRIORITY_32
+/* RT_THREAD_PRIORITY_256 is not set */
 #define RT_THREAD_PRIORITY_MAX 32
 #define RT_TICK_PER_SECOND 100
 #define RT_USING_OVERFLOW_CHECK
@@ -37,7 +39,10 @@
 
 #define RT_USING_MEMPOOL
 #define RT_USING_MEMHEAP
+/* RT_USING_NOHEAP is not set */
 #define RT_USING_SMALL_MEM
+/* RT_USING_SLAB is not set */
+/* RT_USING_MEMHEAP_AS_HEAP is not set */
 #define RT_USING_MEMTRACE
 #define RT_USING_HEAP
 
@@ -53,6 +58,7 @@
 #define ARCH_ARM
 #define ARCH_ARM_CORTEX_A
 #define ARCH_ARM_CORTEX_A9
+/* ARCH_CPU_STACK_GROWS_UPWARD is not set */
 
 /* RT-Thread Components */
 
@@ -73,11 +79,14 @@
 #define FINSH_HISTORY_LINES 5
 #define FINSH_USING_SYMTAB
 #define FINSH_USING_DESCRIPTION
+/* FINSH_ECHO_DISABLE_DEFAULT is not set */
 #define FINSH_THREAD_PRIORITY 20
 #define FINSH_THREAD_STACK_SIZE 4096
 #define FINSH_CMD_SIZE 80
+/* FINSH_USING_AUTH is not set */
 #define FINSH_USING_MSH
 #define FINSH_USING_MSH_DEFAULT
+/* FINSH_USING_MSH_ONLY is not set */
 #define FINSH_ARG_MAX 10
 
 /* Device virtual file system */
@@ -87,21 +96,29 @@
 #define DFS_FILESYSTEMS_MAX 2
 #define DFS_FILESYSTEM_TYPES_MAX 8
 #define DFS_FD_MAX 16
+/* RT_USING_DFS_MNTTABLE is not set */
 #define RT_USING_DFS_ELMFAT
 
 /* elm-chan's FatFs, Generic FAT Filesystem Module */
 
 #define RT_DFS_ELM_CODE_PAGE 437
 #define RT_DFS_ELM_WORD_ACCESS
+/* RT_DFS_ELM_USE_LFN_0 is not set */
+/* RT_DFS_ELM_USE_LFN_1 is not set */
+/* RT_DFS_ELM_USE_LFN_2 is not set */
 #define RT_DFS_ELM_USE_LFN_3
 #define RT_DFS_ELM_USE_LFN 3
 #define RT_DFS_ELM_MAX_LFN 255
 #define RT_DFS_ELM_DRIVES 2
 #define RT_DFS_ELM_MAX_SECTOR_SIZE 4096
+/* RT_DFS_ELM_USE_ERASE is not set */
 #define RT_DFS_ELM_REENTRANT
 #define RT_USING_DFS_DEVFS
 #define RT_USING_DFS_ROMFS
 #define RT_USING_DFS_RAMFS
+/* RT_USING_DFS_UFFS is not set */
+/* RT_USING_DFS_JFFS2 is not set */
+/* RT_USING_DFS_NFS is not set */
 
 /* Device Drivers */
 
@@ -110,12 +127,19 @@
 #define RT_USING_SERIAL
 #define RT_SERIAL_USING_DMA
 #define RT_SERIAL_RB_BUFSZ 64
+/* RT_USING_CAN is not set */
+/* RT_USING_HWTIMER is not set */
+/* RT_USING_CPUTIME is not set */
 #define RT_USING_I2C
 #define RT_USING_I2C_BITOPS
 #define RT_USING_PIN
+/* RT_USING_ADC is not set */
+/* RT_USING_PWM is not set */
 #define RT_USING_MTD_NOR
 #define RT_USING_MTD_NAND
 #define RT_MTD_NAND_DEBUG
+/* RT_USING_MTD is not set */
+/* RT_USING_PM is not set */
 #define RT_USING_RTC
 #define RT_USING_SOFT_RTC
 #define RT_USING_SDIO
@@ -124,18 +148,31 @@
 #define RT_MMCSD_STACK_SIZE 1024
 #define RT_MMCSD_THREAD_PREORITY 22
 #define RT_MMCSD_MAX_PARTITION 16
+/* RT_SDIO_DEBUG is not set */
 #define RT_USING_SPI
+/* RT_USING_QSPI is not set */
 #define RT_USING_SPI_MSD
 #define RT_USING_SFUD
 #define RT_SFUD_USING_SFDP
 #define RT_SFUD_USING_FLASH_INFO_TABLE
+/* RT_SFUD_USING_QSPI is not set */
+/* RT_DEBUG_SFUD is not set */
+/* RT_USING_W25QXX is not set */
+/* RT_USING_GD is not set */
+/* RT_USING_ENC28J60 is not set */
+/* RT_USING_SPI_WIFI is not set */
 #define RT_USING_WDT
+/* RT_USING_AUDIO is not set */
+/* RT_USING_SENSOR is not set */
 
 /* Using WiFi */
 
+/* RT_USING_WIFI is not set */
 
 /* Using USB */
 
+/* RT_USING_USB_HOST is not set */
+/* RT_USING_USB_DEVICE is not set */
 
 /* POSIX layer and C standard library */
 
@@ -145,6 +182,7 @@
 #define RT_USING_POSIX_MMAP
 #define RT_USING_POSIX_TERMIOS
 #define RT_USING_POSIX_AIO
+/* RT_USING_MODULE is not set */
 
 /* Network */
 
@@ -161,9 +199,13 @@
 /* light weight TCP/IP stack */
 
 #define RT_USING_LWIP
+/* RT_USING_LWIP141 is not set */
 #define RT_USING_LWIP202
+/* RT_USING_LWIP210 is not set */
 #define RT_USING_LWIP_IPV6
+/* RT_LWIP_IGMP is not set */
 #define RT_LWIP_ICMP
+/* RT_LWIP_SNMP is not set */
 #define RT_LWIP_DNS
 #define RT_LWIP_DHCP
 #define IP_SOF_BROADCAST 1
@@ -176,6 +218,8 @@
 #define RT_LWIP_MSKADDR "255.255.255.0"
 #define RT_LWIP_UDP
 #define RT_LWIP_TCP
+/* RT_LWIP_RAW is not set */
+/* RT_LWIP_PPP is not set */
 #define RT_MEMP_NUM_NETCONN 8
 #define RT_LWIP_PBUF_NUM 16
 #define RT_LWIP_RAW_PCB_NUM 4
@@ -187,6 +231,8 @@
 #define RT_LWIP_TCPTHREAD_PRIORITY 10
 #define RT_LWIP_TCPTHREAD_MBOX_SIZE 8
 #define RT_LWIP_TCPTHREAD_STACKSIZE 1024
+/* LWIP_NO_RX_THREAD is not set */
+/* LWIP_NO_TX_THREAD is not set */
 #define RT_LWIP_ETHTHREAD_PRIORITY 12
 #define RT_LWIP_ETHTHREAD_STACKSIZE 1024
 #define RT_LWIP_ETHTHREAD_MBOX_SIZE 8
@@ -196,62 +242,164 @@
 #define LWIP_SO_RCVTIMEO 1
 #define LWIP_SO_SNDTIMEO 1
 #define LWIP_SO_RCVBUF 1
+/* RT_LWIP_NETIF_LOOPBACK is not set */
 #define LWIP_NETIF_LOOPBACK 0
+/* RT_LWIP_STATS is not set */
+/* RT_LWIP_DEBUG is not set */
 
 /* Modbus master and slave stack */
 
+/* RT_USING_MODBUS is not set */
 
 /* AT commands */
 
+/* RT_USING_AT is not set */
+/* LWIP_USING_DHCPD is not set */
 
 /* VBUS(Virtual Software BUS) */
 
+/* RT_USING_VBUS is not set */
 
 /* Utilities */
 
 #define RT_USING_LOGTRACE
 #define LOG_TRACE_MAX_SESSION 16
+/* LOG_TRACE_USING_LEVEL_NOTRACE is not set */
+/* LOG_TRACE_USING_LEVEL_ERROR is not set */
+/* LOG_TRACE_USING_LEVEL_WARNING is not set */
 #define LOG_TRACE_USING_LEVEL_INFO
+/* LOG_TRACE_USING_LEVEL_VERBOSE is not set */
+/* LOG_TRACE_USING_LEVEL_DEBUG is not set */
+/* LOG_TRACE_USING_MEMLOG is not set */
+/* RT_USING_RYM is not set */
+/* RT_USING_ULOG is not set */
+/* RT_USING_UTEST is not set */
 #define RT_USING_LWP
 
 /* RT-Thread online packages */
 
 /* IoT - internet of things */
 
+/* PKG_USING_PAHOMQTT is not set */
+/* PKG_USING_WEBCLIENT is not set */
+/* PKG_USING_WEBNET is not set */
+/* PKG_USING_MONGOOSE is not set */
+/* PKG_USING_WEBTERMINAL is not set */
+/* PKG_USING_CJSON is not set */
+/* PKG_USING_JSMN is not set */
+/* PKG_USING_LIBMODBUS is not set */
+/* PKG_USING_LJSON is not set */
+/* PKG_USING_EZXML is not set */
+/* PKG_USING_NANOPB is not set */
 
 /* Wi-Fi */
 
 /* Marvell WiFi */
 
+/* PKG_USING_WLANMARVELL is not set */
 
 /* Wiced WiFi */
 
+/* PKG_USING_WLAN_WICED is not set */
+/* PKG_USING_RW007 is not set */
+/* PKG_USING_COAP is not set */
+/* PKG_USING_NOPOLL is not set */
+/* PKG_USING_NETUTILS is not set */
+/* PKG_USING_AT_DEVICE is not set */
+/* PKG_USING_WIZNET is not set */
 
 /* IoT Cloud */
 
+/* PKG_USING_ONENET is not set */
+/* PKG_USING_GAGENT_CLOUD is not set */
+/* PKG_USING_ALI_IOTKIT is not set */
+/* PKG_USING_AZURE is not set */
+/* PKG_USING_TENCENT_IOTKIT is not set */
+/* PKG_USING_NIMBLE is not set */
+/* PKG_USING_OTA_DOWNLOADER is not set */
 
 /* security packages */
 
+/* PKG_USING_MBEDTLS is not set */
+/* PKG_USING_libsodium is not set */
+/* PKG_USING_TINYCRYPT is not set */
 
 /* language packages */
 
+/* PKG_USING_LUA is not set */
+/* PKG_USING_JERRYSCRIPT is not set */
+/* PKG_USING_MICROPYTHON is not set */
 
 /* multimedia packages */
 
+/* PKG_USING_OPENMV is not set */
+/* PKG_USING_MUPDF is not set */
 
 /* tools packages */
 
+/* PKG_USING_CMBACKTRACE is not set */
+/* PKG_USING_EASYFLASH is not set */
+/* PKG_USING_EASYLOGGER is not set */
+/* PKG_USING_SYSTEMVIEW is not set */
+/* PKG_USING_RDB is not set */
+/* PKG_USING_QRCODE is not set */
+/* PKG_USING_ULOG_EASYFLASH is not set */
+/* PKG_USING_ADBD is not set */
 
 /* system packages */
 
+/* PKG_USING_GUIENGINE is not set */
+/* PKG_USING_PERSIMMON is not set */
+/* PKG_USING_CAIRO is not set */
+/* PKG_USING_PIXMAN is not set */
+/* PKG_USING_LWEXT4 is not set */
+/* PKG_USING_PARTITION is not set */
+/* PKG_USING_FAL is not set */
+/* PKG_USING_SQLITE is not set */
+/* PKG_USING_RTI is not set */
+/* PKG_USING_LITTLEVGL2RTT is not set */
+/* PKG_USING_CMSIS is not set */
+/* PKG_USING_DFS_YAFFS is not set */
+/* PKG_USING_LITTLEFS is not set */
 
 /* peripheral libraries and drivers */
 
 /* sensors drivers */
 
+/* PKG_USING_LSM6DSL is not set */
+/* PKG_USING_LPS22HB is not set */
+/* PKG_USING_HTS221 is not set */
+/* PKG_USING_LSM303AGR is not set */
+/* PKG_USING_BME280 is not set */
+/* PKG_USING_BMA400 is not set */
+/* PKG_USING_BMI160_BMX160 is not set */
+/* PKG_USING_SPL0601 is not set */
+/* PKG_USING_REALTEK_AMEBA is not set */
+/* PKG_USING_SHT2X is not set */
+/* PKG_USING_AHT10 is not set */
+/* PKG_USING_AP3216C is not set */
+/* PKG_USING_STM32_SDIO is not set */
+/* PKG_USING_ICM20608 is not set */
+/* PKG_USING_U8G2 is not set */
+/* PKG_USING_BUTTON is not set */
+/* PKG_USING_MPU6XXX is not set */
+/* PKG_USING_PCF8574 is not set */
+/* PKG_USING_SX12XX is not set */
+/* PKG_USING_KENDRYTE_SDK is not set */
 
 /* miscellaneous packages */
 
+/* PKG_USING_LIBCSV is not set */
+/* PKG_USING_OPTPARSE is not set */
+/* PKG_USING_FASTLZ is not set */
+/* PKG_USING_MINILZO is not set */
+/* PKG_USING_QUICKLZ is not set */
+/* PKG_USING_MULTIBUTTON is not set */
+/* PKG_USING_CANFESTIVAL is not set */
+/* PKG_USING_ZLIB is not set */
+/* PKG_USING_DSTR is not set */
+/* PKG_USING_TINYFRAME is not set */
+/* PKG_USING_KENDRYTE_DEMO is not set */
 
 /* samples: kernel and components samples */
 
@@ -259,5 +407,6 @@
 #define RT_USING_UART0
 #define RT_USING_UART1
 #define BSP_DRV_EMAC
+/* BSP_DRV_AUDIO is not set */
 
 #endif

+ 3 - 2
bsp/qemu-vexpress-a9/rtconfig.py

@@ -2,14 +2,15 @@ import os
 
 # toolchains options
 ARCH='arm'
-CPU='cortex-a9'
+CPU='cortex-a'
 CROSS_TOOL='gcc'
 
 if os.getenv('RTT_CC'):
     CROSS_TOOL = os.getenv('RTT_CC')
 
+# only support GNU GCC compiler.
 PLATFORM    = 'gcc'
-EXEC_PATH   = '/opt/gcc-arm-none-eabi-4_8-2014q1_gri/bin'
+EXEC_PATH   = '/usr/bin'
 
 if os.getenv('RTT_EXEC_PATH'):
     EXEC_PATH = os.getenv('RTT_EXEC_PATH')

+ 8 - 26
bsp/stm32/libraries/HAL_Drivers/drv_common.c

@@ -93,32 +93,14 @@ void _Error_Handler(char *s, int num)
  */
 void rt_hw_us_delay(rt_uint32_t us)
 {
-    rt_uint32_t ticks;
-    rt_uint32_t told, tnow, tcnt = 0;
-    rt_uint32_t reload = SysTick->LOAD;
-
-    ticks = us * reload / (1000000 / RT_TICK_PER_SECOND);
-    told = SysTick->VAL;
-    while (1)
-    {
-        tnow = SysTick->VAL;
-        if (tnow != told)
-        {
-            if (tnow < told)
-            {
-                tcnt += told - tnow;
-            }
-            else
-            {
-                tcnt += reload - tnow + told;
-            }
-            told = tnow;
-            if (tcnt >= ticks)
-            {
-                break;
-            }
-        }
-    }
+    rt_uint32_t start, now, delta, reload, us_tick;
+    start = SysTick->VAL;
+    reload = SysTick->LOAD;
+    us_tick = SystemCoreClock / 1000000UL;
+    do {
+        now = SysTick->VAL;
+        delta = start > now ? start - now : reload + start - now;
+    } while(delta < us_tick * us);
 }
 
 /**

+ 1 - 1
components/lwp/SConscript

@@ -5,7 +5,7 @@ cwd     = GetCurrentDir()
 src     = []
 CPPPATH = [cwd]
 
-support_arch  = {"arm": ["cortex-m3", "cortex-m4", "cortex-m7", "arm926", "cortex-a9"]}
+support_arch  = {"arm": ["cortex-m3", "cortex-m4", "cortex-m7", "arm926", "cortex-a"]}
 platform_file = {'armcc': 'rvds.S', 'gcc': 'gcc.S', 'iar': 'iar.S'}
 
 if rtconfig.PLATFORM in platform_file.keys():	# support platforms

+ 70 - 0
components/lwp/arch/arm/cortex-a/lwp_gcc.S

@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-12-10     Jesven       first version
+ */
+
+#define  Mode_USR       0x10
+#define  Mode_FIQ       0x11
+#define  Mode_IRQ       0x12
+#define  Mode_SVC       0x13
+#define  Mode_MON       0x16
+#define  Mode_ABT       0x17
+#define  Mode_UDF       0x1B
+#define  Mode_SYS       0x1F
+
+#define A_Bit        0x100 
+#define I_Bit        0x80 @; when I bit is set, IRQ is disabled
+#define F_Bit        0x40 @; when F bit is set, FIQ is disabled
+#define T_Bit        0x20
+
+.cpu cortex-a9
+.syntax unified
+.text
+
+/*
+ * void lwp_user_entry(args, text, data);
+ */
+.global lwp_user_entry
+.type lwp_user_entry, % function
+lwp_user_entry:
+    mrs     r9, cpsr
+    bic     r9, #0x1f
+    orr     r9, #Mode_USR
+    cpsid i
+    msr     spsr, r9
+
+    /* set data address. */
+    mov     r9, r2
+    movs    pc, r1
+
+/*
+ * void SVC_Handler(void);
+ */
+.global SVC_Handler
+.type SVC_Handler, % function
+SVC_Handler:
+    push {lr}
+    mrs lr, spsr
+    push {r4, r5, lr}
+    cpsie i
+
+    push {r0 - r3, r12}
+    and r0, r7, #0xff
+    bl lwp_get_sys_api
+    cmp r0, #0           /* r0 = api */
+    mov lr, r0
+    pop {r0 - r3, r12}
+    beq svc_exit
+    blx lr
+
+svc_exit:
+    cpsid i
+    pop {r4, r5, lr}
+    msr spsr_cxsf, lr
+    pop {lr}
+    movs pc, lr

+ 92 - 0
libcpu/arm/cortex-a/context_gcc.S

@@ -8,7 +8,14 @@
  * 2013-07-05     Bernard      the first version
  */
 
+#include "rtconfig.h"
 .section .text, "ax"
+
+#ifdef RT_USING_SMP
+#define rt_hw_interrupt_disable rt_hw_local_irq_disable
+#define rt_hw_interrupt_enable  rt_hw_local_irq_enable
+#endif
+
 /*
  * rt_base_t rt_hw_interrupt_disable();
  */
@@ -34,6 +41,16 @@ rt_hw_interrupt_enable:
 rt_hw_context_switch_to:
     ldr sp, [r0]            @ get new task stack pointer
 
+#ifdef RT_USING_SMP
+    mov     r0, r1
+    bl      rt_cpus_lock_status_restore
+#endif /*RT_USING_SMP*/
+
+#ifdef RT_USING_LWP
+    ldmfd sp, {r13, r14}^   @ pop usr_sp usr_lr
+    add sp, #8
+#endif
+
     ldmfd sp!, {r4}         @ pop new task spsr
     msr spsr_cxsf, r4
 
@@ -62,9 +79,24 @@ rt_hw_context_switch:
 
     stmfd sp!, {r4}         @ push cpsr
 
+#ifdef RT_USING_LWP
+    stmfd sp, {r13, r14}^   @ push usr_sp usr_lr
+    sub sp, #8
+#endif
+
     str sp, [r0]            @ store sp in preempted tasks TCB
     ldr sp, [r1]            @ get new task stack pointer
 
+#ifdef RT_USING_SMP
+    mov     r0, r2
+    bl      rt_cpus_lock_status_restore
+#endif /*RT_USING_SMP*/
+
+#ifdef RT_USING_LWP
+    ldmfd sp, {r13, r14}^   @ pop usr_sp usr_lr
+    add sp, #8
+#endif
+
     ldmfd sp!, {r4}         @ pop new task cpsr to spsr
     msr spsr_cxsf, r4
     ldmfd sp!, {r0-r12, lr, pc}^  @ pop new task r0-r12, lr & pc, copy spsr to cpsr
@@ -72,11 +104,70 @@ rt_hw_context_switch:
 /*
  * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
  */
+.equ Mode_USR,        0x10
+.equ Mode_FIQ,        0x11
+.equ Mode_IRQ,        0x12
+.equ Mode_SVC,        0x13
+.equ Mode_ABT,        0x17
+.equ Mode_UND,        0x1B
+.equ Mode_SYS,        0x1F
+
+.equ I_Bit,           0x80            @ when I bit is set, IRQ is disabled
+.equ F_Bit,           0x40            @ when F bit is set, FIQ is disabled
+
 .globl rt_thread_switch_interrupt_flag
 .globl rt_interrupt_from_thread
 .globl rt_interrupt_to_thread
 .globl rt_hw_context_switch_interrupt
 rt_hw_context_switch_interrupt:
+#ifdef RT_USING_SMP
+    /* r0 :irq_mod context
+     * r1 :addr of from_thread's sp
+     * r2 :addr of to_thread's sp
+     * r3 :to_thread's tcb
+     */
+
+    @ r0 point to {r0-r3} in stack
+    push    {r1 - r3}
+    mov     r1, r0
+    add     r0, r0, #4*4
+    ldmfd   r0!, {r4-r12,lr}@ reload saved registers
+    mrs     r3,  spsr       @ get cpsr of interrupt thread
+    sub     r2,  lr, #4     @ save old task's pc to r2
+    msr     cpsr_c, #I_Bit|F_Bit|Mode_SVC
+
+    stmfd   sp!, {r2}       @ push old task's pc
+    stmfd   sp!, {r4-r12,lr}@ push old task's lr,r12-r4
+    ldmfd   r1,  {r4-r7}    @ restore r0-r3 of the interrupt thread
+    stmfd   sp!, {r4-r7}    @ push old task's r0-r3
+    stmfd   sp!, {r3}       @ push old task's cpsr
+
+#ifdef RT_USING_LWP
+    stmfd sp, {r13,r14}^    @push usr_sp usr_lr
+    sub sp, #8
+#endif
+
+    msr     cpsr_c, #I_Bit|F_Bit|Mode_IRQ
+    pop     {r1 - r3}
+    mov     sp, r0
+    msr     cpsr_c, #I_Bit|F_Bit|Mode_SVC
+    str     sp, [r1]
+
+    ldr     sp, [r2]
+    mov     r0, r3
+    bl      rt_cpus_lock_status_restore
+
+#ifdef RT_USING_LWP
+    ldmfd sp, {r13,r14}^  @pop usr_sp usr_lr
+    add sp, #8
+#endif
+
+    ldmfd   sp!, {r4}       @ pop new task's cpsr to spsr
+    msr     spsr_cxsf, r4
+
+    ldmfd   sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
+
+#else /*RT_USING_SMP*/
     ldr r2, =rt_thread_switch_interrupt_flag
     ldr r3, [r2]
     cmp r3, #1
@@ -89,3 +180,4 @@ _reswitch:
     ldr r2, =rt_interrupt_to_thread     @ set rt_interrupt_to_thread
     str r1, [r2]
     bx  lr
+#endif /*RT_USING_SMP*/

+ 4 - 0
libcpu/arm/cortex-a/cp15.h

@@ -5,6 +5,7 @@
  *
  * Change Logs:
  * Date           Author       Notes
+ * 2018-03-25     quanzhao     the first version
  */
 #ifndef __CP15_H__
 #define __CP15_H__
@@ -15,6 +16,9 @@ void rt_cpu_mmu_disable(void);
 void rt_cpu_mmu_enable(void);
 void rt_cpu_tlb_set(volatile unsigned long*);
 
+void rt_cpu_dcache_clean_flush(void);
+void rt_cpu_icache_flush(void);
+
 void rt_cpu_vector_set_base(unsigned int addr);
 
 #endif

+ 14 - 1
libcpu/arm/cortex-a/cp15_gcc.S

@@ -15,6 +15,11 @@ rt_cpu_get_smp_id:
 
 .globl rt_cpu_vector_set_base
 rt_cpu_vector_set_base:
+    /* clear SCTRL.V to customize the vector address */
+    mrc     p15, #0, r1, c1, c0, #0
+    bic     r1, #(1 << 13)
+    mcr     p15, #0, r1, c1, c0, #0
+    /* set up the vector address */
     mcr     p15, #0, r0, c12, c0, #0
     dsb
     bx      lr
@@ -36,7 +41,7 @@ rt_hw_cpu_icache_enable:
 _FLD_MAX_WAY:
    .word  0x3ff
 _FLD_MAX_IDX:
-   .word  0x7ff
+   .word  0x7fff
 
 .globl rt_cpu_dcache_clean_flush
 rt_cpu_dcache_clean_flush:
@@ -84,6 +89,14 @@ finished:
     pop     {r4-r11}
     bx      lr
 
+.globl rt_cpu_icache_flush
+rt_cpu_icache_flush:
+    mov r0, #0
+    mcr p15, 0, r0, c7, c5, 0       @ I+BTB cache invalidate
+    dsb
+    isb
+    bx      lr
+
 .globl rt_hw_cpu_dcache_disable
 rt_hw_cpu_dcache_disable:
     push    {r4-r11, lr}

+ 59 - 9
libcpu/arm/cortex-a/cpu.c

@@ -6,28 +6,78 @@
  * Change Logs:
  * Date           Author       Notes
  * 2011-09-15     Bernard      first version
+ * 2018-11-22     Jesven       add rt_hw_cpu_id()
  */
 
 #include <rthw.h>
 #include <rtthread.h>
 #include <board.h>
 
+#ifdef RT_USING_SMP
+int rt_hw_cpu_id(void)
+{
+    int cpu_id;
+    __asm__ volatile (
+            "mrc p15, 0, %0, c0, c0, 5"
+            :"=r"(cpu_id)
+            );
+    cpu_id &= 0xf;
+    return cpu_id;
+};
+
+void rt_hw_spin_lock(rt_hw_spinlock_t *lock)
+{
+    unsigned long tmp;
+    unsigned long newval;
+    rt_hw_spinlock_t lockval;
+
+    __asm__ __volatile__(
+            "pld [%0]"
+            ::"r"(&lock->slock)
+            );
+
+    __asm__ __volatile__(
+            "1: ldrex   %0, [%3]\n"
+            "   add %1, %0, %4\n"
+            "   strex   %2, %1, [%3]\n"
+            "   teq %2, #0\n"
+            "   bne 1b"
+            : "=&r" (lockval), "=&r" (newval), "=&r" (tmp)
+            : "r" (&lock->slock), "I" (1 << 16)
+            : "cc");
+
+    while (lockval.tickets.next != lockval.tickets.owner) {
+        __asm__ __volatile__("wfe":::"memory");
+        lockval.tickets.owner = *(volatile unsigned short *)(&lock->tickets.owner);
+    }
+
+    __asm__ volatile ("dmb":::"memory");
+}
+
+void rt_hw_spin_unlock(rt_hw_spinlock_t *lock)
+{
+    __asm__ volatile ("dmb":::"memory");
+    lock->tickets.owner++;
+    __asm__ volatile ("dsb ishst\nsev":::"memory");
+}
+#endif /*RT_USING_SMP*/
+
 /**
- * @addtogroup AM33xx
+ * @addtogroup ARM CPU
  */
 /*@{*/
 
 /** shutdown CPU */
 void rt_hw_cpu_shutdown()
 {
-	rt_uint32_t level;
-	rt_kprintf("shutdown...\n");
-
-	level = rt_hw_interrupt_disable();
-	while (level)
-	{
-		RT_ASSERT(0);
-	}
+    rt_uint32_t level;
+    rt_kprintf("shutdown...\n");
+
+    level = rt_hw_interrupt_disable();
+    while (level)
+    {
+        RT_ASSERT(0);
+    }
 }
 
 /*@}*/

+ 14 - 12
bsp/qemu-vexpress-a9/cpu/gic.c → libcpu/arm/cortex-a/gic.c

@@ -1,11 +1,7 @@
 /*
- * File      : gic.c, ARM Generic Interrupt Controller
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2013-2014, RT-Thread Develop Team
+ * Copyright (c) 2006-2018, RT-Thread Development Team
  *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
+ * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
  * Date           Author       Notes
@@ -17,18 +13,19 @@
 
 #include <rthw.h>
 #include <rtthread.h>
-#include <board.h>
 
 #include "gic.h"
 #include "cp15.h"
 
 struct arm_gic
 {
-    rt_uint32_t offset;
+    rt_uint32_t offset;         /* the first interrupt index in the vector table */
 
-    rt_uint32_t dist_hw_base;
-    rt_uint32_t cpu_hw_base;
+    rt_uint32_t dist_hw_base;   /* the base address of the gic distributor */
+    rt_uint32_t cpu_hw_base;    /* the base addrees of the gic cpu interface */
 };
+
+/* 'ARM_GIC_MAX_NR' is the number of cores */
 static struct arm_gic _gic_table[ARM_GIC_MAX_NR];
 
 #define GIC_CPU_CTRL(hw_base)               __REG32((hw_base) + 0x00)
@@ -118,6 +115,7 @@ void arm_gic_clear_active(rt_uint32_t index, int irq)
     GIC_DIST_ACTIVE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask;
 }
 
+/* Set up the cpu mask for the specific interrupt */
 void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask)
 {
     rt_uint32_t old_tgt;
@@ -215,11 +213,12 @@ int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start)
      */
     if (_gic_max_irq > 1020)
         _gic_max_irq = 1020;
-    if (_gic_max_irq > ARM_GIC_NR_IRQS)
+    if (_gic_max_irq > ARM_GIC_NR_IRQS) /* the platform maximum interrupts */
         _gic_max_irq = ARM_GIC_NR_IRQS;
 
     cpumask |= cpumask << 8;
     cpumask |= cpumask << 16;
+    cpumask |= cpumask << 24;
 
     GIC_DIST_CTRL(dist_base) = 0x0;
 
@@ -244,9 +243,11 @@ int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start)
     for (i = 0; i < _gic_max_irq; i += 32)
         GIC_DIST_IGROUP(dist_base, i) = 0xffffffff;
 #endif
+    for (i = 0; i < _gic_max_irq; i += 32)
+        GIC_DIST_IGROUP(dist_base, i) = 0;
 
     /* Enable group0 and group1 interrupt forwarding. */
-    GIC_DIST_CTRL(dist_base) = 0x03;
+    GIC_DIST_CTRL(dist_base) = 0x01;
 
     return 0;
 }
@@ -258,6 +259,7 @@ int arm_gic_cpu_init(rt_uint32_t index, rt_uint32_t cpu_base)
     _gic_table[index].cpu_hw_base = cpu_base;
 
     GIC_CPU_PRIMASK(cpu_base) = 0xf0;
+    GIC_CPU_BINPOINT(cpu_base) = 0x7;
     /* Enable CPU interrupt */
     GIC_CPU_CTRL(cpu_base) = 0x01;
 

+ 9 - 7
bsp/qemu-vexpress-a9/cpu/gic.h → libcpu/arm/cortex-a/gic.h

@@ -1,11 +1,7 @@
 /*
- * File      : gic.h, ARM Generic Interrupt Controller
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2013, RT-Thread Develop Team
+ * Copyright (c) 2006-2018, RT-Thread Development Team
  *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
+ * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
  * Date           Author       Notes
@@ -15,6 +11,9 @@
 #ifndef __GIC_H__
 #define __GIC_H__
 
+#include <rthw.h>
+#include <platform.h>
+
 int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start);
 int arm_gic_cpu_init(rt_uint32_t index, rt_uint32_t cpu_base);
 
@@ -26,8 +25,11 @@ void arm_gic_set_group(rt_uint32_t index, int vector, int group);
 int arm_gic_get_active_irq(rt_uint32_t index);
 void arm_gic_ack(rt_uint32_t index, int irq);
 
+void arm_gic_clear_active(rt_uint32_t index, int irq);
+void arm_gic_clear_pending(rt_uint32_t index, int irq);
+
 void arm_gic_dump_type(rt_uint32_t index);
-void rt_hw_vector_init(void);
+void arm_gic_dump(rt_uint32_t index);
 
 #endif
 

+ 47 - 72
libcpu/arm/cortex-a/interrupt.c

@@ -6,68 +6,32 @@
  * Change Logs:
  * Date           Author       Notes
  * 2013-07-06     Bernard      first version
- * 2014-04-03     Grissiom     port to VMM
+ * 2018-11-22     Jesven       add smp support
  */
 
 #include <rthw.h>
 #include <rtthread.h>
+#include "interrupt.h"
+#include "gic.h"
 
-#include <irq_numbers.h>
-#include <interrupt.h>
-
-#include <gic.h>
-#include "cp15.h"
-
-#define MAX_HANDLERS                IMX_INTERRUPT_COUNT
-
-extern volatile rt_uint8_t rt_interrupt_nest;
 
 /* exception and interrupt handler table */
 struct rt_irq_desc isr_table[MAX_HANDLERS];
 
-rt_uint32_t rt_interrupt_from_thread;
-rt_uint32_t rt_interrupt_to_thread;
-rt_uint32_t rt_thread_switch_interrupt_flag;
+#ifndef RT_USING_SMP
+/* Those varibles will be accessed in ISR, so we need to share them. */
+rt_uint32_t rt_interrupt_from_thread        = 0;
+rt_uint32_t rt_interrupt_to_thread          = 0;
+rt_uint32_t rt_thread_switch_interrupt_flag = 0;
+#endif
 
+const unsigned int VECTOR_BASE = 0x00;
 extern void rt_cpu_vector_set_base(unsigned int addr);
 extern int system_vectors;
 
-/* keep compatible with platform SDK */
-void register_interrupt_routine(uint32_t irq_id, irq_hdlr_t isr)
-{
-    rt_hw_interrupt_install(irq_id, (rt_isr_handler_t)isr, NULL, "unknown");
-}
-
-void enable_interrupt(uint32_t irq_id, uint32_t cpu_id, uint32_t priority)
-{
-    gic_set_irq_priority(irq_id, priority);
-    gic_set_irq_security(irq_id, false);    // set IRQ as non-secure
-    gic_set_cpu_target(irq_id, cpu_id, true);
-    gic_enable_irq(irq_id, true);
-}
-
-void disable_interrupt(uint32_t irq_id, uint32_t cpu_id)
+void rt_hw_vector_init(void)
 {
-    gic_enable_irq(irq_id, false);
-    gic_set_cpu_target(irq_id, cpu_id, false);
-}
-
-static void rt_hw_vector_init(void)
-{
-    int sctrl;
-    unsigned int *src = (unsigned int *)&system_vectors;
-
-    /* C12-C0 is only active when SCTLR.V = 0 */
-    asm volatile ("mrc p15, #0, %0, c1, c0, #0"
-                  :"=r" (sctrl));
-    sctrl &= ~(1 << 13);
-    asm volatile ("mcr p15, #0, %0, c1, c0, #0"
-                  :
-                  :"r" (sctrl));
-
-    asm volatile ("mcr p15, #0, %0, c12, c0, #0"
-                  :
-                  :"r" (src));
+    rt_cpu_vector_set_base((unsigned int)&system_vectors);
 }
 
 /**
@@ -75,14 +39,24 @@ static void rt_hw_vector_init(void)
  */
 void rt_hw_interrupt_init(void)
 {
+    rt_uint32_t gic_cpu_base;
+    rt_uint32_t gic_dist_base;
+    rt_uint32_t gic_irq_start;
+
+    /* initialize vector table */
     rt_hw_vector_init();
-    gic_init();
 
-    /* init interrupt nest, and context in thread sp */
-    rt_interrupt_nest = 0;
-    rt_interrupt_from_thread = 0;
-    rt_interrupt_to_thread = 0;
-    rt_thread_switch_interrupt_flag = 0;
+    /* initialize exceptions table */
+    rt_memset(isr_table, 0x00, sizeof(isr_table));
+
+    /* initialize ARM GIC */
+    gic_dist_base = platform_get_gic_dist_base();
+    gic_cpu_base = platform_get_gic_cpu_base();
+
+    gic_irq_start = GIC_IRQ_START;
+
+    arm_gic_dist_init(0, gic_dist_base, gic_irq_start);
+    arm_gic_cpu_init(0, gic_cpu_base);
 }
 
 /**
@@ -91,7 +65,7 @@ void rt_hw_interrupt_init(void)
  */
 void rt_hw_interrupt_mask(int vector)
 {
-    disable_interrupt(vector, 0);
+    arm_gic_mask(0, vector);
 }
 
 /**
@@ -100,9 +74,26 @@ void rt_hw_interrupt_mask(int vector)
  */
 void rt_hw_interrupt_umask(int vector)
 {
-    enable_interrupt(vector, 0, 0);
+    arm_gic_umask(0, vector);
 }
 
+/**
+ * This function returns the active interrupt number.
+ * @param none
+ */
+int rt_hw_interrupt_get_irq(void)
+{
+    return arm_gic_get_active_irq(0) & GIC_ACK_INTID_MASK;
+}
+
+/**
+ * This function acknowledges the interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_ack(int vector)
+{
+    arm_gic_ack(0, vector);
+}
 /**
  * This function will install a interrupt service routine to a interrupt.
  * @param vector the interrupt number
@@ -126,23 +117,7 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
             isr_table[vector].handler = handler;
             isr_table[vector].param = param;
         }
-        // arm_gic_set_cpu(0, vector, 1 << rt_cpu_get_smp_id());
     }
 
     return old_handler;
 }
-
-/**
- * Trigger a software IRQ
- *
- * Since we are running in single core, the target CPU are always CPU0.
- */
-void rt_hw_interrupt_trigger(int vector)
-{
-    // arm_gic_trigger(0, 1, vector);
-}
-
-void rt_hw_interrupt_clear(int vector)
-{
-    gic_write_end_of_irq(vector);
-}

+ 32 - 0
libcpu/arm/cortex-a/interrupt.h

@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-07-06     Bernard      first version
+ */
+
+#ifndef __INTERRUPT_H__
+#define __INTERRUPT_H__
+
+#include <rthw.h>
+#include <platform.h>
+
+#define INT_IRQ     0x00
+#define INT_FIQ     0x01
+
+void rt_hw_interrupt_control(int vector, int priority, int route);
+
+void rt_hw_interrupt_init(void);
+void rt_hw_interrupt_mask(int vector);
+void rt_hw_interrupt_umask(int vector);
+
+int rt_hw_interrupt_get_irq(void);
+void rt_hw_interrupt_ack(int vector);
+
+rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
+        void *param, const char *name);
+
+#endif

+ 14 - 35
libcpu/arm/cortex-a/mmu.c

@@ -13,35 +13,7 @@
 #include <board.h>
 
 #include "cp15.h"
-
-#define DESC_SEC       (0x2)
-#define CB             (3<<2)  //cache_on, write_back
-#define CNB            (2<<2)  //cache_on, write_through
-#define NCB            (1<<2)  //cache_off,WR_BUF on
-#define NCNB           (0<<2)  //cache_off,WR_BUF off
-#define AP_RW          (3<<10) //supervisor=RW, user=RW
-#define AP_RO          (2<<10) //supervisor=RW, user=RO
-#define XN             (1<<4)  // eXecute Never
-
-#define DOMAIN_FAULT   (0x0)
-#define DOMAIN_CHK     (0x1)
-#define DOMAIN_NOTCHK  (0x3)
-#define DOMAIN0        (0x0<<5)
-#define DOMAIN1        (0x1<<5)
-
-#define DOMAIN0_ATTR   (DOMAIN_CHK<<0)
-#define DOMAIN1_ATTR   (DOMAIN_FAULT<<2)
-
-/* Read/Write, cache, write back */
-#define RW_CB          (AP_RW|DOMAIN0|CB|DESC_SEC)
-/* Read/Write, cache, write through */
-#define RW_CNB         (AP_RW|DOMAIN0|CNB|DESC_SEC)
-/* Read/Write without cache and write buffer */
-#define RW_NCNB        (AP_RW|DOMAIN0|NCNB|DESC_SEC)
-/* Read/Write without cache and write buffer, no execute */
-#define RW_NCNBXN      (AP_RW|DOMAIN0|NCNB|DESC_SEC|XN)
-/* Read/Write without cache and write buffer */
-#define RW_FAULT       (AP_RW|DOMAIN1|NCNB|DESC_SEC)
+#include "mmu.h"
 
 /* dump 2nd level page table */
 void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb)
@@ -178,18 +150,25 @@ unsigned long rt_hw_set_domain_register(unsigned long domain_val)
     return old_domain;
 }
 
+void rt_hw_init_mmu_table(struct mem_desc *mdesc, rt_uint32_t size)
+{
+    /* set page table */
+    for(; size > 0; size--)
+    {
+        rt_hw_mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end,
+                mdesc->paddr_start, mdesc->attr);
+        mdesc++;
+    }
+}
+
 void rt_hw_mmu_init(void)
 {
+    rt_cpu_dcache_clean_flush();
+    rt_cpu_icache_flush();
     rt_hw_cpu_dcache_disable();
     rt_hw_cpu_icache_disable();
     rt_cpu_mmu_disable();
 
-    /* set page table */
-    /* 4G 1:1 memory */
-    rt_hw_mmu_setmtt(0, 0xffffffff-1, 0, RW_CB);
-    /* IO memory region */
-    rt_hw_mmu_setmtt(0x44000000, 0x80000000-1, 0x44000000, RW_NCNBXN);
-
     /*rt_hw_cpu_dump_page_table(MMUTable);*/
     rt_hw_set_domain_register(0x55555555);
 

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

@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-03-25     quanzhao     the first version
+ */
+#ifndef __MMU_H_
+#define __MMU_H_
+
+#include <rtthread.h>
+
+#define DESC_SEC       (0x2)
+#define MEMWB          (3<<2)  /* write back, no write allocate */
+#define MEMWT          (2<<2)  /* write through, no write allocate */
+#define SHAREDEVICE    (1<<2)  /* shared device */
+#define STRONGORDER    (0<<2)  /* strong ordered */
+#define XN             (1<<4)  /* eXecute Never */
+#define AP_RW          (3<<10) /* supervisor=RW, user=RW */
+#define AP_RO          (2<<10) /* supervisor=RW, user=RO */
+#define SHARED         (1<<16) /* shareable */
+
+#define DOMAIN_FAULT   (0x0)
+#define DOMAIN_CHK     (0x1)
+#define DOMAIN_NOTCHK  (0x3)
+#define DOMAIN0        (0x0<<5)
+#define DOMAIN1        (0x1<<5)
+
+#define DOMAIN0_ATTR   (DOMAIN_CHK<<0)
+#define DOMAIN1_ATTR   (DOMAIN_FAULT<<2)
+
+/* device mapping type */
+#define DEVICE_MEM     (SHARED|AP_RW|DOMAIN0|SHAREDEVICE|DESC_SEC|XN)
+/* normal memory mapping type */
+#define NORMAL_MEM     (SHARED|AP_RW|DOMAIN0|MEMWB|DESC_SEC)
+
+struct mem_desc
+{
+    rt_uint32_t vaddr_start;
+    rt_uint32_t vaddr_end;
+    rt_uint32_t paddr_start;
+    rt_uint32_t attr;
+};
+
+
+#endif

+ 5 - 1
libcpu/arm/cortex-a/stack.c

@@ -50,13 +50,17 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
     *(--stk) = 0xdeadbeef;                  /* r2 */
     *(--stk) = 0xdeadbeef;                  /* r1 */
     *(--stk) = (rt_uint32_t)parameter;      /* r0 : argument */
-
     /* cpsr */
     if ((rt_uint32_t)tentry & 0x01)
         *(--stk) = SVCMODE | 0x20;          /* thumb mode */
     else
         *(--stk) = SVCMODE;                 /* arm mode   */
 
+#ifdef RT_USING_LWP
+    *(--stk) = 0;       /* user lr */
+    *(--stk) = 0;       /* user sp*/
+#endif
+
     /* return task's current stack address */
     return (rt_uint8_t *)stk;
 }

+ 99 - 13
libcpu/arm/cortex-a/start_gcc.S

@@ -6,8 +6,12 @@
  * Change Logs:
  * Date           Author       Notes
  * 2013-07-05     Bernard      the first version
+ * 2018-11-22     Jesven       in the interrupt context, use rt_scheduler_do_irq_switch checks
+ *                             and switches to a new thread
  */
 
+#include "rtconfig.h"
+
 .equ Mode_USR,        0x10
 .equ Mode_FIQ,        0x11
 .equ Mode_IRQ,        0x12
@@ -20,11 +24,11 @@
 .equ F_Bit,           0x40            @ when F bit is set, FIQ is disabled
 
 .equ UND_Stack_Size,     0x00000000
-.equ SVC_Stack_Size,     0x00000100
+.equ SVC_Stack_Size,     0x00000400
 .equ ABT_Stack_Size,     0x00000000
 .equ RT_FIQ_STACK_PGSZ,  0x00000000
-.equ RT_IRQ_STACK_PGSZ,  0x00000100
-.equ USR_Stack_Size,     0x00000100
+.equ RT_IRQ_STACK_PGSZ,  0x00000800
+.equ USR_Stack_Size,     0x00000400
 
 #define ISR_Stack_Size  (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
                  RT_FIQ_STACK_PGSZ + RT_IRQ_STACK_PGSZ)
@@ -44,12 +48,8 @@ stack_top:
 /* reset entry */
 .globl _reset
 _reset:
-    bl      rt_cpu_mmu_disable
     /* set the cpu to SVC32 mode and disable interrupt */
-    mrs     r0, cpsr
-    bic     r0, r0, #0x1f
-    orr     r0, r0, #0x13
-    msr     cpsr_c, r0
+    cps #Mode_SVC
 
     /* setup stack */
     bl      stack_setup
@@ -64,6 +64,20 @@ bss_loop:
     strlo   r0,[r1],#4              /* clear 4 bytes                    */
     blo     bss_loop                /* loop until done                  */
 
+#ifdef RT_USING_SMP
+    mrc p15, 0, r1, c1, c0, 1
+    mov r0, #(1<<6)
+    orr r1, r0
+    mcr p15, 0, r1, c1, c0, 1 //enable smp
+#endif
+
+    /* initialize the mmu table and enable mmu */
+    ldr r0, =platform_mem_desc
+    ldr r1, =platform_mem_desc_size
+    ldr r1, [r1]
+    bl rt_hw_init_mmu_table
+    bl rt_hw_mmu_init
+
     /* call C++ constructors of global objects                          */
     ldr     r0, =__ctors_start__
     ldr     r1, =__ctors_end__
@@ -137,12 +151,22 @@ vector_fiq:
     .align  5
 .globl vector_irq
 vector_irq:
+#ifdef RT_USING_SMP
+    clrex
+#endif
     stmfd   sp!, {r0-r12,lr}
 
     bl      rt_interrupt_enter
     bl      rt_hw_trap_irq
     bl      rt_interrupt_leave
 
+#ifdef RT_USING_SMP
+    mov     r0, sp
+    bl      rt_scheduler_do_irq_switch
+
+    ldmfd   sp!, {r0-r12,lr}
+    subs    pc,  lr, #4
+#else
     @ if rt_thread_switch_interrupt_flag set, jump to
     @ rt_hw_context_switch_interrupt_do and don't return
     ldr     r0, =rt_thread_switch_interrupt_flag
@@ -174,6 +198,11 @@ rt_hw_context_switch_interrupt_do:
     stmfd   sp!, {r1-r4}    @ push old task's r0-r3
     stmfd   sp!, {r0}       @ push old task's cpsr
 
+#ifdef RT_USING_LWP
+    stmfd sp, {r13, r14}^  @push usr_sp, usr_lr
+    sub sp, #8
+#endif
+
     ldr     r4,  =rt_interrupt_from_thread
     ldr     r5,  [r4]
     str     sp,  [r5]       @ store sp in preempted tasks's TCB
@@ -182,11 +211,18 @@ rt_hw_context_switch_interrupt_do:
     ldr     r6,  [r6]
     ldr     sp,  [r6]       @ get new task's stack pointer
 
+#ifdef RT_USING_LWP
+    ldmfd sp, {r13, r14}^  @pop usr_sp, usr_lr
+    add sp, #8
+#endif
+
     ldmfd   sp!, {r4}       @ pop new task's cpsr to spsr
     msr     spsr_cxsf, r4
 
     ldmfd   sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
 
+#endif
+
 .macro push_svc_reg
     sub     sp, sp, #17 * 4         @/* Sizeof(struct rt_hw_exp_stack)  */
     stmia   sp, {r0 - r12}          @/* Calling r0-r12                  */
@@ -200,36 +236,86 @@ rt_hw_context_switch_interrupt_do:
 .endm
 
     .align  5
-    .globl	vector_swi
+    .globl  vector_swi
+.weak SVC_Handler
+SVC_Handler:
 vector_swi:
     push_svc_reg
     bl      rt_hw_trap_swi
     b       .
 
     .align  5
-    .globl	vector_undef
+    .globl  vector_undef
 vector_undef:
     push_svc_reg
     bl      rt_hw_trap_undef
     b       .
 
     .align  5
-    .globl	vector_pabt
+    .globl  vector_pabt
 vector_pabt:
     push_svc_reg
     bl      rt_hw_trap_pabt
     b       .
 
     .align  5
-    .globl	vector_dabt
+    .globl  vector_dabt
 vector_dabt:
     push_svc_reg
     bl      rt_hw_trap_dabt
     b       .
 
     .align  5
-    .globl	vector_resv
+    .globl  vector_resv
 vector_resv:
     push_svc_reg
     bl      rt_hw_trap_resv
     b       .
+
+#ifdef RT_USING_SMP
+.global set_secondary_cpu_boot_address
+set_secondary_cpu_boot_address:
+    ldr r0, =secondary_cpu_start
+
+    mvn r1, #0 //0xffffffff
+    ldr r2, =0x10000034
+    str r1, [r2]
+    str r0, [r2, #-4]
+    mov pc, lr
+
+.global secondary_cpu_start
+secondary_cpu_start:
+    mrc p15, 0, r1, c1, c0, 1
+    mov r0, #(1<<6)
+    orr r1, r0
+    mcr p15, 0, r1, c1, c0, 1 //enable smp
+
+    mrc p15, 0, r0, c1, c0, 0
+    bic r0, #(1<<13)
+    mcr p15, 0, r0, c1, c0, 0
+
+    cps #Mode_IRQ
+    ldr sp, =irq_stack_2_limit
+
+    cps #Mode_FIQ
+    ldr sp, =irq_stack_2_limit
+
+    cps #Mode_SVC
+    ldr sp, =svc_stack_2_limit
+
+    /* initialize the mmu table and enable mmu */
+    bl rt_hw_mmu_init
+
+    b secondary_cpu_c_start
+#endif
+
+.bss
+.align 2   //align to  2~2=4
+svc_stack_2:
+    .space (1 << 10)
+svc_stack_2_limit:
+
+irq_stack_2:
+    .space (1 << 10)
+irq_stack_2_limit:
+

+ 36 - 34
libcpu/arm/cortex-a/trap.c

@@ -10,13 +10,11 @@
 
 #include <rtthread.h>
 #include <rthw.h>
-#include <board.h>
+#include <platform.h>
 
 #include "armv7.h"
+#include "interrupt.h"
 
-#include "gic.h"
-
-extern struct rt_thread *rt_current_thread;
 #ifdef RT_USING_FINSH
 extern long list_thread(void);
 #endif
@@ -130,48 +128,52 @@ void rt_hw_trap_resv(struct rt_hw_exp_stack *regs)
 void rt_hw_trap_irq(void)
 {
     void *param;
+    int ir;
     rt_isr_handler_t isr_func;
     extern struct rt_irq_desc isr_table[];
 
-    // vectNum = RESERVED[31:13] | CPUID[12:10] | INTERRUPT_ID[9:0]
-    // send ack and get ID source
-    uint32_t vectNum = gic_read_irq_ack();
+    ir = rt_hw_interrupt_get_irq();
 
-    // Check that INT_ID isn't 1023 or 1022 (spurious interrupt)
-    if (vectNum & 0x0200)
+    if (ir == 1023)
     {
-        gic_write_end_of_irq(vectNum);  // send end of irq
+        /* Spurious interrupt */
+        return;
     }
-    else
-    {
-        // copy the local value to the global image of CPUID
-        unsigned cpu = (vectNum >> 10) & 0x7;
-        unsigned irq = vectNum & 0x1FF;
 
-        /* skip warning */
-        cpu = cpu;
-
-        // Call the service routine stored in the handlers array. If there isn't
-        // one for this IRQ, then call the default handler.
-        /* get interrupt service routine */
-        isr_func = isr_table[irq].handler;
+    /* get interrupt service routine */
+    isr_func = isr_table[ir].handler;
 #ifdef RT_USING_INTERRUPT_INFO
-        isr_table[irq].counter++;
+    isr_table[ir].counter++;
 #endif
-        if (isr_func)
-        {
-            /* Interrupt for myself. */
-            param = isr_table[irq].param;
-            /* turn to interrupt service routine */
-            isr_func(irq, param);
-        }
-
-        // Signal the end of the irq.
-        gic_write_end_of_irq(vectNum);
+    if (isr_func)
+    {
+        /* Interrupt for myself. */
+        param = isr_table[ir].param;
+        /* turn to interrupt service routine */
+        isr_func(ir, param);
     }
+
+    /* end of interrupt */
+    rt_hw_interrupt_ack(ir);
 }
 
 void rt_hw_trap_fiq(void)
 {
-    /* TODO */
+    void *param;
+    int ir;
+    rt_isr_handler_t isr_func;
+    extern struct rt_irq_desc isr_table[];
+
+    ir = rt_hw_interrupt_get_irq();
+
+    /* get interrupt service routine */
+    isr_func = isr_table[ir].handler;
+    param = isr_table[ir].param;
+
+    /* turn to interrupt service routine */
+    isr_func(ir, param);
+
+    /* end of interrupt */
+    rt_hw_interrupt_ack(ir);
 }
+

+ 0 - 14
libcpu/mips/xburst/SConscript.1

@@ -1,14 +0,0 @@
-# RT-Thread building script for component
-
-from building import *
-
-Import('rtconfig')
-
-cwd     = GetCurrentDir()
-src     = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
-CPPPATH = [cwd]
-ASFLAGS = ''
-
-group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS)
-
-Return('group')

+ 29 - 23
src/kservice.c

@@ -668,7 +668,7 @@ static char *print_number(char *buf,
 
         while (size-- > 0)
         {
-            if (buf <= end)
+            if (buf < end)
                 *buf = ' ';
             ++ buf;
         }
@@ -676,11 +676,11 @@ static char *print_number(char *buf,
 
     if (sign)
     {
-        if (buf <= end)
+        if (buf < end)
         {
             *buf = sign;
-            -- size;
         }
+        -- size;
         ++ buf;
     }
 
@@ -689,16 +689,16 @@ static char *print_number(char *buf,
     {
         if (base == 8)
         {
-            if (buf <= end)
+            if (buf < end)
                 *buf = '0';
             ++ buf;
         }
         else if (base == 16)
         {
-            if (buf <= end)
+            if (buf < end)
                 *buf = '0';
             ++ buf;
-            if (buf <= end)
+            if (buf < end)
             {
                 *buf = type & LARGE ? 'X' : 'x';
             }
@@ -712,7 +712,7 @@ static char *print_number(char *buf,
     {
         while (size-- > 0)
         {
-            if (buf <= end)
+            if (buf < end)
                 *buf = c;
             ++ buf;
         }
@@ -721,7 +721,7 @@ static char *print_number(char *buf,
 #ifdef RT_PRINTF_PRECISION
     while (i < precision--)
     {
-        if (buf <= end)
+        if (buf < end)
             *buf = '0';
         ++ buf;
     }
@@ -730,14 +730,14 @@ static char *print_number(char *buf,
     /* put number in the temporary buffer */
     while (i-- > 0 && (precision_bak != 0))
     {
-        if (buf <= end)
+        if (buf < end)
             *buf = tmp[i];
         ++ buf;
     }
 
     while (size-- > 0)
     {
-        if (buf <= end)
+        if (buf < end)
             *buf = ' ';
         ++ buf;
     }
@@ -769,7 +769,7 @@ rt_int32_t rt_vsnprintf(char       *buf,
 #endif
 
     str = buf;
-    end = buf + size - 1;
+    end = buf + size;
 
     /* Make sure end is always >= buf */
     if (end < buf)
@@ -782,7 +782,7 @@ rt_int32_t rt_vsnprintf(char       *buf,
     {
         if (*fmt != '%')
         {
-            if (str <= end)
+            if (str < end)
                 *str = *fmt;
             ++ str;
             continue;
@@ -863,20 +863,20 @@ rt_int32_t rt_vsnprintf(char       *buf,
             {
                 while (--field_width > 0)
                 {
-                    if (str <= end) *str = ' ';
+                    if (str < end) *str = ' ';
                     ++ str;
                 }
             }
 
             /* get character */
             c = (rt_uint8_t)va_arg(args, int);
-            if (str <= end) *str = c;
+            if (str < end) *str = c;
             ++ str;
 
             /* put width */
             while (--field_width > 0)
             {
-                if (str <= end) *str = ' ';
+                if (str < end) *str = ' ';
                 ++ str;
             }
             continue;
@@ -894,21 +894,21 @@ rt_int32_t rt_vsnprintf(char       *buf,
             {
                 while (len < field_width--)
                 {
-                    if (str <= end) *str = ' ';
+                    if (str < end) *str = ' ';
                     ++ str;
                 }
             }
 
             for (i = 0; i < len; ++i)
             {
-                if (str <= end) *str = *s;
+                if (str < end) *str = *s;
                 ++ str;
                 ++ s;
             }
 
             while (len < field_width--)
             {
-                if (str <= end) *str = ' ';
+                if (str < end) *str = ' ';
                 ++ str;
             }
             continue;
@@ -931,7 +931,7 @@ rt_int32_t rt_vsnprintf(char       *buf,
             continue;
 
         case '%':
-            if (str <= end) *str = '%';
+            if (str < end) *str = '%';
             ++ str;
             continue;
 
@@ -953,12 +953,12 @@ rt_int32_t rt_vsnprintf(char       *buf,
             break;
 
         default:
-            if (str <= end) *str = '%';
+            if (str < end) *str = '%';
             ++ str;
 
             if (*fmt)
             {
-                if (str <= end) *str = *fmt;
+                if (str < end) *str = *fmt;
                 ++ str;
             }
             else
@@ -995,8 +995,14 @@ rt_int32_t rt_vsnprintf(char       *buf,
 #endif
     }
 
-    if (str <= end) *str = '\0';
-    else *end = '\0';
+    if (size > 0)
+    {
+        if (str < end) *str = '\0';
+        else
+        {
+            end[-1] = '\0';
+        }
+    }
 
     /* the trailing null byte doesn't count towards the total
     * ++str;

+ 7 - 1
tools/building.py

@@ -187,7 +187,7 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [
     AddOption('--target',
                       dest = 'target',
                       type = 'string',
-                      help = 'set target project: mdk/mdk4/mdk5/iar/vs/vsc/ua/cdk/ses')
+                      help = 'set target project: mdk/mdk4/mdk5/iar/vs/vsc/ua/cdk/ses/makefile/eclipse')
     AddOption('--genconfig',
                 dest = 'genconfig',
                 action = 'store_true',
@@ -228,6 +228,8 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [
                 'cb':('keil', 'armcc'),
                 'ua':('gcc', 'gcc'),
                 'cdk':('gcc', 'gcc'),
+                'makefile':('gcc', 'gcc'),
+                'eclipse':('gcc', 'gcc'),
                 'ses' : ('gcc', 'gcc')}
     tgt_name = GetOption('target')
 
@@ -824,6 +826,10 @@ def GenTargetProject(program = None):
         from ses import SESProject
         SESProject(Env)
 
+    if GetOption('target') == 'makefile':
+        from makefile import TargetMakefile
+        TargetMakefile(Env)
+
 def EndBuilding(target, program = None):
     import rtconfig
 

+ 299 - 0
tools/eclipse.py

@@ -0,0 +1,299 @@
+import os
+import sys
+import glob
+
+from utils import *
+from utils import _make_path_relative
+from utils import xml_indent
+
+import xml.etree.ElementTree as etree
+from xml.etree.ElementTree import SubElement
+
+source_pattern = ['*.c', '*.cpp', '*.cxx', '*.s', '*.S', '*.asm']
+
+def OSPath(path):
+    import platform
+
+    if type(path) == type('str'):
+        if platform.system() == 'Windows':
+            return path.replace('/', '\\')
+        else:
+            return path.replace('\\', '/')
+    else:
+        if platform.system() == 'Windows':
+            return [item.replace('/', '\\') for item in path]
+        else:
+            return [item.replace('\\', '/') for item in path]
+
+def CollectPaths(paths):
+    all_paths = []
+
+    def ParentPaths(path):
+        ret = os.path.dirname(path)
+        if ret == path or ret == '':
+            return []
+
+        return [ret] + ParentPaths(ret)
+
+    for path in paths:
+        # path = os.path.abspath(path)
+        path = path.replace('\\', '/')
+        all_paths = all_paths + [path] + ParentPaths(path)
+
+    all_paths = list(set(all_paths))
+    return sorted(all_paths)
+
+'''
+Collect all of files under paths
+'''
+def CollectFiles(paths, pattern):
+    files = []
+    for path in paths:
+        if type(pattern) == type(''):
+            files = files + glob.glob(path + '/' + pattern)
+        else:
+            for item in pattern:
+                # print('--> %s' % (path + '/' + item))
+                files = files + glob.glob(path + '/' + item)
+
+    return sorted(files)
+
+def CollectAllFilesinPath(path, pattern):
+    files = []
+
+    for item in pattern:
+        files += glob.glob(path + '/' + item)
+
+    list = os.listdir(path)
+    if len(list):
+        for item in list:
+            if item.startswith('.'):
+                continue
+            if item == 'bsp':
+                continue
+
+            if os.path.isdir(os.path.join(path, item)):
+                files = files + CollectAllFilesinPath(os.path.join(path, item), pattern)
+    return files
+
+'''
+Exclude files from infiles
+'''
+def ExcludeFiles(infiles, files):
+    in_files  = set([OSPath(file) for file in infiles])
+    exl_files = set([OSPath(file) for file in files])
+
+    exl_files = in_files - exl_files
+
+    return exl_files
+
+def ExcludePaths(filepath, paths):
+    ret = []
+
+    files = os.listdir(filepath)
+    for file in files:
+        if file.startswith('.'):
+            continue
+
+        fullname = os.path.join(filepath, file)
+
+        if os.path.isdir(fullname):
+            # print(fullname)
+            if not fullname in paths:
+                ret = ret + [fullname]
+            else:
+                ret = ret + ExcludePaths(fullname, paths)
+
+    return ret
+
+def HandleToolOption(tools, env):
+    project = ProjectInfo(env)
+    BSP_ROOT = os.path.abspath(env['BSP_ROOT'])
+
+    CPPDEFINES = project['CPPDEFINES']
+    paths = ['${ProjDirPath}/' + _make_path_relative(BSP_ROOT, os.path.normpath(i)).replace('\\', '/') for i in project['CPPPATH']]
+
+    for tool in tools:
+        if tool.get('id').find('c.compile') != 1:
+            options = tool.findall('option')
+            for option in options:
+                if option.get('id').find('c.compiler.include.paths') != -1:
+                    # find all of paths in this project
+                    include_paths = option.findall('listOptionValue')
+                    project_paths = []
+                    for item in include_paths:
+                        project_paths += [item.get('value')]
+
+                    if len(project_paths) > 0:
+                        cproject_paths = set(paths) - set(project_paths)
+                    else:
+                        cproject_paths = paths
+
+                    # print('c.compiler.include.paths')
+                    cproject_paths = sorted(cproject_paths)
+                    for item in cproject_paths:
+                        SubElement(option, 'listOptionValue', {'builtIn': 'false', 'value': item})
+
+                if option.get('id').find('c.compiler.defs') != -1:
+                    defs = option.findall('listOptionValue')
+                    project_defs = []
+                    for item in defs:
+                        project_defs += [item.get('value')]
+                    if len(project_defs) > 0:
+                        cproject_defs = set(CPPDEFINES) - set(project_defs)
+                    else:
+                        cproject_defs = CPPDEFINES
+
+                    # print('c.compiler.defs')
+                    cproject_defs = sorted(cproject_defs)
+                    for item in cproject_defs:
+                        SubElement(option, 'listOptionValue', {'builtIn': 'false', 'value': item})
+
+        if tool.get('id').find('c.linker') != -1:
+            options = tool.findall('option')
+            for option in options:
+                if option.get('id').find('c.linker.scriptfile') != -1:
+                    linker_script = 'link.lds'
+                    items = env['LINKFLAGS'].split(' ')
+                    if '-T' in items:
+                        linker_script = items[items.index('-T') + 1]
+                        linker_script = '${ProjDirPath}/' + linker_script
+
+                    # print('c.linker.scriptfile')
+                    listOptionValue = option.find('listOptionValue')
+                    if listOptionValue != None:
+                        listOptionValue.set('value', linker_script)
+                    else:
+                        SubElement(option, 'listOptionValue', {'builtIn': 'false', 'value': linker_script})
+
+                if option.get('id').find('c.linker.nostart') != -1:
+                    if env['LINKFLAGS'].find('-nostartfiles') != -1:
+                        option.set('value', 'true')
+                    else:
+                        option.set('value', 'false')
+
+    return
+
+def HandleRTTRoot(env):
+    bsp_root = env['BSP_ROOT']
+    rtt_root = env['RTT_ROOT']
+
+    if not rtt_root.startswith(bsp_root):
+        to_SubElement = True
+        # print('handle virtual root')
+
+        # always use '/' path separator
+        rtt_root = rtt_root.replace('\\', '/')
+
+        project = etree.parse('.project')
+        root = project.getroot()
+
+        linkedResources = root.find('linkedResources')
+        if linkedResources == None:
+            # add linkedResources
+            linkedResources = SubElement(root, 'linkedResources')
+            # print('add linkedResources')
+        else:
+            links = linkedResources.findall('link')
+            # search exist 'rt-thread' virtual folder
+            for link in links:
+                if link.find('name').text == 'rt-thread':
+                    # handle location
+                    to_SubElement = False
+                    location = link.find('location')
+                    location.text = rtt_root
+
+        if to_SubElement:
+            # print('to subelement for virtual folder')
+            link = SubElement(linkedResources, 'link')
+            name = SubElement(link, 'name')
+            name.text = 'rt-thread'
+            type = SubElement(link, 'type')
+            type.text = '2'
+            location = SubElement(link, 'location')
+            location.text = rtt_root
+
+        out = open('.project', 'w')
+        out.write('<?xml version="1.0" encoding="UTF-8"?>\n')
+        xml_indent(root)
+        out.write(etree.tostring(root, encoding='utf-8'))
+        out.close()
+
+    return
+
+def TargetEclipse(env):
+    global source_pattern
+
+    print('Update eclipse setting...')
+
+    if not os.path.exists('.cproject'):
+        print('no eclipse CDT project found!')
+        return
+
+    HandleRTTRoot(env)
+
+    project = ProjectInfo(env)
+
+    all_paths = [OSPath(path) for path in CollectPaths(project['DIRS'])]
+    # print(all_paths)
+    bsp_root = os.path.abspath(env['BSP_ROOT'])
+
+    exclude_paths = ExcludePaths(bsp_root, all_paths)
+    paths = exclude_paths
+    exclude_paths = []
+    for path in paths:
+        # add bsp and libcpu folder and not collect source files (too more files)
+        if path.endswith('rt-thread\\bsp') or path.endswith('rt-thread\\libcpu'):
+            exclude_paths += [path]
+            continue
+
+        set = CollectAllFilesinPath(path, source_pattern)
+        if len(set):
+            exclude_paths += [path]
+
+    exclude_paths = [_make_path_relative(bsp_root, path).replace('\\', '/') for path in exclude_paths]
+    env['ExPaths'] = exclude_paths
+
+    all_files = CollectFiles(all_paths, source_pattern)
+    src_files = project['FILES']
+
+    exclude_files = ExcludeFiles(all_files, src_files)
+    exclude_files = [_make_path_relative(bsp_root, file).replace('\\', '/') for file in exclude_files]
+    env['ExFiles'] = exclude_files
+
+    cproject = etree.parse('.cproject')
+
+    root = cproject.getroot()
+    cconfigurations = root.findall('storageModule/cconfiguration')
+    for cconfiguration in cconfigurations:
+        tools = cconfiguration.findall('storageModule/configuration/folderInfo/toolChain/tool')
+        HandleToolOption(tools, env)
+
+        sourceEntries = cconfiguration.find('storageModule/configuration/sourceEntries')
+        entry = sourceEntries.find('entry')
+        if entry != None:
+            sourceEntries.remove(entry)
+
+        excluding = exclude_paths + exclude_files
+        excluding = sorted(excluding)
+        value = ''
+        for item in excluding:
+            if value == '':
+                value = item
+            else:
+                value += '|' + item
+        excluding = value
+
+        SubElement(sourceEntries, 'entry', {'excluding': excluding, 'flags': 'VALUE_WORKSPACE_PATH|RESOLVED', 'kind':'sourcePath', 'name':""})
+
+    # write back to .cproject
+    out = open('.cproject', 'w')
+    out.write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n')
+    out.write('<?fileVersion 4.0.0?>')
+    xml_indent(root)
+    out.write(etree.tostring(root, encoding='utf-8'))
+    out.close()
+
+    print('done!')
+
+    return

+ 107 - 0
tools/makefile.py

@@ -0,0 +1,107 @@
+import os
+import sys
+
+from utils import *
+from utils import _make_path_relative
+import rtconfig
+
+def TargetMakefile(env):
+    project = ProjectInfo(env)
+
+    BSP_ROOT = os.path.abspath(env['BSP_ROOT'])
+    RTT_ROOT = os.path.abspath(env['RTT_ROOT'])
+
+    match_bsp = False
+    if BSP_ROOT.startswith(RTT_ROOT): 
+        match_bsp = True
+
+    make = open('config.mk', 'w')
+
+    make.write('BSP_ROOT ?= %s\n' % BSP_ROOT.replace('\\', '\\\\'))
+    make.write('RTT_ROOT ?= %s\n' % RTT_ROOT.replace('\\', '\\\\'))
+    make.write('\n')
+
+    cross = os.path.abspath(rtconfig.EXEC_PATH)
+    cross = os.path.join(cross, rtconfig.PREFIX)
+    make.write('CROSS_COMPILE ?=%s' % cross.replace('\\', '\\\\'))
+    make.write('\n')
+    make.write('\n')
+
+    make.write('CFLAGS :=%s' % (rtconfig.CFLAGS))
+    make.write('\n')
+    make.write('AFLAGS :=%s' % (rtconfig.AFLAGS))
+    make.write('\n')
+    make.write('LFLAGS :=%s' % (rtconfig.LFLAGS))
+    make.write('\n')
+    if 'CXXFLAGS' in dir(rtconfig):
+        make.write('CXXFLAGS :=%s' % (rtconfig.CXXFLAGS))
+        make.write('\n')
+
+    make.write('\n')
+
+    Files   = project['FILES']
+    Headers = project['HEADERS']
+    CPPDEFINES = project['CPPDEFINES']
+
+    paths = [os.path.normpath(i) for i in project['CPPPATH']]
+    CPPPATH = []
+    for path in paths:
+        fn = os.path.normpath(path)
+        if match_bsp:
+            if fn.startswith(BSP_ROOT):
+                fn = '$(BSP_ROOT)' + fn.replace(BSP_ROOT, '')
+            elif fn.startswith(RTT_ROOT):
+                fn = '$(RTT_ROOT)' + fn.replace(RTT_ROOT, '')
+        else:
+            if fn.startswith(RTT_ROOT):
+                fn = '$(RTT_ROOT)' + fn.replace(RTT_ROOT, '')
+            elif fn.startswith(BSP_ROOT):
+                fn = '$(BSP_ROOT)' + fn.replace(BSP_ROOT, '')
+
+        CPPPATH.append(fn)
+
+    path = ''
+    paths = CPPPATH
+    for item in paths:
+        path += '\t-I%s \\\n' % item
+
+    make.write('CPPPATHS :=')
+    if path[0] == '\t': path = path[1:]
+    length = len(path)
+    if path[length - 2] == '\\': path = path[:length - 2]
+    make.write(path)
+    make.write('\n')
+    make.write('\n')
+
+    defines = ''
+    for item in project['CPPDEFINES']:
+        defines += ' -D%s' % item
+    make.write('DEFINES :=')
+    make.write(defines)
+    make.write('\n')
+
+    files = Files
+    Files = []
+    for file in files:
+        fn = os.path.normpath(file)
+        if match_bsp:
+            if fn.startswith(BSP_ROOT):
+                fn = '$(BSP_ROOT)' + fn.replace(BSP_ROOT, '')
+            elif fn.startswith(RTT_ROOT):
+                fn = '$(RTT_ROOT)' + fn.replace(RTT_ROOT, '')
+        else:
+            if fn.startswith(RTT_ROOT):
+                fn = '$(RTT_ROOT)' + fn.replace(RTT_ROOT, '')
+            elif fn.startswith(BSP_ROOT):
+                fn = '$(BSP_ROOT)' + fn.replace(BSP_ROOT, '')
+
+        Files.append(fn)
+        # print(fn)
+
+    src = open('src.mk', 'w')
+    files = Files
+    src.write('SRC_FILES :=\n')
+    for item in files:
+        src.write('SRC_FILES +=%s\n' % item)
+
+    return

+ 122 - 0
tools/rtthread.mk

@@ -0,0 +1,122 @@
+$(if $(strip $(TARGET)),,$(error TARGET not defined))
+$(if $(strip $(SRC_FILES)),,$(error No source files))
+$(if $(strip $(BSP_ROOT)),,$(error BSP_ROOT not defined))
+
+ifneq ($(MAKE_LIB),1)
+BUILD_DIR := $(BSP_ROOT)/build
+endif
+
+$(if $(strip $(BUILD_DIR)),,$(error BUILD_DIR not defined))
+
+RTT_BUILD_DIR := .
+BSP_BUILD_DIR := bsp
+
+#################
+
+define add_c_file
+$(eval C_SRC := $(1:$(BSP_ROOT)/%=%)) \
+$(eval C_SRC := $(C_SRC:$(RTT_ROOT)/%=%)) \
+$(eval COBJ := $(1:%.c=%.o)) \
+$(eval COBJ := $(COBJ:$(BSP_ROOT)/%=$(BSP_BUILD_DIR)/%)) \
+$(eval COBJ := $(COBJ:$(RTT_ROOT)/%=$(RTT_BUILD_DIR)/%)) \
+$(eval LOCALC := $(addprefix $(BUILD_DIR)/,$(COBJ))) \
+$(eval OBJS += $(LOCALC)) \
+$(if $(strip $(LOCALC)),$(eval $(LOCALC): $(C_SRC)
+	@if [ ! -d $$(@D) ]; then mkdir -p $$(@D); fi
+	@echo cc $$<
+	@$(CROSS_COMPILE)gcc $$(CFLAGS) -c $$< -o $$@))
+endef
+
+define add_cxx_file
+$(eval CXX_SRC := $(1:$(BSP_ROOT)/%=%)) \
+$(eval CXX_SRC := $(CXX_SRC:$(RTT_ROOT)/%=%)) \
+$(eval CXXOBJ := $(1:%.cpp=%.o)) \
+$(eval CXXOBJ := $(CXXOBJ:$(BSP_ROOT)/%=$(BSP_BUILD_DIR)/%)) \
+$(eval CXXOBJ := $(CXXOBJ:$(RTT_ROOT)/%=$(RTT_BUILD_DIR)/%)) \
+$(eval LOCALCXX := $(addprefix $(BUILD_DIR)/,$(CXXOBJ))) \
+$(eval OBJS += $(LOCALCXX)) \
+$(if $(strip $(LOCALCXX)),$(eval $(LOCALCXX): $(CXX_SRC)
+	@if [ ! -d $$(@D) ]; then mkdir -p $$(@D); fi
+	@echo cc $$<
+	@$(CROSS_COMPILE)g++ $$(CXXFLAGS) -c $$< -o $$@))
+endef
+
+define add_S_file
+$(eval S_SRC := $(1:$(BSP_ROOT)/%=%)) \
+$(eval S_SRC := $(S_SRC:$(RTT_ROOT)/%=%)) \
+$(eval SOBJ := $(1:%.S=%.o)) \
+$(eval SOBJ := $(SOBJ:$(BSP_ROOT)/%=$(BSP_BUILD_DIR)/%)) \
+$(eval SOBJ := $(SOBJ:$(RTT_ROOT)/%=$(RTT_BUILD_DIR)/%)) \
+$(eval LOCALS := $(addprefix $(BUILD_DIR)/,$(SOBJ))) \
+$(eval OBJS += $(LOCALS)) \
+$(if $(strip $(LOCALS)),$(eval $(LOCALS): $(S_SRC)
+	@if [ ! -d $$(@D) ]; then mkdir -p $$(@D); fi
+	@echo cc $$<
+	@$(CROSS_COMPILE)gcc $$(AFLAGS) -c $$< -o $$@))
+endef
+
+add_flg = $(eval CFLAGS += $1) \
+          $(eval AFLAGS += $1) \
+          $(eval CXXFLAGS += $1)
+
+add_inc = $(eval CFLAGS += -I$1) \
+          $(eval AFLAGS += -I$1) \
+          $(eval CXXFLAGS += -I$1)
+
+add_def = $(eval CFLAGS += -D$1) \
+          $(eval AFLAGS += -D$1) \
+          $(eval CXXFLAGS += -D$1)
+
+OBJS := 
+#VPATH := $(BSP_ROOT) $(RTT_ROOT)
+VPATH := $(RTT_ROOT)
+
+CONFIG_FLG := $(strip $(EXTERN_FLAGS))
+$(if $(CONFIG_FLG),$(foreach f,$(CONFIG_FLG),$(call add_flg,$(f))))
+
+CONFIG_DEF := $(strip $(PROJECT_DEFS))
+$(if $(CONFIG_DEF),$(foreach d,$(CONFIG_DEF),$(call add_def,$(d))))
+
+CONFIG_INC := $(strip $(INCLUDE_PATH))
+$(if $(CONFIG_INC),$(foreach i,$(CONFIG_INC),$(call add_inc,$(i))))
+
+SRCS := $(strip $(filter %.c,$(SRC_FILES)))
+$(if $(SRCS),$(foreach f,$(SRCS),$(call add_c_file,$(f))))
+
+SRCS := $(strip $(filter %.cpp,$(SRC_FILES)))
+$(if $(SRCS),$(foreach f,$(SRCS),$(call add_cxx_file,$(f))))
+
+SRCS := $(strip $(filter %.S,$(SRC_FILES)))
+$(if $(SRCS),$(foreach f,$(SRCS),$(call add_S_file,$(f))))
+
+CFLAGS += $(CPPPATHS)
+CXXFLAGS += $(CPPPATHS)
+AFLAGS += $(CPPPATHS)
+
+CFLAGS += $(DEFINES)
+CXXFLAGS += $(DEFINES)
+AFLAGS += $(DEFINES)
+
+all: $(TARGET)
+
+ifeq ($(MAKE_LIB),1)
+$(TARGET): $(OBJS)
+	@echo ------------------------------------------------
+	@echo ar $(TARGET)
+	@$(CROSS_COMPILE)ar -rv $@ $(OBJS)
+else
+$(TARGET): $(OBJS) $(EXTERN_LIB)
+	@echo ------------------------------------------------
+	@echo link $(TARGET)
+	@$(CROSS_COMPILE)g++ -o $@ $(LFLAGS) $(OBJS) $(EXTERN_LIB) -lc -lm
+	@echo ------------------------------------------------
+	@$(CROSS_COMPILE)objcopy -O binary $@ rtthread.bin
+	@$(CROSS_COMPILE)size $@
+endif
+
+phony += clean
+clean:
+	@echo clean
+	@rm -rf $(TARGET) $(BUILD_DIR)
+
+.PHONY: $(phony)