Support XiZi_AIoT

This commit is contained in:
TXuian
2024-01-31 10:30:34 +08:00
parent f6cf46027d
commit 494312183b
351 changed files with 46408 additions and 450091 deletions
@@ -0,0 +1,3 @@
SRC_DIR := arm/armv7-a/cortex-a9
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,4 @@
SRC_DIR := gicv2
SRC_FILES := vector.S trampoline.S trap_common.c error_debug.c spinlock.c hard_spinlock.S
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,141 @@
/* Copyright (c) 2006-2018 Frans Kaashoek, Robert Morris, Russ Cox,
* Massachusetts Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* @file error_debug.c
* @brief handle program abort
* @version 3.0
* @author AIIT XUOS Lab
* @date 2024.11.23
*/
/*************************************************
File name: error_debug.c
Description: handle program abort
Others:
History:
1. Date: 2024-11-23
Author: AIIT XUOS Lab
Modification:
1. first version
*************************************************/
#include "core.h"
#include "memlayout.h"
#include "log.h"
#include "multicores.h"
#include "syscall.h"
__attribute__((always_inline)) static inline void _abort_reason(uint32_t fault_status)
{
if ((fault_status & 0xd) == 0x1) // Alignment failure
KPrintf("reason: alignment\n");
else if ((fault_status & 0xd) == 0x5) // External abort "on translation"
KPrintf("reason: ext. abort on trnslt.\n");
else if ((fault_status & 0xd) == 0x5) // Translation
KPrintf("reason: sect. translation\n");
else if ((fault_status & 0xd) == 0x9) // Domain
KPrintf("reason: sect. domain\n");
else if ((fault_status & 0xd) == 0xd) // Permission
KPrintf("reason: sect. permission\n");
else if ((fault_status & 0xd) == 0x8) // External abort
KPrintf("reason: ext. abort\n");
else
KPrintf("reason: unknown???\n");
}
void dump_tf(struct trapframe* tf)
{
KPrintf("lr_svc: 0x%x\n", tf->lr_svc);
KPrintf(" spsr: 0x%x\n", tf->spsr);
KPrintf(" r0: 0x%x\n", tf->r0);
KPrintf(" r1: 0x%x\n", tf->r1);
KPrintf(" r2: 0x%x\n", tf->r2);
KPrintf(" r3: 0x%x\n", tf->r3);
KPrintf(" r4: 0x%x\n", tf->r4);
KPrintf(" r5: 0x%x\n", tf->r5);
KPrintf(" r6: 0x%x\n", tf->r6);
KPrintf(" r7: 0x%x\n", tf->r7);
KPrintf(" r8: 0x%x\n", tf->r8);
KPrintf(" r9: 0x%x\n", tf->r9);
KPrintf(" r10: 0x%x\n", tf->r10);
KPrintf(" r11: 0x%x\n", tf->r11);
KPrintf(" r12: 0x%x\n", tf->r12);
KPrintf(" pc: 0x%x\n", tf->pc);
}
void handle_undefined_instruction(struct trapframe* tf)
{
// unimplemented trap handler
KPrintf("undefined instruction at %x\n", tf->pc);
panic("");
}
void dabort_handler(struct trapframe* r)
{
uint32_t dfs, dfa;
__asm__ __volatile__("mrc p15, 0, %0, c5, c0, 0" : "=r"(dfs)::);
__asm__ __volatile__("mrc p15, 0, %0, c6, c0, 0" : "=r"(dfa)::);
if (r->pc < KERN_MEM_BASE) { // Exception occured in User space: exit
ERROR("dabort in user space: %s\n", cur_cpu()->task->name);
LOG("program counter: 0x%x(%s) caused\n", r->pc, cur_cpu()->task);
LOG("data abort at 0x%x, status 0x%x\n", dfa, dfs);
_abort_reason(dfs);
dump_tf(r);
}
if (cur_cpu()->task != NULL) {
sys_exit();
} else { // Exception occured in Kernel space: panic
LOG("program counter: 0x%x(%s) caused\n", r->pc, cur_cpu()->task);
LOG("data abort at 0x%x, status 0x%x\n", dfa, dfs);
_abort_reason(dfs);
dump_tf(r);
panic("data abort exception\n");
}
}
void iabort_handler(struct trapframe* r)
{
uint32_t ifs, ifa;
__asm__ __volatile__("mrc p15, 0, %0, c5, c0, 1" : "=r"(ifs)::);
__asm__ __volatile__("mrc p15, 0, %0, c6, c0, 2" : "=r"(ifa)::);
if (r->pc < KERN_MEM_BASE) { // Exception occured in User space: exit
ERROR("iabort in user space: %s\n", cur_cpu()->task->name);
LOG("program counter: 0x%x(%s) caused\n", r->pc, cur_cpu()->task);
LOG("prefetch abort at 0x%x, status 0x%x\n", ifa, ifs);
_abort_reason(ifs);
dump_tf(r);
}
if (cur_cpu()->task != NULL) {
sys_exit();
} else { // Exception occured in Kernel space: panic
LOG("program counter: 0x%x(%s) caused\n", r->pc, cur_cpu()->task);
LOG("prefetch abort at 0x%x, status 0x%x\n", ifa, ifs);
_abort_reason(ifs);
dump_tf(r);
panic("prefetch abort exception\n");
}
}
@@ -0,0 +1,4 @@
SRC_FILES := gicv2_distributer_to_device.c \
gicv2_interface_to_core.c \
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,230 @@
/*
* 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.
*/
/*
* 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 gicv2_common_opa.c
* @brief gicv2 operation
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.08.25
*/
/*************************************************
File name: gicv2_common_opa.c
Description: gicv2 operation
Others:
History:
1. Date: 2023-08-28
Author: AIIT XUOS Lab
Modification:
*************************************************/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <mmio_access.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
__attribute__((__always_inline__)) static inline uint32_t get_arm_private_peripheral_base()
{
return MMIO_P2V(0x00A00000);
}
__attribute__((__always_inline__)) static inline uint32_t irq_get_register_offset(uint32_t irqID)
{
return irqID / 32;
}
__attribute__((__always_inline__)) static inline uint32_t irq_get_bit_offset(uint32_t irqID)
{
return irqID & 0x1f;
}
__attribute__((__always_inline__)) static inline uint32_t irq_get_bit_mask(uint32_t irqID)
{
return 1 << irq_get_bit_offset(irqID);
}
//! @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
//! @}
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,161 @@
/*
* 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.
*/
/**
* @file gicv2_distributer_to_device.c
* @brief gicv2 operation
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.08.25
*/
/*************************************************
File name: gicv2_distributer_to_device.c
Description: gicv2 operation
Others:
History:
1. Date: 2023-08-28
Author: AIIT XUOS Lab
Modification:
1. take only gicd part
*************************************************/
#include "gicv2_common_opa.h"
#include "gicv2_registers.h"
static inline gicd_t* gic_get_gicd(void);
static inline gicd_t* gic_get_gicd(void)
{
uint32_t base = get_arm_private_peripheral_base() + kGICDBaseOffset;
return (gicd_t*)base;
}
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_init(void)
{
gicd_t* gicd = gic_get_gicd();
// First disable the distributor.
gic_enable(false);
for (uint32_t i = 0; i < 8; i++) {
gicd->IGROUPRn[i] = 0;
}
for (uint32_t i = 0; i < 255; i++) {
*(uint32_t*)(&gicd->IPRIORITYRn[i * sizeof(uint32_t)]) = (uint32_t)0x80808080;
*(uint32_t*)(&gicd->ITARGETSRn[i * sizeof(uint32_t)]) = (uint32_t)0x01010101;
}
// Init the GIC CPU interface.
gic_init_cpu();
// Now enable the distributor.
gic_enable(true);
}
@@ -0,0 +1,97 @@
/*
* 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.
*/
/**
* @file gicv2_distributer_to_core.c
* @brief gicv2 operation
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.08.25
*/
/*************************************************
File name: gicv2_distributer_to_core.c
Description: gicv2 operation
Others:
History:
1. Date: 2023-08-28
Author: AIIT XUOS Lab
Modification:
1. take only gicc part
*************************************************/
#include "gicv2_common_opa.h"
#include "gicv2_registers.h"
static inline gicc_t* gic_get_gicc(void)
{
uint32_t base = get_arm_private_peripheral_base() + kGICCBaseOffset;
return (gicc_t*)base;
}
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;
}
inline 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_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);
}
@@ -0,0 +1,151 @@
/*
* 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.
*/
/**
* @file gicv2_registers.c
* @brief gicv2 registers
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.08.25
*/
/*************************************************
File name: gicv2_registers.c
Description: gicv2 registers
Others:
History:
1. Date: 2023-08-28
Author: AIIT XUOS Lab
Modification:
*************************************************/
#include <stdint.h>
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! @brief Offsets to the GIC registers.
enum _gic_base_offsets {
kGICDBaseOffset = 0x1000, //!< GIC distributor offset.
kGICCBaseOffset = 0x100 //!< GIC CPU interface offset.
};
//! @brief GIC distributor registers.
//!
//! Uses the GICv2 register names, but does not include GICv2 registers.
//!
//! The IPRIORITYRn and ITARGETSRn registers are byte accessible, so their types are uint8_t
//! instead of uint32_t to reflect this. These members are indexed directly with the interrupt
//! number.
struct _gicd_registers {
uint32_t CTLR; //!< Distributor Control Register.
uint32_t TYPER; //!< Interrupt Controller Type Register.
uint32_t IIDR; //!< Distributor Implementer Identification Register.
uint32_t _reserved0[29];
uint32_t IGROUPRn[8]; //!< Interrupt Group Registers.
uint32_t _reserved1[24];
uint32_t ISENABLERn[32]; //!< Interrupt Set-Enable Registers.
uint32_t ICENABLERn[32]; //!< Interrupt Clear-Enable Registers.
uint32_t ISPENDRn[32]; //!< Interrupt Set-Pending Registers.
uint32_t ICPENDRn[32]; //!< Interrupt Clear-Pending Registers.
uint32_t ICDABRn[32]; //!< Active Bit Registers.
uint32_t _reserved2[32];
uint8_t IPRIORITYRn[255 * sizeof(uint32_t)]; //!< Interrupt Priority Registers. (Byte accessible)
uint32_t _reserved3;
uint8_t ITARGETSRn[255 * sizeof(uint32_t)]; //!< Interrupt Processor Targets Registers. (Byte accessible)
uint32_t _reserved4;
uint32_t ICFGRn[64]; //!< Interrupt Configuration Registers.
uint32_t _reserved5[128];
uint32_t SGIR; //!< Software Generated Interrupt Register
};
//! @brief Bitfields constants for the GICD_CTLR register.
enum _gicd_ctlr_fields {
kBM_GICD_CTLR_EnableGrp1 = (1 << 1),
kBM_GICD_CTLR_EnableGrp0 = (1 << 0)
};
//! @brief Bitfields constants for the GICD_SGIR register.
enum _gicd_sgir_fields {
kBP_GICD_SGIR_TargetListFilter = 24,
kBM_GICD_SGIR_TargetListFilter = (0x3 << kBP_GICD_SGIR_TargetListFilter),
kBP_GICD_SGIR_CPUTargetList = 16,
kBM_GICD_SGIR_CPUTargetList = (0xff << kBP_GICD_SGIR_CPUTargetList),
kBP_GICD_SGIR_NSATT = 15,
kBM_GICD_SGIR_NSATT = (1 << kBP_GICD_SGIR_NSATT),
kBP_GICD_SGIR_SGIINTID = 0,
kBM_GICD_SGIR_SGIINTID = 0xf
};
//! @brief GIC CPU interface registers.
//!
//! Uses the GICv2 register names. Does not include GICv2 registers.
struct _gicc_registers {
uint32_t CTLR; //!< CPU Interface Control Register.
uint32_t PMR; //!< Interrupt Priority Mask Register.
uint32_t BPR; //!< Binary Point Register.
uint32_t IAR; //!< Interrupt Acknowledge Register.
uint32_t EOIR; //!< End of Interrupt Register.
uint32_t RPR; //!< Running Priority Register.
uint32_t HPPIR; //!< Highest Priority Pending Interrupt Register.
uint32_t ABPR; //!< Aliased Binary Point Register. (only visible with a secure access)
uint32_t _reserved[56];
uint32_t IIDR; //!< CPU Interface Identification Register.
};
//! @brief Bitfields constants for the GICC_CTLR register.
enum _gicc_ctlr_fields {
kBP_GICC_CTLR_EnableS = 0,
kBM_GICC_CTLR_EnableS = (1 << 0),
kBP_GICC_CTLR_EnableNS = 1,
kBM_GICC_CTLR_EnableNS = (1 << 1),
kBP_GICC_CTLR_AckCtl = 2,
kBM_GICC_CTLR_AckCtl = (1 << 2),
kBP_GICC_CTLR_FIQEn = 3,
kBM_GICC_CTLR_FIQEn = (1 << 3),
kBP_GICC_CTLR_SBPR = 4,
kBM_GICC_CTLR_SBPR = (1 << 4)
};
//! @brier Type for the GIC distributor registers.
typedef volatile struct _gicd_registers gicd_t;
//! @brier Type for the GIC CPU interface registers.
typedef volatile struct _gicc_registers gicc_t;
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,112 @@
/*
* Copyright (c) 2013, 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.
*/
/*
* Portions Copyright (c) 2011-2012 ARM Ltd. All rights reserved.
*/
/**
* @file hard_spinlock.S
* @brief spinlock implementation
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.08.25
*/
/*************************************************
File name: hard_spinlock.S
Description: spinlock implementation
Others:
History:
1. Date: 2023-08-28
Author: AIIT XUOS Lab
Modification:
1. add return of _spinlock_lock
*************************************************/
.code 32
.section ".text","ax"
.global cpu_get_current
#define UNLOCKED 0xFF
// int spinlock_lock(spinlock_t * lock, uint32_t timeout)
.global _spinlock_lock
.func _spinlock_lock
_spinlock_lock:
ldrex r1, [r0] // check if the spinlock is currently unlocked
cmp r1, #UNLOCKED
wfene // wait for an event signal
bne _spinlock_lock
mrc p15, 0, r1, c0, c0, 5 // get our CPU ID
and r1, r1, #3
strex r2, r1, [r0] // attempt to grab lock by writing CPU number into spinlock
cmp r2, #0 // check if the write was successful
bne _spinlock_lock // if the write failed, start over
dmb // Ensure that accesses to shared resource have completed
mov r0, #0
bx lr // return to caller
.endfunc // spinlock_lock
// void spinlock_unlock(spinlock_t * lock)
.global _spinlock_unlock
.func _spinlock_unlock
_spinlock_unlock:
mrc p15, 0, r1, c0, c0, 5 // get our CPU ID
and r1, r1, #3
ldr r2, [r0] // read lock field of spinlock
cmp r1, r2 // compare lock field with our CPU ID
movne r0, #1 // doesn't match, so exit with failure
bxne lr
dmb // Ensure that accesses to shared resource have completed
mov r1, #UNLOCKED // load unlocked value
str r1, [r0] // write into lock field of spinlock
dsb // Ensure that no instructions following the barrier execute until
// all memory accesses prior to the barrier have completed.
sev // send event to wake up other cores waiting on spinlock
mov r0, #0 // return success
bx lr
.endfunc
.end
@@ -0,0 +1,247 @@
/*
* 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.
*/
/**
* @file irq_numbers.c
* @brief irq numbers
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.08.25
*/
/*************************************************
File name: irq_numbers.c
Description: irq numbers
Others:
History:
1. Date: 2023-08-28
Author: AIIT XUOS Lab
Modification:
1. Add HW_NR_IRQS
*************************************************/
#if !defined(__IRQ_NUMBERS_H__)
#define __IRQ_NUMBERS_H__
#define HW_NR_IRQS IMX_INTERRUPT_COUNT
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! @brief i.MX6 interrupt numbers.
//!
//! This enumeration lists the numbers for all of the interrupts available on the i.MX6 series.
//! Use these numbers when specifying an interrupt to the GIC.
//!
//! The first 16 interrupts are special in that they are reserved for software interrupts generated
//! by the SWI instruction.
enum _imx_interrupts {
SW_INTERRUPT_0 = 0, //!< Software interrupt 0.
SW_INTERRUPT_1 = 1, //!< Software interrupt 1.
SW_INTERRUPT_2 = 2, //!< Software interrupt 2.
SW_INTERRUPT_3 = 3, //!< Software interrupt 3.
SW_INTERRUPT_4 = 4, //!< Software interrupt 4.
SW_INTERRUPT_5 = 5, //!< Software interrupt 5.
SW_INTERRUPT_6 = 6, //!< Software interrupt 6.
SW_INTERRUPT_7 = 7, //!< Software interrupt 7.
SW_INTERRUPT_8 = 8, //!< Software interrupt 8.
SW_INTERRUPT_9 = 9, //!< Software interrupt 9.
SW_INTERRUPT_10 = 10, //!< Software interrupt 10.
SW_INTERRUPT_11 = 11, //!< Software interrupt 11.
SW_INTERRUPT_12 = 12, //!< Software interrupt 12.
SW_INTERRUPT_13 = 13, //!< Software interrupt 13.
SW_INTERRUPT_14 = 14, //!< Software interrupt 14.
SW_INTERRUPT_15 = 15, //!< Software interrupt 15.
RSVD_INTERRUPT_16 = 16, //!< Reserved.
RSVD_INTERRUPT_17 = 17, //!< Reserved.
RSVD_INTERRUPT_18 = 18, //!< Reserved.
RSVD_INTERRUPT_19 = 19, //!< Reserved.
RSVD_INTERRUPT_20 = 20, //!< Reserved.
RSVD_INTERRUPT_21 = 21, //!< Reserved.
RSVD_INTERRUPT_22 = 22, //!< Reserved.
RSVD_INTERRUPT_23 = 23, //!< Reserved.
RSVD_INTERRUPT_24 = 24, //!< Reserved.
RSVD_INTERRUPT_25 = 25, //!< Reserved.
RSVD_INTERRUPT_26 = 26, //!< Reserved.
RSVD_INTERRUPT_27 = 27, //!< Reserved.
RSVD_INTERRUPT_28 = 28, //!< Reserved.
RSVD_INTERRUPT_29 = 29, //!< Reserved.
RSVD_INTERRUPT_30 = 30, //!< Reserved.
RSVD_INTERRUPT_31 = 31, //!< Reserved.
IMX_INT_IOMUXC_GPR = 32, //!< General Purpose Register 1 from IOMUXC. Used to notify cores on exception condition while boot.
IMX_INT_CHEETAH_CSYSPWRUPREQ = 33, //!< @todo Listed as DAP in RM
IMX_INT_SDMA = 34, //!< Logical OR of all 48 SDMA interrupt requests/events from all channels.
IMX_INT_VPU_JPG = 35, //!< JPEG codec interrupt request.
IMX_INT_SNVS_LP_SET_PWR_OFF = 36, //!< PMIC power off request.
IMX_INT_IPU1_ERR = 37, //!< IPU1 error interrupt request.
IMX_INT_IPU1_FUNC = 38, //!< IPU1 sync interrupt request.
IMX_INT_IPU2_ERR = 39, //!< IPU2 error interrupt request.
IMX_INT_IPU2_FUNC = 40, //!< IPU2 sync interrupt request.
IMX_INT_GPU3D = 41, //!< GPU3D interrupt request.
IMX_INT_GPU2D = 42, //!< Idle interrupt from GPU2D (for S/W power gating).
IMX_INT_OPENVG_XAQ2 = 43, //!< GPU2D general interrupt request.
IMX_INT_VPU_IPI = 44, //!< VPU interrupt request.
IMX_INT_APBHDMA = 45, //!< Logical OR of 4 signals: dma_chan[0-3]_irq, GPMI operation channel description complete interrupt.
IMX_INT_EIM = 46, //!< EIM interrupt request.
IMX_INT_BCH = 47, //!< BCH operation complete interrupt.
IMX_INT_GPMI = 48, //!< GPMI operation timeout error interrupt.
IMX_INT_DTCP = 49, //!< DTCP interrupt request.
IMX_INT_VDOA = 50, //!< Logical OR of VDOA interrupt requests.
IMX_INT_SNVS = 51, //!< SNVS consolidated interrupt.
IMX_INT_SNVS_SEC = 52, //!< SNVS security interrupt.
IMX_INT_CSU = 53, //!< CSU interrupt request 1. Indicates to the processor that one or more alarm inputs were asserted.
IMX_INT_USDHC1 = 54, //!< uSDHC1 (Enhanced SDHC) interrupt request.
IMX_INT_USDHC2 = 55, //!< uSDHC2 (Enhanced SDHC) interrupt request.
IMX_INT_USDHC3 = 56, //!< uSDHC3 (Enhanced SDHC) interrupt request.
IMX_INT_USDHC4 = 57, //!< uSDHC4 (Enhanced SDHC) interrupt request.
IMX_INT_UART1 = 58, //!< Logical OR of UART1 interrupt requests.
IMX_INT_UART2 = 59, //!< Logical OR of UART2 interrupt requests.
IMX_INT_UART3 = 60, //!< Logical OR of UART3 interrupt requests.
IMX_INT_UART4 = 61, //!< Logical OR of UART4 interrupt requests.
IMX_INT_UART5 = 62, //!< Logical OR of UART5 interrupt requests.
IMX_INT_ECSPI1 = 63, //!< eCSPI1 interrupt request.
IMX_INT_ECSPI2 = 64, //!< eCSPI2 interrupt request.
IMX_INT_ECSPI3 = 65, //!< eCSPI3 interrupt request.
IMX_INT_ECSPI4 = 66, //!< eCSPI4 interrupt request.
IMX_INT_ECSPI5 = 67, //!< eCSPI5 interrupt request.
IMX_INT_I2C1 = 68, //!< I2C1 interrupt request.
IMX_INT_I2C2 = 69, //!< I2C2 interrupt request.
IMX_INT_I2C3 = 70, //!< I2C3 interrupt request.
IMX_INT_SATA = 71, //!< SATA interrupt request.
IMX_INT_USBOH3_UH1 = 72, //!< USB Host 1 interrupt request.
IMX_INT_USBOH3_UH2 = 73, //!< USB Host 2 interrupt request.
IMX_INT_USBOH3_UH3 = 74, //!< USB Host 3 interrupt request.
IMX_INT_USBOH3_UOTG = 75, //!< USB OTG interrupt request.
IMX_INT_USB_UTMI0 = 76, //!< UTMI0 interrupt request.
IMX_INT_USB_UTMI1 = 77, //!< UTMI1 interrupt request.
IMX_INT_SSI1 = 78, //!< SSI1 interrupt request.
IMX_INT_SSI2 = 79, //!< SSI2 interrupt request.
IMX_INT_SSI3 = 80, //!< SSI3 interrupt request.
IMX_INT_TEMPERATURE = 81, //!< Temperature Sensor (temp. greater than threshold) interrupt request.
IMX_INT_ASRC = 82, //!< ASRC interrupt request.
IMX_INT_ESAI = 83, //!< ESAI interrupt request.
IMX_INT_SPDIF = 84, //!< Logical OR of SPDIF TX and SPDIF RX interrupts.
IMX_INT_MLB = 85, //!< MLB error interrupt request.
IMX_INT_PMU_ANA_BO = 86, //!< PMU analog regulator brown-out interrupt request.
IMX_INT_GPT = 87, //!< Logical OR of GPT rollover interrupt line, input capture 1 & 2 lines, output compare 1, 2 & 3 interrupt lines.
IMX_INT_EPIT1 = 88, //!< EPIT1 output compare interrupt.
IMX_INT_EPIT2 = 89, //!< EPIT2 output compare interrupt.
IMX_INT_GPIO1_INT7 = 90, //!< INT7 interrupt request.
IMX_INT_GPIO1_INT6 = 91, //!< INT6 interrupt request.
IMX_INT_GPIO1_INT5 = 92, //!< INT5 interrupt request.
IMX_INT_GPIO1_INT4 = 93, //!< INT4 interrupt request.
IMX_INT_GPIO1_INT3 = 94, //!< INT3 interrupt request.
IMX_INT_GPIO1_INT2 = 95, //!< INT2 interrupt request.
IMX_INT_GPIO1_INT1 = 96, //!< INT1 interrupt request.
IMX_INT_GPIO1_INT0 = 97, //!< INT0 interrupt request.
IMX_INT_GPIO1_INT15_0 = 98, //!< Combined interrupt indication for GPIO1 signals 0 - 15.
IMX_INT_GPIO1_INT31_16 = 99, //!< Combined interrupt indication for GPIO1 signals 16 - 31.
IMX_INT_GPIO2_INT15_0 = 100, //!< Combined interrupt indication for GPIO2 signals 0 - 15.
IMX_INT_GPIO2_INT31_16 = 101, //!< Combined interrupt indication for GPIO2 signals 16 - 31.
IMX_INT_GPIO3_INT15_0 = 102, //!< Combined interrupt indication for GPIO3 signals 0 - 15.
IMX_INT_GPIO3_INT31_16 = 103, //!< Combined interrupt indication for GPIO3 signals 16 - 31.
IMX_INT_GPIO4_INT15_0 = 104, //!< Combined interrupt indication for GPIO4 signals 0 - 15.
IMX_INT_GPIO4_INT31_16 = 105, //!< Combined interrupt indication for GPIO4 signals 16 - 31.
IMX_INT_GPIO5_INT15_0 = 106, //!< Combined interrupt indication for GPIO5 signals 0 - 15.
IMX_INT_GPIO5_INT31_16 = 107, //!< Combined interrupt indication for GPIO5 signals 16 - 31.
IMX_INT_GPIO6_INT15_0 = 108, //!< Combined interrupt indication for GPIO6 signals 0 - 15.
IMX_INT_GPIO6_INT31_16 = 109, //!< Combined interrupt indication for GPIO6 signals 16 - 31.
IMX_INT_GPIO7_INT15_0 = 110, //!< Combined interrupt indication for GPIO7 signals 0 - 15.
IMX_INT_GPIO7_INT31_16 = 111, //!< Combined interrupt indication for GPIO7 signals 16 - 31.
IMX_INT_WDOG1 = 112, //!< WDOG1 timer reset interrupt request.
IMX_INT_WDOG2 = 113, //!< WDOG2 timer reset interrupt request.
IMX_INT_KPP = 114, //!< Key Pad interrupt request.
IMX_INT_PWM1 = 115, //!< Cumulative interrupt line for PWM1. Logical OR of rollover, compare, and FIFO waterlevel crossing interrupts.
IMX_INT_PWM2 = 116, //!< Cumulative interrupt line for PWM2. Logical OR of rollover, compare, and FIFO waterlevel crossing interrupts.
IMX_INT_PWM3 = 117, //!< Cumulative interrupt line for PWM3. Logical OR of rollover, compare, and FIFO waterlevel crossing interrupts.
IMX_INT_PWM4 = 118, //!< Cumulative interrupt line for PWM4. Logical OR of rollover, compare, and FIFO waterlevel crossing interrupts.
IMX_INT_CCM_INT1 = 119, //!< CCM interrupt request 1.
IMX_INT_CCM_INT2 = 120, //!< CCM interrupt request 2.
IMX_INT_GPC_INT1 = 121, //!< GPC interrupt request 1.
IMX_INT_GPC_INT2 = 122, //!< GPC interrupt request 2.
IMX_INT_SRC = 123, //!< SRC interrupt request.
IMX_INT_CHEETAH_L2 = 124, //!< Logical OR of all L2 interrupt requests.
IMX_INT_CHEETAH_PARITY = 125, //!< Parity Check error interrupt request.
IMX_INT_CHEETAH_PERFORM = 126, //!< Logical OR of Performance Unit interrupts.
IMX_INT_CHEETAH_TRIGGER = 127, //!< Logical OR of CTI trigger outputs.
IMX_INT_SRC_CPU_WDOG = 128, //!< Combined CPU wdog interrupts (4x) out of SRC.
IMX_INT_INTERRUPT_129 = 129, //!< Reserved.
IMX_INT_INTERRUPT_130 = 130, //!< Reserved.
IMX_INT_INTERRUPT_131 = 131, //!< Reserved.
IMX_INT_CSI_INTR1 = 132, //!< MIPI CSI interrupt request 1.
IMX_INT_CSI_INTR2 = 133, //!< MIPI CSI interrupt request 2.
IMX_INT_DSI = 134, //!< MIPI DSI interrupt request.
IMX_INT_HSI = 135, //!< MIPI HSI interrupt request.
IMX_INT_SJC = 136, //!< SJC interrupt from General Purpose register.
IMX_INT_CAAM_INT0 = 137, //!< CAAM job ring 0 interrupt.
IMX_INT_CAAM_INT1 = 138, //!< CAAM job ring 1 interrupt.
IMX_INT_INTERRUPT_139 = 139, //!< Reserved.
IMX_INT_TZASC1 = 140, //!< ASC1 interrupt request.
IMX_INT_TZASC2 = 141, //!< ASC2 interrupt request.
IMX_INT_FLEXCAN1 = 142, //!< FLEXCAN1 combined interrupt. Logical OR of ini_int_busoff, ini_int_error, ipi_int_mbor, ipi_int_rxwarning, ipi_int_txwarning and ipi_int_wakein.
IMX_INT_FLEXCAN2 = 143, //!< FLEXCAN2 combined interrupt. Logical OR of ini_int_busoff, ini_int_error, ipi_int_mbor, ipi_int_rxwarning, ipi_int_txwarning and ipi_int_wakein.
IMX_INT_PERFMON1 = 144, //!< Reserved.
IMX_INT_PERFMON2 = 145, //!< Reserved.
IMX_INT_PERFMON3 = 146, //!< Reserved.
IMX_INT_HDMI_TX = 147, //!< HDMI master interrupt request.
IMX_INT_HDMI_TX_WAKEUP = 148, //!< HDMI CEC engine dedicated interrupt signal raised by a wake-up event.
IMX_INT_MLB_AHB0 = 149, //!< Channels [31:0] interrupt requests.
IMX_INT_ENET = 150, //!< MAC 0 IRQ, Logical OR of:
//! - MAC 0 Periodic Timer Overflow
//! - MAC 0 Time Stamp Available
//! - MAC 0 Payload Receive Error
//! - MAC 0 Transmit FIFO Underrun
//! - MAC 0 Collision Retry Limit
//! - MAC 0 Late Collision
//! - MAC 0 Ethernet Bus Error
//! - MAC 0 MII Data Transfer Done
//! - MAC 0 Receive Buffer Done
//! - MAC 0 Receive Frame Done
//! - MAC 0 Transmit Buffer Done
//! - MAC 0 Transmit Frame Done
//! - MAC 0 Graceful Stop
//! - MAC 0 Babbling Transmit Error
//! - MAC 0 Babbling Receive Error
//! - MAC 0 Wakeup Request [synchronous]
IMX_INT_ENET_1588 = 151, //!< MAC 0 1588 Timer interrupt [synchronous] request.
IMX_INT_PCIE_1 = 152, //!< PCIe interrupt request 1.
IMX_INT_PCIE_2 = 153, //!< PCIe interrupt request 2.
IMX_INT_PCIE_3 = 154, //!< PCIe interrupt request 3.
IMX_INT_PCIE_4 = 155, //!< PCIe interrupt request 4.
IMX_INT_DCIC1 = 156, //!< Logical OR of DCIC1 interrupt requests.
IMX_INT_DCIC2 = 157, //!< Logical OR of DCIC2 interrupt requests.
IMX_INT_MLB_AHB1 = 158, //!< Logical OR of channel[63:32] interrupt requests.
IMX_INT_PMU_DIG_BO = 159, //!< //!< PMU digital regulator brown-out interrupt request.
IMX_INTERRUPT_COUNT = 160 //!< Total number of interrupts.
};
#endif // __IRQ_NUMBERS_H__
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,50 @@
/*
* 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.
*/
#include <stdint.h>
#include <string.h>
#include "assert.h"
#include "spinlock.h"
bool module_spinlock_use_intr_init(void)
{
return true;
}
#define SPINLOCK_STATE_UNLOCK 0xFF
enum {
SPINLOCK_LOCK_NOWAIT = 0,
SPINLOCK_LOCK_WAITFOREVER = 0xFFFFFFFF,
};
void spinlock_init(struct spinlock* lock, char* name)
{
lock->owner_cpu = SPINLOCK_STATE_UNLOCK;
strncpy(lock->name, name, 24);
}
extern int _spinlock_lock(struct spinlock* lock, uint32_t timeout);
void spinlock_lock(struct spinlock* lock)
{
if (lock->owner_cpu != SPINLOCK_STATE_UNLOCK) {
ERROR("spinlock %s lock double locked by core %d\n", lock->name, lock->owner_cpu);
panic("");
}
assert(_spinlock_lock(lock, SPINLOCK_LOCK_WAITFOREVER) == 0);
}
void _spinlock_unlock(struct spinlock* lock);
void spinlock_unlock(struct spinlock* lock)
{
_spinlock_unlock(lock);
}
@@ -0,0 +1,255 @@
/*
* 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 trampoline.S
* @brief trap in and out code
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.08.25
*/
/*************************************************
File name: trampoline.S.c
Description: trap in and out code
Others:
History:
1. Date: 2023-08-28
Author: AIIT XUOS Lab
Modification:
1. first version
*************************************************/
#include "memlayout.h"
#include "core.h"
.globl trap_return
.globl user_trap_swi_enter
.globl trap_irq_enter
.globl trap_reset_enter
.globl trap_iabort
.globl trap_dabort
.globl trap_undefined_instruction
.globl init_stack
trap_return:
# restore context from trapframe
ldm r13, {sp, lr}^
add r13, r13, #8
ldmfd r13!, {r14}
ldmfd r13!, {r2}
msr spsr_cxsf, r2
ldr r0, [r13], #4
ldr r1, [r13], #4
ldr r2, [r13], #4
ldr r3, [r13], #4
ldr r4, [r13], #4
ldr r5, [r13], #4
ldr r6, [r13], #4
ldr r7, [r13], #4
ldr r8, [r13], #4
ldr r9, [r13], #4
ldr r10, [r13], #4
ldr r11, [r13], #4
ldr r12, [r13], #4
ldm r13!, {pc}^
user_trap_swi_enter:
# save trapframe to swi stack
sub sp, sp, #56
str r14, [sp, #52]
str r12, [sp, #48]
str r11, [sp, #44]
str r10, [sp, #40]
str r9, [sp, #36]
str r8, [sp, #32]
str r7, [sp, #28]
str r6, [sp, #24]
str r5, [sp, #20]
str r4, [sp, #16]
str r3, [sp, #12]
str r2, [sp, #8]
str r1, [sp, #4]
str r0, [sp]
mrs r2, spsr
stmfd r13!, {r2}
stmfd r13!, {r14}
stmfd r13, {sp, lr}^
sub r13, r13, #8
# call syscall handler
mov r0, r13
bl software_irq_dispatch
b trap_return
trap_irq_enter:
# save context in irq stack
sub r14, r14, #4
sub sp, sp, #16
str r14, [sp, #12]
str r2, [sp, #8]
str r1, [sp, #4]
str r0, [sp]
mrs r1, spsr
mov r0, r13 // irq stack stop
add r13, r13, #16 // reset IRQ stack
# switch to the SVC mode
mrs r2, cpsr
bic r2, r2, #ARM_CPSR_MODE_MASK
orr r2, r2, #ARM_MODE_SVC
msr cpsr_cxsf, r2
# build the trap frame
ldr r2, [r0, #12]
stmfd r13!, {r2}
sub r13, r13, #40
str r12, [r13, #36]
str r11, [r13, #32]
str r10, [r13, #28]
str r9, [r13, #24]
str r8, [r13, #20]
str r7, [r13, #16]
str r6, [r13, #12]
str r5, [r13, #8]
str r4, [r13, #4]
str r3, [r13]
ldmfd r0, {r3-r5}
stmfd r13!, {r3-r5}
stmfd r13!, {r1}
stmfd r13!, {lr}
stmfd r13, {sp, lr}^
sub r13, r13, #8
mov r0, r13 // trapframe as parameters
bl intr_irq_dispatch
b trap_return
trap_reset_enter:
mov r14, #0
sub r13, r13, #56
str r14, [r13, #52]
str r12, [r13, #48]
str r11, [r13, #44]
str r10, [r13, #40]
str r9, [r13, #36]
str r8, [r13, #32]
str r7, [r13, #28]
str r6, [r13, #24]
str r5, [r13, #20]
str r4, [r13, #16]
str r3, [r13, #12]
str r2, [r13, #8]
str r1, [r13, #4]
str r0, [r13]
mrs r2, spsr
stmfd r13!, {r2}
stmfd r13!, {r14}
stmfd r13, {sp, lr}^
sub r13, r13, #8
mov r0, r13
bl _vector_jumper
trap_dabort:
sub r14, r14, #8
sub r13, r13, #56
str r14, [r13, #52]
str r12, [r13, #48]
str r11, [r13, #44]
str r10, [r13, #40]
str r9, [r13, #36]
str r8, [r13, #32]
str r7, [r13, #28]
str r6, [r13, #24]
str r5, [r13, #20]
str r4, [r13, #16]
str r3, [r13, #12]
str r2, [r13, #8]
str r1, [r13, #4]
str r0, [r13]
mrs r2, spsr
stmfd r13!, {r2}
stmfd r13!, {r14}
stmfd r13, {sp, lr}^
sub r13, r13, #8
mov r0, r13
bl dabort_handler
trap_iabort:
sub r14, r14, #4
sub r13, r13, #56
str r14, [r13, #52]
str r12, [r13, #48]
str r11, [r13, #44]
str r10, [r13, #40]
str r9, [r13, #36]
str r8, [r13, #32]
str r7, [r13, #28]
str r6, [r13, #24]
str r5, [r13, #20]
str r4, [r13, #16]
str r3, [r13, #12]
str r2, [r13, #8]
str r1, [r13, #4]
str r0, [r13]
mrs r2, spsr
stmfd r13!, {r2}
stmfd r13!, {r14}
stmfd r13, {sp, lr}^
sub r13, r13, #8
mov r0, r13
bl iabort_handler
trap_undefined_instruction:
sub r13, r13, #56
str r14, [r13, #52]
str r12, [r13, #48]
str r11, [r13, #44]
str r10, [r13, #40]
str r9, [r13, #36]
str r8, [r13, #32]
str r7, [r13, #28]
str r6, [r13, #24]
str r5, [r13, #20]
str r4, [r13, #16]
str r3, [r13, #12]
str r2, [r13, #8]
str r1, [r13, #4]
str r0, [r13]
mrs r2, spsr
stmfd r13!, {r2}
stmfd r13!, {r14}
stmfd r13, {sp, lr}^
sub r13, r13, #8
mov r0, r13
bl handle_undefined_instruction
init_stack:
# set the stack for Other mode
mrs r2, cpsr
bic r2, r2, #ARM_CPSR_MODE_MASK
orr r2, r2, r0
msr cpsr_cxsf, r2
# switch back to the SVC mode
mov sp, r1
bic r2, r2, #ARM_CPSR_MODE_MASK
orr r2, r2, #ARM_MODE_SVC
msr cpsr_cxsf, r2
bx lr
@@ -0,0 +1,240 @@
/*
* 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 trap_common.c
* @brief trap interface of hardkernel
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.08.25
*/
/*************************************************
File name: trap_common.c
Description: trap interface of hardkernel
Others:
History:
1. Date: 2023-08-28
Author: AIIT XUOS Lab
Modification:
1. first version
*************************************************/
#include <string.h>
#include "core.h"
#include "gicv2_common_opa.h"
#include "trap_common.h"
#include "log.h"
extern void init_stack(uint32_t, uint32_t);
extern void user_trap_swi_enter(void);
extern void trap_iabort(void);
extern void trap_dabort(void);
extern void trap_irq_enter(void);
extern void trap_undefined_instruction(void);
static struct XiziTrapDriver xizi_trap_driver;
void panic(char* s)
{
xizi_trap_driver.cpu_irq_disable();
KPrintf("panic: %s\n", s);
for (;;)
;
}
/* stack for different mode*/
static char mode_stack_pages[NR_CPU][NR_MODE_STACKS][MODE_STACK_SIZE];
extern uint32_t _vector_jumper;
extern uint32_t _vector_start;
extern uint32_t _vector_end;
void init_cpu_mode_stacks(int cpu_id)
{
uint32_t modes[] = { ARM_MODE_FIQ, ARM_MODE_IRQ, ARM_MODE_ABT, ARM_MODE_UND };
// initialize the stacks for different mode
for (int i = 0; i < sizeof(modes) / sizeof(uint32_t); i++) {
memset(mode_stack_pages[cpu_id][i], 0, MODE_STACK_SIZE);
init_stack(modes[i], (uint32_t)mode_stack_pages[cpu_id][i]);
}
}
void handle_reserved(void)
{
// unimplemented trap handler
LOG("Unimplemented Reserved\n");
panic("");
}
void handle_fiq(void)
{
LOG("Unimplemented FIQ\n");
panic("");
}
static void _sys_irq_init()
{
/* load exception vectors */
volatile uint32_t* vector_base = &_vector_start;
// Set Interrupt handler start address
vector_base[1] = (uint32_t)trap_undefined_instruction; // Undefined Instruction
vector_base[2] = (uint32_t)user_trap_swi_enter; // Software Interrupt
vector_base[3] = (uint32_t)trap_iabort; // Prefetch Abort
vector_base[4] = (uint32_t)trap_dabort; // Data Abort
vector_base[5] = (uint32_t)handle_reserved; // Reserved
vector_base[6] = (uint32_t)trap_irq_enter; // IRQ
vector_base[7] = (uint32_t)handle_fiq; // FIQ
init_cpu_mode_stacks(0);
/* active hardware irq responser */
gic_init();
xizi_trap_driver.switch_hw_irqtbl((uint32_t*)&_vector_jumper);
}
static void _cpu_irq_enable(void)
{
arm_set_interrupt_state(true);
}
static void _cpu_irq_disable(void)
{
arm_set_interrupt_state(false);
}
static void _single_irq_enable(int irq, int cpu, int prio)
{
gic_set_irq_priority(irq, prio);
gic_set_irq_security(irq, false); // set IRQ as non-secure
gic_set_cpu_target(irq, cpu, true);
gic_enable_irq(irq, true);
}
static void _single_irq_disable(int irq, int cpu)
{
gic_enable_irq(irq, false);
gic_set_cpu_target(irq, cpu, false);
}
#define VBAR
static inline uint32_t* _switch_hw_irqtbl(uint32_t* new_tbl_base)
{
// get old irq table base addr
uint32_t old_tbl_base = 0;
_ARM_MRC(15, 0, old_tbl_base, 12, 0, 0);
// set new irq table base addr
_ARM_MCR(15, 0, new_tbl_base, 12, 0, 0);
// set sctlr to use VBAR
uint32_t sctlr = 0;
_ARM_MRC(15, 0, sctlr, 1, 0, 0);
sctlr &= ~(1 << 13);
_ARM_MCR(15, 0, sctlr, 1, 0, 0);
return (uint32_t*)old_tbl_base;
}
static void _bind_irq_handler(int irq, irq_handler_t handler)
{
xizi_trap_driver.sw_irqtbl[irq].handler = handler;
}
static bool _send_sgi(uint32_t irq, uint32_t bitmask, enum SgiFilterType type)
{
if (bitmask > (1 << NR_CPU) - 1) {
return false;
}
enum _gicd_sgi_filter sgi_filter;
switch (type) {
case SgiFilter_TargetList:
sgi_filter = kGicSgiFilter_UseTargetList;
break;
case SgiFilter_AllOtherCPUs:
sgi_filter = kGicSgiFilter_AllOtherCPUs;
break;
default:
sgi_filter = kGicSgiFilter_OnlyThisCPU;
break;
}
gic_send_sgi(irq, bitmask, sgi_filter);
return true;
}
static uint32_t _hw_before_irq()
{
uint32_t vectNum = gic_read_irq_ack();
if (vectNum & 0x200) {
gic_write_end_of_irq(vectNum);
return 0;
}
return vectNum;
}
static uint32_t _hw_cur_int_num(uint32_t int_info)
{
return int_info & 0x1FF;
}
static uint32_t _hw_cur_int_cpu(uint32_t int_info)
{
return (int_info >> 10) & 0x7;
}
static void _hw_after_irq(uint32_t int_info)
{
gic_write_end_of_irq(int_info);
}
static int _is_interruptable(void)
{
uint32_t val;
__asm__ __volatile__(
"mrs %0, cpsr"
: "=r"(val)
:
:);
return !(val & DIS_INT);
}
static struct XiziTrapDriver xizi_trap_driver = (struct XiziTrapDriver) {
.sys_irq_init = _sys_irq_init,
.cpu_irq_enable = _cpu_irq_enable,
.cpu_irq_disable = _cpu_irq_disable,
.single_irq_enable = _single_irq_enable,
.single_irq_disable = _single_irq_disable,
.switch_hw_irqtbl = _switch_hw_irqtbl,
.bind_irq_handler = _bind_irq_handler,
.send_sgi = _send_sgi,
.is_interruptable = _is_interruptable,
.hw_before_irq = _hw_before_irq,
.hw_cur_int_num = _hw_cur_int_num,
.hw_cur_int_cpu = _hw_cur_int_cpu,
.hw_after_irq = _hw_after_irq,
};
struct XiziTrapDriver* hardkernel_intr_init(struct TraceTag* hardkernel_tag)
{
xizi_trap_driver.sys_irq_init();
xizi_trap_driver.cpu_irq_enable();
return &xizi_trap_driver;
}
@@ -0,0 +1,75 @@
/*
* 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 vector_table.S
* @brief define vector table function
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.08.15
*/
/*************************************************
File name: vector_table.S
Description: cortex-a9 vector table
Others:
History:
1. Date: 2023-08-28
Author: AIIT XUOS Lab
Modification:
1. first version
*************************************************/
.globl _vector_jumper
.globl _vector_start
.globl _vector_end
.global _start
.section .vectors, "ax"
.globl _vector_jumper
/* These will be relocated to VECTOR_BASE. */
_vector_jumper:
ldr pc, .LOCATION_resethandler /* 0x00: Reset */
ldr pc, .LOCATION_undefinedhandler /* 0x04: Undefined instruction */
ldr pc, .LOCATION_svchandler /* 0x08: Software interrupt */
ldr pc, .LOCATION_prefetchaborthandler /* 0x0c: Prefetch abort */
ldr pc, .LOCATION_dataaborthandler /* 0x10: Data abort */
ldr pc, .LOCATION_addrexcptnhandler /* 0x14: Address exception (reserved) */
ldr pc, .LOCATION_irqhandler /* 0x18: IRQ */
ldr pc, .LOCATION_fiqhandler /* 0x1c: FIQ */
.globl _vector_start
_vector_start:
.LOCATION_resethandler:
.long _boot_start
.LOCATION_undefinedhandler:
.long _boot_start
.LOCATION_svchandler:
.long _boot_start
.LOCATION_prefetchaborthandler:
.long _boot_start
.LOCATION_dataaborthandler:
.long _boot_start
.LOCATION_addrexcptnhandler:
.long _boot_start
.LOCATION_irqhandler:
.long _boot_start
.LOCATION_fiqhandler:
.long _boot_start
.globl _vector_end
_vector_end:
.size _vector_start, . - _vector_start
.end
@@ -0,0 +1,44 @@
/*
* 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 spinlock.h
* @brief spinlock header
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.08.25
*/
/*************************************************
File name: spinlock.h
Description: spinlock header
Others:
History:
1. Date: 2023-08-28
Author: AIIT XUOS Lab
Modification:
1. first version
*************************************************/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#define STACK_DEPTH 32
struct spinlock { // Mutex.
uint32_t owner_cpu; // 1 for locked, 0 for unlocked
char name[28]; // The call stack (an array of program counters)
} __attribute__((aligned(32)));
bool module_spinlock_use_intr_init(void);
void spinlock_init(struct spinlock* lock, char* name);
void spinlock_lock(struct spinlock* lock);
void spinlock_unlock(struct spinlock* lock);
@@ -0,0 +1,103 @@
/*
* 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 trap_common.h
* @brief image vector table configuration for imx6q
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.08.25
*/
/*************************************************
File name: trap_common.h
Description: trap interface of hardkernel
Others:
History:
1. Date: 2023-08-28
Author: AIIT XUOS Lab
Modification:
1. first version
*************************************************/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "core.h"
#include "irq_numbers.h"
#include "memlayout.h"
#include "actracer.h"
#define NR_IRQS HW_NR_IRQS
#define NR_MODE_STACKS 4
enum SgiFilterType {
SgiFilter_TargetList = 0,
SgiFilter_AllOtherCPUs = 1,
SgiFilter_OnlyThisCPU = 2,
};
typedef int (*irq_handler_t)(int irq, void* context, void* arg);
struct irq_table_entry {
irq_handler_t handler;
};
struct XiziTrapDriver {
/* irq number table*/
struct irq_table_entry sw_irqtbl[NR_IRQS];
/* current irq number happening in cpu*/
uint32_t curr_int[NR_CPU];
void (*sys_irq_init)();
void (*cpu_irq_enable)();
void (*cpu_irq_disable)();
void (*single_irq_enable)(int irq, int cpu, int prio);
void (*single_irq_disable)(int irq, int cpu);
uint32_t* (*switch_hw_irqtbl)(uint32_t*);
bool (*send_sgi)(uint32_t, uint32_t, enum SgiFilterType);
void (*bind_irq_handler)(int, irq_handler_t);
/* check if no if interruptable */
int (*is_interruptable)();
/* code runs before irq handling */
uint32_t (*hw_before_irq)();
uint32_t (*hw_cur_int_num)(uint32_t int_info);
uint32_t (*hw_cur_int_cpu)(uint32_t int_info);
/* code runs after irq handling */
void (*hw_after_irq)(uint32_t int_info);
};
struct IrqDispatcherRightGroup {
struct TraceTag intr_driver_tag;
};
struct SwiDispatcherRightGroup {
struct TraceTag intr_driver_tag;
};
struct XiziTrapDriver* hardkernel_intr_init(struct TraceTag* hardkernel_tag);
static inline int cur_cpuid(void)
{
return cpu_get_current();
}
void panic(char* s);
bool intr_distributer_init(struct IrqDispatcherRightGroup*);
void intr_irq_dispatch(struct trapframe* tf);
bool swi_distributer_init(struct SwiDispatcherRightGroup*);
void software_irq_dispatch(struct trapframe* tf);