初始提交

This commit is contained in:
2024-09-28 14:24:04 +08:00
commit c756587541
5564 changed files with 2413077 additions and 0 deletions

527
driver/src/hw3/intc.c Normal file
View File

@@ -0,0 +1,527 @@
/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
/* os shim includes */
#include "os_types.h"
#include "iot_config.h"
#include "irq.h"
#include "apb.h"
#include "ahb.h"
#include "cpu.h"
#include "intc.h"
#include "intc_reg.h"
#include "hw_reg_api.h"
/* systick timer frq */
#define SYSTICK_FRQ (1 * 1000 * 1000)
#define INT_ID_READ_TIMES (128)
static uint32_t intc_systick_rate = 0;
void IRAM_ATTR intc_write(uint32_t cpu, uint32_t reg, uint32_t data)
{
if(HAL_INTR_CPU_0 == cpu){
INTC0_WRITE_REG(reg, data);
}else if(HAL_INTR_CPU_1 == cpu){
INTC1_WRITE_REG(reg, data);
}else if(HAL_INTR_CPU_2 == cpu){
INTC2_WRITE_REG(reg, data);
}
return;
}
uint32_t IRAM_ATTR intc_read(uint32_t cpu, uint32_t reg)
{
uint32_t data;
if(HAL_INTR_CPU_0 == cpu){
data = INTC0_READ_REG(reg);
}else if(HAL_INTR_CPU_1 == cpu){
data = INTC1_READ_REG(reg);
}else if(HAL_INTR_CPU_2 == cpu){
data = INTC2_READ_REG(reg);
}else{
data = 0;
}
return data;
}
void intc_init(uint32_t cpu)
{
if(cpu == HAL_INTR_CPU_0){
apb_enable(APB_INTC0);
} else if(cpu == HAL_INTR_CPU_1){
apb_enable(APB_INTC1);
} else if(cpu == HAL_INTR_CPU_2){
apb_enable(APB_INTC2);
} else {
return;
}
intc_write(cpu, CFG_INT_ENA0_ADDR, 0x0);
intc_write(cpu, CFG_INT_ENA1_ADDR, 0x0);
intc_write(cpu, CFG_INT_ENA2_ADDR, 0x0);
intc_write(cpu, CFG_INT_ENA3_ADDR, 0x0);
intc_write(cpu, CFG_INT_PRI_SEL_ADDR, 0x0);
intc_write(cpu, CFG_INT_PRI_CFG0_ADDR, 0x0);
intc_write(cpu, CFG_INT_PRI_CFG1_ADDR, 0x0);
intc_write(cpu, CFG_INT_PRI_CFG2_ADDR, 0x0);
intc_write(cpu, CFG_INT_PRI_CFG3_ADDR, 0x0);
intc_write(cpu, CFG_INT_PRI_CFG4_ADDR, 0x0);
intc_write(cpu, CFG_INT_PRI_CFG5_ADDR, 0x0);
intc_write(cpu, CFG_INT_PRI_CFG6_ADDR, 0x0);
intc_write(cpu, CFG_INT_PRI_CFG7_ADDR, 0x0);
intc_write(cpu, CFG_INT_PRI_CFG8_ADDR, 0x0);
intc_write(cpu, CFG_INT_PRI_CFG9_ADDR, 0x0);
intc_write(cpu, CFG_INT_PRI_CFG10_ADDR, 0x0);
intc_write(cpu, CFG_INT_PRI_CFG11_ADDR, 0x0);
intc_write(cpu, CFG_INT_PRI_CFG12_ADDR, 0x0);
intc_write(cpu, CFG_INT_PRI_CFG13_ADDR, 0x0);
intc_write(cpu, CFG_INT_PRI_CFG14_ADDR, 0x0);
intc_write(cpu, CFG_INT_PRI_CFG15_ADDR, 0x0);
return;
}
void intc_set_priority(uint32_t cpu, uint32_t vector, uint32_t priority)
{
uint32_t tmp, addr;
uint32_t group = 0;
(void)cpu;
group = vector>>3;
if(group == 0) {
addr = CFG_INT_PRI_CFG0_ADDR;
}
else if(group == 1) {
addr = CFG_INT_PRI_CFG1_ADDR;
}
else if(group == 2) {
addr = CFG_INT_PRI_CFG2_ADDR;
}
else if(group == 3) {
addr = CFG_INT_PRI_CFG3_ADDR;
}
else if(group == 4) {
addr = CFG_INT_PRI_CFG4_ADDR;
}
else if(group == 5) {
addr = CFG_INT_PRI_CFG5_ADDR;
}
else if(group == 6) {
addr = CFG_INT_PRI_CFG6_ADDR;
}
else if(group == 7) {
addr = CFG_INT_PRI_CFG7_ADDR;
}
else if(group == 8) {
addr = CFG_INT_PRI_CFG8_ADDR;
}
else if(group == 9) {
addr = CFG_INT_PRI_CFG9_ADDR;
}
else if(group == 10) {
addr = CFG_INT_PRI_CFG10_ADDR;
}
else if(group == 11) {
addr = CFG_INT_PRI_CFG11_ADDR;
}
else if(group == 12) {
addr = CFG_INT_PRI_CFG12_ADDR;
}
else if(group == 13) {
addr = CFG_INT_PRI_CFG13_ADDR;
}
else if(group == 14) {
addr = CFG_INT_PRI_CFG14_ADDR;
}
else if(group == 15) {
addr = CFG_INT_PRI_CFG15_ADDR;
}else{
return;
}
tmp = intc_read(cpu, addr);
tmp |= priority << ((vector%8)*4);
intc_write(cpu, addr, tmp);
return;
}
void IRAM_ATTR intc_mask(uint32_t cpu, uint32_t vector)
{
uint32_t tmp, addr;
if(vector < 32){
addr = CFG_INT_ENA0_ADDR;
}else if(vector < 64){
addr = CFG_INT_ENA1_ADDR;
vector -= 32;
}else if(vector < 96){
addr = CFG_INT_ENA2_ADDR;
vector -= 64;
}else if(vector < 128){
addr = CFG_INT_ENA3_ADDR;
vector -= 96;
}
else{
return;
}
tmp = intc_read(cpu, addr);
tmp &= ~(1 << vector);
intc_write(cpu, addr, tmp);
return;
}
void IRAM_ATTR intc_unmask(uint32_t cpu, uint32_t vector)
{
uint32_t tmp, addr;
if(vector < 32){
addr = CFG_INT_ENA0_ADDR;
}else if(vector < 64){
addr = CFG_INT_ENA1_ADDR;
vector -= 32;
}else if(vector < 96){
addr = CFG_INT_ENA2_ADDR;
vector -= 64;
}else if(vector < 128){
addr = CFG_INT_ENA3_ADDR;
vector -= 96;
}
else{
return;
}
tmp = intc_read(cpu, addr);
tmp |= (1 << vector);
intc_write(cpu, addr, tmp);
return;
}
void intc_config(uint32_t cpu, uint32_t vector, uint32_t level, uint32_t up)
{
(void)cpu;
(void)vector;
(void)level;
(void)up;
return;
}
void intc_ack(uint32_t cpu, uint32_t vector)
{
(void)cpu;
(void)vector;
return;
}
uint32_t g_snapshot_triggered = 0;
uint32_t IRAM_ATTR intc_get_vector(uint32_t cpu)
{
uint32_t status;
uint32_t vector = 0;
status = intc_read(cpu, CFG_INT_PRI_STS_ADDR);
vector = REG_FIELD_GET(INT_ID, status);
return vector;
}
void IRAM_ATTR intc_handler(uint32_t cpu)
{
volatile uint32_t status;
volatile uint32_t vector1, vector2;
uint32_t read_cnt = INT_ID_READ_TIMES;
do {
status = intc_read(cpu, CFG_INT_PRI_STS_ADDR);
vector1 = REG_FIELD_GET(INT_ID, status);
status = intc_read(cpu, CFG_INT_PRI_STS_ADDR);
vector2 = REG_FIELD_GET(INT_ID, status);
if (vector1 == vector2) {
break;
}
} while (--read_cnt);
if (0 == read_cnt || vector1 >= HAL_VECTOR_MAX) {
return;
} else {
hal_deliver_interrupt(vector1);
}
}
void IRAM_ATTR intc_force_mtip(uint32_t cpu)
{
uint32_t tmp;
tmp = intc_read(cpu, CFG_INTER_MTIP_CTL1_ADDR);
REG_FIELD_SET(MTIP_INT_FORCE, tmp, 1);
intc_write(cpu, CFG_INTER_MTIP_CTL1_ADDR, tmp);
return;
}
int IRAM_ATTR intc_get_force_mtip(uint32_t cpu)
{
uint32_t tmp;
tmp = intc_read(cpu, CFG_INTER_MTIP_CTL1_ADDR);
return REG_FIELD_GET(MTIP_INT_FORCE, tmp);
}
void IRAM_ATTR intc_clear_force_mtip(uint32_t cpu)
{
uint32_t tmp;
tmp = intc_read(cpu, CFG_INTER_MTIP_CTL1_ADDR);
REG_FIELD_SET(MTIP_INT_FORCE, tmp, 0);
intc_write(cpu, CFG_INTER_MTIP_CTL1_ADDR, tmp);
return;
}
void IRAM_ATTR systick_clear(uint32_t cpu)
{
uint32_t tmp;
tmp = intc_read(cpu, CFG_INTER_MTIP_CTL2_ADDR);
REG_FIELD_SET(MTIP_CNT_INT_CLR, tmp, 1);
intc_write(cpu, CFG_INTER_MTIP_CTL2_ADDR, tmp);
return;
}
void IRAM_ATTR systick_config(uint32_t cpu, uint32_t clock, uint32_t rate)
{
uint32_t tmp;
uint32_t tick = SYSTICK_FRQ / rate - 1UL;
(void)clock;
tmp = intc_read(cpu, CFG_INTER_MTIP_CMP_ADDR);
REG_FIELD_SET(MTIP_CMP, tmp, tick);
intc_write(cpu, CFG_INTER_MTIP_CMP_ADDR, tmp);
intc_systick_rate = rate;
return;
}
void IRAM_ATTR systick_enable(uint32_t cpu)
{
uint32_t tmp;
tmp = intc_read(cpu, CFG_INTER_MTIP_CTL1_ADDR);
REG_FIELD_SET(MTIP_CNT_EN, tmp, 1);
REG_FIELD_SET(MTIP_INT_EN, tmp, 1);
intc_write(cpu, CFG_INTER_MTIP_CTL1_ADDR, tmp);
return;
}
void systick_update(uint32_t cpu, uint32_t clock)
{
uint32_t tick = (clock / intc_systick_rate) - 1UL;
intc_write(cpu, CFG_INTER_MTIP_CMP_ADDR, tick);
}
uint32_t intc_get_software_int_status(uint32_t cpu)
{
return intc_read(cpu, CFG_INTER_MSIP_ADDR);
}
void intc_send_software_int(uint32_t dst_cpu)
{
uint32_t cpu = cpu_get_mhartid(), tmp;
tmp = intc_read(dst_cpu, CFG_INTER_MSIP_ADDR);
tmp |= (1 << cpu);
intc_write(dst_cpu, CFG_INTER_MSIP_ADDR, tmp);
}
void intc_clear_software_int(uint32_t dst_cpu)
{
uint32_t cpu = cpu_get_mhartid(), tmp;
tmp = intc_read(cpu, CFG_INTER_MSIP_CLR_ADDR);
tmp |= (1 << dst_cpu);
intc_write(cpu, CFG_INTER_MSIP_CLR_ADDR, tmp);
}
void intc_clear_all_software_int(void)
{
uint32_t cpu = cpu_get_mhartid();
intc_write(cpu, CFG_INTER_MSIP_CLR_ADDR, 0xFFFFFFFF);
}
void intc_set_wakeup_enable(intc_wakeup_src_e wakeup_src)
{
uint32_t cpu = cpu_get_mhartid(), tmp;
tmp = intc_read(cpu, CFG_INT_WAKEUP_ENA0_ADDR);
tmp |= (1 << wakeup_src);
intc_write(cpu, CFG_INT_WAKEUP_ENA0_ADDR, tmp);
}
void intc_set_wakeup_disable(intc_wakeup_src_e wakeup_src)
{
uint32_t cpu = cpu_get_mhartid(), tmp;
tmp = intc_read(cpu, CFG_INT_WAKEUP_ENA0_ADDR);
tmp &= ~(1 << wakeup_src);
intc_write(cpu, CFG_INT_WAKEUP_ENA0_ADDR, tmp);
}
uint32_t intc_get_wakeup_state(void)
{
uint32_t cpu = cpu_get_mhartid();
return intc_read(cpu, CFG_INT_WAKEUP_STS0_ADDR);;
}
uint32_t intc_get_wakeup_source(void)
{
uint32_t cpu = cpu_get_mhartid();
return intc_read(cpu, CFG_INT_WAKEUP_SRC0_ADDR);;
}
void intc_mon_cnt_ena(uint8_t ch, uint8_t ena)
{
uint32_t cpu = cpu_get_mhartid(), tmp;
tmp = intc_read(cpu, CFG_INT_MON_CFG0_ADDR);
switch(ch) {
case 0: {
REG_FIELD_SET(INT_MON_SIG0_CNT_EN, tmp, ena);
break;
}
case 1: {
REG_FIELD_SET(INT_MON_SIG1_CNT_EN, tmp, ena);
break;
}
case 2: {
REG_FIELD_SET(INT_MON_SIG2_CNT_EN, tmp, ena);
break;
}
case 3: {
REG_FIELD_SET(INT_MON_SIG3_CNT_EN, tmp, ena);
break;
}
default :{
return ;
}
}
intc_write(cpu, CFG_INT_MON_CFG0_ADDR, tmp);
}
void intc_mon_cnt_clear(uint8_t ch)
{
uint32_t cpu = cpu_get_mhartid(), tmp;
tmp = intc_read(cpu, CFG_INT_MON_CFG0_ADDR);
switch(ch) {
case 0: {
REG_FIELD_SET(INT_MON_SIG0_CNT_CLR, tmp, 1);
break;
}
case 1: {
REG_FIELD_SET(INT_MON_SIG1_CNT_CLR, tmp, 1);
break;
}
case 2: {
REG_FIELD_SET(INT_MON_SIG2_CNT_CLR, tmp, 1);
break;
}
case 3: {
REG_FIELD_SET(INT_MON_SIG3_CNT_CLR, tmp, 1);
break;
}
default :{
return ;
}
}
intc_write(cpu, CFG_INT_MON_CFG0_ADDR, tmp);
}
void intc_mon_sig_sel(uint8_t ch, uint8_t sig)
{
uint32_t cpu = cpu_get_mhartid(), tmp;
tmp = intc_read(cpu, CFG_INT_MON_CFG1_ADDR);
switch(ch) {
case 0: {
REG_FIELD_SET(INT_MON_SIG0_SEL, tmp, sig);
break;
}
case 1: {
REG_FIELD_SET(INT_MON_SIG1_SEL, tmp, sig);
break;
}
case 2: {
REG_FIELD_SET(INT_MON_SIG2_SEL, tmp, sig);
break;
}
case 3: {
REG_FIELD_SET(INT_MON_SIG3_SEL, tmp, sig);
break;
}
default :{
return ;
}
}
intc_write(cpu, CFG_INT_MON_CFG1_ADDR, tmp);
}
uint32_t intc_get_mon_cnt(uint8_t ch)
{
uint32_t cpu = cpu_get_mhartid(), tmp;
switch(ch) {
case 0: {
tmp = intc_read(cpu, CFG_INT_MON_SIG0_CNT_ADDR);
break;
}
case 1: {
tmp = intc_read(cpu, CFG_INT_MON_SIG1_CNT_ADDR);
break;
}
case 2: {
tmp = intc_read(cpu, CFG_INT_MON_SIG2_CNT_ADDR);
break;
}
case 3: {
tmp = intc_read(cpu, CFG_INT_MON_SIG3_CNT_ADDR);
break;
}
default :{
return 0;
}
}
return tmp;
}