Merge branch 'master' of https://github.com/RT-Thread/rt-thread
This commit is contained in:
commit
8327200072
|
@ -344,6 +344,14 @@ CONFIG_BSP_USING_UART1=y
|
||||||
# CONFIG_BSP_USING_PWM2 is not set
|
# CONFIG_BSP_USING_PWM2 is not set
|
||||||
# CONFIG_BSP_USING_PWM3 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
|
# Onboard Peripheral Drivers
|
||||||
#
|
#
|
||||||
|
|
|
@ -42,6 +42,7 @@ ES-PDS-ES32F0334-V1.1
|
||||||
| SPI | 支持 | SPI0/1 |
|
| SPI | 支持 | SPI0/1 |
|
||||||
| I2C | 支持 | I2C0/1 |
|
| I2C | 支持 | I2C0/1 |
|
||||||
| PWM | 支持 | PWM0/1/2/3 |
|
| PWM | 支持 | PWM0/1/2/3 |
|
||||||
|
| TIMER | 支持 | TIMER0/1/2/3 |
|
||||||
|
|
||||||
更多详细信息请咨询[上海东软载波微电子技术支持](http://www.essemi.com/)
|
更多详细信息请咨询[上海东软载波微电子技术支持](http://www.essemi.com/)
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,29 @@ menu "Hardware Drivers Config"
|
||||||
select RT_USING_PWM
|
select RT_USING_PWM
|
||||||
default n
|
default n
|
||||||
endmenu
|
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
|
endmenu
|
||||||
|
|
||||||
menu "Onboard Peripheral Drivers"
|
menu "Onboard Peripheral Drivers"
|
||||||
|
|
|
@ -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'):
|
if GetDepend('BSP_USING_PWM0') or GetDepend('BSP_USING_PWM1') or GetDepend('BSP_USING_PWM2') or GetDepend('BSP_USING_PWM3'):
|
||||||
src += ['drv_pwm.c']
|
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]
|
CPPPATH = [cwd]
|
||||||
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
|
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,250 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2019-3-19 wangyq the first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
#include <drv_hwtimer.h>
|
||||||
|
#include <board.h>
|
||||||
|
#include <ald_cmu.h>
|
||||||
|
#include <ald_timer.h>
|
||||||
|
|
||||||
|
#ifdef RT_USING_HWTIMER
|
||||||
|
|
||||||
|
struct es32f0_hwtimer_dev
|
||||||
|
{
|
||||||
|
rt_hwtimer_t parent;
|
||||||
|
timer_handle_t *hwtimer_periph;
|
||||||
|
IRQn_Type IRQn;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef BSP_USING_HWTIMER0
|
||||||
|
static struct es32f0_hwtimer_dev hwtimer0;
|
||||||
|
|
||||||
|
void BS16T0_Handler(void)
|
||||||
|
{
|
||||||
|
timer_clear_flag_status(hwtimer0.hwtimer_periph, TIMER_FLAG_UPDATE);
|
||||||
|
rt_device_hwtimer_isr(&hwtimer0.parent);
|
||||||
|
|
||||||
|
if (HWTIMER_MODE_ONESHOT == hwtimer0.parent.mode)
|
||||||
|
{
|
||||||
|
timer_base_stop(hwtimer0.hwtimer_periph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_HWTIMER1
|
||||||
|
static struct es32f0_hwtimer_dev hwtimer1;
|
||||||
|
|
||||||
|
void BS16T1_UART2_Handler(void)
|
||||||
|
{
|
||||||
|
if (timer_get_it_status(hwtimer1.hwtimer_periph, TIMER_IT_UPDATE) &&
|
||||||
|
timer_get_flag_status(hwtimer1.hwtimer_periph, TIMER_FLAG_UPDATE))
|
||||||
|
{
|
||||||
|
timer_clear_flag_status(hwtimer1.hwtimer_periph, TIMER_FLAG_UPDATE);
|
||||||
|
rt_device_hwtimer_isr(&hwtimer1.parent);
|
||||||
|
|
||||||
|
if (HWTIMER_MODE_ONESHOT == hwtimer1.parent.mode)
|
||||||
|
{
|
||||||
|
timer_base_stop(hwtimer1.hwtimer_periph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_HWTIMER2
|
||||||
|
static struct es32f0_hwtimer_dev hwtimer2;
|
||||||
|
|
||||||
|
void BS16T2_UART3_Handler(void)
|
||||||
|
{
|
||||||
|
if (timer_get_it_status(hwtimer2.hwtimer_periph, TIMER_IT_UPDATE) &&
|
||||||
|
timer_get_flag_status(hwtimer2.hwtimer_periph, TIMER_FLAG_UPDATE))
|
||||||
|
{
|
||||||
|
timer_clear_flag_status(hwtimer2.hwtimer_periph, TIMER_FLAG_UPDATE);
|
||||||
|
rt_device_hwtimer_isr(&hwtimer2.parent);
|
||||||
|
|
||||||
|
if (HWTIMER_MODE_ONESHOT == hwtimer2.parent.mode)
|
||||||
|
{
|
||||||
|
timer_base_stop(hwtimer2.hwtimer_periph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_HWTIMER3
|
||||||
|
static struct es32f0_hwtimer_dev hwtimer3;
|
||||||
|
/* can not use when DAC0 Handler is enabled */
|
||||||
|
void BS16T3_DAC0_Handler(void)
|
||||||
|
{
|
||||||
|
/* if BS16T3 it */
|
||||||
|
if (timer_get_it_status(hwtimer3.hwtimer_periph, TIMER_IT_UPDATE) &&
|
||||||
|
timer_get_flag_status(hwtimer3.hwtimer_periph, TIMER_FLAG_UPDATE))
|
||||||
|
{
|
||||||
|
timer_clear_flag_status(hwtimer3.hwtimer_periph, TIMER_FLAG_UPDATE);
|
||||||
|
rt_device_hwtimer_isr(&hwtimer3.parent);
|
||||||
|
|
||||||
|
if (HWTIMER_MODE_ONESHOT == hwtimer3.parent.mode)
|
||||||
|
{
|
||||||
|
timer_base_stop(hwtimer3.hwtimer_periph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct rt_hwtimer_info es32f0_hwtimer_info =
|
||||||
|
{
|
||||||
|
48000000, /* maximum count frequency */
|
||||||
|
1, /* minimum count frequency */
|
||||||
|
65535, /* counter maximum value */
|
||||||
|
HWTIMER_CNTMODE_UP
|
||||||
|
};
|
||||||
|
|
||||||
|
static void es32f0_hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state)
|
||||||
|
{
|
||||||
|
struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
|
||||||
|
|
||||||
|
RT_ASSERT(hwtimer != RT_NULL);
|
||||||
|
|
||||||
|
if (1 == state)
|
||||||
|
{
|
||||||
|
timer_base_init(hwtimer->hwtimer_periph);
|
||||||
|
timer_interrupt_config(hwtimer->hwtimer_periph, TIMER_IT_UPDATE, ENABLE);
|
||||||
|
NVIC_EnableIRQ(hwtimer->IRQn);
|
||||||
|
}
|
||||||
|
hwtimer->parent.freq = cmu_get_pclk1_clock();
|
||||||
|
es32f0_hwtimer_info.maxfreq = cmu_get_pclk1_clock();
|
||||||
|
es32f0_hwtimer_info.minfreq = cmu_get_pclk1_clock();
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t es32f0_hwtimer_start(rt_hwtimer_t *timer,
|
||||||
|
rt_uint32_t cnt,
|
||||||
|
rt_hwtimer_mode_t mode)
|
||||||
|
{
|
||||||
|
struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
|
||||||
|
|
||||||
|
RT_ASSERT(hwtimer != RT_NULL);
|
||||||
|
|
||||||
|
WRITE_REG(hwtimer->hwtimer_periph->perh->AR, cnt);
|
||||||
|
timer_base_start(hwtimer->hwtimer_periph);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void es32f0_hwtimer_stop(rt_hwtimer_t *timer)
|
||||||
|
{
|
||||||
|
struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
|
||||||
|
|
||||||
|
RT_ASSERT(hwtimer != RT_NULL);
|
||||||
|
|
||||||
|
timer_base_stop(hwtimer->hwtimer_periph);
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_uint32_t es32f0_hwtimer_count_get(rt_hwtimer_t *timer)
|
||||||
|
{
|
||||||
|
struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
|
||||||
|
uint32_t hwtimer_count = 0;
|
||||||
|
|
||||||
|
RT_ASSERT(hwtimer != RT_NULL);
|
||||||
|
|
||||||
|
hwtimer_count = READ_REG(hwtimer->hwtimer_periph->perh->COUNT);
|
||||||
|
|
||||||
|
return hwtimer_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t es32f0_hwtimer_control(rt_hwtimer_t *timer,
|
||||||
|
rt_uint32_t cmd,
|
||||||
|
void *args)
|
||||||
|
{
|
||||||
|
rt_err_t ret = RT_EOK;
|
||||||
|
rt_uint32_t freq = 0;
|
||||||
|
struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
|
||||||
|
|
||||||
|
RT_ASSERT(hwtimer != RT_NULL);
|
||||||
|
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case HWTIMER_CTRL_FREQ_SET:
|
||||||
|
freq = *(rt_uint32_t *)args;
|
||||||
|
if (freq != cmu_get_pclk1_clock())
|
||||||
|
{
|
||||||
|
ret = -RT_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HWTIMER_CTRL_STOP:
|
||||||
|
timer_base_stop(hwtimer->hwtimer_periph);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ret = RT_EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct rt_hwtimer_ops es32f0_hwtimer_ops =
|
||||||
|
{
|
||||||
|
es32f0_hwtimer_init,
|
||||||
|
es32f0_hwtimer_start,
|
||||||
|
es32f0_hwtimer_stop,
|
||||||
|
es32f0_hwtimer_count_get,
|
||||||
|
es32f0_hwtimer_control
|
||||||
|
};
|
||||||
|
|
||||||
|
int rt_hw_hwtimer_init(void)
|
||||||
|
{
|
||||||
|
rt_err_t ret = RT_EOK;
|
||||||
|
|
||||||
|
#ifdef BSP_USING_HWTIMER0
|
||||||
|
static timer_handle_t _hwtimer_periph0;
|
||||||
|
_hwtimer_periph0.perh = BS16T0;
|
||||||
|
hwtimer0.IRQn = BS16T0_IRQn;
|
||||||
|
hwtimer0.hwtimer_periph = &_hwtimer_periph0;
|
||||||
|
hwtimer0.parent.info = &es32f0_hwtimer_info;
|
||||||
|
hwtimer0.parent.ops = &es32f0_hwtimer_ops;
|
||||||
|
ret = rt_device_hwtimer_register(&hwtimer0.parent, "timer0", &hwtimer0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_HWTIMER1
|
||||||
|
static timer_handle_t _hwtimer_periph1;
|
||||||
|
_hwtimer_periph1.perh = BS16T1;
|
||||||
|
hwtimer1.IRQn = BS16T1_UART2_IRQn;
|
||||||
|
hwtimer1.hwtimer_periph = &_hwtimer_periph1;
|
||||||
|
hwtimer1.parent.info = &es32f0_hwtimer_info;
|
||||||
|
hwtimer1.parent.ops = &es32f0_hwtimer_ops;
|
||||||
|
ret = rt_device_hwtimer_register(&hwtimer1.parent, "timer1", &hwtimer1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_HWTIMER2
|
||||||
|
static timer_handle_t _hwtimer_periph2;
|
||||||
|
_hwtimer_periph2.perh = BS16T2;
|
||||||
|
hwtimer2.IRQn = BS16T2_UART3_IRQn;
|
||||||
|
hwtimer2.hwtimer_periph = &_hwtimer_periph2;
|
||||||
|
hwtimer2.parent.info = &es32f0_hwtimer_info;
|
||||||
|
hwtimer2.parent.ops = &es32f0_hwtimer_ops;
|
||||||
|
ret = rt_device_hwtimer_register(&hwtimer2.parent, "timer2", &hwtimer2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_HWTIMER3
|
||||||
|
static timer_handle_t _hwtimer_periph3;
|
||||||
|
_hwtimer_periph3.perh = BS16T3;
|
||||||
|
hwtimer3.IRQn = BS16T3_DAC0_IRQn;
|
||||||
|
hwtimer3.hwtimer_periph = &_hwtimer_periph3;
|
||||||
|
hwtimer3.parent.info = &es32f0_hwtimer_info;
|
||||||
|
hwtimer3.parent.ops = &es32f0_hwtimer_ops;
|
||||||
|
ret = rt_device_hwtimer_register(&hwtimer3.parent, "timer3", &hwtimer3);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
INIT_BOARD_EXPORT(rt_hw_hwtimer_init);
|
||||||
|
|
||||||
|
#endif
|
|
@ -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
|
|
@ -172,6 +172,9 @@
|
||||||
/* PWM Drivers */
|
/* PWM Drivers */
|
||||||
|
|
||||||
|
|
||||||
|
/* HWtimer Drivers */
|
||||||
|
|
||||||
|
|
||||||
/* Onboard Peripheral Drivers */
|
/* Onboard Peripheral Drivers */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -346,6 +346,14 @@ CONFIG_BSP_USING_UART2=y
|
||||||
# CONFIG_BSP_USING_PWM2 is not set
|
# CONFIG_BSP_USING_PWM2 is not set
|
||||||
# CONFIG_BSP_USING_PWM3 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
|
# Onboard Peripheral Drivers
|
||||||
#
|
#
|
||||||
|
|
|
@ -35,14 +35,17 @@ ES-PDS-ES32F0654-V1.1
|
||||||
| **板载外设** | **支持情况** | **备注** |
|
| **板载外设** | **支持情况** | **备注** |
|
||||||
| :---------------- | :----------: | :------------------------------------|
|
| :---------------- | :----------: | :------------------------------------|
|
||||||
| SPI FLASH | 支持 | SPI0 |
|
| SPI FLASH | 支持 | SPI0 |
|
||||||
|
|
||||||
| **片上外设** | **支持情况** | **备注** |
|
| **片上外设** | **支持情况** | **备注** |
|
||||||
| :---------------- | :----------: | :------------------------------------|
|
|
||||||
| GPIO | 支持 | 54 GPIOs |
|
| GPIO | 支持 | 54 GPIOs |
|
||||||
| UART | 支持 | UART0/1/2/3 |
|
| UART | 支持 | UART0/1/2/3 |
|
||||||
| SPI | 支持 | SPI0/1 |
|
| SPI | 支持 | SPI0/1 |
|
||||||
| I2C | 支持 | I2C0/1 |
|
| I2C | 支持 | I2C0/1 |
|
||||||
| PWM | 支持 | PWM0/1/2/3 |
|
| PWM | 支持 | PWM0/1/2/3 |
|
||||||
|
| TIMER | 支持 | TIMER0/1/2/3 |
|
||||||
|
|
||||||
|
### 1.2 注意事项
|
||||||
|
|
||||||
|
- 本BSP中,UART2和TIMER1不能同时使用,UART3和TIMER2不能同时使用
|
||||||
|
|
||||||
更多详细信息请咨询[上海东软载波微电子技术支持](http://www.essemi.com/)
|
更多详细信息请咨询[上海东软载波微电子技术支持](http://www.essemi.com/)
|
||||||
|
|
||||||
|
|
|
@ -21,11 +21,13 @@ menu "Hardware Drivers Config"
|
||||||
bool "Enable UART2 PC12/PD02(T/R)"
|
bool "Enable UART2 PC12/PD02(T/R)"
|
||||||
select RT_USING_SERIAL
|
select RT_USING_SERIAL
|
||||||
default y
|
default y
|
||||||
|
depends on !BSP_USING_HWTIMER1
|
||||||
|
|
||||||
config BSP_USING_UART3
|
config BSP_USING_UART3
|
||||||
bool "Enable UART3 PC04/PC05(T/R)"
|
bool "Enable UART3 PC04/PC05(T/R)"
|
||||||
select RT_USING_SERIAL
|
select RT_USING_SERIAL
|
||||||
default n
|
default n
|
||||||
|
depends on !BSP_USING_HWTIMER2
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "SPI Drivers"
|
menu "SPI Drivers"
|
||||||
|
@ -47,6 +49,7 @@ menu "Hardware Drivers Config"
|
||||||
bool "Enable I2C0 BUS PB08/PB09(SCL/SDA)"
|
bool "Enable I2C0 BUS PB08/PB09(SCL/SDA)"
|
||||||
select RT_USING_I2C
|
select RT_USING_I2C
|
||||||
default n
|
default n
|
||||||
|
|
||||||
config BSP_USING_I2C1
|
config BSP_USING_I2C1
|
||||||
bool "Enable I2C1 BUS PB10/PB11(SCL/SDA)"
|
bool "Enable I2C1 BUS PB10/PB11(SCL/SDA)"
|
||||||
select RT_USING_I2C
|
select RT_USING_I2C
|
||||||
|
@ -74,6 +77,31 @@ menu "Hardware Drivers Config"
|
||||||
select RT_USING_PWM
|
select RT_USING_PWM
|
||||||
default n
|
default n
|
||||||
endmenu
|
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
|
endmenu
|
||||||
|
|
||||||
menu "Onboard Peripheral Drivers"
|
menu "Onboard Peripheral Drivers"
|
||||||
|
|
|
@ -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'):
|
if GetDepend('BSP_USING_PWM0') or GetDepend('BSP_USING_PWM1') or GetDepend('BSP_USING_PWM2') or GetDepend('BSP_USING_PWM3'):
|
||||||
src += ['drv_pwm.c']
|
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]
|
CPPPATH = [cwd]
|
||||||
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
|
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,252 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2019-3-19 wangyq the first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
#include <drv_hwtimer.h>
|
||||||
|
#include <board.h>
|
||||||
|
#include <ald_cmu.h>
|
||||||
|
#include <ald_timer.h>
|
||||||
|
|
||||||
|
#ifdef RT_USING_HWTIMER
|
||||||
|
|
||||||
|
struct es32f0_hwtimer_dev
|
||||||
|
{
|
||||||
|
rt_hwtimer_t parent;
|
||||||
|
timer_handle_t *hwtimer_periph;
|
||||||
|
IRQn_Type IRQn;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef BSP_USING_HWTIMER0
|
||||||
|
static struct es32f0_hwtimer_dev hwtimer0;
|
||||||
|
|
||||||
|
void BS16T0_Handler(void)
|
||||||
|
{
|
||||||
|
timer_clear_flag_status(hwtimer0.hwtimer_periph, TIMER_FLAG_UPDATE);
|
||||||
|
rt_device_hwtimer_isr(&hwtimer0.parent);
|
||||||
|
|
||||||
|
if (HWTIMER_MODE_ONESHOT == hwtimer0.parent.mode)
|
||||||
|
{
|
||||||
|
timer_base_stop(hwtimer0.hwtimer_periph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_HWTIMER1
|
||||||
|
static struct es32f0_hwtimer_dev hwtimer1;
|
||||||
|
/* can not use when UART2 Handler is enabled */
|
||||||
|
void BS16T1_UART2_Handler(void)
|
||||||
|
{
|
||||||
|
/* if BS16T1 it */
|
||||||
|
if (timer_get_it_status(hwtimer1.hwtimer_periph, TIMER_IT_UPDATE) &&
|
||||||
|
timer_get_flag_status(hwtimer1.hwtimer_periph, TIMER_FLAG_UPDATE))
|
||||||
|
{
|
||||||
|
timer_clear_flag_status(hwtimer1.hwtimer_periph, TIMER_FLAG_UPDATE);
|
||||||
|
rt_device_hwtimer_isr(&hwtimer1.parent);
|
||||||
|
|
||||||
|
if (HWTIMER_MODE_ONESHOT == hwtimer1.parent.mode)
|
||||||
|
{
|
||||||
|
timer_base_stop(hwtimer1.hwtimer_periph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_HWTIMER2
|
||||||
|
static struct es32f0_hwtimer_dev hwtimer2;
|
||||||
|
/* can not use when UART3 Handler is enabled */
|
||||||
|
void BS16T2_UART3_Handler(void)
|
||||||
|
{
|
||||||
|
/* if BS16T2 it */
|
||||||
|
if (timer_get_it_status(hwtimer2.hwtimer_periph, TIMER_IT_UPDATE) &&
|
||||||
|
timer_get_flag_status(hwtimer2.hwtimer_periph, TIMER_FLAG_UPDATE))
|
||||||
|
{
|
||||||
|
timer_clear_flag_status(hwtimer2.hwtimer_periph, TIMER_FLAG_UPDATE);
|
||||||
|
rt_device_hwtimer_isr(&hwtimer2.parent);
|
||||||
|
|
||||||
|
if (HWTIMER_MODE_ONESHOT == hwtimer2.parent.mode)
|
||||||
|
{
|
||||||
|
timer_base_stop(hwtimer2.hwtimer_periph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_HWTIMER3
|
||||||
|
static struct es32f0_hwtimer_dev hwtimer3;
|
||||||
|
/* can not use when DAC0 Handler is enabled */
|
||||||
|
void BS16T3_DAC0_Handler(void)
|
||||||
|
{
|
||||||
|
/* if BS16T3 it */
|
||||||
|
if (timer_get_it_status(hwtimer3.hwtimer_periph, TIMER_IT_UPDATE) &&
|
||||||
|
timer_get_flag_status(hwtimer3.hwtimer_periph, TIMER_FLAG_UPDATE))
|
||||||
|
{
|
||||||
|
timer_clear_flag_status(hwtimer3.hwtimer_periph, TIMER_FLAG_UPDATE);
|
||||||
|
rt_device_hwtimer_isr(&hwtimer3.parent);
|
||||||
|
|
||||||
|
if (HWTIMER_MODE_ONESHOT == hwtimer3.parent.mode)
|
||||||
|
{
|
||||||
|
timer_base_stop(hwtimer3.hwtimer_periph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct rt_hwtimer_info es32f0_hwtimer_info =
|
||||||
|
{
|
||||||
|
48000000, /* maximum count frequency */
|
||||||
|
1, /* minimum count frequency */
|
||||||
|
65535, /* counter maximum value */
|
||||||
|
HWTIMER_CNTMODE_UP
|
||||||
|
};
|
||||||
|
|
||||||
|
static void es32f0_hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state)
|
||||||
|
{
|
||||||
|
struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
|
||||||
|
|
||||||
|
RT_ASSERT(hwtimer != RT_NULL);
|
||||||
|
|
||||||
|
if (1 == state)
|
||||||
|
{
|
||||||
|
timer_base_init(hwtimer->hwtimer_periph);
|
||||||
|
timer_interrupt_config(hwtimer->hwtimer_periph, TIMER_IT_UPDATE, ENABLE);
|
||||||
|
NVIC_EnableIRQ(hwtimer->IRQn);
|
||||||
|
}
|
||||||
|
hwtimer->parent.freq = cmu_get_pclk1_clock();
|
||||||
|
es32f0_hwtimer_info.maxfreq = cmu_get_pclk1_clock();
|
||||||
|
es32f0_hwtimer_info.minfreq = cmu_get_pclk1_clock();
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t es32f0_hwtimer_start(rt_hwtimer_t *timer,
|
||||||
|
rt_uint32_t cnt,
|
||||||
|
rt_hwtimer_mode_t mode)
|
||||||
|
{
|
||||||
|
struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
|
||||||
|
|
||||||
|
RT_ASSERT(hwtimer != RT_NULL);
|
||||||
|
|
||||||
|
WRITE_REG(hwtimer->hwtimer_periph->perh->AR, cnt);
|
||||||
|
timer_base_start(hwtimer->hwtimer_periph);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void es32f0_hwtimer_stop(rt_hwtimer_t *timer)
|
||||||
|
{
|
||||||
|
struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
|
||||||
|
|
||||||
|
RT_ASSERT(hwtimer != RT_NULL);
|
||||||
|
|
||||||
|
timer_base_stop(hwtimer->hwtimer_periph);
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_uint32_t es32f0_hwtimer_count_get(rt_hwtimer_t *timer)
|
||||||
|
{
|
||||||
|
struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
|
||||||
|
uint32_t hwtimer_count = 0;
|
||||||
|
|
||||||
|
RT_ASSERT(hwtimer != RT_NULL);
|
||||||
|
|
||||||
|
hwtimer_count = READ_REG(hwtimer->hwtimer_periph->perh->COUNT);
|
||||||
|
|
||||||
|
return hwtimer_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t es32f0_hwtimer_control(rt_hwtimer_t *timer,
|
||||||
|
rt_uint32_t cmd,
|
||||||
|
void *args)
|
||||||
|
{
|
||||||
|
rt_err_t ret = RT_EOK;
|
||||||
|
rt_uint32_t freq = 0;
|
||||||
|
struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data;
|
||||||
|
|
||||||
|
RT_ASSERT(hwtimer != RT_NULL);
|
||||||
|
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case HWTIMER_CTRL_FREQ_SET:
|
||||||
|
freq = *(rt_uint32_t *)args;
|
||||||
|
if (freq != cmu_get_pclk1_clock())
|
||||||
|
{
|
||||||
|
ret = -RT_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HWTIMER_CTRL_STOP:
|
||||||
|
timer_base_stop(hwtimer->hwtimer_periph);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ret = RT_EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct rt_hwtimer_ops es32f0_hwtimer_ops =
|
||||||
|
{
|
||||||
|
es32f0_hwtimer_init,
|
||||||
|
es32f0_hwtimer_start,
|
||||||
|
es32f0_hwtimer_stop,
|
||||||
|
es32f0_hwtimer_count_get,
|
||||||
|
es32f0_hwtimer_control
|
||||||
|
};
|
||||||
|
|
||||||
|
int rt_hw_hwtimer_init(void)
|
||||||
|
{
|
||||||
|
rt_err_t ret = RT_EOK;
|
||||||
|
|
||||||
|
#ifdef BSP_USING_HWTIMER0
|
||||||
|
static timer_handle_t _hwtimer_periph0;
|
||||||
|
_hwtimer_periph0.perh = BS16T0;
|
||||||
|
hwtimer0.IRQn = BS16T0_IRQn;
|
||||||
|
hwtimer0.hwtimer_periph = &_hwtimer_periph0;
|
||||||
|
hwtimer0.parent.info = &es32f0_hwtimer_info;
|
||||||
|
hwtimer0.parent.ops = &es32f0_hwtimer_ops;
|
||||||
|
ret = rt_device_hwtimer_register(&hwtimer0.parent, "timer0", &hwtimer0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_HWTIMER1
|
||||||
|
static timer_handle_t _hwtimer_periph1;
|
||||||
|
_hwtimer_periph1.perh = BS16T1;
|
||||||
|
hwtimer1.IRQn = BS16T1_UART2_IRQn;
|
||||||
|
hwtimer1.hwtimer_periph = &_hwtimer_periph1;
|
||||||
|
hwtimer1.parent.info = &es32f0_hwtimer_info;
|
||||||
|
hwtimer1.parent.ops = &es32f0_hwtimer_ops;
|
||||||
|
ret = rt_device_hwtimer_register(&hwtimer1.parent, "timer1", &hwtimer1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_HWTIMER2
|
||||||
|
static timer_handle_t _hwtimer_periph2;
|
||||||
|
_hwtimer_periph2.perh = BS16T2;
|
||||||
|
hwtimer2.IRQn = BS16T2_UART3_IRQn;
|
||||||
|
hwtimer2.hwtimer_periph = &_hwtimer_periph2;
|
||||||
|
hwtimer2.parent.info = &es32f0_hwtimer_info;
|
||||||
|
hwtimer2.parent.ops = &es32f0_hwtimer_ops;
|
||||||
|
ret = rt_device_hwtimer_register(&hwtimer2.parent, "timer2", &hwtimer2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_HWTIMER3
|
||||||
|
static timer_handle_t _hwtimer_periph3;
|
||||||
|
_hwtimer_periph3.perh = BS16T3;
|
||||||
|
hwtimer3.IRQn = BS16T3_DAC0_IRQn;
|
||||||
|
hwtimer3.hwtimer_periph = &_hwtimer_periph3;
|
||||||
|
hwtimer3.parent.info = &es32f0_hwtimer_info;
|
||||||
|
hwtimer3.parent.ops = &es32f0_hwtimer_ops;
|
||||||
|
ret = rt_device_hwtimer_register(&hwtimer3.parent, "timer3", &hwtimer3);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
INIT_BOARD_EXPORT(rt_hw_hwtimer_init);
|
||||||
|
|
||||||
|
#endif
|
|
@ -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
|
|
@ -19,7 +19,7 @@
|
||||||
static void pwm_set_freq(timer_handle_t *timer_initstruct, uint32_t ns)
|
static void pwm_set_freq(timer_handle_t *timer_initstruct, uint32_t ns)
|
||||||
{
|
{
|
||||||
uint64_t _arr = (uint64_t)cmu_get_pclk1_clock() * ns / 1000000000 /
|
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);
|
WRITE_REG(timer_initstruct->perh->AR, (uint32_t)_arr);
|
||||||
timer_initstruct->init.period = (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)
|
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 /
|
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)
|
if (ch == TIMER_CHANNEL_1)
|
||||||
WRITE_REG(timer_initstruct->perh->CCVAL1, (uint32_t)tmp);
|
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);
|
WRITE_REG(timer_initstruct->perh->CCVAL3, (uint32_t)tmp);
|
||||||
else if (ch == TIMER_CHANNEL_4)
|
else if (ch == TIMER_CHANNEL_4)
|
||||||
WRITE_REG(timer_initstruct->perh->CCVAL4, (uint32_t)tmp);
|
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)
|
static rt_err_t es32f0_pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
|
||||||
|
|
|
@ -172,6 +172,9 @@
|
||||||
/* PWM Drivers */
|
/* PWM Drivers */
|
||||||
|
|
||||||
|
|
||||||
|
/* HWtimer Drivers */
|
||||||
|
|
||||||
|
|
||||||
/* Onboard Peripheral Drivers */
|
/* Onboard Peripheral Drivers */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -20,6 +20,15 @@
|
||||||
#include <epit.h>
|
#include <epit.h>
|
||||||
#include <cortex_a.h>
|
#include <cortex_a.h>
|
||||||
|
|
||||||
|
#include <mmu.h>
|
||||||
|
|
||||||
|
struct mem_desc platform_mem_desc[] = {
|
||||||
|
{0x00000000, 0x80000000, 0x00000000, DEVICE_MEM},
|
||||||
|
{0x80000000, 0xFFF00000, 0x80000000, NORMAL_MEM}
|
||||||
|
};
|
||||||
|
|
||||||
|
const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]);
|
||||||
|
|
||||||
static void rt_hw_timer_isr(int vector, void *param)
|
static void rt_hw_timer_isr(int vector, void *param)
|
||||||
{
|
{
|
||||||
rt_tick_increase();
|
rt_tick_increase();
|
||||||
|
|
|
@ -8,9 +8,7 @@ drivers/imx_timer.c
|
||||||
drivers/imx_i2c.c
|
drivers/imx_i2c.c
|
||||||
drivers/imx_uart.c
|
drivers/imx_uart.c
|
||||||
cpu/armv7_cache.c
|
cpu/armv7_cache.c
|
||||||
cpu/gic.c
|
|
||||||
cpu/ccm_pll2.c
|
cpu/ccm_pll2.c
|
||||||
cpu/mmu.c
|
|
||||||
cpu/cortex_a_gcc.S
|
cpu/cortex_a_gcc.S
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
|
|
@ -1,243 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2012, Freescale Semiconductor, Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
* are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* o Redistributions of source code must retain the above copyright notice, this list
|
|
||||||
* of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
|
||||||
* list of conditions and the following disclaimer in the documentation and/or
|
|
||||||
* other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived from this
|
|
||||||
* software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
#include <assert.h>
|
|
||||||
#include "gic.h"
|
|
||||||
#include "gic_registers.h"
|
|
||||||
#include "cortex_a.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Prototypes
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static inline gicd_t * gic_get_gicd(void);
|
|
||||||
static inline gicc_t * gic_get_gicc(void);
|
|
||||||
static inline uint32_t irq_get_register_offset(uint32_t irqID);
|
|
||||||
static inline uint32_t irq_get_bit_offset(uint32_t irqID);
|
|
||||||
static inline uint32_t irq_get_bit_mask(uint32_t irqID);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Code
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static inline gicd_t * gic_get_gicd(void)
|
|
||||||
{
|
|
||||||
uint32_t base = get_arm_private_peripheral_base() + kGICDBaseOffset;
|
|
||||||
return (gicd_t *)base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline gicc_t * gic_get_gicc(void)
|
|
||||||
{
|
|
||||||
uint32_t base = get_arm_private_peripheral_base() + kGICCBaseOffset;
|
|
||||||
return (gicc_t *)base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t irq_get_register_offset(uint32_t irqID)
|
|
||||||
{
|
|
||||||
return irqID / 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t irq_get_bit_offset(uint32_t irqID)
|
|
||||||
{
|
|
||||||
return irqID & 0x1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t irq_get_bit_mask(uint32_t irqID)
|
|
||||||
{
|
|
||||||
return 1 << irq_get_bit_offset(irqID);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gic_enable(bool enableIt)
|
|
||||||
{
|
|
||||||
gicd_t * gicd = gic_get_gicd();
|
|
||||||
|
|
||||||
if (enableIt)
|
|
||||||
{
|
|
||||||
// Enable both secure and non-secure.
|
|
||||||
gicd->CTLR |= kBM_GICD_CTLR_EnableGrp0 | kBM_GICD_CTLR_EnableGrp1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Clear the enable bits.
|
|
||||||
gicd->CTLR &= ~(kBM_GICD_CTLR_EnableGrp0 | kBM_GICD_CTLR_EnableGrp1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void gic_set_irq_security(uint32_t irqID, bool isSecure)
|
|
||||||
{
|
|
||||||
gicd_t * gicd = gic_get_gicd();
|
|
||||||
|
|
||||||
uint32_t reg = irq_get_register_offset(irqID);
|
|
||||||
uint32_t mask = irq_get_bit_mask(irqID);
|
|
||||||
|
|
||||||
uint32_t value = gicd->IGROUPRn[reg];
|
|
||||||
if (!isSecure)
|
|
||||||
{
|
|
||||||
value &= ~mask;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
value |= mask;
|
|
||||||
}
|
|
||||||
gicd->IGROUPRn[reg] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gic_enable_irq(uint32_t irqID, bool isEnabled)
|
|
||||||
{
|
|
||||||
gicd_t * gicd = gic_get_gicd();
|
|
||||||
|
|
||||||
uint32_t reg = irq_get_register_offset(irqID);
|
|
||||||
uint32_t mask = irq_get_bit_mask(irqID);
|
|
||||||
|
|
||||||
// Select set-enable or clear-enable register based on enable flag.
|
|
||||||
if (isEnabled)
|
|
||||||
{
|
|
||||||
gicd->ISENABLERn[reg] = mask;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gicd->ICENABLERn[reg] = mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void gic_set_irq_priority(uint32_t ID, uint32_t priority)
|
|
||||||
{
|
|
||||||
gicd_t * gicd = gic_get_gicd();
|
|
||||||
|
|
||||||
// Update the priority register. The priority registers are byte accessible, and the register
|
|
||||||
// struct has the priority registers as a byte array, so we can just index directly by the
|
|
||||||
// interrupt ID.
|
|
||||||
gicd->IPRIORITYRn[ID] = priority & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gic_set_cpu_target(uint32_t irqID, unsigned cpuNumber, bool enableIt)
|
|
||||||
{
|
|
||||||
// Make sure the CPU number is valid.
|
|
||||||
assert(cpuNumber <= 7);
|
|
||||||
|
|
||||||
gicd_t * gicd = gic_get_gicd();
|
|
||||||
uint8_t cpuMask = 1 << cpuNumber;
|
|
||||||
|
|
||||||
// Like the priority registers, the target registers are byte accessible, and the register
|
|
||||||
// struct has the them as a byte array, so we can just index directly by the
|
|
||||||
// interrupt ID.
|
|
||||||
if (enableIt)
|
|
||||||
{
|
|
||||||
gicd->ITARGETSRn[irqID] |= (cpuMask & 0xff);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gicd->ITARGETSRn[irqID] &= ~(cpuMask & 0xff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void gic_send_sgi(uint32_t irqID, uint32_t target_list, uint32_t filter_list)
|
|
||||||
{
|
|
||||||
gicd_t * gicd = gic_get_gicd();
|
|
||||||
|
|
||||||
gicd->SGIR = (filter_list << kBP_GICD_SGIR_TargetListFilter)
|
|
||||||
| (target_list << kBP_GICD_SGIR_CPUTargetList)
|
|
||||||
| (irqID & 0xf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gic_cpu_enable(bool enableIt)
|
|
||||||
{
|
|
||||||
gicc_t * gicc = gic_get_gicc();
|
|
||||||
|
|
||||||
if (enableIt)
|
|
||||||
{
|
|
||||||
gicc->CTLR |= kBM_GICC_CTLR_EnableS | kBM_GICC_CTLR_EnableNS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gicc->CTLR &= ~(kBM_GICC_CTLR_EnableS | kBM_GICC_CTLR_EnableNS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void gic_set_cpu_priority_mask(uint32_t priority)
|
|
||||||
{
|
|
||||||
gicc_t * gicc = gic_get_gicc();
|
|
||||||
gicc->PMR = priority & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t gic_read_irq_ack(void)
|
|
||||||
{
|
|
||||||
gicc_t * gicc = gic_get_gicc();
|
|
||||||
return gicc->IAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gic_write_end_of_irq(uint32_t irqID)
|
|
||||||
{
|
|
||||||
gicc_t * gicc = gic_get_gicc();
|
|
||||||
gicc->EOIR = irqID;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gic_init(void)
|
|
||||||
{
|
|
||||||
gicd_t * gicd = gic_get_gicd();
|
|
||||||
|
|
||||||
// First disable the distributor.
|
|
||||||
gic_enable(false);
|
|
||||||
|
|
||||||
// Clear all pending interrupts.
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 32; ++i)
|
|
||||||
{
|
|
||||||
gicd->ICPENDRn[i] = 0xffffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set all interrupts to secure.
|
|
||||||
for (i = 0; i < 8; ++i)
|
|
||||||
{
|
|
||||||
gicd->IGROUPRn[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init the GIC CPU interface.
|
|
||||||
gic_init_cpu();
|
|
||||||
|
|
||||||
// Now enable the distributor.
|
|
||||||
gic_enable(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gic_init_cpu(void)
|
|
||||||
{
|
|
||||||
// Init the GIC CPU interface.
|
|
||||||
gic_set_cpu_priority_mask(0xff);
|
|
||||||
|
|
||||||
// Disable preemption.
|
|
||||||
gicc_t * gicc = gic_get_gicc();
|
|
||||||
gicc->BPR = 7;
|
|
||||||
|
|
||||||
// Enable signaling the CPU.
|
|
||||||
gic_cpu_enable(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// EOF
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
|
@ -1,285 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2008-2012, Freescale Semiconductor, Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
* are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* o Redistributions of source code must retain the above copyright notice, this list
|
|
||||||
* of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
|
||||||
* list of conditions and the following disclaimer in the documentation and/or
|
|
||||||
* other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived from this
|
|
||||||
* software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @file mmu.c
|
|
||||||
* @brief System memory arangement.
|
|
||||||
*/
|
|
||||||
#include "cortex_a.h"
|
|
||||||
#include "mmu.h"
|
|
||||||
#include "arm_cp_registers.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Definitions
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//! @brief Size in bytes of the first-level page table.
|
|
||||||
#define MMU_L1_PAGE_TABLE_SIZE (16 * 1024)
|
|
||||||
|
|
||||||
//! @brief First-level 1MB section descriptor entry.
|
|
||||||
typedef union mmu_l1_section {
|
|
||||||
uint32_t u;
|
|
||||||
struct {
|
|
||||||
uint32_t id:2; //!< ID
|
|
||||||
uint32_t b:1; //!< Bufferable
|
|
||||||
uint32_t c:1; //!< Cacheable
|
|
||||||
uint32_t xn:1; //!< Execute-not
|
|
||||||
uint32_t domain:4; //!< Domain
|
|
||||||
uint32_t _impl_defined:1; //!< Implementation defined, should be zero.
|
|
||||||
uint32_t ap1_0:2; //!< Access permissions AP[1:0]
|
|
||||||
uint32_t tex:3; //!< TEX remap
|
|
||||||
uint32_t ap2:1; //!< Access permissions AP[2]
|
|
||||||
uint32_t s:1; //!< Shareable
|
|
||||||
uint32_t ng:1; //!< Not-global
|
|
||||||
uint32_t _zero:1; //!< Should be zero.
|
|
||||||
uint32_t ns:1; //!< Non-secure
|
|
||||||
uint32_t address:12; //!< Physical base address
|
|
||||||
};
|
|
||||||
} mmu_l1_section_t;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
kMMU_L1_Section_ID = 2, //!< ID value for a 1MB section first-level entry.
|
|
||||||
kMMU_L1_Section_Address_Shift = 20 //!< Bit offset of the physical base address field.
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Externs
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
extern char __l1_page_table_start;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Code
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void mmu_enable()
|
|
||||||
{
|
|
||||||
// invalidate all tlb
|
|
||||||
arm_unified_tlb_invalidate();
|
|
||||||
|
|
||||||
// read SCTLR
|
|
||||||
uint32_t sctlr;
|
|
||||||
_ARM_MRC(15, 0, sctlr, 1, 0, 0);
|
|
||||||
|
|
||||||
// set MMU enable bit
|
|
||||||
sctlr |= BM_SCTLR_M;
|
|
||||||
|
|
||||||
// write modified SCTLR
|
|
||||||
_ARM_MCR(15, 0, sctlr, 1, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mmu_disable()
|
|
||||||
{
|
|
||||||
// read current SCTLR
|
|
||||||
uint32_t sctlr;
|
|
||||||
_ARM_MRC(15, 0, sctlr, 1, 0, 0);
|
|
||||||
|
|
||||||
// clear MMU enable bit
|
|
||||||
sctlr &=~ BM_SCTLR_M;
|
|
||||||
|
|
||||||
// write modified SCTLR
|
|
||||||
_ARM_MCR(15, 0, sctlr, 1, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mmu_init()
|
|
||||||
{
|
|
||||||
// Get the L1 page table base address.
|
|
||||||
uint32_t * table = (uint32_t *)&__l1_page_table_start;
|
|
||||||
uint32_t share_attr = kShareable;
|
|
||||||
|
|
||||||
// write table address to TTBR0
|
|
||||||
_ARM_MCR(15, 0, table, 2, 0, 0);
|
|
||||||
|
|
||||||
// set Client mode for all Domains
|
|
||||||
uint32_t dacr = 0x55555555;
|
|
||||||
_ARM_MCR(15, 0, dacr, 3, 0, 0); // MCR p15, 0, <Rd>, c3, c0, 0 ; Write DACR
|
|
||||||
|
|
||||||
// Clear the L1 table.
|
|
||||||
bzero(table, MMU_L1_PAGE_TABLE_SIZE);
|
|
||||||
|
|
||||||
// Create default mappings.
|
|
||||||
mmu_map_l1_range(0x00000000, 0x00000000, 0x00900000, kStronglyOrdered, kShareable, kRWAccess); // ROM and peripherals
|
|
||||||
mmu_map_l1_range(0x00900000, 0x00900000, 0x00100000, kStronglyOrdered, kShareable, kRWAccess); // OCRAM
|
|
||||||
mmu_map_l1_range(0x00a00000, 0x00a00000, 0x0f600000, kStronglyOrdered, kShareable, kRWAccess); // More peripherals
|
|
||||||
|
|
||||||
// Check whether SMP is enabled. If it is not, then we don't want to make SDRAM shareable.
|
|
||||||
uint32_t actlr = 0x0;
|
|
||||||
_ARM_MRC(15, 0, actlr, 1, 0, 1);
|
|
||||||
if (actlr & BM_ACTLR_SMP)
|
|
||||||
{
|
|
||||||
share_attr = kShareable;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
share_attr = kNonshareable;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(CHIP_MX6DQ) || defined(CHIP_MX6SDL)
|
|
||||||
mmu_map_l1_range(0x10000000, 0x10000000, 0x80000000, kOuterInner_WB_WA, share_attr, kRWAccess); // 2GB DDR
|
|
||||||
#elif defined(CHIP_MX6SL) || defined(CHIP_MX6UL)
|
|
||||||
mmu_map_l1_range(0x80000000, 0x80000000, 0x40000000, kOuterInner_WB_WA, share_attr, kRWAccess); // 1GB DDR
|
|
||||||
#else
|
|
||||||
#error Unknown chip type!
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void mmu_map_l1_range(uint32_t pa, uint32_t va, uint32_t length, mmu_memory_type_t memoryType, mmu_shareability_t isShareable, mmu_access_t access)
|
|
||||||
{
|
|
||||||
register mmu_l1_section_t entry;
|
|
||||||
entry.u = 0;
|
|
||||||
|
|
||||||
// Set constant attributes.
|
|
||||||
entry.id = kMMU_L1_Section_ID;
|
|
||||||
entry.xn = 0; // Allow execution
|
|
||||||
entry.domain = 0; // Domain 0
|
|
||||||
entry.ng = 0; // Global
|
|
||||||
entry.ns = 0; // Secure
|
|
||||||
|
|
||||||
// Set attributes based on the selected memory type.
|
|
||||||
switch (memoryType)
|
|
||||||
{
|
|
||||||
case kStronglyOrdered:
|
|
||||||
entry.c = 0;
|
|
||||||
entry.b = 0;
|
|
||||||
entry.tex = 0;
|
|
||||||
entry.s = 1; // Ignored
|
|
||||||
break;
|
|
||||||
case kDevice:
|
|
||||||
if (isShareable)
|
|
||||||
{
|
|
||||||
entry.c = 0;
|
|
||||||
entry.b = 1;
|
|
||||||
entry.tex = 0;
|
|
||||||
entry.s = 1; // Ignored
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entry.c = 0;
|
|
||||||
entry.b = 0;
|
|
||||||
entry.tex = 2;
|
|
||||||
entry.s = 0; // Ignored
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case kOuterInner_WB_WA:
|
|
||||||
entry.c = 1;
|
|
||||||
entry.b = 1;
|
|
||||||
entry.tex = 1;
|
|
||||||
entry.s = isShareable;
|
|
||||||
break;
|
|
||||||
case kOuterInner_WT:
|
|
||||||
entry.c = 1;
|
|
||||||
entry.b = 0;
|
|
||||||
entry.tex = 0;
|
|
||||||
entry.s = isShareable;
|
|
||||||
break;
|
|
||||||
case kNoncacheable:
|
|
||||||
entry.c = 0;
|
|
||||||
entry.b = 0;
|
|
||||||
entry.tex = 1;
|
|
||||||
entry.s = isShareable;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set attributes from specified access mode.
|
|
||||||
switch (access)
|
|
||||||
{
|
|
||||||
case kNoAccess:
|
|
||||||
entry.ap2 = 0;
|
|
||||||
entry.ap1_0 = 0;
|
|
||||||
break;
|
|
||||||
case kROAccess:
|
|
||||||
entry.ap2 = 1;
|
|
||||||
entry.ap1_0 = 3;
|
|
||||||
break;
|
|
||||||
case kRWAccess:
|
|
||||||
entry.ap2 = 0;
|
|
||||||
entry.ap1_0 = 3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the L1 page table base address.
|
|
||||||
uint32_t * table = (uint32_t *)&__l1_page_table_start;
|
|
||||||
|
|
||||||
// Convert addresses to 12-bit bases.
|
|
||||||
uint32_t vbase = va >> kMMU_L1_Section_Address_Shift;
|
|
||||||
uint32_t pbase = pa >> kMMU_L1_Section_Address_Shift;
|
|
||||||
uint32_t entries = length >> kMMU_L1_Section_Address_Shift;
|
|
||||||
|
|
||||||
// Fill in L1 page table entries.
|
|
||||||
for (; entries > 0; ++pbase, ++vbase, --entries)
|
|
||||||
{
|
|
||||||
entry.address = pbase;
|
|
||||||
table[vbase] = entry.u;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invalidate TLB
|
|
||||||
arm_unified_tlb_invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool mmu_virtual_to_physical(uint32_t virtualAddress, uint32_t * physicalAddress)
|
|
||||||
{
|
|
||||||
uint32_t pa = 0;
|
|
||||||
|
|
||||||
// VA to PA translation with privileged read permission check
|
|
||||||
_ARM_MCR(15, 0, virtualAddress & 0xfffffc00, 7, 8, 0);
|
|
||||||
|
|
||||||
// Read PA register
|
|
||||||
_ARM_MRC(15, 0, pa, 7, 4, 0);
|
|
||||||
|
|
||||||
// First bit of returned value is Result of conversion (0 is successful translation)
|
|
||||||
if (pa & 1)
|
|
||||||
{
|
|
||||||
// We can try write permission also
|
|
||||||
// VA to PA translation with privileged write permission check
|
|
||||||
_ARM_MCR(15, 0, virtualAddress & 0xfffffc00, 7, 8, 1);
|
|
||||||
|
|
||||||
// Read PA register
|
|
||||||
_ARM_MRC(15, 0, pa, 7, 4, 0);
|
|
||||||
|
|
||||||
// First bit of returned value is Result of conversion (0 is successful translation)
|
|
||||||
if (pa & 1)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (physicalAddress)
|
|
||||||
{
|
|
||||||
// complete address returning base + offset
|
|
||||||
pa = (pa & 0xfffff000) | (virtualAddress & 0x00000fff);
|
|
||||||
*physicalAddress = pa;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// EOF
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
|
@ -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
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2018-03-22 quanzhao first version
|
||||||
|
*/
|
||||||
|
#ifndef __PLATFORM_H__
|
||||||
|
#define __PLATFORM_H__
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
/* SOC-relative definitions */
|
||||||
|
//#include "realview.h"
|
||||||
|
#include "gic_registers.h"
|
||||||
|
#include "irq_numbers.h"
|
||||||
|
|
||||||
|
/* the maximum number of gic */
|
||||||
|
# define ARM_GIC_MAX_NR 1
|
||||||
|
|
||||||
|
/* the maximum number of interrupts */
|
||||||
|
#define ARM_GIC_NR_IRQS IMX_INTERRUPT_COUNT
|
||||||
|
|
||||||
|
/* the maximum entries of the interrupt table */
|
||||||
|
#define MAX_HANDLERS IMX_INTERRUPT_COUNT
|
||||||
|
|
||||||
|
/* the basic constants needed by gic */
|
||||||
|
rt_inline rt_uint32_t platform_get_gic_dist_base(void)
|
||||||
|
{
|
||||||
|
rt_uint32_t gic_base;
|
||||||
|
asm volatile ("mrc p15, 4, %0, c15, c0, 0" : "=r"(gic_base));
|
||||||
|
return gic_base + kGICDBaseOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_inline rt_uint32_t platform_get_gic_cpu_base(void)
|
||||||
|
{
|
||||||
|
rt_uint32_t gic_base;
|
||||||
|
asm volatile ("mrc p15, 4, %0, c15, c0, 0" : "=r"(gic_base));
|
||||||
|
return gic_base + kGICCBaseOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GIC_IRQ_START 0
|
||||||
|
|
||||||
|
#define GIC_ACK_INTID_MASK 0x000003ff
|
||||||
|
|
||||||
|
/* the definition needed by gic.c */
|
||||||
|
#define __REG32(x) (*((volatile unsigned int *)(x)))
|
||||||
|
|
||||||
|
/* keep compatible with platform SDK */
|
||||||
|
typedef enum {
|
||||||
|
CPU_0,
|
||||||
|
CPU_1,
|
||||||
|
CPU_2,
|
||||||
|
CPU_3,
|
||||||
|
} cpuid_e;
|
||||||
|
|
||||||
|
enum _gicd_sgi_filter
|
||||||
|
{
|
||||||
|
//! Forward the interrupt to the CPU interfaces specified in the @a target_list parameter.
|
||||||
|
kGicSgiFilter_UseTargetList = 0,
|
||||||
|
|
||||||
|
//! Forward the interrupt to all CPU interfaces except that of the processor that requested
|
||||||
|
//! the interrupt.
|
||||||
|
kGicSgiFilter_AllOtherCPUs = 1,
|
||||||
|
|
||||||
|
//! Forward the interrupt only to the CPU interface of the processor that requested the
|
||||||
|
//! interrupt.
|
||||||
|
kGicSgiFilter_OnlyThisCPU = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*irq_hdlr_t) (void);
|
||||||
|
|
||||||
|
extern void rt_hw_interrupt_mask(int vector);
|
||||||
|
extern void rt_hw_interrupt_umask(int vector);
|
||||||
|
extern rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
|
||||||
|
void *param, const char *name);
|
||||||
|
|
||||||
|
rt_inline void register_interrupt_routine(uint32_t irq_id, irq_hdlr_t isr)
|
||||||
|
{
|
||||||
|
rt_hw_interrupt_install(irq_id, (rt_isr_handler_t)isr, NULL, "unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_inline void enable_interrupt(uint32_t irq_id, uint32_t cpu_id, uint32_t priority)
|
||||||
|
{
|
||||||
|
rt_hw_interrupt_umask(irq_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_inline void disable_interrupt(uint32_t irq_id, uint32_t cpu_id)
|
||||||
|
{
|
||||||
|
rt_hw_interrupt_mask(irq_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __PLATFORM_H__ */
|
|
@ -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
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
|
@ -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
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
|
@ -10,7 +10,7 @@ if os.getenv('RTT_CC'):
|
||||||
|
|
||||||
# only support GNU GCC compiler.
|
# only support GNU GCC compiler.
|
||||||
PLATFORM = 'gcc'
|
PLATFORM = 'gcc'
|
||||||
EXEC_PATH = '/opt/gcc-arm-none-eabi-4_8-2014q1_gri/bin'
|
EXEC_PATH = '/usr/bin'
|
||||||
|
|
||||||
if os.getenv('RTT_EXEC_PATH'):
|
if os.getenv('RTT_EXEC_PATH'):
|
||||||
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
|
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
|
||||||
|
|
|
@ -322,6 +322,7 @@ CONFIG_RT_USING_LWP=y
|
||||||
# CONFIG_PKG_USING_WEBTERMINAL is not set
|
# CONFIG_PKG_USING_WEBTERMINAL is not set
|
||||||
# CONFIG_PKG_USING_CJSON is not set
|
# CONFIG_PKG_USING_CJSON is not set
|
||||||
# CONFIG_PKG_USING_JSMN 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_LJSON is not set
|
||||||
# CONFIG_PKG_USING_EZXML is not set
|
# CONFIG_PKG_USING_EZXML is not set
|
||||||
# CONFIG_PKG_USING_NANOPB is not set
|
# CONFIG_PKG_USING_NANOPB is not set
|
||||||
|
|
|
@ -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
|
|
@ -5,7 +5,7 @@ import rtconfig
|
||||||
if os.getenv('RTT_ROOT'):
|
if os.getenv('RTT_ROOT'):
|
||||||
RTT_ROOT = os.getenv('RTT_ROOT')
|
RTT_ROOT = os.getenv('RTT_ROOT')
|
||||||
else:
|
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')]
|
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
|
||||||
from building import *
|
from building import *
|
||||||
|
@ -25,7 +25,7 @@ Export('RTT_ROOT')
|
||||||
Export('rtconfig')
|
Export('rtconfig')
|
||||||
|
|
||||||
# prepare building environment
|
# prepare building environment
|
||||||
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=True)
|
objs = PrepareBuilding(env, RTT_ROOT)
|
||||||
|
|
||||||
# make a building
|
# make a building
|
||||||
DoBuilding(TARGET, objs)
|
DoBuilding(TARGET, objs)
|
||||||
|
|
|
@ -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')
|
|
|
@ -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
|
|
|
@ -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*/
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -1,83 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2011-09-15 Bernard first version
|
|
||||||
* 2018-11-22 Jesven add rt_hw_cpu_id()
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rthw.h>
|
|
||||||
#include <rtthread.h>
|
|
||||||
#include <board.h>
|
|
||||||
|
|
||||||
#ifdef RT_USING_SMP
|
|
||||||
int rt_hw_cpu_id(void)
|
|
||||||
{
|
|
||||||
int cpu_id;
|
|
||||||
__asm__ volatile (
|
|
||||||
"mrc p15, 0, %0, c0, c0, 5"
|
|
||||||
:"=r"(cpu_id)
|
|
||||||
);
|
|
||||||
cpu_id &= 0xf;
|
|
||||||
return cpu_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
void rt_hw_spin_lock(rt_hw_spinlock_t *lock)
|
|
||||||
{
|
|
||||||
unsigned long tmp;
|
|
||||||
unsigned long newval;
|
|
||||||
rt_hw_spinlock_t lockval;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"pld [%0]"
|
|
||||||
::"r"(&lock->slock)
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"1: ldrex %0, [%3]\n"
|
|
||||||
" add %1, %0, %4\n"
|
|
||||||
" strex %2, %1, [%3]\n"
|
|
||||||
" teq %2, #0\n"
|
|
||||||
" bne 1b"
|
|
||||||
: "=&r" (lockval), "=&r" (newval), "=&r" (tmp)
|
|
||||||
: "r" (&lock->slock), "I" (1 << 16)
|
|
||||||
: "cc");
|
|
||||||
|
|
||||||
while (lockval.tickets.next != lockval.tickets.owner) {
|
|
||||||
__asm__ __volatile__("wfe":::"memory");
|
|
||||||
lockval.tickets.owner = *(volatile unsigned short *)(&lock->tickets.owner);
|
|
||||||
}
|
|
||||||
|
|
||||||
__asm__ volatile ("dmb":::"memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
void rt_hw_spin_unlock(rt_hw_spinlock_t *lock)
|
|
||||||
{
|
|
||||||
__asm__ volatile ("dmb":::"memory");
|
|
||||||
lock->tickets.owner++;
|
|
||||||
__asm__ volatile ("dsb ishst\nsev":::"memory");
|
|
||||||
}
|
|
||||||
#endif /*RT_USING_SMP*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup ARM CPU
|
|
||||||
*/
|
|
||||||
/*@{*/
|
|
||||||
|
|
||||||
/** shutdown CPU */
|
|
||||||
void rt_hw_cpu_shutdown()
|
|
||||||
{
|
|
||||||
rt_uint32_t level;
|
|
||||||
rt_kprintf("shutdown...\n");
|
|
||||||
|
|
||||||
level = rt_hw_interrupt_disable();
|
|
||||||
while (level)
|
|
||||||
{
|
|
||||||
RT_ASSERT(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*@}*/
|
|
|
@ -1,108 +0,0 @@
|
||||||
/*
|
|
||||||
* File : interrupt.c
|
|
||||||
* This file is part of RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2013-2014, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may be
|
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rt-thread.org/license/LICENSE
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2013-07-06 Bernard first version
|
|
||||||
* 2018-11-22 Jesven add smp support
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rthw.h>
|
|
||||||
#include <rtthread.h>
|
|
||||||
#include "realview.h"
|
|
||||||
#include "gic.h"
|
|
||||||
|
|
||||||
#define MAX_HANDLERS NR_IRQS_PBA8
|
|
||||||
|
|
||||||
/* exception and interrupt handler table */
|
|
||||||
struct rt_irq_desc isr_table[MAX_HANDLERS];
|
|
||||||
|
|
||||||
#ifndef RT_USING_SMP
|
|
||||||
/* Those varibles will be accessed in ISR, so we need to share them. */
|
|
||||||
rt_uint32_t rt_interrupt_from_thread = 0;
|
|
||||||
rt_uint32_t rt_interrupt_to_thread = 0;
|
|
||||||
rt_uint32_t rt_thread_switch_interrupt_flag = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const unsigned int VECTOR_BASE = 0x00;
|
|
||||||
extern void rt_cpu_vector_set_base(unsigned int addr);
|
|
||||||
extern int system_vectors;
|
|
||||||
|
|
||||||
void rt_hw_vector_init(void)
|
|
||||||
{
|
|
||||||
rt_cpu_vector_set_base((unsigned int)&system_vectors);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will initialize hardware interrupt
|
|
||||||
*/
|
|
||||||
void rt_hw_interrupt_init(void)
|
|
||||||
{
|
|
||||||
rt_uint32_t gic_cpu_base;
|
|
||||||
rt_uint32_t gic_dist_base;
|
|
||||||
|
|
||||||
/* initialize vector table */
|
|
||||||
rt_hw_vector_init();
|
|
||||||
|
|
||||||
/* initialize exceptions table */
|
|
||||||
rt_memset(isr_table, 0x00, sizeof(isr_table));
|
|
||||||
|
|
||||||
/* initialize ARM GIC */
|
|
||||||
gic_dist_base = REALVIEW_GIC_DIST_BASE;
|
|
||||||
gic_cpu_base = REALVIEW_GIC_CPU_BASE;
|
|
||||||
|
|
||||||
arm_gic_dist_init(0, gic_dist_base, 0);
|
|
||||||
arm_gic_cpu_init(0, gic_cpu_base);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will mask a interrupt.
|
|
||||||
* @param vector the interrupt number
|
|
||||||
*/
|
|
||||||
void rt_hw_interrupt_mask(int vector)
|
|
||||||
{
|
|
||||||
arm_gic_mask(0, vector);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will un-mask a interrupt.
|
|
||||||
* @param vector the interrupt number
|
|
||||||
*/
|
|
||||||
void rt_hw_interrupt_umask(int vector)
|
|
||||||
{
|
|
||||||
arm_gic_umask(0, vector);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will install a interrupt service routine to a interrupt.
|
|
||||||
* @param vector the interrupt number
|
|
||||||
* @param new_handler the interrupt service routine to be installed
|
|
||||||
* @param old_handler the old interrupt service routine
|
|
||||||
*/
|
|
||||||
rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
|
|
||||||
void *param, const char *name)
|
|
||||||
{
|
|
||||||
rt_isr_handler_t old_handler = RT_NULL;
|
|
||||||
|
|
||||||
if (vector < MAX_HANDLERS)
|
|
||||||
{
|
|
||||||
old_handler = isr_table[vector].handler;
|
|
||||||
|
|
||||||
if (handler != RT_NULL)
|
|
||||||
{
|
|
||||||
#ifdef RT_USING_INTERRUPT_INFO
|
|
||||||
rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX);
|
|
||||||
#endif /* RT_USING_INTERRUPT_INFO */
|
|
||||||
isr_table[vector].handler = handler;
|
|
||||||
isr_table[vector].param = param;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return old_handler;
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -1,207 +0,0 @@
|
||||||
/*
|
|
||||||
* File : mmu.c
|
|
||||||
* This file is part of RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may be
|
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rt-thread.org/license/LICENSE
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2012-01-10 bernard porting to AM1808
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtthread.h>
|
|
||||||
#include <rthw.h>
|
|
||||||
#include <board.h>
|
|
||||||
|
|
||||||
#include "cp15.h"
|
|
||||||
|
|
||||||
#define DESC_SEC (0x2)
|
|
||||||
#define CB (3<<2) //cache_on, write_back
|
|
||||||
#define CNB (2<<2) //cache_on, write_through
|
|
||||||
#define NCB (1<<2) //cache_off,WR_BUF on
|
|
||||||
#define NCNB (0<<2) //cache_off,WR_BUF off
|
|
||||||
#define AP_RW (3<<10) //supervisor=RW, user=RW
|
|
||||||
#define AP_RO (2<<10) //supervisor=RW, user=RO
|
|
||||||
#define XN (1<<4) // eXecute Never
|
|
||||||
|
|
||||||
#define DOMAIN_FAULT (0x0)
|
|
||||||
#define DOMAIN_CHK (0x1)
|
|
||||||
#define DOMAIN_NOTCHK (0x3)
|
|
||||||
#define DOMAIN0 (0x0<<5)
|
|
||||||
#define DOMAIN1 (0x1<<5)
|
|
||||||
|
|
||||||
#define DOMAIN0_ATTR (DOMAIN_CHK<<0)
|
|
||||||
#define DOMAIN1_ATTR (DOMAIN_FAULT<<2)
|
|
||||||
|
|
||||||
/* Read/Write, cache, write back */
|
|
||||||
#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC)
|
|
||||||
/* Read/Write, cache, write through */
|
|
||||||
#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC)
|
|
||||||
/* Read/Write without cache and write buffer */
|
|
||||||
#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC)
|
|
||||||
/* Read/Write without cache and write buffer, no execute */
|
|
||||||
#define RW_NCNBXN (AP_RW|DOMAIN0|NCNB|DESC_SEC|XN)
|
|
||||||
/* Read/Write without cache and write buffer */
|
|
||||||
#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC)
|
|
||||||
|
|
||||||
/* dump 2nd level page table */
|
|
||||||
void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int fcnt = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
{
|
|
||||||
rt_uint32_t pte2 = ptb[i];
|
|
||||||
if ((pte2 & 0x3) == 0)
|
|
||||||
{
|
|
||||||
if (fcnt == 0)
|
|
||||||
rt_kprintf(" ");
|
|
||||||
rt_kprintf("%04x: ", i);
|
|
||||||
fcnt++;
|
|
||||||
if (fcnt == 16)
|
|
||||||
{
|
|
||||||
rt_kprintf("fault\n");
|
|
||||||
fcnt = 0;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (fcnt != 0)
|
|
||||||
{
|
|
||||||
rt_kprintf("fault\n");
|
|
||||||
fcnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
rt_kprintf(" %04x: %x: ", i, pte2);
|
|
||||||
if ((pte2 & 0x3) == 0x1)
|
|
||||||
{
|
|
||||||
rt_kprintf("L,ap:%x,xn:%d,texcb:%02x\n",
|
|
||||||
((pte2 >> 7) | (pte2 >> 4))& 0xf,
|
|
||||||
(pte2 >> 15) & 0x1,
|
|
||||||
((pte2 >> 10) | (pte2 >> 2)) & 0x1f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rt_kprintf("S,ap:%x,xn:%d,texcb:%02x\n",
|
|
||||||
((pte2 >> 7) | (pte2 >> 4))& 0xf, pte2 & 0x1,
|
|
||||||
((pte2 >> 4) | (pte2 >> 2)) & 0x1f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int fcnt = 0;
|
|
||||||
|
|
||||||
rt_kprintf("page table@%p\n", ptb);
|
|
||||||
for (i = 0; i < 1024*4; i++)
|
|
||||||
{
|
|
||||||
rt_uint32_t pte1 = ptb[i];
|
|
||||||
if ((pte1 & 0x3) == 0)
|
|
||||||
{
|
|
||||||
rt_kprintf("%03x: ", i);
|
|
||||||
fcnt++;
|
|
||||||
if (fcnt == 16)
|
|
||||||
{
|
|
||||||
rt_kprintf("fault\n");
|
|
||||||
fcnt = 0;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (fcnt != 0)
|
|
||||||
{
|
|
||||||
rt_kprintf("fault\n");
|
|
||||||
fcnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
rt_kprintf("%03x: %08x: ", i, pte1);
|
|
||||||
if ((pte1 & 0x3) == 0x3)
|
|
||||||
{
|
|
||||||
rt_kprintf("LPAE\n");
|
|
||||||
}
|
|
||||||
else if ((pte1 & 0x3) == 0x1)
|
|
||||||
{
|
|
||||||
rt_kprintf("pte,ns:%d,domain:%d\n",
|
|
||||||
(pte1 >> 3) & 0x1, (pte1 >> 5) & 0xf);
|
|
||||||
/*
|
|
||||||
*rt_hw_cpu_dump_page_table_2nd((void*)((pte1 & 0xfffffc000)
|
|
||||||
* - 0x80000000 + 0xC0000000));
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
else if (pte1 & (1 << 18))
|
|
||||||
{
|
|
||||||
rt_kprintf("super section,ns:%d,ap:%x,xn:%d,texcb:%02x\n",
|
|
||||||
(pte1 >> 19) & 0x1,
|
|
||||||
((pte1 >> 13) | (pte1 >> 10))& 0xf,
|
|
||||||
(pte1 >> 4) & 0x1,
|
|
||||||
((pte1 >> 10) | (pte1 >> 2)) & 0x1f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rt_kprintf("section,ns:%d,ap:%x,"
|
|
||||||
"xn:%d,texcb:%02x,domain:%d\n",
|
|
||||||
(pte1 >> 19) & 0x1,
|
|
||||||
((pte1 >> 13) | (pte1 >> 10))& 0xf,
|
|
||||||
(pte1 >> 4) & 0x1,
|
|
||||||
(((pte1 & (0x7 << 12)) >> 10) |
|
|
||||||
((pte1 & 0x0c) >> 2)) & 0x1f,
|
|
||||||
(pte1 >> 5) & 0xf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* level1 page table, each entry for 1MB memory. */
|
|
||||||
volatile static unsigned long MMUTable[4*1024] __attribute__((aligned(16*1024)));
|
|
||||||
void rt_hw_mmu_setmtt(rt_uint32_t vaddrStart,
|
|
||||||
rt_uint32_t vaddrEnd,
|
|
||||||
rt_uint32_t paddrStart,
|
|
||||||
rt_uint32_t attr)
|
|
||||||
{
|
|
||||||
volatile rt_uint32_t *pTT;
|
|
||||||
volatile int i, nSec;
|
|
||||||
pTT = (rt_uint32_t *)MMUTable + (vaddrStart >> 20);
|
|
||||||
nSec = (vaddrEnd >> 20) - (vaddrStart >> 20);
|
|
||||||
for(i = 0; i <= nSec; i++)
|
|
||||||
{
|
|
||||||
*pTT = attr | (((paddrStart >> 20) + i) << 20);
|
|
||||||
pTT++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long rt_hw_set_domain_register(unsigned long domain_val)
|
|
||||||
{
|
|
||||||
unsigned long old_domain;
|
|
||||||
|
|
||||||
asm volatile ("mrc p15, 0, %0, c3, c0\n" : "=r" (old_domain));
|
|
||||||
asm volatile ("mcr p15, 0, %0, c3, c0\n" : :"r" (domain_val) : "memory");
|
|
||||||
|
|
||||||
return old_domain;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rt_hw_mmu_init(void)
|
|
||||||
{
|
|
||||||
rt_hw_cpu_dcache_disable();
|
|
||||||
rt_hw_cpu_icache_disable();
|
|
||||||
rt_cpu_mmu_disable();
|
|
||||||
|
|
||||||
/* set page table */
|
|
||||||
/* 4G 1:1 memory */
|
|
||||||
rt_hw_mmu_setmtt(0, 0xffffffff-1, 0, RW_CB);
|
|
||||||
/* IO memory region */
|
|
||||||
rt_hw_mmu_setmtt(0x44000000, 0x80000000-1, 0x44000000, RW_NCNBXN);
|
|
||||||
|
|
||||||
/*rt_hw_cpu_dump_page_table(MMUTable);*/
|
|
||||||
rt_hw_set_domain_register(0x55555555);
|
|
||||||
|
|
||||||
rt_cpu_tlb_set(MMUTable);
|
|
||||||
|
|
||||||
rt_cpu_mmu_enable();
|
|
||||||
|
|
||||||
rt_hw_cpu_icache_enable();
|
|
||||||
rt_hw_cpu_dcache_enable();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
#include <rtthread.h>
|
|
||||||
#include "pmu.h"
|
|
||||||
|
|
||||||
void rt_hw_pmu_dump_feature(void)
|
|
||||||
{
|
|
||||||
unsigned long reg;
|
|
||||||
|
|
||||||
reg = rt_hw_pmu_get_control();
|
|
||||||
rt_kprintf("ARM PMU Implementor: %c, ID code: %02x, %d counters\n",
|
|
||||||
reg >> 24, (reg >> 16) & 0xff, (reg >> 11) & 0x1f);
|
|
||||||
RT_ASSERT(ARM_PMU_CNTER_NR == ((reg >> 11) & 0x1f));
|
|
||||||
}
|
|
|
@ -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__ */
|
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
/*
|
|
||||||
* File : stack.c
|
|
||||||
* This file is part of RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2011, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may be
|
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rt-thread.org/license/LICENSE
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2011-09-23 Bernard the first version
|
|
||||||
* 2011-10-05 Bernard add thumb mode
|
|
||||||
*/
|
|
||||||
#include <rtthread.h>
|
|
||||||
#include <board.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup AM33xx
|
|
||||||
*/
|
|
||||||
/*@{*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will initialize thread stack
|
|
||||||
*
|
|
||||||
* @param tentry the entry of thread
|
|
||||||
* @param parameter the parameter of entry
|
|
||||||
* @param stack_addr the beginning stack address
|
|
||||||
* @param texit the function will be called when thread exit
|
|
||||||
*
|
|
||||||
* @return stack address
|
|
||||||
*/
|
|
||||||
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
|
|
||||||
rt_uint8_t *stack_addr, void *texit)
|
|
||||||
{
|
|
||||||
rt_uint32_t *stk;
|
|
||||||
|
|
||||||
stack_addr += sizeof(rt_uint32_t);
|
|
||||||
stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8);
|
|
||||||
stk = (rt_uint32_t*)stack_addr;
|
|
||||||
*(--stk) = (rt_uint32_t)tentry; /* entry point */
|
|
||||||
*(--stk) = (rt_uint32_t)texit; /* lr */
|
|
||||||
*(--stk) = 0; /* r12 */
|
|
||||||
*(--stk) = 0; /* r11 */
|
|
||||||
*(--stk) = 0; /* r10 */
|
|
||||||
*(--stk) = 0; /* r9 */
|
|
||||||
*(--stk) = 0; /* r8 */
|
|
||||||
*(--stk) = 0; /* r7 */
|
|
||||||
*(--stk) = 0; /* r6 */
|
|
||||||
*(--stk) = 0; /* r5 */
|
|
||||||
*(--stk) = 0; /* r4 */
|
|
||||||
*(--stk) = 0; /* r3 */
|
|
||||||
*(--stk) = 0; /* r2 */
|
|
||||||
*(--stk) = 0; /* r1 */
|
|
||||||
*(--stk) = (rt_uint32_t)parameter; /* r0 : argument */
|
|
||||||
/* cpsr */
|
|
||||||
if ((rt_uint32_t)tentry & 0x01)
|
|
||||||
*(--stk) = SVCMODE | 0x20; /* thumb mode */
|
|
||||||
else
|
|
||||||
*(--stk) = SVCMODE; /* arm mode */
|
|
||||||
|
|
||||||
#ifdef RT_USING_LWP
|
|
||||||
*(--stk) = 0; /* user lr */
|
|
||||||
*(--stk) = 0; /* user sp*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* return task's current stack address */
|
|
||||||
return (rt_uint8_t *)stk;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*@}*/
|
|
|
@ -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
|
|
|
@ -1,190 +0,0 @@
|
||||||
/*
|
|
||||||
* File : trap.c
|
|
||||||
* This file is part of RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2013, RT-Thread Develop Team
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may be
|
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rt-thread.org/license/LICENSE
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2013-07-20 Bernard first version
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtthread.h>
|
|
||||||
#include <rthw.h>
|
|
||||||
#include <board.h>
|
|
||||||
|
|
||||||
#include "armv7.h"
|
|
||||||
|
|
||||||
#include "gic.h"
|
|
||||||
|
|
||||||
#ifdef RT_USING_FINSH
|
|
||||||
extern long list_thread(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* this function will show registers of CPU
|
|
||||||
*
|
|
||||||
* @param regs the registers point
|
|
||||||
*/
|
|
||||||
void rt_hw_show_register(struct rt_hw_exp_stack *regs)
|
|
||||||
{
|
|
||||||
rt_kprintf("Execption:\n");
|
|
||||||
rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
|
|
||||||
rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
|
|
||||||
rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
|
|
||||||
rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
|
|
||||||
rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
|
|
||||||
rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When comes across an instruction which it cannot handle,
|
|
||||||
* it takes the undefined instruction trap.
|
|
||||||
*
|
|
||||||
* @param regs system registers
|
|
||||||
*
|
|
||||||
* @note never invoke this function in application
|
|
||||||
*/
|
|
||||||
void rt_hw_trap_undef(struct rt_hw_exp_stack *regs)
|
|
||||||
{
|
|
||||||
rt_kprintf("undefined instruction:\n");
|
|
||||||
rt_hw_show_register(regs);
|
|
||||||
#ifdef RT_USING_FINSH
|
|
||||||
list_thread();
|
|
||||||
#endif
|
|
||||||
rt_hw_cpu_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The software interrupt instruction (SWI) is used for entering
|
|
||||||
* Supervisor mode, usually to request a particular supervisor
|
|
||||||
* function.
|
|
||||||
*
|
|
||||||
* @param regs system registers
|
|
||||||
*
|
|
||||||
* @note never invoke this function in application
|
|
||||||
*/
|
|
||||||
void rt_hw_trap_swi(struct rt_hw_exp_stack *regs)
|
|
||||||
{
|
|
||||||
rt_kprintf("software interrupt:\n");
|
|
||||||
rt_hw_show_register(regs);
|
|
||||||
#ifdef RT_USING_FINSH
|
|
||||||
list_thread();
|
|
||||||
#endif
|
|
||||||
rt_hw_cpu_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abort indicates that the current memory access cannot be completed,
|
|
||||||
* which occurs during an instruction prefetch.
|
|
||||||
*
|
|
||||||
* @param regs system registers
|
|
||||||
*
|
|
||||||
* @note never invoke this function in application
|
|
||||||
*/
|
|
||||||
void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs)
|
|
||||||
{
|
|
||||||
rt_kprintf("prefetch abort:\n");
|
|
||||||
rt_hw_show_register(regs);
|
|
||||||
#ifdef RT_USING_FINSH
|
|
||||||
list_thread();
|
|
||||||
#endif
|
|
||||||
rt_hw_cpu_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abort indicates that the current memory access cannot be completed,
|
|
||||||
* which occurs during a data access.
|
|
||||||
*
|
|
||||||
* @param regs system registers
|
|
||||||
*
|
|
||||||
* @note never invoke this function in application
|
|
||||||
*/
|
|
||||||
void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs)
|
|
||||||
{
|
|
||||||
rt_kprintf("data abort:");
|
|
||||||
rt_hw_show_register(regs);
|
|
||||||
#ifdef RT_USING_FINSH
|
|
||||||
list_thread();
|
|
||||||
#endif
|
|
||||||
rt_hw_cpu_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Normally, system will never reach here
|
|
||||||
*
|
|
||||||
* @param regs system registers
|
|
||||||
*
|
|
||||||
* @note never invoke this function in application
|
|
||||||
*/
|
|
||||||
void rt_hw_trap_resv(struct rt_hw_exp_stack *regs)
|
|
||||||
{
|
|
||||||
rt_kprintf("reserved trap:\n");
|
|
||||||
rt_hw_show_register(regs);
|
|
||||||
#ifdef RT_USING_FINSH
|
|
||||||
list_thread();
|
|
||||||
#endif
|
|
||||||
rt_hw_cpu_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GIC_ACK_INTID_MASK 0x000003ff
|
|
||||||
|
|
||||||
void rt_hw_trap_irq(void)
|
|
||||||
{
|
|
||||||
void *param;
|
|
||||||
unsigned long ir;
|
|
||||||
unsigned long fullir;
|
|
||||||
rt_isr_handler_t isr_func;
|
|
||||||
extern struct rt_irq_desc isr_table[];
|
|
||||||
|
|
||||||
fullir = arm_gic_get_active_irq(0);
|
|
||||||
ir = fullir & GIC_ACK_INTID_MASK;
|
|
||||||
|
|
||||||
if (ir == 1023)
|
|
||||||
{
|
|
||||||
/* Spurious interrupt */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get interrupt service routine */
|
|
||||||
isr_func = isr_table[ir].handler;
|
|
||||||
#ifdef RT_USING_INTERRUPT_INFO
|
|
||||||
isr_table[ir].counter++;
|
|
||||||
#endif
|
|
||||||
if (isr_func)
|
|
||||||
{
|
|
||||||
/* Interrupt for myself. */
|
|
||||||
param = isr_table[ir].param;
|
|
||||||
/* turn to interrupt service routine */
|
|
||||||
isr_func(ir, param);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* end of interrupt */
|
|
||||||
arm_gic_ack(0, fullir);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rt_hw_trap_fiq(void)
|
|
||||||
{
|
|
||||||
void *param;
|
|
||||||
unsigned long ir;
|
|
||||||
unsigned long fullir;
|
|
||||||
rt_isr_handler_t isr_func;
|
|
||||||
extern struct rt_irq_desc isr_table[];
|
|
||||||
|
|
||||||
fullir = arm_gic_get_active_irq(0);
|
|
||||||
ir = fullir & GIC_ACK_INTID_MASK;
|
|
||||||
|
|
||||||
/* get interrupt service routine */
|
|
||||||
isr_func = isr_table[ir].handler;
|
|
||||||
param = isr_table[ir].param;
|
|
||||||
|
|
||||||
/* turn to interrupt service routine */
|
|
||||||
isr_func(ir, param);
|
|
||||||
|
|
||||||
/* end of interrupt */
|
|
||||||
arm_gic_ack(0, fullir);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
|
|
@ -17,6 +17,15 @@
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "drv_timer.h"
|
#include "drv_timer.h"
|
||||||
|
|
||||||
|
#include <mmu.h>
|
||||||
|
|
||||||
|
struct mem_desc platform_mem_desc[] = {
|
||||||
|
{0x10000000, 0x50000000, 0x10000000, DEVICE_MEM},
|
||||||
|
{0x60000000, 0xe0000000, 0x60000000, NORMAL_MEM}
|
||||||
|
};
|
||||||
|
|
||||||
|
const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]);
|
||||||
|
|
||||||
#define SYS_CTRL __REG32(REALVIEW_SCTL_BASE)
|
#define SYS_CTRL __REG32(REALVIEW_SCTL_BASE)
|
||||||
|
|
||||||
extern void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler);
|
extern void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler);
|
||||||
|
|
|
@ -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')
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2018-03-22 quanzhao first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PLATFORM_H__
|
||||||
|
#define __PLATFORM_H__
|
||||||
|
|
||||||
|
/* for 'rt_inline' */
|
||||||
|
#include <rtdef.h>
|
||||||
|
/* SOC-relative definitions */
|
||||||
|
#include "realview.h"
|
||||||
|
|
||||||
|
/* the maximum entries of the exception table */
|
||||||
|
#define MAX_HANDLERS NR_IRQS_PBA8
|
||||||
|
|
||||||
|
/* the basic constants and interfaces needed by gic */
|
||||||
|
rt_inline rt_uint32_t platform_get_gic_dist_base(void)
|
||||||
|
{
|
||||||
|
return REALVIEW_GIC_DIST_BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_inline rt_uint32_t platform_get_gic_cpu_base(void)
|
||||||
|
{
|
||||||
|
return REALVIEW_GIC_CPU_BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GIC_IRQ_START 0
|
||||||
|
|
||||||
|
#define GIC_ACK_INTID_MASK 0x000003ff
|
||||||
|
|
||||||
|
#endif /* __PLATFORM_H__ */
|
|
@ -10,7 +10,9 @@
|
||||||
#define RT_USING_SMP
|
#define RT_USING_SMP
|
||||||
#define RT_CPUS_NR 2
|
#define RT_CPUS_NR 2
|
||||||
#define RT_ALIGN_SIZE 4
|
#define RT_ALIGN_SIZE 4
|
||||||
|
/* RT_THREAD_PRIORITY_8 is not set */
|
||||||
#define RT_THREAD_PRIORITY_32
|
#define RT_THREAD_PRIORITY_32
|
||||||
|
/* RT_THREAD_PRIORITY_256 is not set */
|
||||||
#define RT_THREAD_PRIORITY_MAX 32
|
#define RT_THREAD_PRIORITY_MAX 32
|
||||||
#define RT_TICK_PER_SECOND 100
|
#define RT_TICK_PER_SECOND 100
|
||||||
#define RT_USING_OVERFLOW_CHECK
|
#define RT_USING_OVERFLOW_CHECK
|
||||||
|
@ -37,7 +39,10 @@
|
||||||
|
|
||||||
#define RT_USING_MEMPOOL
|
#define RT_USING_MEMPOOL
|
||||||
#define RT_USING_MEMHEAP
|
#define RT_USING_MEMHEAP
|
||||||
|
/* RT_USING_NOHEAP is not set */
|
||||||
#define RT_USING_SMALL_MEM
|
#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_MEMTRACE
|
||||||
#define RT_USING_HEAP
|
#define RT_USING_HEAP
|
||||||
|
|
||||||
|
@ -53,6 +58,7 @@
|
||||||
#define ARCH_ARM
|
#define ARCH_ARM
|
||||||
#define ARCH_ARM_CORTEX_A
|
#define ARCH_ARM_CORTEX_A
|
||||||
#define ARCH_ARM_CORTEX_A9
|
#define ARCH_ARM_CORTEX_A9
|
||||||
|
/* ARCH_CPU_STACK_GROWS_UPWARD is not set */
|
||||||
|
|
||||||
/* RT-Thread Components */
|
/* RT-Thread Components */
|
||||||
|
|
||||||
|
@ -73,11 +79,14 @@
|
||||||
#define FINSH_HISTORY_LINES 5
|
#define FINSH_HISTORY_LINES 5
|
||||||
#define FINSH_USING_SYMTAB
|
#define FINSH_USING_SYMTAB
|
||||||
#define FINSH_USING_DESCRIPTION
|
#define FINSH_USING_DESCRIPTION
|
||||||
|
/* FINSH_ECHO_DISABLE_DEFAULT is not set */
|
||||||
#define FINSH_THREAD_PRIORITY 20
|
#define FINSH_THREAD_PRIORITY 20
|
||||||
#define FINSH_THREAD_STACK_SIZE 4096
|
#define FINSH_THREAD_STACK_SIZE 4096
|
||||||
#define FINSH_CMD_SIZE 80
|
#define FINSH_CMD_SIZE 80
|
||||||
|
/* FINSH_USING_AUTH is not set */
|
||||||
#define FINSH_USING_MSH
|
#define FINSH_USING_MSH
|
||||||
#define FINSH_USING_MSH_DEFAULT
|
#define FINSH_USING_MSH_DEFAULT
|
||||||
|
/* FINSH_USING_MSH_ONLY is not set */
|
||||||
#define FINSH_ARG_MAX 10
|
#define FINSH_ARG_MAX 10
|
||||||
|
|
||||||
/* Device virtual file system */
|
/* Device virtual file system */
|
||||||
|
@ -87,21 +96,29 @@
|
||||||
#define DFS_FILESYSTEMS_MAX 2
|
#define DFS_FILESYSTEMS_MAX 2
|
||||||
#define DFS_FILESYSTEM_TYPES_MAX 8
|
#define DFS_FILESYSTEM_TYPES_MAX 8
|
||||||
#define DFS_FD_MAX 16
|
#define DFS_FD_MAX 16
|
||||||
|
/* RT_USING_DFS_MNTTABLE is not set */
|
||||||
#define RT_USING_DFS_ELMFAT
|
#define RT_USING_DFS_ELMFAT
|
||||||
|
|
||||||
/* elm-chan's FatFs, Generic FAT Filesystem Module */
|
/* elm-chan's FatFs, Generic FAT Filesystem Module */
|
||||||
|
|
||||||
#define RT_DFS_ELM_CODE_PAGE 437
|
#define RT_DFS_ELM_CODE_PAGE 437
|
||||||
#define RT_DFS_ELM_WORD_ACCESS
|
#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_USE_LFN 3
|
#define RT_DFS_ELM_USE_LFN 3
|
||||||
#define RT_DFS_ELM_MAX_LFN 255
|
#define RT_DFS_ELM_MAX_LFN 255
|
||||||
#define RT_DFS_ELM_DRIVES 2
|
#define RT_DFS_ELM_DRIVES 2
|
||||||
#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096
|
#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096
|
||||||
|
/* RT_DFS_ELM_USE_ERASE is not set */
|
||||||
#define RT_DFS_ELM_REENTRANT
|
#define RT_DFS_ELM_REENTRANT
|
||||||
#define RT_USING_DFS_DEVFS
|
#define RT_USING_DFS_DEVFS
|
||||||
#define RT_USING_DFS_ROMFS
|
#define RT_USING_DFS_ROMFS
|
||||||
#define RT_USING_DFS_RAMFS
|
#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 */
|
/* Device Drivers */
|
||||||
|
|
||||||
|
@ -110,12 +127,19 @@
|
||||||
#define RT_USING_SERIAL
|
#define RT_USING_SERIAL
|
||||||
#define RT_SERIAL_USING_DMA
|
#define RT_SERIAL_USING_DMA
|
||||||
#define RT_SERIAL_RB_BUFSZ 64
|
#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
|
||||||
#define RT_USING_I2C_BITOPS
|
#define RT_USING_I2C_BITOPS
|
||||||
#define RT_USING_PIN
|
#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_NOR
|
||||||
#define RT_USING_MTD_NAND
|
#define RT_USING_MTD_NAND
|
||||||
#define RT_MTD_NAND_DEBUG
|
#define RT_MTD_NAND_DEBUG
|
||||||
|
/* RT_USING_MTD is not set */
|
||||||
|
/* RT_USING_PM is not set */
|
||||||
#define RT_USING_RTC
|
#define RT_USING_RTC
|
||||||
#define RT_USING_SOFT_RTC
|
#define RT_USING_SOFT_RTC
|
||||||
#define RT_USING_SDIO
|
#define RT_USING_SDIO
|
||||||
|
@ -124,18 +148,31 @@
|
||||||
#define RT_MMCSD_STACK_SIZE 1024
|
#define RT_MMCSD_STACK_SIZE 1024
|
||||||
#define RT_MMCSD_THREAD_PREORITY 22
|
#define RT_MMCSD_THREAD_PREORITY 22
|
||||||
#define RT_MMCSD_MAX_PARTITION 16
|
#define RT_MMCSD_MAX_PARTITION 16
|
||||||
|
/* RT_SDIO_DEBUG is not set */
|
||||||
#define RT_USING_SPI
|
#define RT_USING_SPI
|
||||||
|
/* RT_USING_QSPI is not set */
|
||||||
#define RT_USING_SPI_MSD
|
#define RT_USING_SPI_MSD
|
||||||
#define RT_USING_SFUD
|
#define RT_USING_SFUD
|
||||||
#define RT_SFUD_USING_SFDP
|
#define RT_SFUD_USING_SFDP
|
||||||
#define RT_SFUD_USING_FLASH_INFO_TABLE
|
#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
|
#define RT_USING_WDT
|
||||||
|
/* RT_USING_AUDIO is not set */
|
||||||
|
/* RT_USING_SENSOR is not set */
|
||||||
|
|
||||||
/* Using WiFi */
|
/* Using WiFi */
|
||||||
|
|
||||||
|
/* RT_USING_WIFI is not set */
|
||||||
|
|
||||||
/* Using USB */
|
/* Using USB */
|
||||||
|
|
||||||
|
/* RT_USING_USB_HOST is not set */
|
||||||
|
/* RT_USING_USB_DEVICE is not set */
|
||||||
|
|
||||||
/* POSIX layer and C standard library */
|
/* POSIX layer and C standard library */
|
||||||
|
|
||||||
|
@ -145,6 +182,7 @@
|
||||||
#define RT_USING_POSIX_MMAP
|
#define RT_USING_POSIX_MMAP
|
||||||
#define RT_USING_POSIX_TERMIOS
|
#define RT_USING_POSIX_TERMIOS
|
||||||
#define RT_USING_POSIX_AIO
|
#define RT_USING_POSIX_AIO
|
||||||
|
/* RT_USING_MODULE is not set */
|
||||||
|
|
||||||
/* Network */
|
/* Network */
|
||||||
|
|
||||||
|
@ -161,9 +199,13 @@
|
||||||
/* light weight TCP/IP stack */
|
/* light weight TCP/IP stack */
|
||||||
|
|
||||||
#define RT_USING_LWIP
|
#define RT_USING_LWIP
|
||||||
|
/* RT_USING_LWIP141 is not set */
|
||||||
#define RT_USING_LWIP202
|
#define RT_USING_LWIP202
|
||||||
|
/* RT_USING_LWIP210 is not set */
|
||||||
#define RT_USING_LWIP_IPV6
|
#define RT_USING_LWIP_IPV6
|
||||||
|
/* RT_LWIP_IGMP is not set */
|
||||||
#define RT_LWIP_ICMP
|
#define RT_LWIP_ICMP
|
||||||
|
/* RT_LWIP_SNMP is not set */
|
||||||
#define RT_LWIP_DNS
|
#define RT_LWIP_DNS
|
||||||
#define RT_LWIP_DHCP
|
#define RT_LWIP_DHCP
|
||||||
#define IP_SOF_BROADCAST 1
|
#define IP_SOF_BROADCAST 1
|
||||||
|
@ -176,6 +218,8 @@
|
||||||
#define RT_LWIP_MSKADDR "255.255.255.0"
|
#define RT_LWIP_MSKADDR "255.255.255.0"
|
||||||
#define RT_LWIP_UDP
|
#define RT_LWIP_UDP
|
||||||
#define RT_LWIP_TCP
|
#define RT_LWIP_TCP
|
||||||
|
/* RT_LWIP_RAW is not set */
|
||||||
|
/* RT_LWIP_PPP is not set */
|
||||||
#define RT_MEMP_NUM_NETCONN 8
|
#define RT_MEMP_NUM_NETCONN 8
|
||||||
#define RT_LWIP_PBUF_NUM 16
|
#define RT_LWIP_PBUF_NUM 16
|
||||||
#define RT_LWIP_RAW_PCB_NUM 4
|
#define RT_LWIP_RAW_PCB_NUM 4
|
||||||
|
@ -187,6 +231,8 @@
|
||||||
#define RT_LWIP_TCPTHREAD_PRIORITY 10
|
#define RT_LWIP_TCPTHREAD_PRIORITY 10
|
||||||
#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8
|
#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8
|
||||||
#define RT_LWIP_TCPTHREAD_STACKSIZE 1024
|
#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_PRIORITY 12
|
||||||
#define RT_LWIP_ETHTHREAD_STACKSIZE 1024
|
#define RT_LWIP_ETHTHREAD_STACKSIZE 1024
|
||||||
#define RT_LWIP_ETHTHREAD_MBOX_SIZE 8
|
#define RT_LWIP_ETHTHREAD_MBOX_SIZE 8
|
||||||
|
@ -196,62 +242,164 @@
|
||||||
#define LWIP_SO_RCVTIMEO 1
|
#define LWIP_SO_RCVTIMEO 1
|
||||||
#define LWIP_SO_SNDTIMEO 1
|
#define LWIP_SO_SNDTIMEO 1
|
||||||
#define LWIP_SO_RCVBUF 1
|
#define LWIP_SO_RCVBUF 1
|
||||||
|
/* RT_LWIP_NETIF_LOOPBACK is not set */
|
||||||
#define LWIP_NETIF_LOOPBACK 0
|
#define LWIP_NETIF_LOOPBACK 0
|
||||||
|
/* RT_LWIP_STATS is not set */
|
||||||
|
/* RT_LWIP_DEBUG is not set */
|
||||||
|
|
||||||
/* Modbus master and slave stack */
|
/* Modbus master and slave stack */
|
||||||
|
|
||||||
|
/* RT_USING_MODBUS is not set */
|
||||||
|
|
||||||
/* AT commands */
|
/* AT commands */
|
||||||
|
|
||||||
|
/* RT_USING_AT is not set */
|
||||||
|
/* LWIP_USING_DHCPD is not set */
|
||||||
|
|
||||||
/* VBUS(Virtual Software BUS) */
|
/* VBUS(Virtual Software BUS) */
|
||||||
|
|
||||||
|
/* RT_USING_VBUS is not set */
|
||||||
|
|
||||||
/* Utilities */
|
/* Utilities */
|
||||||
|
|
||||||
#define RT_USING_LOGTRACE
|
#define RT_USING_LOGTRACE
|
||||||
#define LOG_TRACE_MAX_SESSION 16
|
#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
|
#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
|
#define RT_USING_LWP
|
||||||
|
|
||||||
/* RT-Thread online packages */
|
/* RT-Thread online packages */
|
||||||
|
|
||||||
/* IoT - internet of things */
|
/* 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 */
|
/* Wi-Fi */
|
||||||
|
|
||||||
/* Marvell WiFi */
|
/* Marvell WiFi */
|
||||||
|
|
||||||
|
/* PKG_USING_WLANMARVELL is not set */
|
||||||
|
|
||||||
/* Wiced WiFi */
|
/* 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 */
|
/* 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 */
|
/* security packages */
|
||||||
|
|
||||||
|
/* PKG_USING_MBEDTLS is not set */
|
||||||
|
/* PKG_USING_libsodium is not set */
|
||||||
|
/* PKG_USING_TINYCRYPT is not set */
|
||||||
|
|
||||||
/* language packages */
|
/* language packages */
|
||||||
|
|
||||||
|
/* PKG_USING_LUA is not set */
|
||||||
|
/* PKG_USING_JERRYSCRIPT is not set */
|
||||||
|
/* PKG_USING_MICROPYTHON is not set */
|
||||||
|
|
||||||
/* multimedia packages */
|
/* multimedia packages */
|
||||||
|
|
||||||
|
/* PKG_USING_OPENMV is not set */
|
||||||
|
/* PKG_USING_MUPDF is not set */
|
||||||
|
|
||||||
/* tools packages */
|
/* 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 */
|
/* 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 */
|
/* peripheral libraries and drivers */
|
||||||
|
|
||||||
/* sensors 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 */
|
/* 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 */
|
/* samples: kernel and components samples */
|
||||||
|
|
||||||
|
@ -259,5 +407,6 @@
|
||||||
#define RT_USING_UART0
|
#define RT_USING_UART0
|
||||||
#define RT_USING_UART1
|
#define RT_USING_UART1
|
||||||
#define BSP_DRV_EMAC
|
#define BSP_DRV_EMAC
|
||||||
|
/* BSP_DRV_AUDIO is not set */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,14 +2,15 @@ import os
|
||||||
|
|
||||||
# toolchains options
|
# toolchains options
|
||||||
ARCH='arm'
|
ARCH='arm'
|
||||||
CPU='cortex-a9'
|
CPU='cortex-a'
|
||||||
CROSS_TOOL='gcc'
|
CROSS_TOOL='gcc'
|
||||||
|
|
||||||
if os.getenv('RTT_CC'):
|
if os.getenv('RTT_CC'):
|
||||||
CROSS_TOOL = os.getenv('RTT_CC')
|
CROSS_TOOL = os.getenv('RTT_CC')
|
||||||
|
|
||||||
|
# only support GNU GCC compiler.
|
||||||
PLATFORM = 'gcc'
|
PLATFORM = 'gcc'
|
||||||
EXEC_PATH = '/opt/gcc-arm-none-eabi-4_8-2014q1_gri/bin'
|
EXEC_PATH = '/usr/bin'
|
||||||
|
|
||||||
if os.getenv('RTT_EXEC_PATH'):
|
if os.getenv('RTT_EXEC_PATH'):
|
||||||
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
|
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
|
||||||
|
|
|
@ -93,32 +93,14 @@ void _Error_Handler(char *s, int num)
|
||||||
*/
|
*/
|
||||||
void rt_hw_us_delay(rt_uint32_t us)
|
void rt_hw_us_delay(rt_uint32_t us)
|
||||||
{
|
{
|
||||||
rt_uint32_t ticks;
|
rt_uint32_t start, now, delta, reload, us_tick;
|
||||||
rt_uint32_t told, tnow, tcnt = 0;
|
start = SysTick->VAL;
|
||||||
rt_uint32_t reload = SysTick->LOAD;
|
reload = SysTick->LOAD;
|
||||||
|
us_tick = SystemCoreClock / 1000000UL;
|
||||||
ticks = us * reload / (1000000 / RT_TICK_PER_SECOND);
|
do {
|
||||||
told = SysTick->VAL;
|
now = SysTick->VAL;
|
||||||
while (1)
|
delta = start > now ? start - now : reload + start - now;
|
||||||
{
|
} while(delta < us_tick * us);
|
||||||
tnow = SysTick->VAL;
|
|
||||||
if (tnow != told)
|
|
||||||
{
|
|
||||||
if (tnow < told)
|
|
||||||
{
|
|
||||||
tcnt += told - tnow;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tcnt += reload - tnow + told;
|
|
||||||
}
|
|
||||||
told = tnow;
|
|
||||||
if (tcnt >= ticks)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5,7 +5,7 @@ cwd = GetCurrentDir()
|
||||||
src = []
|
src = []
|
||||||
CPPPATH = [cwd]
|
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'}
|
platform_file = {'armcc': 'rvds.S', 'gcc': 'gcc.S', 'iar': 'iar.S'}
|
||||||
|
|
||||||
if rtconfig.PLATFORM in platform_file.keys(): # support platforms
|
if rtconfig.PLATFORM in platform_file.keys(): # support platforms
|
||||||
|
|
|
@ -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
|
|
@ -8,7 +8,14 @@
|
||||||
* 2013-07-05 Bernard the first version
|
* 2013-07-05 Bernard the first version
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "rtconfig.h"
|
||||||
.section .text, "ax"
|
.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();
|
* rt_base_t rt_hw_interrupt_disable();
|
||||||
*/
|
*/
|
||||||
|
@ -34,6 +41,16 @@ rt_hw_interrupt_enable:
|
||||||
rt_hw_context_switch_to:
|
rt_hw_context_switch_to:
|
||||||
ldr sp, [r0] @ get new task stack pointer
|
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
|
ldmfd sp!, {r4} @ pop new task spsr
|
||||||
msr spsr_cxsf, r4
|
msr spsr_cxsf, r4
|
||||||
|
|
||||||
|
@ -62,9 +79,24 @@ rt_hw_context_switch:
|
||||||
|
|
||||||
stmfd sp!, {r4} @ push cpsr
|
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
|
str sp, [r0] @ store sp in preempted tasks TCB
|
||||||
ldr sp, [r1] @ get new task stack pointer
|
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
|
ldmfd sp!, {r4} @ pop new task cpsr to spsr
|
||||||
msr spsr_cxsf, r4
|
msr spsr_cxsf, r4
|
||||||
ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc, copy spsr to cpsr
|
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);
|
* 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_thread_switch_interrupt_flag
|
||||||
.globl rt_interrupt_from_thread
|
.globl rt_interrupt_from_thread
|
||||||
.globl rt_interrupt_to_thread
|
.globl rt_interrupt_to_thread
|
||||||
.globl rt_hw_context_switch_interrupt
|
.globl rt_hw_context_switch_interrupt
|
||||||
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 r2, =rt_thread_switch_interrupt_flag
|
||||||
ldr r3, [r2]
|
ldr r3, [r2]
|
||||||
cmp r3, #1
|
cmp r3, #1
|
||||||
|
@ -89,3 +180,4 @@ _reswitch:
|
||||||
ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread
|
ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread
|
||||||
str r1, [r2]
|
str r1, [r2]
|
||||||
bx lr
|
bx lr
|
||||||
|
#endif /*RT_USING_SMP*/
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
|
* 2018-03-25 quanzhao the first version
|
||||||
*/
|
*/
|
||||||
#ifndef __CP15_H__
|
#ifndef __CP15_H__
|
||||||
#define __CP15_H__
|
#define __CP15_H__
|
||||||
|
@ -15,6 +16,9 @@ void rt_cpu_mmu_disable(void);
|
||||||
void rt_cpu_mmu_enable(void);
|
void rt_cpu_mmu_enable(void);
|
||||||
void rt_cpu_tlb_set(volatile unsigned long*);
|
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);
|
void rt_cpu_vector_set_base(unsigned int addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,6 +15,11 @@ rt_cpu_get_smp_id:
|
||||||
|
|
||||||
.globl rt_cpu_vector_set_base
|
.globl rt_cpu_vector_set_base
|
||||||
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
|
mcr p15, #0, r0, c12, c0, #0
|
||||||
dsb
|
dsb
|
||||||
bx lr
|
bx lr
|
||||||
|
@ -36,7 +41,7 @@ rt_hw_cpu_icache_enable:
|
||||||
_FLD_MAX_WAY:
|
_FLD_MAX_WAY:
|
||||||
.word 0x3ff
|
.word 0x3ff
|
||||||
_FLD_MAX_IDX:
|
_FLD_MAX_IDX:
|
||||||
.word 0x7ff
|
.word 0x7fff
|
||||||
|
|
||||||
.globl rt_cpu_dcache_clean_flush
|
.globl rt_cpu_dcache_clean_flush
|
||||||
rt_cpu_dcache_clean_flush:
|
rt_cpu_dcache_clean_flush:
|
||||||
|
@ -84,6 +89,14 @@ finished:
|
||||||
pop {r4-r11}
|
pop {r4-r11}
|
||||||
bx lr
|
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
|
.globl rt_hw_cpu_dcache_disable
|
||||||
rt_hw_cpu_dcache_disable:
|
rt_hw_cpu_dcache_disable:
|
||||||
push {r4-r11, lr}
|
push {r4-r11, lr}
|
||||||
|
|
|
@ -6,14 +6,64 @@
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2011-09-15 Bernard first version
|
* 2011-09-15 Bernard first version
|
||||||
|
* 2018-11-22 Jesven add rt_hw_cpu_id()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rthw.h>
|
#include <rthw.h>
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
#include <board.h>
|
#include <board.h>
|
||||||
|
|
||||||
|
#ifdef RT_USING_SMP
|
||||||
|
int rt_hw_cpu_id(void)
|
||||||
|
{
|
||||||
|
int cpu_id;
|
||||||
|
__asm__ volatile (
|
||||||
|
"mrc p15, 0, %0, c0, c0, 5"
|
||||||
|
:"=r"(cpu_id)
|
||||||
|
);
|
||||||
|
cpu_id &= 0xf;
|
||||||
|
return cpu_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
void rt_hw_spin_lock(rt_hw_spinlock_t *lock)
|
||||||
|
{
|
||||||
|
unsigned long tmp;
|
||||||
|
unsigned long newval;
|
||||||
|
rt_hw_spinlock_t lockval;
|
||||||
|
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"pld [%0]"
|
||||||
|
::"r"(&lock->slock)
|
||||||
|
);
|
||||||
|
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"1: ldrex %0, [%3]\n"
|
||||||
|
" add %1, %0, %4\n"
|
||||||
|
" strex %2, %1, [%3]\n"
|
||||||
|
" teq %2, #0\n"
|
||||||
|
" bne 1b"
|
||||||
|
: "=&r" (lockval), "=&r" (newval), "=&r" (tmp)
|
||||||
|
: "r" (&lock->slock), "I" (1 << 16)
|
||||||
|
: "cc");
|
||||||
|
|
||||||
|
while (lockval.tickets.next != lockval.tickets.owner) {
|
||||||
|
__asm__ __volatile__("wfe":::"memory");
|
||||||
|
lockval.tickets.owner = *(volatile unsigned short *)(&lock->tickets.owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
__asm__ volatile ("dmb":::"memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
void rt_hw_spin_unlock(rt_hw_spinlock_t *lock)
|
||||||
|
{
|
||||||
|
__asm__ volatile ("dmb":::"memory");
|
||||||
|
lock->tickets.owner++;
|
||||||
|
__asm__ volatile ("dsb ishst\nsev":::"memory");
|
||||||
|
}
|
||||||
|
#endif /*RT_USING_SMP*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup AM33xx
|
* @addtogroup ARM CPU
|
||||||
*/
|
*/
|
||||||
/*@{*/
|
/*@{*/
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* File : gic.c, ARM Generic Interrupt Controller
|
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||||
* This file is part of RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2013-2014, RT-Thread Develop Team
|
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rt-thread.org/license/LICENSE
|
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
|
@ -17,18 +13,19 @@
|
||||||
|
|
||||||
#include <rthw.h>
|
#include <rthw.h>
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
#include <board.h>
|
|
||||||
|
|
||||||
#include "gic.h"
|
#include "gic.h"
|
||||||
#include "cp15.h"
|
#include "cp15.h"
|
||||||
|
|
||||||
struct arm_gic
|
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 dist_hw_base; /* the base address of the gic distributor */
|
||||||
rt_uint32_t cpu_hw_base;
|
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];
|
static struct arm_gic _gic_table[ARM_GIC_MAX_NR];
|
||||||
|
|
||||||
#define GIC_CPU_CTRL(hw_base) __REG32((hw_base) + 0x00)
|
#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;
|
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)
|
void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask)
|
||||||
{
|
{
|
||||||
rt_uint32_t old_tgt;
|
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)
|
if (_gic_max_irq > 1020)
|
||||||
_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;
|
_gic_max_irq = ARM_GIC_NR_IRQS;
|
||||||
|
|
||||||
cpumask |= cpumask << 8;
|
cpumask |= cpumask << 8;
|
||||||
cpumask |= cpumask << 16;
|
cpumask |= cpumask << 16;
|
||||||
|
cpumask |= cpumask << 24;
|
||||||
|
|
||||||
GIC_DIST_CTRL(dist_base) = 0x0;
|
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)
|
for (i = 0; i < _gic_max_irq; i += 32)
|
||||||
GIC_DIST_IGROUP(dist_base, i) = 0xffffffff;
|
GIC_DIST_IGROUP(dist_base, i) = 0xffffffff;
|
||||||
#endif
|
#endif
|
||||||
|
for (i = 0; i < _gic_max_irq; i += 32)
|
||||||
|
GIC_DIST_IGROUP(dist_base, i) = 0;
|
||||||
|
|
||||||
/* Enable group0 and group1 interrupt forwarding. */
|
/* Enable group0 and group1 interrupt forwarding. */
|
||||||
GIC_DIST_CTRL(dist_base) = 0x03;
|
GIC_DIST_CTRL(dist_base) = 0x01;
|
||||||
|
|
||||||
return 0;
|
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_table[index].cpu_hw_base = cpu_base;
|
||||||
|
|
||||||
GIC_CPU_PRIMASK(cpu_base) = 0xf0;
|
GIC_CPU_PRIMASK(cpu_base) = 0xf0;
|
||||||
|
GIC_CPU_BINPOINT(cpu_base) = 0x7;
|
||||||
/* Enable CPU interrupt */
|
/* Enable CPU interrupt */
|
||||||
GIC_CPU_CTRL(cpu_base) = 0x01;
|
GIC_CPU_CTRL(cpu_base) = 0x01;
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* File : gic.h, ARM Generic Interrupt Controller
|
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||||
* 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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rt-thread.org/license/LICENSE
|
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
|
@ -15,6 +11,9 @@
|
||||||
#ifndef __GIC_H__
|
#ifndef __GIC_H__
|
||||||
#define __GIC_H__
|
#define __GIC_H__
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <platform.h>
|
||||||
|
|
||||||
int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start);
|
int arm_gic_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);
|
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);
|
int arm_gic_get_active_irq(rt_uint32_t index);
|
||||||
void arm_gic_ack(rt_uint32_t index, int irq);
|
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 arm_gic_dump_type(rt_uint32_t index);
|
||||||
void rt_hw_vector_init(void);
|
void arm_gic_dump(rt_uint32_t index);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,68 +6,32 @@
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2013-07-06 Bernard first version
|
* 2013-07-06 Bernard first version
|
||||||
* 2014-04-03 Grissiom port to VMM
|
* 2018-11-22 Jesven add smp support
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rthw.h>
|
#include <rthw.h>
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
#include "interrupt.h"
|
||||||
|
#include "gic.h"
|
||||||
|
|
||||||
#include <irq_numbers.h>
|
|
||||||
#include <interrupt.h>
|
|
||||||
|
|
||||||
#include <gic.h>
|
|
||||||
#include "cp15.h"
|
|
||||||
|
|
||||||
#define MAX_HANDLERS IMX_INTERRUPT_COUNT
|
|
||||||
|
|
||||||
extern volatile rt_uint8_t rt_interrupt_nest;
|
|
||||||
|
|
||||||
/* exception and interrupt handler table */
|
/* exception and interrupt handler table */
|
||||||
struct rt_irq_desc isr_table[MAX_HANDLERS];
|
struct rt_irq_desc isr_table[MAX_HANDLERS];
|
||||||
|
|
||||||
rt_uint32_t rt_interrupt_from_thread;
|
#ifndef RT_USING_SMP
|
||||||
rt_uint32_t rt_interrupt_to_thread;
|
/* Those varibles will be accessed in ISR, so we need to share them. */
|
||||||
rt_uint32_t rt_thread_switch_interrupt_flag;
|
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 void rt_cpu_vector_set_base(unsigned int addr);
|
||||||
extern int system_vectors;
|
extern int system_vectors;
|
||||||
|
|
||||||
/* keep compatible with platform SDK */
|
void rt_hw_vector_init(void)
|
||||||
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_cpu_vector_set_base((unsigned int)&system_vectors);
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,14 +39,24 @@ static void rt_hw_vector_init(void)
|
||||||
*/
|
*/
|
||||||
void rt_hw_interrupt_init(void)
|
void rt_hw_interrupt_init(void)
|
||||||
{
|
{
|
||||||
rt_hw_vector_init();
|
rt_uint32_t gic_cpu_base;
|
||||||
gic_init();
|
rt_uint32_t gic_dist_base;
|
||||||
|
rt_uint32_t gic_irq_start;
|
||||||
|
|
||||||
/* init interrupt nest, and context in thread sp */
|
/* initialize vector table */
|
||||||
rt_interrupt_nest = 0;
|
rt_hw_vector_init();
|
||||||
rt_interrupt_from_thread = 0;
|
|
||||||
rt_interrupt_to_thread = 0;
|
/* initialize exceptions table */
|
||||||
rt_thread_switch_interrupt_flag = 0;
|
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)
|
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)
|
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.
|
* This function will install a interrupt service routine to a interrupt.
|
||||||
* @param vector the interrupt number
|
* @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].handler = handler;
|
||||||
isr_table[vector].param = param;
|
isr_table[vector].param = param;
|
||||||
}
|
}
|
||||||
// arm_gic_set_cpu(0, vector, 1 << rt_cpu_get_smp_id());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return old_handler;
|
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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2013-07-06 Bernard first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __INTERRUPT_H__
|
||||||
|
#define __INTERRUPT_H__
|
||||||
|
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <platform.h>
|
||||||
|
|
||||||
|
#define INT_IRQ 0x00
|
||||||
|
#define INT_FIQ 0x01
|
||||||
|
|
||||||
|
void rt_hw_interrupt_control(int vector, int priority, int route);
|
||||||
|
|
||||||
|
void rt_hw_interrupt_init(void);
|
||||||
|
void rt_hw_interrupt_mask(int vector);
|
||||||
|
void rt_hw_interrupt_umask(int vector);
|
||||||
|
|
||||||
|
int rt_hw_interrupt_get_irq(void);
|
||||||
|
void rt_hw_interrupt_ack(int vector);
|
||||||
|
|
||||||
|
rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
|
||||||
|
void *param, const char *name);
|
||||||
|
|
||||||
|
#endif
|
|
@ -13,35 +13,7 @@
|
||||||
#include <board.h>
|
#include <board.h>
|
||||||
|
|
||||||
#include "cp15.h"
|
#include "cp15.h"
|
||||||
|
#include "mmu.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 */
|
/* dump 2nd level page table */
|
||||||
void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb)
|
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;
|
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)
|
void rt_hw_mmu_init(void)
|
||||||
{
|
{
|
||||||
|
rt_cpu_dcache_clean_flush();
|
||||||
|
rt_cpu_icache_flush();
|
||||||
rt_hw_cpu_dcache_disable();
|
rt_hw_cpu_dcache_disable();
|
||||||
rt_hw_cpu_icache_disable();
|
rt_hw_cpu_icache_disable();
|
||||||
rt_cpu_mmu_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_cpu_dump_page_table(MMUTable);*/
|
||||||
rt_hw_set_domain_register(0x55555555);
|
rt_hw_set_domain_register(0x55555555);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2019-03-25 quanzhao the first version
|
||||||
|
*/
|
||||||
|
#ifndef __MMU_H_
|
||||||
|
#define __MMU_H_
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
#define DESC_SEC (0x2)
|
||||||
|
#define MEMWB (3<<2) /* write back, no write allocate */
|
||||||
|
#define MEMWT (2<<2) /* write through, no write allocate */
|
||||||
|
#define SHAREDEVICE (1<<2) /* shared device */
|
||||||
|
#define STRONGORDER (0<<2) /* strong ordered */
|
||||||
|
#define XN (1<<4) /* eXecute Never */
|
||||||
|
#define AP_RW (3<<10) /* supervisor=RW, user=RW */
|
||||||
|
#define AP_RO (2<<10) /* supervisor=RW, user=RO */
|
||||||
|
#define SHARED (1<<16) /* shareable */
|
||||||
|
|
||||||
|
#define DOMAIN_FAULT (0x0)
|
||||||
|
#define DOMAIN_CHK (0x1)
|
||||||
|
#define DOMAIN_NOTCHK (0x3)
|
||||||
|
#define DOMAIN0 (0x0<<5)
|
||||||
|
#define DOMAIN1 (0x1<<5)
|
||||||
|
|
||||||
|
#define DOMAIN0_ATTR (DOMAIN_CHK<<0)
|
||||||
|
#define DOMAIN1_ATTR (DOMAIN_FAULT<<2)
|
||||||
|
|
||||||
|
/* device mapping type */
|
||||||
|
#define DEVICE_MEM (SHARED|AP_RW|DOMAIN0|SHAREDEVICE|DESC_SEC|XN)
|
||||||
|
/* normal memory mapping type */
|
||||||
|
#define NORMAL_MEM (SHARED|AP_RW|DOMAIN0|MEMWB|DESC_SEC)
|
||||||
|
|
||||||
|
struct mem_desc
|
||||||
|
{
|
||||||
|
rt_uint32_t vaddr_start;
|
||||||
|
rt_uint32_t vaddr_end;
|
||||||
|
rt_uint32_t paddr_start;
|
||||||
|
rt_uint32_t attr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -50,13 +50,17 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
|
||||||
*(--stk) = 0xdeadbeef; /* r2 */
|
*(--stk) = 0xdeadbeef; /* r2 */
|
||||||
*(--stk) = 0xdeadbeef; /* r1 */
|
*(--stk) = 0xdeadbeef; /* r1 */
|
||||||
*(--stk) = (rt_uint32_t)parameter; /* r0 : argument */
|
*(--stk) = (rt_uint32_t)parameter; /* r0 : argument */
|
||||||
|
|
||||||
/* cpsr */
|
/* cpsr */
|
||||||
if ((rt_uint32_t)tentry & 0x01)
|
if ((rt_uint32_t)tentry & 0x01)
|
||||||
*(--stk) = SVCMODE | 0x20; /* thumb mode */
|
*(--stk) = SVCMODE | 0x20; /* thumb mode */
|
||||||
else
|
else
|
||||||
*(--stk) = SVCMODE; /* arm mode */
|
*(--stk) = SVCMODE; /* arm mode */
|
||||||
|
|
||||||
|
#ifdef RT_USING_LWP
|
||||||
|
*(--stk) = 0; /* user lr */
|
||||||
|
*(--stk) = 0; /* user sp*/
|
||||||
|
#endif
|
||||||
|
|
||||||
/* return task's current stack address */
|
/* return task's current stack address */
|
||||||
return (rt_uint8_t *)stk;
|
return (rt_uint8_t *)stk;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,12 @@
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2013-07-05 Bernard the first version
|
* 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_USR, 0x10
|
||||||
.equ Mode_FIQ, 0x11
|
.equ Mode_FIQ, 0x11
|
||||||
.equ Mode_IRQ, 0x12
|
.equ Mode_IRQ, 0x12
|
||||||
|
@ -20,11 +24,11 @@
|
||||||
.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled
|
.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled
|
||||||
|
|
||||||
.equ UND_Stack_Size, 0x00000000
|
.equ UND_Stack_Size, 0x00000000
|
||||||
.equ SVC_Stack_Size, 0x00000100
|
.equ SVC_Stack_Size, 0x00000400
|
||||||
.equ ABT_Stack_Size, 0x00000000
|
.equ ABT_Stack_Size, 0x00000000
|
||||||
.equ RT_FIQ_STACK_PGSZ, 0x00000000
|
.equ RT_FIQ_STACK_PGSZ, 0x00000000
|
||||||
.equ RT_IRQ_STACK_PGSZ, 0x00000100
|
.equ RT_IRQ_STACK_PGSZ, 0x00000800
|
||||||
.equ USR_Stack_Size, 0x00000100
|
.equ USR_Stack_Size, 0x00000400
|
||||||
|
|
||||||
#define ISR_Stack_Size (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
|
#define ISR_Stack_Size (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
|
||||||
RT_FIQ_STACK_PGSZ + RT_IRQ_STACK_PGSZ)
|
RT_FIQ_STACK_PGSZ + RT_IRQ_STACK_PGSZ)
|
||||||
|
@ -44,12 +48,8 @@ stack_top:
|
||||||
/* reset entry */
|
/* reset entry */
|
||||||
.globl _reset
|
.globl _reset
|
||||||
_reset:
|
_reset:
|
||||||
bl rt_cpu_mmu_disable
|
|
||||||
/* set the cpu to SVC32 mode and disable interrupt */
|
/* set the cpu to SVC32 mode and disable interrupt */
|
||||||
mrs r0, cpsr
|
cps #Mode_SVC
|
||||||
bic r0, r0, #0x1f
|
|
||||||
orr r0, r0, #0x13
|
|
||||||
msr cpsr_c, r0
|
|
||||||
|
|
||||||
/* setup stack */
|
/* setup stack */
|
||||||
bl stack_setup
|
bl stack_setup
|
||||||
|
@ -64,6 +64,20 @@ bss_loop:
|
||||||
strlo r0,[r1],#4 /* clear 4 bytes */
|
strlo r0,[r1],#4 /* clear 4 bytes */
|
||||||
blo bss_loop /* loop until done */
|
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 */
|
/* call C++ constructors of global objects */
|
||||||
ldr r0, =__ctors_start__
|
ldr r0, =__ctors_start__
|
||||||
ldr r1, =__ctors_end__
|
ldr r1, =__ctors_end__
|
||||||
|
@ -137,12 +151,22 @@ vector_fiq:
|
||||||
.align 5
|
.align 5
|
||||||
.globl vector_irq
|
.globl vector_irq
|
||||||
vector_irq:
|
vector_irq:
|
||||||
|
#ifdef RT_USING_SMP
|
||||||
|
clrex
|
||||||
|
#endif
|
||||||
stmfd sp!, {r0-r12,lr}
|
stmfd sp!, {r0-r12,lr}
|
||||||
|
|
||||||
bl rt_interrupt_enter
|
bl rt_interrupt_enter
|
||||||
bl rt_hw_trap_irq
|
bl rt_hw_trap_irq
|
||||||
bl rt_interrupt_leave
|
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
|
@ if rt_thread_switch_interrupt_flag set, jump to
|
||||||
@ rt_hw_context_switch_interrupt_do and don't return
|
@ rt_hw_context_switch_interrupt_do and don't return
|
||||||
ldr r0, =rt_thread_switch_interrupt_flag
|
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!, {r1-r4} @ push old task's r0-r3
|
||||||
stmfd sp!, {r0} @ push old task's cpsr
|
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 r4, =rt_interrupt_from_thread
|
||||||
ldr r5, [r4]
|
ldr r5, [r4]
|
||||||
str sp, [r5] @ store sp in preempted tasks's TCB
|
str sp, [r5] @ store sp in preempted tasks's TCB
|
||||||
|
@ -182,11 +211,18 @@ rt_hw_context_switch_interrupt_do:
|
||||||
ldr r6, [r6]
|
ldr r6, [r6]
|
||||||
ldr sp, [r6] @ get new task's stack pointer
|
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
|
ldmfd sp!, {r4} @ pop new task's cpsr to spsr
|
||||||
msr spsr_cxsf, r4
|
msr spsr_cxsf, r4
|
||||||
|
|
||||||
ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
|
ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
.macro push_svc_reg
|
.macro push_svc_reg
|
||||||
sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */
|
sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */
|
||||||
stmia sp, {r0 - r12} @/* Calling r0-r12 */
|
stmia sp, {r0 - r12} @/* Calling r0-r12 */
|
||||||
|
@ -201,6 +237,8 @@ rt_hw_context_switch_interrupt_do:
|
||||||
|
|
||||||
.align 5
|
.align 5
|
||||||
.globl vector_swi
|
.globl vector_swi
|
||||||
|
.weak SVC_Handler
|
||||||
|
SVC_Handler:
|
||||||
vector_swi:
|
vector_swi:
|
||||||
push_svc_reg
|
push_svc_reg
|
||||||
bl rt_hw_trap_swi
|
bl rt_hw_trap_swi
|
||||||
|
@ -233,3 +271,51 @@ vector_resv:
|
||||||
push_svc_reg
|
push_svc_reg
|
||||||
bl rt_hw_trap_resv
|
bl rt_hw_trap_resv
|
||||||
b .
|
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:
|
||||||
|
|
||||||
|
|
|
@ -10,13 +10,11 @@
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
#include <rthw.h>
|
#include <rthw.h>
|
||||||
#include <board.h>
|
#include <platform.h>
|
||||||
|
|
||||||
#include "armv7.h"
|
#include "armv7.h"
|
||||||
|
#include "interrupt.h"
|
||||||
|
|
||||||
#include "gic.h"
|
|
||||||
|
|
||||||
extern struct rt_thread *rt_current_thread;
|
|
||||||
#ifdef RT_USING_FINSH
|
#ifdef RT_USING_FINSH
|
||||||
extern long list_thread(void);
|
extern long list_thread(void);
|
||||||
#endif
|
#endif
|
||||||
|
@ -130,48 +128,52 @@ void rt_hw_trap_resv(struct rt_hw_exp_stack *regs)
|
||||||
void rt_hw_trap_irq(void)
|
void rt_hw_trap_irq(void)
|
||||||
{
|
{
|
||||||
void *param;
|
void *param;
|
||||||
|
int ir;
|
||||||
rt_isr_handler_t isr_func;
|
rt_isr_handler_t isr_func;
|
||||||
extern struct rt_irq_desc isr_table[];
|
extern struct rt_irq_desc isr_table[];
|
||||||
|
|
||||||
// vectNum = RESERVED[31:13] | CPUID[12:10] | INTERRUPT_ID[9:0]
|
ir = rt_hw_interrupt_get_irq();
|
||||||
// send ack and get ID source
|
|
||||||
uint32_t vectNum = gic_read_irq_ack();
|
|
||||||
|
|
||||||
// Check that INT_ID isn't 1023 or 1022 (spurious interrupt)
|
if (ir == 1023)
|
||||||
if (vectNum & 0x0200)
|
|
||||||
{
|
{
|
||||||
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 */
|
/* get interrupt service routine */
|
||||||
isr_func = isr_table[irq].handler;
|
isr_func = isr_table[ir].handler;
|
||||||
#ifdef RT_USING_INTERRUPT_INFO
|
#ifdef RT_USING_INTERRUPT_INFO
|
||||||
isr_table[irq].counter++;
|
isr_table[ir].counter++;
|
||||||
#endif
|
#endif
|
||||||
if (isr_func)
|
if (isr_func)
|
||||||
{
|
{
|
||||||
/* Interrupt for myself. */
|
/* Interrupt for myself. */
|
||||||
param = isr_table[irq].param;
|
param = isr_table[ir].param;
|
||||||
/* turn to interrupt service routine */
|
/* turn to interrupt service routine */
|
||||||
isr_func(irq, param);
|
isr_func(ir, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signal the end of the irq.
|
/* end of interrupt */
|
||||||
gic_write_end_of_irq(vectNum);
|
rt_hw_interrupt_ack(ir);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rt_hw_trap_fiq(void)
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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')
|
|
|
@ -668,7 +668,7 @@ static char *print_number(char *buf,
|
||||||
|
|
||||||
while (size-- > 0)
|
while (size-- > 0)
|
||||||
{
|
{
|
||||||
if (buf <= end)
|
if (buf < end)
|
||||||
*buf = ' ';
|
*buf = ' ';
|
||||||
++ buf;
|
++ buf;
|
||||||
}
|
}
|
||||||
|
@ -676,11 +676,11 @@ static char *print_number(char *buf,
|
||||||
|
|
||||||
if (sign)
|
if (sign)
|
||||||
{
|
{
|
||||||
if (buf <= end)
|
if (buf < end)
|
||||||
{
|
{
|
||||||
*buf = sign;
|
*buf = sign;
|
||||||
-- size;
|
|
||||||
}
|
}
|
||||||
|
-- size;
|
||||||
++ buf;
|
++ buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -689,16 +689,16 @@ static char *print_number(char *buf,
|
||||||
{
|
{
|
||||||
if (base == 8)
|
if (base == 8)
|
||||||
{
|
{
|
||||||
if (buf <= end)
|
if (buf < end)
|
||||||
*buf = '0';
|
*buf = '0';
|
||||||
++ buf;
|
++ buf;
|
||||||
}
|
}
|
||||||
else if (base == 16)
|
else if (base == 16)
|
||||||
{
|
{
|
||||||
if (buf <= end)
|
if (buf < end)
|
||||||
*buf = '0';
|
*buf = '0';
|
||||||
++ buf;
|
++ buf;
|
||||||
if (buf <= end)
|
if (buf < end)
|
||||||
{
|
{
|
||||||
*buf = type & LARGE ? 'X' : 'x';
|
*buf = type & LARGE ? 'X' : 'x';
|
||||||
}
|
}
|
||||||
|
@ -712,7 +712,7 @@ static char *print_number(char *buf,
|
||||||
{
|
{
|
||||||
while (size-- > 0)
|
while (size-- > 0)
|
||||||
{
|
{
|
||||||
if (buf <= end)
|
if (buf < end)
|
||||||
*buf = c;
|
*buf = c;
|
||||||
++ buf;
|
++ buf;
|
||||||
}
|
}
|
||||||
|
@ -721,7 +721,7 @@ static char *print_number(char *buf,
|
||||||
#ifdef RT_PRINTF_PRECISION
|
#ifdef RT_PRINTF_PRECISION
|
||||||
while (i < precision--)
|
while (i < precision--)
|
||||||
{
|
{
|
||||||
if (buf <= end)
|
if (buf < end)
|
||||||
*buf = '0';
|
*buf = '0';
|
||||||
++ buf;
|
++ buf;
|
||||||
}
|
}
|
||||||
|
@ -730,14 +730,14 @@ static char *print_number(char *buf,
|
||||||
/* put number in the temporary buffer */
|
/* put number in the temporary buffer */
|
||||||
while (i-- > 0 && (precision_bak != 0))
|
while (i-- > 0 && (precision_bak != 0))
|
||||||
{
|
{
|
||||||
if (buf <= end)
|
if (buf < end)
|
||||||
*buf = tmp[i];
|
*buf = tmp[i];
|
||||||
++ buf;
|
++ buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (size-- > 0)
|
while (size-- > 0)
|
||||||
{
|
{
|
||||||
if (buf <= end)
|
if (buf < end)
|
||||||
*buf = ' ';
|
*buf = ' ';
|
||||||
++ buf;
|
++ buf;
|
||||||
}
|
}
|
||||||
|
@ -769,7 +769,7 @@ rt_int32_t rt_vsnprintf(char *buf,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
str = buf;
|
str = buf;
|
||||||
end = buf + size - 1;
|
end = buf + size;
|
||||||
|
|
||||||
/* Make sure end is always >= buf */
|
/* Make sure end is always >= buf */
|
||||||
if (end < buf)
|
if (end < buf)
|
||||||
|
@ -782,7 +782,7 @@ rt_int32_t rt_vsnprintf(char *buf,
|
||||||
{
|
{
|
||||||
if (*fmt != '%')
|
if (*fmt != '%')
|
||||||
{
|
{
|
||||||
if (str <= end)
|
if (str < end)
|
||||||
*str = *fmt;
|
*str = *fmt;
|
||||||
++ str;
|
++ str;
|
||||||
continue;
|
continue;
|
||||||
|
@ -863,20 +863,20 @@ rt_int32_t rt_vsnprintf(char *buf,
|
||||||
{
|
{
|
||||||
while (--field_width > 0)
|
while (--field_width > 0)
|
||||||
{
|
{
|
||||||
if (str <= end) *str = ' ';
|
if (str < end) *str = ' ';
|
||||||
++ str;
|
++ str;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get character */
|
/* get character */
|
||||||
c = (rt_uint8_t)va_arg(args, int);
|
c = (rt_uint8_t)va_arg(args, int);
|
||||||
if (str <= end) *str = c;
|
if (str < end) *str = c;
|
||||||
++ str;
|
++ str;
|
||||||
|
|
||||||
/* put width */
|
/* put width */
|
||||||
while (--field_width > 0)
|
while (--field_width > 0)
|
||||||
{
|
{
|
||||||
if (str <= end) *str = ' ';
|
if (str < end) *str = ' ';
|
||||||
++ str;
|
++ str;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
@ -894,21 +894,21 @@ rt_int32_t rt_vsnprintf(char *buf,
|
||||||
{
|
{
|
||||||
while (len < field_width--)
|
while (len < field_width--)
|
||||||
{
|
{
|
||||||
if (str <= end) *str = ' ';
|
if (str < end) *str = ' ';
|
||||||
++ str;
|
++ str;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < len; ++i)
|
for (i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
if (str <= end) *str = *s;
|
if (str < end) *str = *s;
|
||||||
++ str;
|
++ str;
|
||||||
++ s;
|
++ s;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (len < field_width--)
|
while (len < field_width--)
|
||||||
{
|
{
|
||||||
if (str <= end) *str = ' ';
|
if (str < end) *str = ' ';
|
||||||
++ str;
|
++ str;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
@ -931,7 +931,7 @@ rt_int32_t rt_vsnprintf(char *buf,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case '%':
|
case '%':
|
||||||
if (str <= end) *str = '%';
|
if (str < end) *str = '%';
|
||||||
++ str;
|
++ str;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -953,12 +953,12 @@ rt_int32_t rt_vsnprintf(char *buf,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (str <= end) *str = '%';
|
if (str < end) *str = '%';
|
||||||
++ str;
|
++ str;
|
||||||
|
|
||||||
if (*fmt)
|
if (*fmt)
|
||||||
{
|
{
|
||||||
if (str <= end) *str = *fmt;
|
if (str < end) *str = *fmt;
|
||||||
++ str;
|
++ str;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -995,8 +995,14 @@ rt_int32_t rt_vsnprintf(char *buf,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str <= end) *str = '\0';
|
if (size > 0)
|
||||||
else *end = '\0';
|
{
|
||||||
|
if (str < end) *str = '\0';
|
||||||
|
else
|
||||||
|
{
|
||||||
|
end[-1] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* the trailing null byte doesn't count towards the total
|
/* the trailing null byte doesn't count towards the total
|
||||||
* ++str;
|
* ++str;
|
||||||
|
|
|
@ -187,7 +187,7 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [
|
||||||
AddOption('--target',
|
AddOption('--target',
|
||||||
dest = 'target',
|
dest = 'target',
|
||||||
type = 'string',
|
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',
|
AddOption('--genconfig',
|
||||||
dest = 'genconfig',
|
dest = 'genconfig',
|
||||||
action = 'store_true',
|
action = 'store_true',
|
||||||
|
@ -228,6 +228,8 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [
|
||||||
'cb':('keil', 'armcc'),
|
'cb':('keil', 'armcc'),
|
||||||
'ua':('gcc', 'gcc'),
|
'ua':('gcc', 'gcc'),
|
||||||
'cdk':('gcc', 'gcc'),
|
'cdk':('gcc', 'gcc'),
|
||||||
|
'makefile':('gcc', 'gcc'),
|
||||||
|
'eclipse':('gcc', 'gcc'),
|
||||||
'ses' : ('gcc', 'gcc')}
|
'ses' : ('gcc', 'gcc')}
|
||||||
tgt_name = GetOption('target')
|
tgt_name = GetOption('target')
|
||||||
|
|
||||||
|
@ -824,6 +826,10 @@ def GenTargetProject(program = None):
|
||||||
from ses import SESProject
|
from ses import SESProject
|
||||||
SESProject(Env)
|
SESProject(Env)
|
||||||
|
|
||||||
|
if GetOption('target') == 'makefile':
|
||||||
|
from makefile import TargetMakefile
|
||||||
|
TargetMakefile(Env)
|
||||||
|
|
||||||
def EndBuilding(target, program = None):
|
def EndBuilding(target, program = None):
|
||||||
import rtconfig
|
import rtconfig
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,299 @@
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import glob
|
||||||
|
|
||||||
|
from utils import *
|
||||||
|
from utils import _make_path_relative
|
||||||
|
from utils import xml_indent
|
||||||
|
|
||||||
|
import xml.etree.ElementTree as etree
|
||||||
|
from xml.etree.ElementTree import SubElement
|
||||||
|
|
||||||
|
source_pattern = ['*.c', '*.cpp', '*.cxx', '*.s', '*.S', '*.asm']
|
||||||
|
|
||||||
|
def OSPath(path):
|
||||||
|
import platform
|
||||||
|
|
||||||
|
if type(path) == type('str'):
|
||||||
|
if platform.system() == 'Windows':
|
||||||
|
return path.replace('/', '\\')
|
||||||
|
else:
|
||||||
|
return path.replace('\\', '/')
|
||||||
|
else:
|
||||||
|
if platform.system() == 'Windows':
|
||||||
|
return [item.replace('/', '\\') for item in path]
|
||||||
|
else:
|
||||||
|
return [item.replace('\\', '/') for item in path]
|
||||||
|
|
||||||
|
def CollectPaths(paths):
|
||||||
|
all_paths = []
|
||||||
|
|
||||||
|
def ParentPaths(path):
|
||||||
|
ret = os.path.dirname(path)
|
||||||
|
if ret == path or ret == '':
|
||||||
|
return []
|
||||||
|
|
||||||
|
return [ret] + ParentPaths(ret)
|
||||||
|
|
||||||
|
for path in paths:
|
||||||
|
# path = os.path.abspath(path)
|
||||||
|
path = path.replace('\\', '/')
|
||||||
|
all_paths = all_paths + [path] + ParentPaths(path)
|
||||||
|
|
||||||
|
all_paths = list(set(all_paths))
|
||||||
|
return sorted(all_paths)
|
||||||
|
|
||||||
|
'''
|
||||||
|
Collect all of files under paths
|
||||||
|
'''
|
||||||
|
def CollectFiles(paths, pattern):
|
||||||
|
files = []
|
||||||
|
for path in paths:
|
||||||
|
if type(pattern) == type(''):
|
||||||
|
files = files + glob.glob(path + '/' + pattern)
|
||||||
|
else:
|
||||||
|
for item in pattern:
|
||||||
|
# print('--> %s' % (path + '/' + item))
|
||||||
|
files = files + glob.glob(path + '/' + item)
|
||||||
|
|
||||||
|
return sorted(files)
|
||||||
|
|
||||||
|
def CollectAllFilesinPath(path, pattern):
|
||||||
|
files = []
|
||||||
|
|
||||||
|
for item in pattern:
|
||||||
|
files += glob.glob(path + '/' + item)
|
||||||
|
|
||||||
|
list = os.listdir(path)
|
||||||
|
if len(list):
|
||||||
|
for item in list:
|
||||||
|
if item.startswith('.'):
|
||||||
|
continue
|
||||||
|
if item == 'bsp':
|
||||||
|
continue
|
||||||
|
|
||||||
|
if os.path.isdir(os.path.join(path, item)):
|
||||||
|
files = files + CollectAllFilesinPath(os.path.join(path, item), pattern)
|
||||||
|
return files
|
||||||
|
|
||||||
|
'''
|
||||||
|
Exclude files from infiles
|
||||||
|
'''
|
||||||
|
def ExcludeFiles(infiles, files):
|
||||||
|
in_files = set([OSPath(file) for file in infiles])
|
||||||
|
exl_files = set([OSPath(file) for file in files])
|
||||||
|
|
||||||
|
exl_files = in_files - exl_files
|
||||||
|
|
||||||
|
return exl_files
|
||||||
|
|
||||||
|
def ExcludePaths(filepath, paths):
|
||||||
|
ret = []
|
||||||
|
|
||||||
|
files = os.listdir(filepath)
|
||||||
|
for file in files:
|
||||||
|
if file.startswith('.'):
|
||||||
|
continue
|
||||||
|
|
||||||
|
fullname = os.path.join(filepath, file)
|
||||||
|
|
||||||
|
if os.path.isdir(fullname):
|
||||||
|
# print(fullname)
|
||||||
|
if not fullname in paths:
|
||||||
|
ret = ret + [fullname]
|
||||||
|
else:
|
||||||
|
ret = ret + ExcludePaths(fullname, paths)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def HandleToolOption(tools, env):
|
||||||
|
project = ProjectInfo(env)
|
||||||
|
BSP_ROOT = os.path.abspath(env['BSP_ROOT'])
|
||||||
|
|
||||||
|
CPPDEFINES = project['CPPDEFINES']
|
||||||
|
paths = ['${ProjDirPath}/' + _make_path_relative(BSP_ROOT, os.path.normpath(i)).replace('\\', '/') for i in project['CPPPATH']]
|
||||||
|
|
||||||
|
for tool in tools:
|
||||||
|
if tool.get('id').find('c.compile') != 1:
|
||||||
|
options = tool.findall('option')
|
||||||
|
for option in options:
|
||||||
|
if option.get('id').find('c.compiler.include.paths') != -1:
|
||||||
|
# find all of paths in this project
|
||||||
|
include_paths = option.findall('listOptionValue')
|
||||||
|
project_paths = []
|
||||||
|
for item in include_paths:
|
||||||
|
project_paths += [item.get('value')]
|
||||||
|
|
||||||
|
if len(project_paths) > 0:
|
||||||
|
cproject_paths = set(paths) - set(project_paths)
|
||||||
|
else:
|
||||||
|
cproject_paths = paths
|
||||||
|
|
||||||
|
# print('c.compiler.include.paths')
|
||||||
|
cproject_paths = sorted(cproject_paths)
|
||||||
|
for item in cproject_paths:
|
||||||
|
SubElement(option, 'listOptionValue', {'builtIn': 'false', 'value': item})
|
||||||
|
|
||||||
|
if option.get('id').find('c.compiler.defs') != -1:
|
||||||
|
defs = option.findall('listOptionValue')
|
||||||
|
project_defs = []
|
||||||
|
for item in defs:
|
||||||
|
project_defs += [item.get('value')]
|
||||||
|
if len(project_defs) > 0:
|
||||||
|
cproject_defs = set(CPPDEFINES) - set(project_defs)
|
||||||
|
else:
|
||||||
|
cproject_defs = CPPDEFINES
|
||||||
|
|
||||||
|
# print('c.compiler.defs')
|
||||||
|
cproject_defs = sorted(cproject_defs)
|
||||||
|
for item in cproject_defs:
|
||||||
|
SubElement(option, 'listOptionValue', {'builtIn': 'false', 'value': item})
|
||||||
|
|
||||||
|
if tool.get('id').find('c.linker') != -1:
|
||||||
|
options = tool.findall('option')
|
||||||
|
for option in options:
|
||||||
|
if option.get('id').find('c.linker.scriptfile') != -1:
|
||||||
|
linker_script = 'link.lds'
|
||||||
|
items = env['LINKFLAGS'].split(' ')
|
||||||
|
if '-T' in items:
|
||||||
|
linker_script = items[items.index('-T') + 1]
|
||||||
|
linker_script = '${ProjDirPath}/' + linker_script
|
||||||
|
|
||||||
|
# print('c.linker.scriptfile')
|
||||||
|
listOptionValue = option.find('listOptionValue')
|
||||||
|
if listOptionValue != None:
|
||||||
|
listOptionValue.set('value', linker_script)
|
||||||
|
else:
|
||||||
|
SubElement(option, 'listOptionValue', {'builtIn': 'false', 'value': linker_script})
|
||||||
|
|
||||||
|
if option.get('id').find('c.linker.nostart') != -1:
|
||||||
|
if env['LINKFLAGS'].find('-nostartfiles') != -1:
|
||||||
|
option.set('value', 'true')
|
||||||
|
else:
|
||||||
|
option.set('value', 'false')
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def HandleRTTRoot(env):
|
||||||
|
bsp_root = env['BSP_ROOT']
|
||||||
|
rtt_root = env['RTT_ROOT']
|
||||||
|
|
||||||
|
if not rtt_root.startswith(bsp_root):
|
||||||
|
to_SubElement = True
|
||||||
|
# print('handle virtual root')
|
||||||
|
|
||||||
|
# always use '/' path separator
|
||||||
|
rtt_root = rtt_root.replace('\\', '/')
|
||||||
|
|
||||||
|
project = etree.parse('.project')
|
||||||
|
root = project.getroot()
|
||||||
|
|
||||||
|
linkedResources = root.find('linkedResources')
|
||||||
|
if linkedResources == None:
|
||||||
|
# add linkedResources
|
||||||
|
linkedResources = SubElement(root, 'linkedResources')
|
||||||
|
# print('add linkedResources')
|
||||||
|
else:
|
||||||
|
links = linkedResources.findall('link')
|
||||||
|
# search exist 'rt-thread' virtual folder
|
||||||
|
for link in links:
|
||||||
|
if link.find('name').text == 'rt-thread':
|
||||||
|
# handle location
|
||||||
|
to_SubElement = False
|
||||||
|
location = link.find('location')
|
||||||
|
location.text = rtt_root
|
||||||
|
|
||||||
|
if to_SubElement:
|
||||||
|
# print('to subelement for virtual folder')
|
||||||
|
link = SubElement(linkedResources, 'link')
|
||||||
|
name = SubElement(link, 'name')
|
||||||
|
name.text = 'rt-thread'
|
||||||
|
type = SubElement(link, 'type')
|
||||||
|
type.text = '2'
|
||||||
|
location = SubElement(link, 'location')
|
||||||
|
location.text = rtt_root
|
||||||
|
|
||||||
|
out = open('.project', 'w')
|
||||||
|
out.write('<?xml version="1.0" encoding="UTF-8"?>\n')
|
||||||
|
xml_indent(root)
|
||||||
|
out.write(etree.tostring(root, encoding='utf-8'))
|
||||||
|
out.close()
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def TargetEclipse(env):
|
||||||
|
global source_pattern
|
||||||
|
|
||||||
|
print('Update eclipse setting...')
|
||||||
|
|
||||||
|
if not os.path.exists('.cproject'):
|
||||||
|
print('no eclipse CDT project found!')
|
||||||
|
return
|
||||||
|
|
||||||
|
HandleRTTRoot(env)
|
||||||
|
|
||||||
|
project = ProjectInfo(env)
|
||||||
|
|
||||||
|
all_paths = [OSPath(path) for path in CollectPaths(project['DIRS'])]
|
||||||
|
# print(all_paths)
|
||||||
|
bsp_root = os.path.abspath(env['BSP_ROOT'])
|
||||||
|
|
||||||
|
exclude_paths = ExcludePaths(bsp_root, all_paths)
|
||||||
|
paths = exclude_paths
|
||||||
|
exclude_paths = []
|
||||||
|
for path in paths:
|
||||||
|
# add bsp and libcpu folder and not collect source files (too more files)
|
||||||
|
if path.endswith('rt-thread\\bsp') or path.endswith('rt-thread\\libcpu'):
|
||||||
|
exclude_paths += [path]
|
||||||
|
continue
|
||||||
|
|
||||||
|
set = CollectAllFilesinPath(path, source_pattern)
|
||||||
|
if len(set):
|
||||||
|
exclude_paths += [path]
|
||||||
|
|
||||||
|
exclude_paths = [_make_path_relative(bsp_root, path).replace('\\', '/') for path in exclude_paths]
|
||||||
|
env['ExPaths'] = exclude_paths
|
||||||
|
|
||||||
|
all_files = CollectFiles(all_paths, source_pattern)
|
||||||
|
src_files = project['FILES']
|
||||||
|
|
||||||
|
exclude_files = ExcludeFiles(all_files, src_files)
|
||||||
|
exclude_files = [_make_path_relative(bsp_root, file).replace('\\', '/') for file in exclude_files]
|
||||||
|
env['ExFiles'] = exclude_files
|
||||||
|
|
||||||
|
cproject = etree.parse('.cproject')
|
||||||
|
|
||||||
|
root = cproject.getroot()
|
||||||
|
cconfigurations = root.findall('storageModule/cconfiguration')
|
||||||
|
for cconfiguration in cconfigurations:
|
||||||
|
tools = cconfiguration.findall('storageModule/configuration/folderInfo/toolChain/tool')
|
||||||
|
HandleToolOption(tools, env)
|
||||||
|
|
||||||
|
sourceEntries = cconfiguration.find('storageModule/configuration/sourceEntries')
|
||||||
|
entry = sourceEntries.find('entry')
|
||||||
|
if entry != None:
|
||||||
|
sourceEntries.remove(entry)
|
||||||
|
|
||||||
|
excluding = exclude_paths + exclude_files
|
||||||
|
excluding = sorted(excluding)
|
||||||
|
value = ''
|
||||||
|
for item in excluding:
|
||||||
|
if value == '':
|
||||||
|
value = item
|
||||||
|
else:
|
||||||
|
value += '|' + item
|
||||||
|
excluding = value
|
||||||
|
|
||||||
|
SubElement(sourceEntries, 'entry', {'excluding': excluding, 'flags': 'VALUE_WORKSPACE_PATH|RESOLVED', 'kind':'sourcePath', 'name':""})
|
||||||
|
|
||||||
|
# write back to .cproject
|
||||||
|
out = open('.cproject', 'w')
|
||||||
|
out.write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n')
|
||||||
|
out.write('<?fileVersion 4.0.0?>')
|
||||||
|
xml_indent(root)
|
||||||
|
out.write(etree.tostring(root, encoding='utf-8'))
|
||||||
|
out.close()
|
||||||
|
|
||||||
|
print('done!')
|
||||||
|
|
||||||
|
return
|
|
@ -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
|
|
@ -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)
|
Loading…
Reference in New Issue