diff --git a/bsp/es32f0334/.config b/bsp/es32f0334/.config index b49063d9fce9fab1bed60b1ad2cf019a709b50c1..293b4810e0bcb4132131f6d9c7fbc90524a04edc 100644 --- a/bsp/es32f0334/.config +++ b/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 # diff --git a/bsp/es32f0334/README.md b/bsp/es32f0334/README.md index ba41b0ef9690162b70f7002c551628f453ea53f9..086d941d7e6eb89b847dde85339483484b8948fd 100644 --- a/bsp/es32f0334/README.md +++ b/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/) diff --git a/bsp/es32f0334/drivers/Kconfig b/bsp/es32f0334/drivers/Kconfig index 68ac89c99873c4a83acfecac1259b4f8026b4b93..6f91a318d6c42012713433499a15f6f3934e852d 100644 --- a/bsp/es32f0334/drivers/Kconfig +++ b/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" diff --git a/bsp/es32f0334/drivers/SConscript b/bsp/es32f0334/drivers/SConscript index a52e6f193db94af93468173a52ad0a004447a8bd..99e346538815f80b966027f92fd8d16cf4c509b8 100644 --- a/bsp/es32f0334/drivers/SConscript +++ b/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) diff --git a/bsp/es32f0334/drivers/drv_hwtimer.c b/bsp/es32f0334/drivers/drv_hwtimer.c new file mode 100644 index 0000000000000000000000000000000000000000..457c263f305d07b7804fbb78c4da4f891320ceaa --- /dev/null +++ b/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 +#include +#include +#include +#include +#include +#include + +#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 diff --git a/bsp/es32f0334/drivers/drv_hwtimer.h b/bsp/es32f0334/drivers/drv_hwtimer.h new file mode 100644 index 0000000000000000000000000000000000000000..e18d580fbdd3673553d6a7b568d07ea88c1b4c48 --- /dev/null +++ b/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 diff --git a/bsp/es32f0334/rtconfig.h b/bsp/es32f0334/rtconfig.h index 36c6a2e25600a13e9baf3307483d18b3d15af541..d081a962cded87941e3409c6df1096d2cd4ed49f 100644 --- a/bsp/es32f0334/rtconfig.h +++ b/bsp/es32f0334/rtconfig.h @@ -172,6 +172,9 @@ /* PWM Drivers */ +/* HWtimer Drivers */ + + /* Onboard Peripheral Drivers */ diff --git a/bsp/es32f0654/.config b/bsp/es32f0654/.config index 10825f5a19284ef5e79074cc27e58a504ad8fe2f..f0af98f0acb50368d2b205459e5b3b2814f47661 100644 --- a/bsp/es32f0654/.config +++ b/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 # diff --git a/bsp/es32f0654/README.md b/bsp/es32f0654/README.md index c7cbfa22068d21e40da84d44a2782a4f99263d39..87eb82c118469b7b1993280e96ce3634bbf77117 100644 --- a/bsp/es32f0654/README.md +++ b/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/) diff --git a/bsp/es32f0654/drivers/Kconfig b/bsp/es32f0654/drivers/Kconfig index 248e02dc1468082d80aabc032063288529fb62e9..d5af1bbd9518f0fcf4b57814f2c1895067e69a46 100644 --- a/bsp/es32f0654/drivers/Kconfig +++ b/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" diff --git a/bsp/es32f0654/drivers/SConscript b/bsp/es32f0654/drivers/SConscript index 17484f349158f3d7db0da2fd0c9415bcce59abab..31f75af3b324cfbc9b660b5ad035923b021e39fc 100644 --- a/bsp/es32f0654/drivers/SConscript +++ b/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) diff --git a/bsp/es32f0654/drivers/drv_hwtimer.c b/bsp/es32f0654/drivers/drv_hwtimer.c new file mode 100644 index 0000000000000000000000000000000000000000..6eceab627be96ae7e9b5f2d67c9473f8c2965768 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include +#include + +#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 diff --git a/bsp/es32f0654/drivers/drv_hwtimer.h b/bsp/es32f0654/drivers/drv_hwtimer.h new file mode 100644 index 0000000000000000000000000000000000000000..e18d580fbdd3673553d6a7b568d07ea88c1b4c48 --- /dev/null +++ b/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 diff --git a/bsp/es32f0654/drivers/drv_pwm.c b/bsp/es32f0654/drivers/drv_pwm.c index a64ff5cbd1298f4264c82cd2b8422fe4ef8cf666..4bb747654d2d814520d676417f96d31448931431 100644 --- a/bsp/es32f0654/drivers/drv_pwm.c +++ b/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) diff --git a/bsp/es32f0654/rtconfig.h b/bsp/es32f0654/rtconfig.h index 1e4d3edbfee3a0e9eae0679b8907e7c9b927fd6d..52cb4930e09f4ebb206fe14bfa113e4ef12664e8 100644 --- a/bsp/es32f0654/rtconfig.h +++ b/bsp/es32f0654/rtconfig.h @@ -172,6 +172,9 @@ /* PWM Drivers */ +/* HWtimer Drivers */ + + /* Onboard Peripheral Drivers */ diff --git a/bsp/imx6ul/.config b/bsp/imx6ul/.config new file mode 100644 index 0000000000000000000000000000000000000000..a9299a366bfd7cdf12aa6d2cea79d73b3a61c7aa --- /dev/null +++ b/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 diff --git a/bsp/imx6ul/drivers/board.c b/bsp/imx6ul/drivers/board.c index e53e2405b67b71f5272f7579e4e6d09e6cf3f66c..015a3709c16bf54d82f360db61f592f63a5cfc32 100644 --- a/bsp/imx6ul/drivers/board.c +++ b/bsp/imx6ul/drivers/board.c @@ -20,6 +20,15 @@ #include #include +#include + +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; diff --git a/bsp/imx6ul/platform/SConscript b/bsp/imx6ul/platform/SConscript index 34834e639167c66b03d176f3b6966d6daf6d6b7d..9ba43b14831130bdde4a6bbe00acdf9bb7ecf704 100644 --- a/bsp/imx6ul/platform/SConscript +++ b/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' ] diff --git a/bsp/imx6ul/platform/cpu/gic.c b/bsp/imx6ul/platform/cpu/gic.c deleted file mode 100644 index 2f140e02c64c20e1ddcca30c89d383b27263bc17..0000000000000000000000000000000000000000 --- a/bsp/imx6ul/platform/cpu/gic.c +++ /dev/null @@ -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 -#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 -//////////////////////////////////////////////////////////////////////////////// diff --git a/bsp/imx6ul/platform/cpu/mmu.c b/bsp/imx6ul/platform/cpu/mmu.c deleted file mode 100644 index 0cf20c9942bc484e444fcade8238609c0c95ca8d..0000000000000000000000000000000000000000 --- a/bsp/imx6ul/platform/cpu/mmu.c +++ /dev/null @@ -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, , 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 -//////////////////////////////////////////////////////////////////////////////// diff --git a/bsp/imx6ul/platform/cpu/mmu.h b/bsp/imx6ul/platform/cpu/mmu.h deleted file mode 100644 index 961c17f5412868411c4497d43880fa700df62d51..0000000000000000000000000000000000000000 --- a/bsp/imx6ul/platform/cpu/mmu.h +++ /dev/null @@ -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 -//////////////////////////////////////////////////////////////////////////////// - diff --git a/bsp/imx6ul/platform/cpu/platform.h b/bsp/imx6ul/platform/cpu/platform.h new file mode 100644 index 0000000000000000000000000000000000000000..f6a3995bc5279f7994d2e8dc2d0eb13ce3918a8b --- /dev/null +++ b/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 +#include + +/* 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__ */ diff --git a/bsp/imx6ul/platform/include/gic.h b/bsp/imx6ul/platform/include/gic.h deleted file mode 100644 index f3eee8499c6e2528618fa1ed49ef89e81f43e72a..0000000000000000000000000000000000000000 --- a/bsp/imx6ul/platform/include/gic.h +++ /dev/null @@ -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 -//////////////////////////////////////////////////////////////////////////////// diff --git a/bsp/imx6ul/platform/include/interrupt.h b/bsp/imx6ul/platform/include/interrupt.h deleted file mode 100644 index 318e34f3bd65e1c757a32d4df24e63ac9dcbb7b0..0000000000000000000000000000000000000000 --- a/bsp/imx6ul/platform/include/interrupt.h +++ /dev/null @@ -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 -//////////////////////////////////////////////////////////////////////////////// diff --git a/bsp/imx6ul/rtconfig.py b/bsp/imx6ul/rtconfig.py index 2c08665920bdd2783ee941a6e3c1a332a6888cdd..0a9ea3dce37b5a9826a38e2a35a2ba7772d962e0 100644 --- a/bsp/imx6ul/rtconfig.py +++ b/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') diff --git a/bsp/qemu-vexpress-a9/.config b/bsp/qemu-vexpress-a9/.config index c8814d366aff2060206110ac67f2e454e88c118c..6fde000858ef22e553dd14356e38f18e9d1f25ca 100644 --- a/bsp/qemu-vexpress-a9/.config +++ b/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 diff --git a/bsp/qemu-vexpress-a9/Makefile b/bsp/qemu-vexpress-a9/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f2efa4a561f7bd8742cdf7ded463ca3424c300a5 --- /dev/null +++ b/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 diff --git a/bsp/qemu-vexpress-a9/SConstruct b/bsp/qemu-vexpress-a9/SConstruct index 638311d6977e1b7226d942d76d63626627c7b314..d618790dec9dc03404532b0d749f32356a5f125f 100644 --- a/bsp/qemu-vexpress-a9/SConstruct +++ b/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) diff --git a/bsp/qemu-vexpress-a9/cpu/SConscript b/bsp/qemu-vexpress-a9/cpu/SConscript deleted file mode 100644 index b45f95cc1a5084f4bcfd68bf0a7dd1b1960522e1..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/cpu/SConscript +++ /dev/null @@ -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') diff --git a/bsp/qemu-vexpress-a9/cpu/armv7.h b/bsp/qemu-vexpress-a9/cpu/armv7.h deleted file mode 100644 index 69c556eb3c7eba4d87df16249afb218db576dfb2..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/cpu/armv7.h +++ /dev/null @@ -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 diff --git a/bsp/qemu-vexpress-a9/cpu/context_gcc.S b/bsp/qemu-vexpress-a9/cpu/context_gcc.S deleted file mode 100644 index 0aad0200d558acdf4acbe9a04bb2628867c7e7a9..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/cpu/context_gcc.S +++ /dev/null @@ -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*/ diff --git a/bsp/qemu-vexpress-a9/cpu/cp15.h b/bsp/qemu-vexpress-a9/cpu/cp15.h deleted file mode 100644 index ebea3f0fe307d44979db5b895e8d71d30926c17d..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/cpu/cp15.h +++ /dev/null @@ -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 diff --git a/bsp/qemu-vexpress-a9/cpu/cp15_gcc.S b/bsp/qemu-vexpress-a9/cpu/cp15_gcc.S deleted file mode 100644 index f1ed6492aad55f8f0deb769583e738dc79a8a6f2..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/cpu/cp15_gcc.S +++ /dev/null @@ -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 diff --git a/bsp/qemu-vexpress-a9/cpu/cpuport.c b/bsp/qemu-vexpress-a9/cpu/cpuport.c deleted file mode 100644 index 6b129f89eee4334361781d13c5a3c5409460c5fe..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/cpu/cpuport.c +++ /dev/null @@ -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 -#include -#include - -#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); - } -} - -/*@}*/ diff --git a/bsp/qemu-vexpress-a9/cpu/interrupt.c b/bsp/qemu-vexpress-a9/cpu/interrupt.c deleted file mode 100644 index d7e9ec08fa4531d4088ea31f866a911e8f359e4f..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/cpu/interrupt.c +++ /dev/null @@ -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 -#include -#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; -} diff --git a/bsp/qemu-vexpress-a9/cpu/interrupt.h b/bsp/qemu-vexpress-a9/cpu/interrupt.h deleted file mode 100644 index 045246b21d2fa87816c6a17c95253e8e8b783aac..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/cpu/interrupt.h +++ /dev/null @@ -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 diff --git a/bsp/qemu-vexpress-a9/cpu/mmu.c b/bsp/qemu-vexpress-a9/cpu/mmu.c deleted file mode 100644 index b2503e4260c77ece6e044a68d5ea6d2802a793f2..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/cpu/mmu.c +++ /dev/null @@ -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 -#include -#include - -#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(); -} - diff --git a/bsp/qemu-vexpress-a9/cpu/pmu.c b/bsp/qemu-vexpress-a9/cpu/pmu.c deleted file mode 100644 index 07911a2db721bd1c82cffbb2d8f4816393663b91..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/cpu/pmu.c +++ /dev/null @@ -1,12 +0,0 @@ -#include -#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)); -} diff --git a/bsp/qemu-vexpress-a9/cpu/pmu.h b/bsp/qemu-vexpress-a9/cpu/pmu.h deleted file mode 100644 index 05c1420dd8fbf7a7177ea1bd4699750690c3b720..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/cpu/pmu.h +++ /dev/null @@ -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__ */ - diff --git a/bsp/qemu-vexpress-a9/cpu/stack.c b/bsp/qemu-vexpress-a9/cpu/stack.c deleted file mode 100644 index dfb97557bc006d5350096b7adf766b8f15c9dd2e..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/cpu/stack.c +++ /dev/null @@ -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 -#include - -/** - * @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; -} - -/*@}*/ diff --git a/bsp/qemu-vexpress-a9/cpu/start_gcc.S b/bsp/qemu-vexpress-a9/cpu/start_gcc.S deleted file mode 100644 index b71d8a15683999a582432b87ca4588422d4a1e84..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/cpu/start_gcc.S +++ /dev/null @@ -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 diff --git a/bsp/qemu-vexpress-a9/cpu/trap.c b/bsp/qemu-vexpress-a9/cpu/trap.c deleted file mode 100644 index a1f00d00755a2b9bf80772cb7f81b10a41f22ae2..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/cpu/trap.c +++ /dev/null @@ -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 -#include -#include - -#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); -} - diff --git a/bsp/qemu-vexpress-a9/cpu/vector_gcc.S b/bsp/qemu-vexpress-a9/cpu/vector_gcc.S deleted file mode 100644 index 2473e1f850464649e9fcfc9a1e267f50f8ce60d5..0000000000000000000000000000000000000000 --- a/bsp/qemu-vexpress-a9/cpu/vector_gcc.S +++ /dev/null @@ -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 diff --git a/bsp/qemu-vexpress-a9/drivers/board.c b/bsp/qemu-vexpress-a9/drivers/board.c index 6ffac7efd74aa981636ae11919d82dd32bbe9629..e236c68b80b1f611bd8fe51b714228d8998ed7c4 100644 --- a/bsp/qemu-vexpress-a9/drivers/board.c +++ b/bsp/qemu-vexpress-a9/drivers/board.c @@ -17,6 +17,15 @@ #include "board.h" #include "drv_timer.h" +#include + +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); diff --git a/bsp/qemu-vexpress-a9/platform/SConscript b/bsp/qemu-vexpress-a9/platform/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..1b580929dac4f7d540c3484014fc4070c5b390cb --- /dev/null +++ b/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') diff --git a/bsp/qemu-vexpress-a9/platform/cpu/platform.h b/bsp/qemu-vexpress-a9/platform/cpu/platform.h new file mode 100644 index 0000000000000000000000000000000000000000..2d5cc5f61b6cd24b186213ad64e958158407a8fc --- /dev/null +++ b/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 +/* 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__ */ diff --git a/bsp/qemu-vexpress-a9/rtconfig.h b/bsp/qemu-vexpress-a9/rtconfig.h index b6c3399da37758779072795968169e7727c39b0c..831d54c52f67962edab25a32de36e7cd1ef7ca79 100644 --- a/bsp/qemu-vexpress-a9/rtconfig.h +++ b/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 diff --git a/bsp/qemu-vexpress-a9/rtconfig.py b/bsp/qemu-vexpress-a9/rtconfig.py index 8ccd0227e456f9d5ee2a738f12e0c4c9bc936f0c..d4176738985bb9d76cb545208f761bbff59fd5c9 100644 --- a/bsp/qemu-vexpress-a9/rtconfig.py +++ b/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') diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_common.c b/bsp/stm32/libraries/HAL_Drivers/drv_common.c index 350c3fab40fafca7f5b75a301494ee3a21261333..9bffc026e404041a14b980e53591e1becc096671 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_common.c +++ b/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); } /** diff --git a/components/lwp/SConscript b/components/lwp/SConscript index d3b799257bac9242aad9d21b25e7ff93e7713278..f151f3b92e17146f34b8ce69718ec42f71452fd2 100644 --- a/components/lwp/SConscript +++ b/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 diff --git a/components/lwp/arch/arm/cortex-a/lwp_gcc.S b/components/lwp/arch/arm/cortex-a/lwp_gcc.S new file mode 100644 index 0000000000000000000000000000000000000000..6c89152b0c86bc395cd90cb35593f7790e7e3c25 --- /dev/null +++ b/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 diff --git a/libcpu/arm/cortex-a/context_gcc.S b/libcpu/arm/cortex-a/context_gcc.S index 97b3dbc4475d81a1eebe07f17c68f44a469df509..b009630fa8a8fc24ce780a7f70d92d707dab1392 100644 --- a/libcpu/arm/cortex-a/context_gcc.S +++ b/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*/ diff --git a/libcpu/arm/cortex-a/cp15.h b/libcpu/arm/cortex-a/cp15.h index 486f38200d942dd0f4e0dcb9d753fcdd271b464b..97c5b93ad24a1bf21488f6b9d3fa0664b0ab73d7 100644 --- a/libcpu/arm/cortex-a/cp15.h +++ b/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 diff --git a/libcpu/arm/cortex-a/cp15_gcc.S b/libcpu/arm/cortex-a/cp15_gcc.S index 0e3e60655c8963ac0023e48260641d52adb8a5e5..dd2436ffee75919e0b9c6a7a52b9d3b9c3150fee 100644 --- a/libcpu/arm/cortex-a/cp15_gcc.S +++ b/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} diff --git a/libcpu/arm/cortex-a/cpu.c b/libcpu/arm/cortex-a/cpu.c index 2d7871501160a78edc7f1687d426f08de359a508..6b129f89eee4334361781d13c5a3c5409460c5fe 100644 --- a/libcpu/arm/cortex-a/cpu.c +++ b/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 #include #include +#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); + } } /*@}*/ diff --git a/bsp/qemu-vexpress-a9/cpu/gic.c b/libcpu/arm/cortex-a/gic.c similarity index 92% rename from bsp/qemu-vexpress-a9/cpu/gic.c rename to libcpu/arm/cortex-a/gic.c index 66876518ce90fc1b2d7d7c23bc9edc66f1391e73..2a46142b54cde9c6a528db9f3260a6d62da7d349 100644 --- a/bsp/qemu-vexpress-a9/cpu/gic.c +++ b/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 #include -#include #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; diff --git a/bsp/qemu-vexpress-a9/cpu/gic.h b/libcpu/arm/cortex-a/gic.h similarity index 67% rename from bsp/qemu-vexpress-a9/cpu/gic.h rename to libcpu/arm/cortex-a/gic.h index 9d0368ec943536e075ce68632ae90bf8d4872a3b..6d86dd31e00b746249fbbe4c2d2eddd0b786c0e8 100644 --- a/bsp/qemu-vexpress-a9/cpu/gic.h +++ b/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 +#include + 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 diff --git a/libcpu/arm/cortex-a/interrupt.c b/libcpu/arm/cortex-a/interrupt.c index fb6e3ff3e06f53dd7fa9a3ba7ccf7e6508a4424e..b7a70719a9024741d0d39e10af0f3551780c274f 100644 --- a/libcpu/arm/cortex-a/interrupt.c +++ b/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 #include +#include "interrupt.h" +#include "gic.h" -#include -#include - -#include -#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); -} diff --git a/libcpu/arm/cortex-a/interrupt.h b/libcpu/arm/cortex-a/interrupt.h new file mode 100644 index 0000000000000000000000000000000000000000..bff29d402de23fda65b1fb9e1b550062f426fa94 --- /dev/null +++ b/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 +#include + +#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 diff --git a/libcpu/arm/cortex-a/mmu.c b/libcpu/arm/cortex-a/mmu.c index 58acdd81458f7e2dd619d4f3e0fbaff445a3b276..1260f41fe52dbac75f9bb0d2f6ec6e17a8a27305 100644 --- a/libcpu/arm/cortex-a/mmu.c +++ b/libcpu/arm/cortex-a/mmu.c @@ -13,35 +13,7 @@ #include #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); diff --git a/libcpu/arm/cortex-a/mmu.h b/libcpu/arm/cortex-a/mmu.h new file mode 100644 index 0000000000000000000000000000000000000000..deec690c6992e54d90ba3820e42366e9e8b0e342 --- /dev/null +++ b/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 + +#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 diff --git a/libcpu/arm/cortex-a/stack.c b/libcpu/arm/cortex-a/stack.c index 1d3ebcb9e6ec7c1961a371cec8dde0eac2c8483f..d76b8a428a8d332e9c6a244cf2e3d7160b2f629e 100644 --- a/libcpu/arm/cortex-a/stack.c +++ b/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; } diff --git a/libcpu/arm/cortex-a/start_gcc.S b/libcpu/arm/cortex-a/start_gcc.S index 2f16d168075ccab2b00a194fb76ec3b70fcb776f..0f4ff58364676d137fc4877eb7c070de61aa0a34 100644 --- a/libcpu/arm/cortex-a/start_gcc.S +++ b/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: + diff --git a/libcpu/arm/cortex-a/trap.c b/libcpu/arm/cortex-a/trap.c index f3b2c26e6d531ca8de8a53c55fa1947cb3029d76..54628933ff2a51a5cf89771da67f90424c279fb8 100644 --- a/libcpu/arm/cortex-a/trap.c +++ b/libcpu/arm/cortex-a/trap.c @@ -10,13 +10,11 @@ #include #include -#include +#include #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); } + diff --git a/libcpu/mips/xburst/SConscript.1 b/libcpu/mips/xburst/SConscript.1 deleted file mode 100644 index b0ae20ba0298e00e05eba2ddc73df9424d22ec79..0000000000000000000000000000000000000000 --- a/libcpu/mips/xburst/SConscript.1 +++ /dev/null @@ -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') diff --git a/src/kservice.c b/src/kservice.c index 36637662253261c2fd8a95b5d41611311b175513..c940e86d0b254db291a92dab70d9b64c02d7ab00 100644 --- a/src/kservice.c +++ b/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; diff --git a/tools/building.py b/tools/building.py index 978c0f7237bcd8bf3d377356a7ef75f22bce485e..4da64f6fcfc569fa5eed21120049422e982fb4de 100644 --- a/tools/building.py +++ b/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 diff --git a/tools/eclipse.py b/tools/eclipse.py new file mode 100644 index 0000000000000000000000000000000000000000..dc86c7be5a05cfe693c73b53134b9e7586df0a3f --- /dev/null +++ b/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('\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('\n') + out.write('') + xml_indent(root) + out.write(etree.tostring(root, encoding='utf-8')) + out.close() + + print('done!') + + return diff --git a/tools/makefile.py b/tools/makefile.py new file mode 100644 index 0000000000000000000000000000000000000000..9292233601c8396dc3937efe963d137c90021324 --- /dev/null +++ b/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 diff --git a/tools/rtthread.mk b/tools/rtthread.mk new file mode 100644 index 0000000000000000000000000000000000000000..fdc96d4156a35b0b136081412a4d4e69bd31b10c --- /dev/null +++ b/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)