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