mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-09-22 03:09:16 +08:00
add bsp/raspi4 gicv2
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,35 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2013-07-20 Bernard first version
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_MACHINE_GIC_PL400_H
|
||||
#define __ARCH_MACHINE_GIC_PL400_H
|
||||
#ifndef __GIC_PL400_H__
|
||||
#define __GIC_PL400_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <rthw.h>
|
||||
#include <board.h>
|
||||
|
||||
typedef uint16_t interrupt_t;
|
||||
typedef uint16_t irq_t;
|
||||
typedef uint64_t bool_t;
|
||||
#define __REG32(x) (*((volatile unsigned int*)((rt_uint64_t)x)))
|
||||
|
||||
/** MODIFIES: [*] */
|
||||
interrupt_t getActiveIRQ(void);
|
||||
/** MODIFIES: [*] */
|
||||
interrupt_t getPendingIRQ(void);
|
||||
/** MODIFIES: [*] */
|
||||
bool_t isIRQPending(void);
|
||||
/** MODIFIES: [*] */
|
||||
void maskInterrupt(bool_t disable, interrupt_t irq);
|
||||
/** MODIFIES: [*] */
|
||||
void ackInterrupt(irq_t irq);
|
||||
/** MODIFIES: [*] */
|
||||
static inline void setInterruptMode(irq_t irq, bool_t levelTrigger, bool_t polarityLow) { }
|
||||
#define GIC_CPU_CTRL(hw_base) __REG32((hw_base) + 0x00)
|
||||
#define GIC_CPU_PRIMASK(hw_base) __REG32((hw_base) + 0x04)
|
||||
#define GIC_CPU_BINPOINT(hw_base) __REG32((hw_base) + 0x08)
|
||||
#define GIC_CPU_INTACK(hw_base) __REG32((hw_base) + 0x0c)
|
||||
#define GIC_CPU_EOI(hw_base) __REG32((hw_base) + 0x10)
|
||||
#define GIC_CPU_RUNNINGPRI(hw_base) __REG32((hw_base) + 0x14)
|
||||
#define GIC_CPU_HIGHPRI(hw_base) __REG32((hw_base) + 0x18)
|
||||
|
||||
/** MODIFIES: [*] */
|
||||
void initIRQController(void);
|
||||
#define GIC_DIST_CTRL(hw_base) __REG32((hw_base) + 0x000)
|
||||
#define GIC_DIST_TYPE(hw_base) __REG32((hw_base) + 0x004)
|
||||
#define GIC_DIST_IGROUP(hw_base, n) __REG32((hw_base) + 0x080 + ((n)/32) * 4)
|
||||
#define GIC_DIST_ENABLE_SET(hw_base, n) __REG32((hw_base) + 0x100 + ((n)/32) * 4)
|
||||
#define GIC_DIST_ENABLE_CLEAR(hw_base, n) __REG32((hw_base) + 0x180 + ((n)/32) * 4)
|
||||
#define GIC_DIST_PENDING_SET(hw_base, n) __REG32((hw_base) + 0x200 + ((n)/32) * 4)
|
||||
#define GIC_DIST_PENDING_CLEAR(hw_base, n) __REG32((hw_base) + 0x280 + ((n)/32) * 4)
|
||||
#define GIC_DIST_ACTIVE_SET(hw_base, n) __REG32((hw_base) + 0x300 + ((n)/32) * 4)
|
||||
#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) __REG32((hw_base) + 0x380 + ((n)/32) * 4)
|
||||
#define GIC_DIST_PRI(hw_base, n) __REG32((hw_base) + 0x400 + ((n)/4) * 4)
|
||||
#define GIC_DIST_TARGET(hw_base, n) __REG32((hw_base) + 0x800 + ((n)/4) * 4)
|
||||
#define GIC_DIST_CONFIG(hw_base, n) __REG32((hw_base) + 0xc00 + ((n)/16) * 4)
|
||||
#define GIC_DIST_SOFTINT(hw_base) __REG32((hw_base) + 0xf00)
|
||||
#define GIC_DIST_CPENDSGI(hw_base, n) __REG32((hw_base) + 0xf10 + ((n)/4) * 4)
|
||||
#define GIC_DIST_ICPIDR2(hw_base) __REG32((hw_base) + 0xfe8)
|
||||
|
||||
void handleSpuriousIRQ(void);
|
||||
int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start);
|
||||
int arm_gic_cpu_init(rt_uint32_t index, rt_uint32_t cpu_base);
|
||||
|
||||
void rt_hw_interrupt_umask(int vector);
|
||||
void arm_gic_mask(rt_uint32_t index, int irq);
|
||||
void arm_gic_umask(rt_uint32_t index, int irq);
|
||||
void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask);
|
||||
void arm_gic_set_group(rt_uint32_t index, int vector, int group);
|
||||
|
||||
int rt_hw_interrupt_get_irq(void);
|
||||
int arm_gic_get_active_irq(rt_uint32_t index);
|
||||
void arm_gic_ack(rt_uint32_t index, int irq);
|
||||
|
||||
void rt_hw_interrupt_ack(int fiq_irq);
|
||||
#endif /* !__ARCH_MACHINE_GIC400_H */
|
||||
void arm_gic_clear_active(rt_uint32_t index, int irq);
|
||||
void arm_gic_clear_pending(rt_uint32_t index, int irq);
|
||||
|
||||
void arm_gic_dump_type(rt_uint32_t index);
|
||||
void arm_gic_dump(rt_uint32_t index);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -13,8 +13,10 @@
|
||||
#include <gic_pl400.h>
|
||||
#include <board.h>
|
||||
#include <armv8.h>
|
||||
#include "iomap.h"
|
||||
|
||||
#define MAX_HANDLERS 256
|
||||
#define GIC_ACK_INTID_MASK 0x000003ff
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
#define rt_interrupt_nest rt_cpu_self()->irq_nest
|
||||
@@ -41,7 +43,15 @@ void rt_hw_vector_init(void)
|
||||
*/
|
||||
void rt_hw_interrupt_init(void)
|
||||
{
|
||||
initIRQController();
|
||||
|
||||
rt_uint32_t gic_cpu_base = 0;
|
||||
rt_uint32_t gic_dist_base = 0;
|
||||
|
||||
/* initialize ARM GIC */
|
||||
gic_dist_base = GIC_PL400_DISTRIBUTOR_PPTR;
|
||||
gic_cpu_base = GIC_PL400_CONTROLLER_PPTR;
|
||||
arm_gic_dist_init(0, gic_dist_base, 0);
|
||||
arm_gic_cpu_init(0, gic_cpu_base);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,4 +80,40 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
|
||||
}
|
||||
|
||||
return old_handler;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will mask a interrupt.
|
||||
* @param vector the interrupt number
|
||||
*/
|
||||
void rt_hw_interrupt_mask(int vector)
|
||||
{
|
||||
arm_gic_mask(0, vector);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will un-mask a interrupt.
|
||||
* @param vector the interrupt number
|
||||
*/
|
||||
void rt_hw_interrupt_umask(int vector)
|
||||
{
|
||||
arm_gic_umask(0, vector);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the active interrupt number.
|
||||
* @param none
|
||||
*/
|
||||
int rt_hw_interrupt_get_irq(void)
|
||||
{
|
||||
return arm_gic_get_active_irq(0) & GIC_ACK_INTID_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function acknowledges the interrupt.
|
||||
* @param vector the interrupt number
|
||||
*/
|
||||
void rt_hw_interrupt_ack(int vector)
|
||||
{
|
||||
arm_gic_ack(0, vector);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user