mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-09-21 18:57:16 +08:00
Merge pull request #4583 from fenghuijie/master
[Cortex-A]add gic>imer interface
This commit is contained in:
@@ -10,6 +10,11 @@
|
||||
#ifndef __CP15_H__
|
||||
#define __CP15_H__
|
||||
|
||||
#define __get_cp(cp, op1, Rt, CRn, CRm, op2) __asm__ volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" )
|
||||
#define __set_cp(cp, op1, Rt, CRn, CRm, op2) __asm__ volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" )
|
||||
#define __get_cp64(cp, op1, Rt, CRm) __asm__ volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" )
|
||||
#define __set_cp64(cp, op1, Rt, CRm) __asm__ volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" )
|
||||
|
||||
unsigned long rt_cpu_get_smp_id(void);
|
||||
|
||||
void rt_cpu_mmu_disable(void);
|
||||
|
||||
+321
-126
File diff suppressed because it is too large
Load Diff
@@ -14,19 +14,46 @@
|
||||
#include <rthw.h>
|
||||
#include <board.h>
|
||||
|
||||
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 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 arm_gic_get_active_irq(rt_uint32_t index);
|
||||
void arm_gic_ack(rt_uint32_t index, int irq);
|
||||
|
||||
void arm_gic_mask(rt_uint32_t index, int irq);
|
||||
void arm_gic_umask(rt_uint32_t index, int irq);
|
||||
|
||||
rt_uint32_t arm_gic_get_pending_irq(rt_uint32_t index, int irq);
|
||||
void arm_gic_set_pending_irq(rt_uint32_t index, int irq);
|
||||
void arm_gic_clear_pending_irq(rt_uint32_t index, int irq);
|
||||
|
||||
void arm_gic_set_configuration(rt_uint32_t index, int irq, uint32_t config);
|
||||
rt_uint32_t arm_gic_get_configuration(rt_uint32_t index, int irq);
|
||||
|
||||
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_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask);
|
||||
rt_uint32_t arm_gic_get_target_cpu(rt_uint32_t index, int irq);
|
||||
|
||||
void arm_gic_set_priority(rt_uint32_t index, int irq, rt_uint32_t priority);
|
||||
rt_uint32_t arm_gic_get_priority(rt_uint32_t index, int irq);
|
||||
|
||||
void arm_gic_set_interface_prior_mask(rt_uint32_t index, rt_uint32_t priority);
|
||||
rt_uint32_t arm_gic_get_interface_prior_mask(rt_uint32_t index);
|
||||
|
||||
void arm_gic_set_binary_point(rt_uint32_t index, rt_uint32_t binary_point);
|
||||
rt_uint32_t arm_gic_get_binary_point(rt_uint32_t index);
|
||||
|
||||
rt_uint32_t arm_gic_get_irq_status(rt_uint32_t index, int irq);
|
||||
|
||||
void arm_gic_send_sgi(rt_uint32_t index, int irq, rt_uint32_t target_list, rt_uint32_t filter_list);
|
||||
|
||||
rt_uint32_t arm_gic_get_high_pending_irq(rt_uint32_t index);
|
||||
|
||||
rt_uint32_t arm_gic_get_interface_id(rt_uint32_t index);
|
||||
|
||||
void arm_gic_set_group(rt_uint32_t index, int irq, rt_uint32_t group);
|
||||
rt_uint32_t arm_gic_get_group(rt_uint32_t index, int irq);
|
||||
|
||||
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 arm_gic_dump_type(rt_uint32_t index);
|
||||
void arm_gic_dump(rt_uint32_t index);
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-03-30 huijie.feng first version
|
||||
*/
|
||||
|
||||
#include "cp15.h"
|
||||
#include <rtdef.h>
|
||||
|
||||
/** Set CNTFRQ
|
||||
* This function assigns the given value to PL1 Physical Timer Counter Frequency Register (CNTFRQ).
|
||||
* @param value: CNTFRQ Register value to set
|
||||
*/
|
||||
static inline void __set_cntfrq(rt_uint32_t value)
|
||||
{
|
||||
__set_cp(15, 0, value, 14, 0, 0);
|
||||
}
|
||||
|
||||
/** Get CNTFRQ
|
||||
* This function returns the value of the PL1 Physical Timer Counter Frequency Register (CNTFRQ).
|
||||
* return CNTFRQ Register value
|
||||
*/
|
||||
static inline rt_uint32_t __get_cntfrq(void)
|
||||
{
|
||||
rt_uint32_t result;
|
||||
__get_cp(15, 0, result, 14, 0 , 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Set CNTP_TVAL
|
||||
* This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL).
|
||||
* param value: CNTP_TVAL Register value to set
|
||||
*/
|
||||
static inline void __set_cntp_tval(rt_uint32_t value)
|
||||
{
|
||||
__set_cp(15, 0, value, 14, 2, 0);
|
||||
}
|
||||
|
||||
/** Get CNTP_TVAL
|
||||
* This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL).
|
||||
* return CNTP_TVAL Register value
|
||||
*/
|
||||
static inline rt_uint32_t __get_cntp_tval(void)
|
||||
{
|
||||
rt_uint32_t result;
|
||||
__get_cp(15, 0, result, 14, 2, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Get CNTPCT
|
||||
* This function returns the value of the 64 bits PL1 Physical Count Register (CNTPCT).
|
||||
* return CNTPCT Register value
|
||||
*/
|
||||
static inline rt_uint64_t __get_cntpct(void)
|
||||
{
|
||||
rt_uint64_t result;
|
||||
__get_cp64(15, 0, result, 14);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Set CNTP_CVAL
|
||||
* This function assigns the given value to 64bits PL1 Physical Timer CompareValue Register (CNTP_CVAL).
|
||||
* param value: CNTP_CVAL Register value to set
|
||||
*/
|
||||
static inline void __set_cntp_cval(rt_uint64_t value)
|
||||
{
|
||||
__set_cp64(15, 2, value, 14);
|
||||
}
|
||||
|
||||
/** Get CNTP_CVAL
|
||||
* This function returns the value of the 64 bits PL1 Physical Timer CompareValue Register (CNTP_CVAL).
|
||||
* return CNTP_CVAL Register value
|
||||
*/
|
||||
static inline rt_uint64_t __get_cntp_cval(void)
|
||||
{
|
||||
rt_uint64_t result;
|
||||
__get_cp64(15, 2, result, 14);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Set CNTP_CTL
|
||||
* This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL).
|
||||
* param value: CNTP_CTL Register value to set
|
||||
*/
|
||||
static inline void __set_cntp_ctl(uint32_t value)
|
||||
{
|
||||
__set_cp(15, 0, value, 14, 2, 1);
|
||||
}
|
||||
|
||||
/** Get CNTP_CTL register
|
||||
* return CNTP_CTL Register value
|
||||
*/
|
||||
static inline rt_uint32_t __get_cntp_ctl(void)
|
||||
{
|
||||
rt_uint32_t result;
|
||||
__get_cp(15, 0, result, 14, 2, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Configures the frequency the timer shall run at.
|
||||
* param value The timer frequency in Hz.
|
||||
*/
|
||||
void gtimer_set_counter_frequency(rt_uint32_t value)
|
||||
{
|
||||
__set_cntfrq(value);
|
||||
__asm__ volatile ("isb 0xF":::"memory");
|
||||
}
|
||||
|
||||
/** Sets the reset value of the timer.
|
||||
* param value: The value the timer is loaded with.
|
||||
*/
|
||||
void gtimer_set_load_value(rt_uint32_t value)
|
||||
{
|
||||
__set_cntp_tval(value);
|
||||
__asm__ volatile ("isb 0xF":::"memory");
|
||||
}
|
||||
|
||||
/** Get the current counter value.
|
||||
* return Current counter value.
|
||||
*/
|
||||
rt_uint32_t gtimer_get_current_value(void)
|
||||
{
|
||||
return(__get_cntp_tval());
|
||||
}
|
||||
|
||||
/** Get the current physical counter value.
|
||||
* return Current physical counter value.
|
||||
*/
|
||||
rt_uint64_t gtimer_get_current_physical_value(void)
|
||||
{
|
||||
return(__get_cntpct());
|
||||
}
|
||||
|
||||
/** Set the physical compare value.
|
||||
* param value: New physical timer compare value.
|
||||
*/
|
||||
void gtimer_set_physical_compare_value(rt_uint64_t value)
|
||||
{
|
||||
__set_cntp_cval(value);
|
||||
__asm__ volatile ("isb 0xF":::"memory");
|
||||
}
|
||||
|
||||
/** Get the physical compare value.
|
||||
* return Physical compare value.
|
||||
*/
|
||||
rt_uint64_t gtimer_get_physical_compare_value(void)
|
||||
{
|
||||
return(__get_cntp_cval());
|
||||
}
|
||||
|
||||
/** Configure the timer by setting the control value.
|
||||
* param value: New timer control value.
|
||||
*/
|
||||
void gtimer_set_control(rt_uint32_t value)
|
||||
{
|
||||
__set_cntp_ctl(value);
|
||||
__asm__ volatile ("isb 0xF":::"memory");
|
||||
}
|
||||
|
||||
/** Get the control value.
|
||||
* return Control value.
|
||||
*/
|
||||
rt_uint32_t gtimer_get_control(void)
|
||||
{
|
||||
return(__get_cntp_ctl());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-03-30 huijie.feng first version
|
||||
*/
|
||||
|
||||
#ifndef __GTIMER_H__
|
||||
#define __GTIMER_H__
|
||||
|
||||
#include <rtdef.h>
|
||||
|
||||
void gtimer_set_counter_frequency(rt_uint32_t value);
|
||||
void gtimer_set_load_value(rt_uint32_t value);
|
||||
rt_uint32_t gtimer_get_current_value(void);
|
||||
rt_uint64_t gtimer_get_current_physical_value(void);
|
||||
void gtimer_set_physical_compare_value(rt_uint64_t value);
|
||||
rt_uint64_t gtimer_get_physical_compare_value(void);
|
||||
void gtimer_set_control(rt_uint32_t value);
|
||||
rt_uint32_t gtimer_get_control(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -83,7 +83,7 @@ void rt_hw_interrupt_umask(int vector)
|
||||
*/
|
||||
int rt_hw_interrupt_get_irq(void)
|
||||
{
|
||||
return arm_gic_get_active_irq(0) & GIC_ACK_INTID_MASK;
|
||||
return arm_gic_get_active_irq(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,6 +94,150 @@ void rt_hw_interrupt_ack(int vector)
|
||||
{
|
||||
arm_gic_ack(0, vector);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function set interrupt CPU targets.
|
||||
* @param vector: the interrupt number
|
||||
* cpu_mask: target cpus mask, one bit for one core
|
||||
*/
|
||||
void rt_hw_interrupt_set_target_cpus(int vector, unsigned int cpu_mask)
|
||||
{
|
||||
arm_gic_set_cpu(0, vector, cpu_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function get interrupt CPU targets.
|
||||
* @param vector: the interrupt number
|
||||
* @return target cpus mask, one bit for one core
|
||||
*/
|
||||
unsigned int rt_hw_interrupt_get_target_cpus(int vector)
|
||||
{
|
||||
return arm_gic_get_target_cpu(0, vector);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function set interrupt triger mode.
|
||||
* @param vector: the interrupt number
|
||||
* mode: interrupt triger mode; 0: level triger, 1: edge triger
|
||||
*/
|
||||
void rt_hw_interrupt_set_triger_mode(int vector, unsigned int mode)
|
||||
{
|
||||
arm_gic_set_configuration(0, vector, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function get interrupt triger mode.
|
||||
* @param vector: the interrupt number
|
||||
* @return interrupt triger mode; 0: level triger, 1: edge triger
|
||||
*/
|
||||
unsigned int rt_hw_interrupt_get_triger_mode(int vector)
|
||||
{
|
||||
return arm_gic_get_configuration(0, vector);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function set interrupt pending flag.
|
||||
* @param vector: the interrupt number
|
||||
*/
|
||||
void rt_hw_interrupt_set_pending(int vector)
|
||||
{
|
||||
arm_gic_set_pending_irq(0, vector);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function get interrupt pending flag.
|
||||
* @param vector: the interrupt number
|
||||
* @return interrupt pending flag, 0: not pending; 1: pending
|
||||
*/
|
||||
unsigned int rt_hw_interrupt_get_pending(int vector)
|
||||
{
|
||||
return arm_gic_get_pending_irq(0, vector);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function clear interrupt pending flag.
|
||||
* @param vector: the interrupt number
|
||||
*/
|
||||
void rt_hw_interrupt_clear_pending(int vector)
|
||||
{
|
||||
arm_gic_clear_pending_irq(0, vector);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function set interrupt priority value.
|
||||
* @param vector: the interrupt number
|
||||
* priority: the priority of interrupt to set
|
||||
*/
|
||||
void rt_hw_interrupt_set_priority(int vector, unsigned int priority)
|
||||
{
|
||||
arm_gic_set_priority(0, vector, priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function get interrupt priority.
|
||||
* @param vector: the interrupt number
|
||||
* @return interrupt priority value
|
||||
*/
|
||||
unsigned int rt_hw_interrupt_get_priority(int vector)
|
||||
{
|
||||
return arm_gic_get_priority(0, vector);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function set priority masking threshold.
|
||||
* @param priority: priority masking threshold
|
||||
*/
|
||||
void rt_hw_interrupt_set_priority_mask(unsigned int priority)
|
||||
{
|
||||
arm_gic_set_interface_prior_mask(0, priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function get priority masking threshold.
|
||||
* @param none
|
||||
* @return priority masking threshold
|
||||
*/
|
||||
unsigned int rt_hw_interrupt_get_priority_mask(void)
|
||||
{
|
||||
return arm_gic_get_interface_prior_mask(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function set priority grouping field split point.
|
||||
* @param bits: priority grouping field split point
|
||||
* @return 0: success; -1: failed
|
||||
*/
|
||||
int rt_hw_interrupt_set_prior_group_bits(unsigned int bits)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (bits < 8)
|
||||
{
|
||||
arm_gic_set_binary_point(0, (7 - bits));
|
||||
status = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function get priority grouping field split point.
|
||||
* @param none
|
||||
* @return priority grouping field split point
|
||||
*/
|
||||
unsigned int rt_hw_interrupt_get_prior_group_bits(void)
|
||||
{
|
||||
unsigned int bp;
|
||||
|
||||
bp = arm_gic_get_binary_point(0) & 0x07;
|
||||
|
||||
return (7 - bp);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will install a interrupt service routine to a interrupt.
|
||||
* @param vector the interrupt number
|
||||
@@ -121,3 +265,17 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
|
||||
|
||||
return old_handler;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask)
|
||||
{
|
||||
arm_gic_send_sgi(0, ipi_vector, cpu_mask, 0);
|
||||
}
|
||||
|
||||
void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler)
|
||||
{
|
||||
/* note: ipi_vector maybe different with irq_vector */
|
||||
rt_hw_interrupt_install(ipi_vector, ipi_isr_handler, 0, "IPI_HANDLER");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
#define INT_IRQ 0x00
|
||||
#define INT_FIQ 0x01
|
||||
|
||||
void rt_hw_vector_init(void);
|
||||
#define IRQ_MODE_TRIG_LEVEL (0x00) /* Trigger: level triggered interrupt */
|
||||
#define IRQ_MODE_TRIG_EDGE (0x01) /* Trigger: edge triggered interrupt */
|
||||
|
||||
void rt_hw_interrupt_control(int vector, int priority, int route);
|
||||
void rt_hw_vector_init(void);
|
||||
|
||||
void rt_hw_interrupt_init(void);
|
||||
void rt_hw_interrupt_mask(int vector);
|
||||
@@ -28,7 +29,32 @@ void rt_hw_interrupt_umask(int vector);
|
||||
int rt_hw_interrupt_get_irq(void);
|
||||
void rt_hw_interrupt_ack(int vector);
|
||||
|
||||
void rt_hw_interrupt_set_target_cpus(int vector, unsigned int cpu_mask);
|
||||
unsigned int rt_hw_interrupt_get_target_cpus(int vector);
|
||||
|
||||
void rt_hw_interrupt_set_triger_mode(int vector, unsigned int mode);
|
||||
unsigned int rt_hw_interrupt_get_triger_mode(int vector);
|
||||
|
||||
void rt_hw_interrupt_set_pending(int vector);
|
||||
unsigned int rt_hw_interrupt_get_pending(int vector);
|
||||
void rt_hw_interrupt_clear_pending(int vector);
|
||||
|
||||
void rt_hw_interrupt_set_priority(int vector, unsigned int priority);
|
||||
unsigned int rt_hw_interrupt_get_priority(int vector);
|
||||
|
||||
void rt_hw_interrupt_set_priority_mask(unsigned int priority);
|
||||
unsigned int rt_hw_interrupt_get_priority_mask(void);
|
||||
|
||||
int rt_hw_interrupt_set_prior_group_bits(unsigned int bits);
|
||||
unsigned int rt_hw_interrupt_get_prior_group_bits(void);
|
||||
|
||||
rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
|
||||
void *param, const char *name);
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask);
|
||||
void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user