forked from xuos/xiuos
add some files
This commit is contained in:
parent
3fe9cf3d91
commit
196a8e001a
|
@ -0,0 +1,3 @@
|
||||||
|
SRC_FILES := cache.c isr.c abstraction_mmu.c
|
||||||
|
|
||||||
|
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,206 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 AIIT XUOS Lab
|
||||||
|
* XiUOS is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file: abstraction_mmu.c
|
||||||
|
* @brief: the general management of system mmu
|
||||||
|
* @version: 3.0
|
||||||
|
* @author: AIIT XUOS Lab
|
||||||
|
* @date: 2023/4/27
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <abstraction_mmu.h>
|
||||||
|
|
||||||
|
AbstractionMmu abstraction_mmu;
|
||||||
|
|
||||||
|
volatile uint32_t global_L1_pte_table[4096];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: write cmd to CP15 register
|
||||||
|
* @param reg_type - CP15 register type
|
||||||
|
* @param val - ops val pointer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static void MmuCp15Write(uint8_t reg_type, uint32_t *val)
|
||||||
|
{
|
||||||
|
uint32_t write_val = *val;
|
||||||
|
switch (reg_type) {
|
||||||
|
case AM_MMU_CP15_TTBCR:
|
||||||
|
TTBCR_W(write_val);
|
||||||
|
AM_ISB;
|
||||||
|
case AM_MMU_CP15_TTBR0:
|
||||||
|
TTBR0_W(write_val);
|
||||||
|
AM_ISB;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: read CP15 register from mmu
|
||||||
|
* @param reg_type - CP15 register type
|
||||||
|
* @param val - ops val pointer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static void MmuCp15Read(uint8_t reg_type, uint32_t *val)
|
||||||
|
{
|
||||||
|
uint32_t read_val = 0;
|
||||||
|
switch (reg_type) {
|
||||||
|
case AM_MMU_CP15_TTBCR:
|
||||||
|
TTBCR_R(read_val);
|
||||||
|
case AM_MMU_CP15_TTBR0:
|
||||||
|
TTBR0_R(read_val);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*val = read_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: write or read CP15 register to set mmu
|
||||||
|
* @param ops_type - CP15 write or read
|
||||||
|
* @param reg_type - CP15 register type
|
||||||
|
* @param val - ops val pointer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static void MmuRegOps(uint8_t ops_type, uint8_t reg_type, uint32_t *val)
|
||||||
|
{
|
||||||
|
switch (ops_type) {
|
||||||
|
case AM_MMU_CP15_WRITE:
|
||||||
|
MmuCp15Write(reg_type, val);
|
||||||
|
case AM_MMU_CP15_READ:
|
||||||
|
MmuCp15Read(reg_type, val);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Init abstraction_mmu function
|
||||||
|
* @param mmu - abstraction mmu pointer
|
||||||
|
* @param ttb_base - ttb base pointer
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
static int _AbstractionMmuInit(AbstractionMmu *mmu, uint32_t *ttb_base)
|
||||||
|
{
|
||||||
|
mmu_init();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: map L1 or L2 page table section
|
||||||
|
* @param mmu - abstraction mmu pointer
|
||||||
|
* @param section_size - section size
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
static int _AbstractionMmuSectionMap(AbstractionMmu *mmu, uint32_t section_size)
|
||||||
|
{
|
||||||
|
uint32_t vaddr_length = mmu->vaddr_end - mmu->vaddr_start + 1;
|
||||||
|
|
||||||
|
mmu_map_l1_range(mmu->paddr_start, mmu->vaddr_start, vaddr_length,
|
||||||
|
mmu->mmu_memory_type, mmu->mmu_shareability, mmu->mmu_access);
|
||||||
|
|
||||||
|
mmu->mmu_status = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: unmap L1 or L2 page table section
|
||||||
|
* @param mmu - abstraction mmu pointer
|
||||||
|
* @param vaddr_start - virtual address start
|
||||||
|
* @param vaddr_size - virtual address size
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
static int _AbstractionMmuSectionUnmap(AbstractionMmu *mmu, uint32_t vaddr_start, uint32_t vaddr_size)
|
||||||
|
{
|
||||||
|
uint32_t *l1_umap_ventry = mmu->ttb_vbase + (vaddr_start >> AM_MMU_L1_SECTION_SHIFT);
|
||||||
|
uint32_t vaddr_end = vaddr_start + vaddr_size - 1;
|
||||||
|
uint32_t umap_count = (vaddr_end >> AM_MMU_L1_SECTION_SHIFT) - (vaddr_start >> AM_MMU_L1_SECTION_SHIFT) + 1;
|
||||||
|
|
||||||
|
while (umap_count) {
|
||||||
|
AM_DMB;
|
||||||
|
*l1_umap_ventry = 0;
|
||||||
|
AM_DSB;
|
||||||
|
|
||||||
|
umap_count--;
|
||||||
|
l1_umap_ventry += (1 << AM_MMU_L1_SECTION_SHIFT);//1MB section
|
||||||
|
}
|
||||||
|
|
||||||
|
AM_DSB;
|
||||||
|
CLEARTLB(0);//clear TLB data and configure
|
||||||
|
AM_DSB;
|
||||||
|
AM_ISB;
|
||||||
|
mmu->mmu_status = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: switch ttb base by re-write ttbr register
|
||||||
|
* @param mmu - abstraction mmu pointer
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
static int _AbstractionMmuTtbSwitch(AbstractionMmu *mmu)
|
||||||
|
{
|
||||||
|
uint32_t ttbr, ttbcr;
|
||||||
|
MmuRegOps(AM_MMU_CP15_READ, AM_MMU_CP15_TTBCR, &ttbcr);
|
||||||
|
|
||||||
|
/* Set TTBR0 with inner/outer write back write allocate and not shareable, [4:3]=01, [1]=0, [6,0]=01 */
|
||||||
|
ttbr = ((mmu->ttb_pbase & 0xFFFFC000UL) | 0x9UL);
|
||||||
|
/* enable TTBR0 */
|
||||||
|
ttbcr = 0;
|
||||||
|
|
||||||
|
AM_DSB;
|
||||||
|
MmuRegOps(AM_MMU_CP15_WRITE, AM_MMU_CP15_TTBR0, &ttbr);
|
||||||
|
MmuRegOps(AM_MMU_CP15_WRITE, AM_MMU_CP15_TTBCR, &ttbcr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: get physical address transformed from virtual address
|
||||||
|
* @param mmu - abstraction mmu pointer
|
||||||
|
* @param vaddr - virtual address pointer
|
||||||
|
* @param paddr - physical address pointer
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
static int _AbstracktonMmuTransform(AbstractionMmu *mmu, uint32_t *vaddr, uint32_t *paddr)
|
||||||
|
{
|
||||||
|
uint32_t virtualAddress = *vaddr;
|
||||||
|
|
||||||
|
if (mmu->mmu_status) {
|
||||||
|
mmu_virtual_to_physical(virtualAddress, paddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct AbstractionMmuDone mmu_done = {
|
||||||
|
.AbstractionMmuInit = _AbstractionMmuInit,
|
||||||
|
.AbstractionMmuSectionMap = _AbstractionMmuSectionMap,
|
||||||
|
.AbstractionMmuSectionUnmap = _AbstractionMmuSectionUnmap,
|
||||||
|
.AbstractionMmuTtbSwitch = _AbstractionMmuTtbSwitch,
|
||||||
|
.AbstracktonMmuTransform = _AbstracktonMmuTransform,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: init abstraciton mmu info when system start
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
int SysInitAbstractionMmu(void)
|
||||||
|
{
|
||||||
|
abstraction_mmu.mmu_done = &mmu_done;
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 AIIT XUOS Lab
|
||||||
|
* XiUOS is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file: mmu.h
|
||||||
|
* @brief: the general management of system mmu
|
||||||
|
* @version: 3.0
|
||||||
|
* @author: AIIT XUOS Lab
|
||||||
|
* @date: 2023/5/24
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <mmu.h>
|
||||||
|
|
||||||
|
#define ARCH_ARM
|
||||||
|
#ifdef ARCH_ARM
|
||||||
|
/* ARM System Registers */
|
||||||
|
#define AM_DSB __asm__ volatile("dsb" ::: "memory")
|
||||||
|
#define AM_DMB __asm__ volatile("dmb" ::: "memory")
|
||||||
|
#define AM_ISB __asm__ volatile("isb" ::: "memory")
|
||||||
|
#define AM_WFI __asm__ volatile("wfi" ::: "memory")
|
||||||
|
#define AM_BARRIER __asm__ volatile("":::"memory")
|
||||||
|
#define AM_WFE __asm__ volatile("wfe" ::: "memory")
|
||||||
|
#define AM_SEV __asm__ volatile("sev" ::: "memory")
|
||||||
|
|
||||||
|
#define TTBR0_R(val) __asm__ volatile("mrc p15, 0, %0, c2, c0, 0" : "=r"(val))
|
||||||
|
#define TTBR0_W(val) __asm__ volatile("mcr p15, 0, %0, c2, c0, 0" ::"r"(val))
|
||||||
|
|
||||||
|
#define TTBCR_R(val) __asm__ volatile("mrc p15, 0, %0, c2, c0, 2" : "=r"(val))
|
||||||
|
#define TTBCR_W(val) __asm__ volatile("mcr p15, 0, %0, c2, c0, 2" ::"r"(val))
|
||||||
|
|
||||||
|
#define CLEARTLB(val) __asm__ volatile("mcr p15, 0, %0, c8, c7, 0" ::"r"(val))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define AM_MMU_L1_PAGE_TABLE_SIZE (4 * 4096)
|
||||||
|
#define AM_MMU_L1_SECTION_SHIFT 20
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
AM_MMU_CP15_WRITE = 0,
|
||||||
|
AM_MMU_CP15_READ,
|
||||||
|
}MmuCP15OpsType;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
AM_MMU_CP15_TTBCR = 0,
|
||||||
|
AM_MMU_CP15_TTBR0,
|
||||||
|
AM_MMU_CP15_CLEARTLB,
|
||||||
|
}MmuCP15RegType;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
AM_StronglyOrdered = 0,
|
||||||
|
AM_Device,
|
||||||
|
AM_OuterInner_WB_WA,
|
||||||
|
AM_OuterInner_WT,
|
||||||
|
AM_Noncacheable,
|
||||||
|
}MmuMemoryType;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
AM_Noaccess = 0,
|
||||||
|
AM_Read_Write,
|
||||||
|
AM_Read,
|
||||||
|
}MmuAccess;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
AM_Shareable = 1,
|
||||||
|
AM_Nonshareable = 0
|
||||||
|
}MmuShareability;
|
||||||
|
|
||||||
|
struct AbstractionMmuDone
|
||||||
|
{
|
||||||
|
int (*AbstractionMmuInit)(AbstractionMmu *mmu, uint32_t *ttb_base);
|
||||||
|
int (*AbstractionMmuSectionMap)(AbstractionMmu *mmu, uint32_t section_size);
|
||||||
|
int (*AbstractionMmuSectionUnmap)(AbstractionMmu *mmu, uint32_t vaddr_start, uint32_t vaddr_size);
|
||||||
|
int (*AbstractionMmuTtbSwitch)(AbstractionMmu *mmu);
|
||||||
|
int (*AbstracktonMmuTransform)(AbstractionMmu *mmu, uint32_t *vaddr, uint32_t *paddr);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t ttb_vbase;
|
||||||
|
uint32_t ttb_pbase;
|
||||||
|
|
||||||
|
uint32_t vaddr_start;
|
||||||
|
uint32_t vaddr_end;
|
||||||
|
uint32_t paddr_start;
|
||||||
|
uint32_t paddr_end;
|
||||||
|
|
||||||
|
uint32_t vpaddr_offset;
|
||||||
|
|
||||||
|
uint32_t pte_attr;
|
||||||
|
uint32_t mmu_status;
|
||||||
|
|
||||||
|
MmuMemoryType mmu_memory_type;
|
||||||
|
MmuAccess mmu_access;
|
||||||
|
MmuShareability mmu_shareability;
|
||||||
|
|
||||||
|
struct AbstractionMmuDone *mmu_done;
|
||||||
|
|
||||||
|
int lock;
|
||||||
|
int link_list;
|
||||||
|
}AbstractionMmu;
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 AIIT XUOS Lab
|
||||||
|
* XiUOS is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file: cache.c
|
||||||
|
* @brief: the general management of system cache
|
||||||
|
* @version: 3.0
|
||||||
|
* @author: AIIT XUOS Lab
|
||||||
|
* @date: 2023/4/27
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void InvalidInsCache()
|
||||||
|
{
|
||||||
|
PlatInvalidInsCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InvalidDataCache(unsigned long start, unsigned long end)
|
||||||
|
{
|
||||||
|
PlatInvalidDateCache(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CleanDataCache(unsigned long start, unsigned long end)
|
||||||
|
{
|
||||||
|
PlatCleanDateCache(start, end);
|
||||||
|
}
|
|
@ -0,0 +1,215 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 AIIT XUOS Lab
|
||||||
|
* XiUOS is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file: isr.c
|
||||||
|
* @brief: the general management of system isr
|
||||||
|
* @version: 1.0
|
||||||
|
* @author: AIIT XUOS Lab
|
||||||
|
* @date: 2020/3/15
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
#include "isr.h"
|
||||||
|
|
||||||
|
struct InterruptServiceRoutines isrManager = {0} ;
|
||||||
|
|
||||||
|
#ifdef ARCH_SMP
|
||||||
|
extern int GetCpuId(void);
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* This functionwill get the isr nest level.
|
||||||
|
*
|
||||||
|
* @return isr nest level
|
||||||
|
*/
|
||||||
|
static uint16_t GetIsrCounter()
|
||||||
|
{
|
||||||
|
uint16_t ret = 0;
|
||||||
|
|
||||||
|
#ifdef ARCH_SMP
|
||||||
|
ret = isrManager.isr_count[GetCpuId()];
|
||||||
|
#else
|
||||||
|
ret = isrManager.isr_count;
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void IncIsrCounter()
|
||||||
|
{
|
||||||
|
#ifdef ARCH_SMP
|
||||||
|
isrManager.isr_count[GetCpuId()] ++ ;
|
||||||
|
#else
|
||||||
|
isrManager.isr_count ++;
|
||||||
|
#endif
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DecIsrCounter()
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef ARCH_SMP
|
||||||
|
isrManager.isr_count[GetCpuId()] -- ;
|
||||||
|
#else
|
||||||
|
isrManager.isr_count --;
|
||||||
|
#endif
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsInIsr()
|
||||||
|
{
|
||||||
|
#ifdef ARCH_SMP
|
||||||
|
return ( isrManager.isr_count[GetCpuId()] != 0 ? TRUE : FALSE ) ;
|
||||||
|
#else
|
||||||
|
return ( isrManager.isr_count != 0 ? TRUE : FALSE ) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function will register a new irq.
|
||||||
|
*
|
||||||
|
* @param irq_num the number of the irq
|
||||||
|
* @param handler the callback of the interrupt
|
||||||
|
* @param arg param of thge callback
|
||||||
|
*
|
||||||
|
* @return 0 on success; -1 on failure
|
||||||
|
*/
|
||||||
|
static int32_t RegisterHwIrq(uint32_t irq_num, IsrHandlerType handler, void *arg)
|
||||||
|
{
|
||||||
|
if (irq_num >= ARCH_MAX_IRQ_NUM )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
struct IrqDesc *desc = &isrManager.irq_table[irq_num];
|
||||||
|
|
||||||
|
desc->handler = handler;
|
||||||
|
desc->param = arg;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function will free a irq.
|
||||||
|
*
|
||||||
|
* @param irq_num the number of the irq
|
||||||
|
*
|
||||||
|
* @return 0 on success; -1 on failure
|
||||||
|
*/
|
||||||
|
static int32_t FreeHwIrq(uint32_t irq_num)
|
||||||
|
{
|
||||||
|
if (irq_num >= ARCH_MAX_IRQ_NUM )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memset(&isrManager.irq_table[irq_num], 0, sizeof(struct IrqDesc));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will enable a irq.
|
||||||
|
*
|
||||||
|
* @param irq_num the number of the irq
|
||||||
|
*
|
||||||
|
* @return 0 on success; -1 on failure
|
||||||
|
*/
|
||||||
|
static int32_t EnableHwIrq(uint32_t irq_num, uint32_t cpu_id)
|
||||||
|
{
|
||||||
|
if (irq_num >= ARCH_MAX_IRQ_NUM )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return ArchEnableHwIrq(irq_num, cpu_id);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function will disable a irq.
|
||||||
|
*
|
||||||
|
* @param irq_num the number of the irq
|
||||||
|
*
|
||||||
|
* @return 0 on success; -1 on failure
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int32_t DisableHwIrq(uint32_t irq_num, uint32_t cpu_id)
|
||||||
|
{
|
||||||
|
if (irq_num >= ARCH_MAX_IRQ_NUM )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return ArchDisableHwIrq(irq_num, cpu_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* called from arch-specific ISR wrapper */
|
||||||
|
static void IsrCommon(uint32_t irq_num)
|
||||||
|
{
|
||||||
|
struct IrqDesc *desc = &isrManager.irq_table[irq_num];
|
||||||
|
|
||||||
|
if (desc->handler == NULL) {
|
||||||
|
// SYS_KDEBUG_LOG(KDBG_IRQ, ("Spurious interrupt: IRQ No. %d\n", irq_num));
|
||||||
|
while (1) {}
|
||||||
|
}
|
||||||
|
desc->handler(irq_num, desc->param);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetIsrSwitchTrigerFlag()
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef ARCH_SMP
|
||||||
|
isrManager.isr_switch_trigger_flag[GetCpuId()] = 1;
|
||||||
|
#else
|
||||||
|
isrManager.isr_switch_trigger_flag = 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ClearIsrSwitchTrigerFlag()
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef ARCH_SMP
|
||||||
|
isrManager.isr_switch_trigger_flag[GetCpuId()] = 0;
|
||||||
|
#else
|
||||||
|
isrManager.isr_switch_trigger_flag = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t GetIsrSwitchTrigerFlag()
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef ARCH_SMP
|
||||||
|
return isrManager.isr_switch_trigger_flag[GetCpuId()];
|
||||||
|
#else
|
||||||
|
return isrManager.isr_switch_trigger_flag ;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
struct IsrDone isrDone = {
|
||||||
|
IsInIsr,
|
||||||
|
RegisterHwIrq ,
|
||||||
|
FreeHwIrq,
|
||||||
|
EnableHwIrq,
|
||||||
|
DisableHwIrq,
|
||||||
|
IsrCommon,
|
||||||
|
GetIsrCounter,
|
||||||
|
IncIsrCounter,
|
||||||
|
DecIsrCounter,
|
||||||
|
GetIsrSwitchTrigerFlag,
|
||||||
|
SetIsrSwitchTrigerFlag,
|
||||||
|
ClearIsrSwitchTrigerFlag
|
||||||
|
};
|
||||||
|
|
||||||
|
void SysInitIsrManager()
|
||||||
|
{
|
||||||
|
extern int __isrtbl_idx_start;
|
||||||
|
extern int __isrtbl_start;
|
||||||
|
extern int __isrtbl_end;
|
||||||
|
memset(&isrManager,0,sizeof(struct InterruptServiceRoutines));
|
||||||
|
isrManager.done = &isrDone;
|
||||||
|
|
||||||
|
uint32_t *index = (uint32_t *)&__isrtbl_idx_start;
|
||||||
|
struct IrqDesc *desc = (struct IrqDesc *)&__isrtbl_start;
|
||||||
|
|
||||||
|
while (desc != (struct IrqDesc *)&__isrtbl_end)
|
||||||
|
isrManager.irq_table[*index++] = *desc++;
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 AIIT XUOS Lab
|
||||||
|
* XiUOS is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file: isr.h
|
||||||
|
* @brief: function declaration and structure defintion of isr
|
||||||
|
* @version: 1.0
|
||||||
|
* @author: AIIT XUOS Lab
|
||||||
|
* @date: 2020/3/10
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ISR_H__
|
||||||
|
#define __ISR_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <arch_interrupt.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define DECLARE_HW_IRQ(_irq_num, _handler, _arg) \
|
||||||
|
const uint32_t __irq_desc_idx_##_handler SECTION(".isrtbl.idx") = _irq_num + ARCH_IRQ_NUM_OFFSET ; \
|
||||||
|
const struct IrqDesc __irq_desc_##_handler SECTION(".isrtbl") = { \
|
||||||
|
.handler = _handler, \
|
||||||
|
.param = _arg, \
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef void (*IsrHandlerType)(int vector, void *param);
|
||||||
|
|
||||||
|
struct IrqDesc
|
||||||
|
{
|
||||||
|
IsrHandlerType handler;
|
||||||
|
void *param;
|
||||||
|
|
||||||
|
#ifdef CONFIG_INTERRUPT_INFO
|
||||||
|
char name[NAME_NUM_MAX];
|
||||||
|
uint32_t counter;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IsrDone
|
||||||
|
{
|
||||||
|
bool (*isInIsr)();
|
||||||
|
int32_t (*registerIrq)(uint32_t irq_num, IsrHandlerType handler, void *arg);
|
||||||
|
int32_t (*freeIrq)(uint32_t irq_num);
|
||||||
|
int32_t (*enableIrq)(uint32_t irq_num, uint32_t cpu_id);
|
||||||
|
int32_t (*disableIrq)(uint32_t irq_num, uint32_t cpu_id);
|
||||||
|
void (*handleIrq)(uint32_t irq_num);
|
||||||
|
uint16_t (*getCounter)() ;
|
||||||
|
void (*incCounter)();
|
||||||
|
void (*decCounter)();
|
||||||
|
uint8_t (*getSwitchTrigerFlag)();
|
||||||
|
void (*setSwitchTrigerFlag)();
|
||||||
|
void (*clearSwitchTrigerFlag)();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct InterruptServiceRoutines {
|
||||||
|
|
||||||
|
#ifdef ARCH_SMP
|
||||||
|
volatile uint16_t isr_count[CPU_NUMBERS];
|
||||||
|
volatile uint8_t isr_switch_trigger_flag[CPU_NUMBERS];
|
||||||
|
#else
|
||||||
|
volatile uint16_t isr_count ;
|
||||||
|
volatile uint8_t isr_switch_trigger_flag;
|
||||||
|
#endif
|
||||||
|
struct IrqDesc irq_table[ARCH_MAX_IRQ_NUM];
|
||||||
|
struct IsrDone *done;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct InterruptServiceRoutines isrManager ;
|
||||||
|
|
||||||
|
uint32_t DisableLocalInterrupt();
|
||||||
|
void EnableLocalInterrupt(unsigned long level);
|
||||||
|
|
||||||
|
#define DISABLE_INTERRUPT DisableLocalInterrupt
|
||||||
|
#define ENABLE_INTERRUPT EnableLocalInterrupt
|
||||||
|
|
||||||
|
void SysInitIsrManager();
|
||||||
|
void InitHwinterrupt(void);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue