Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
BaiXuePrincess
rt-thread
提交
0b4416f0
R
rt-thread
项目概览
BaiXuePrincess
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
You need to sign in or sign up before continuing.
提交
0b4416f0
编写于
4月 08, 2021
作者:
F
fenghuijie
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add gic>imer interface
上级
11c20878
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
686 addition
and
79 deletion
+686
-79
libcpu/arm/cortex-a/cp15.h
libcpu/arm/cortex-a/cp15.h
+5
-0
libcpu/arm/cortex-a/gic.c
libcpu/arm/cortex-a/gic.c
+263
-69
libcpu/arm/cortex-a/gic.h
libcpu/arm/cortex-a/gic.h
+34
-7
libcpu/arm/cortex-a/gtimer.c
libcpu/arm/cortex-a/gtimer.c
+171
-0
libcpu/arm/cortex-a/gtimer.h
libcpu/arm/cortex-a/gtimer.h
+26
-0
libcpu/arm/cortex-a/interrupt.c
libcpu/arm/cortex-a/interrupt.c
+159
-1
libcpu/arm/cortex-a/interrupt.h
libcpu/arm/cortex-a/interrupt.h
+28
-2
未找到文件。
libcpu/arm/cortex-a/cp15.h
浏览文件 @
0b4416f0
...
...
@@ -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
);
...
...
libcpu/arm/cortex-a/gic.c
浏览文件 @
0b4416f0
...
...
@@ -17,6 +17,10 @@
#include "gic.h"
#include "cp15.h"
#ifdef RT_USING_FINSH
#include <finsh.h>
#endif
struct
arm_gic
{
rt_uint32_t
offset
;
/* the first interrupt index in the vector table */
...
...
@@ -28,6 +32,8 @@ struct arm_gic
/* 'ARM_GIC_MAX_NR' is the number of cores */
static
struct
arm_gic
_gic_table
[
ARM_GIC_MAX_NR
];
/** Macro to access the Generic Interrupt Controller Interface (GICC)
*/
#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)
...
...
@@ -35,7 +41,10 @@ static struct arm_gic _gic_table[ARM_GIC_MAX_NR];
#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)
#define GIC_CPU_IIDR(hw_base) __REG32((hw_base) + 0xFC)
/** Macro to access the Generic Interrupt Controller Distributor (GICD)
*/
#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)
...
...
@@ -50,6 +59,7 @@ static struct arm_gic _gic_table[ARM_GIC_MAX_NR];
#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_SPENDSGI(hw_base, n) __REG32((hw_base) + 0xf20 + ((n)/4) * 4)
#define GIC_DIST_ICPIDR2(hw_base) __REG32((hw_base) + 0xfe8)
static
unsigned
int
_gic_max_irq
;
...
...
@@ -90,7 +100,7 @@ void arm_gic_mask(rt_uint32_t index, int irq)
GIC_DIST_ENABLE_CLEAR
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
=
mask
;
}
void
arm_gic_
clear_pending
(
rt_uint32_t
index
,
int
irq
)
void
arm_gic_
umask
(
rt_uint32_t
index
,
int
irq
)
{
rt_uint32_t
mask
=
1
<<
(
irq
%
32
);
...
...
@@ -99,7 +109,107 @@ void arm_gic_clear_pending(rt_uint32_t index, int irq)
irq
=
irq
-
_gic_table
[
index
].
offset
;
RT_ASSERT
(
irq
>=
0
);
GIC_DIST_PENDING_CLEAR
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
=
mask
;
GIC_DIST_ENABLE_SET
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
=
mask
;
}
rt_uint32_t
arm_gic_get_pending_irq
(
rt_uint32_t
index
,
int
irq
)
{
rt_uint32_t
pend
;
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
irq
=
irq
-
_gic_table
[
index
].
offset
;
RT_ASSERT
(
irq
>=
0
);
if
(
irq
>=
16
)
{
pend
=
(
GIC_DIST_PENDING_SET
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
>>
(
irq
%
32
))
&
0x1
;
}
else
{
/* INTID 0-15 Software Generated Interrupt */
pend
=
(
GIC_DIST_SPENDSGI
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
>>
((
irq
%
4
)
*
8
))
&
0xFF
;
/* No CPU identification offered */
if
(
pend
!=
0
)
{
pend
=
1
;
}
else
{
pend
=
0
;
}
}
return
(
pend
);
}
void
arm_gic_set_pending_irq
(
rt_uint32_t
index
,
int
irq
)
{
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
irq
=
irq
-
_gic_table
[
index
].
offset
;
RT_ASSERT
(
irq
>=
0
);
if
(
irq
>=
16
)
{
GIC_DIST_PENDING_SET
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
=
1
<<
(
irq
%
32
);
}
else
{
/* INTID 0-15 Software Generated Interrupt */
/* Forward the interrupt to the CPU interface that requested it */
GIC_DIST_SOFTINT
(
_gic_table
[
index
].
dist_hw_base
)
=
(
irq
|
0x02000000
);
}
}
void
arm_gic_clear_pending_irq
(
rt_uint32_t
index
,
int
irq
)
{
rt_uint32_t
mask
;
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
irq
=
irq
-
_gic_table
[
index
].
offset
;
RT_ASSERT
(
irq
>=
0
);
if
(
irq
>=
16
)
{
mask
=
1
<<
(
irq
%
32
);
GIC_DIST_PENDING_CLEAR
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
=
mask
;
}
else
{
mask
=
1
<<
((
irq
%
4
)
*
8
);
GIC_DIST_CPENDSGI
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
=
mask
;
}
}
void
arm_gic_set_configuration
(
rt_uint32_t
index
,
int
irq
,
uint32_t
config
)
{
rt_uint32_t
icfgr
;
rt_uint32_t
shift
;
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
irq
=
irq
-
_gic_table
[
index
].
offset
;
RT_ASSERT
(
irq
>=
0
);
icfgr
=
GIC_DIST_CONFIG
(
_gic_table
[
index
].
dist_hw_base
,
irq
);
shift
=
(
irq
%
16
)
<<
1
;
icfgr
&=
(
~
(
3
<<
shift
));
icfgr
|=
(
config
<<
shift
);
GIC_DIST_CONFIG
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
=
icfgr
;
}
rt_uint32_t
arm_gic_get_configuration
(
rt_uint32_t
index
,
int
irq
)
{
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
irq
=
irq
-
_gic_table
[
index
].
offset
;
RT_ASSERT
(
irq
>=
0
);
return
(
GIC_DIST_CONFIG
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
>>
((
irq
%
16
)
>>
1
));
}
void
arm_gic_clear_active
(
rt_uint32_t
index
,
int
irq
)
...
...
@@ -126,70 +236,140 @@ void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask)
old_tgt
=
GIC_DIST_TARGET
(
_gic_table
[
index
].
dist_hw_base
,
irq
);
old_tgt
&=
~
(
0x0FF
UL
<<
((
irq
%
4
)
*
8
));
old_tgt
|=
cpumask
<<
((
irq
%
4
)
*
8
);
old_tgt
&=
~
(
0x0FF
<<
((
irq
%
4
)
*
8
));
old_tgt
|=
cpumask
<<
((
irq
%
4
)
*
8
);
GIC_DIST_TARGET
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
=
old_tgt
;
}
void
arm_gic_umask
(
rt_uint32_t
index
,
int
irq
)
rt_uint32_t
arm_gic_get_target_cpu
(
rt_uint32_t
index
,
int
irq
)
{
rt_uint32_t
mask
=
1
<<
(
irq
%
32
);
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
irq
=
irq
-
_gic_table
[
index
].
offset
;
RT_ASSERT
(
irq
>=
0
);
return
(
GIC_DIST_TARGET
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
>>
((
irq
%
4
)
*
8
))
&
0xFF
;
}
void
arm_gic_set_priority
(
rt_uint32_t
index
,
int
irq
,
rt_uint32_t
priority
)
{
rt_uint32_t
mask
;
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
irq
=
irq
-
_gic_table
[
index
].
offset
;
RT_ASSERT
(
irq
>=
0
);
GIC_DIST_ENABLE_SET
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
=
mask
;
mask
=
GIC_DIST_PRI
(
_gic_table
[
index
].
dist_hw_base
,
irq
);
mask
&=
~
(
0xFF
<<
((
irq
%
4
)
*
8
));
mask
|=
((
priority
&
0xFF
)
<<
((
irq
%
4
)
*
8
));
GIC_DIST_PRI
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
=
mask
;
}
void
arm_gic_dump_type
(
rt_uint32_t
index
)
rt_uint32_t
arm_gic_get_priority
(
rt_uint32_t
index
,
int
irq
)
{
unsigned
int
gic_type
;
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
)
;
gic_type
=
GIC_DIST_TYPE
(
_gic_table
[
index
].
dist_hw_base
);
rt_kprintf
(
"GICv%d on %p, max IRQs: %d, %s security extension(%08x)
\n
"
,
(
GIC_DIST_ICPIDR2
(
_gic_table
[
index
].
dist_hw_base
)
>>
4
)
&
0xf
,
_gic_table
[
index
].
dist_hw_base
,
_gic_max_irq
,
gic_type
&
(
1
<<
10
)
?
"has"
:
"no"
,
gic_type
);
irq
=
irq
-
_gic_table
[
index
].
offset
;
RT_ASSERT
(
irq
>=
0
);
return
(
GIC_DIST_PRI
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
>>
((
irq
%
4
)
*
8
))
&
0xFF
;
}
void
arm_gic_
dump
(
rt_uint32_t
index
)
void
arm_gic_
set_interface_prior_mask
(
rt_uint32_t
index
,
rt_uint32_t
priority
)
{
unsigned
int
i
,
k
;
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
)
;
k
=
GIC_CPU_HIGHPRI
(
_gic_table
[
index
].
cpu_hw_base
);
rt_kprintf
(
"--- high pending priority: %d(%08x)
\n
"
,
k
,
k
);
rt_kprintf
(
"--- hw mask ---
\n
"
);
for
(
i
=
0
;
i
<
_gic_max_irq
/
32
;
i
++
)
{
rt_kprintf
(
"0x%08x, "
,
GIC_DIST_ENABLE_SET
(
_gic_table
[
index
].
dist_hw_base
,
i
*
32
));
}
rt_kprintf
(
"
\n
--- hw pending ---
\n
"
);
for
(
i
=
0
;
i
<
_gic_max_irq
/
32
;
i
++
)
{
rt_kprintf
(
"0x%08x, "
,
GIC_DIST_PENDING_SET
(
_gic_table
[
index
].
dist_hw_base
,
i
*
32
));
}
rt_kprintf
(
"
\n
--- hw active ---
\n
"
);
for
(
i
=
0
;
i
<
_gic_max_irq
/
32
;
i
++
)
{
rt_kprintf
(
"0x%08x, "
,
GIC_DIST_ACTIVE_SET
(
_gic_table
[
index
].
dist_hw_base
,
i
*
32
));
}
rt_kprintf
(
"
\n
"
);
/* set priority mask */
GIC_CPU_PRIMASK
(
_gic_table
[
index
].
cpu_hw_base
)
=
priority
&
0xFF
;
}
rt_uint32_t
arm_gic_get_interface_prior_mask
(
rt_uint32_t
index
)
{
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
return
GIC_CPU_PRIMASK
(
_gic_table
[
index
].
cpu_hw_base
);
}
void
arm_gic_set_binary_point
(
rt_uint32_t
index
,
rt_uint32_t
binary_point
)
{
GIC_CPU_BINPOINT
(
_gic_table
[
index
].
cpu_hw_base
)
=
binary_point
&
0x7
;
}
rt_uint32_t
arm_gic_get_binary_point
(
rt_uint32_t
index
)
{
return
GIC_CPU_BINPOINT
(
_gic_table
[
index
].
cpu_hw_base
);
}
rt_uint32_t
arm_gic_get_irq_status
(
rt_uint32_t
index
,
int
irq
)
{
rt_uint32_t
pending
;
rt_uint32_t
active
;
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
irq
=
irq
-
_gic_table
[
index
].
offset
;
RT_ASSERT
(
irq
>=
0
);
active
=
(
GIC_DIST_ACTIVE_SET
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
>>
(
irq
%
32
))
&
0x1
;
pending
=
(
GIC_DIST_PENDING_SET
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
>>
(
irq
%
32
))
&
0x1
;
return
((
active
<<
1
)
|
pending
);
}
void
arm_gic_send_sgi
(
rt_uint32_t
index
,
int
irq
,
rt_uint32_t
target_list
,
rt_uint32_t
filter_list
)
{
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
irq
=
irq
-
_gic_table
[
index
].
offset
;
RT_ASSERT
(
irq
>=
0
);
GIC_DIST_SOFTINT
(
_gic_table
[
index
].
dist_hw_base
)
=
((
filter_list
&
0x3
)
<<
24
)
|
((
target_list
&
0xFF
)
<<
16
)
|
(
irq
&
0x0F
);
}
rt_uint32_t
arm_gic_get_high_pending_irq
(
rt_uint32_t
index
)
{
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
return
GIC_CPU_HIGHPRI
(
_gic_table
[
index
].
cpu_hw_base
);
}
rt_uint32_t
arm_gic_get_interface_id
(
rt_uint32_t
index
)
{
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
return
GIC_CPU_IIDR
(
_gic_table
[
index
].
cpu_hw_base
);
}
void
arm_gic_set_group
(
rt_uint32_t
index
,
int
irq
,
rt_uint32_t
group
)
{
uint32_t
igroupr
;
uint32_t
shift
;
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
RT_ASSERT
(
group
<=
1
);
irq
=
irq
-
_gic_table
[
index
].
offset
;
RT_ASSERT
(
irq
>=
0
);
igroupr
=
GIC_DIST_IGROUP
(
_gic_table
[
index
].
dist_hw_base
,
irq
);
shift
=
(
irq
%
32
);
igroupr
&=
(
~
(
1
<<
shift
));
igroupr
|=
(
(
group
&
0x1
)
<<
shift
);
GIC_DIST_IGROUP
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
=
igroupr
;
}
rt_uint32_t
arm_gic_get_group
(
rt_uint32_t
index
,
int
irq
)
{
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
irq
=
irq
-
_gic_table
[
index
].
offset
;
RT_ASSERT
(
irq
>=
0
);
return
(
GIC_DIST_IGROUP
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
>>
(
irq
%
32
))
&
0x1
;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT_ALIAS
(
arm_gic_dump
,
gic
,
show
gic
status
);
#endif
int
arm_gic_dist_init
(
rt_uint32_t
index
,
rt_uint32_t
dist_base
,
int
irq_start
)
{
...
...
@@ -265,36 +445,50 @@ int arm_gic_cpu_init(rt_uint32_t index, rt_uint32_t cpu_base)
return
0
;
}
void
arm_gic_
set_group
(
rt_uint32_t
index
,
int
vector
,
int
group
)
void
arm_gic_
dump_type
(
rt_uint32_t
index
)
{
/* As for GICv2, there are only group0 and group1. */
RT_ASSERT
(
group
<=
1
);
RT_ASSERT
(
vector
<
_gic_max_irq
);
unsigned
int
gic_type
;
gic_type
=
GIC_DIST_TYPE
(
_gic_table
[
index
].
dist_hw_base
);
rt_kprintf
(
"GICv%d on %p, max IRQs: %d, %s security extension(%08x)
\n
"
,
(
GIC_DIST_ICPIDR2
(
_gic_table
[
index
].
dist_hw_base
)
>>
4
)
&
0xf
,
_gic_table
[
index
].
dist_hw_base
,
_gic_max_irq
,
gic_type
&
(
1
<<
10
)
?
"has"
:
"no"
,
gic_type
);
}
if
(
group
==
0
)
void
arm_gic_dump
(
rt_uint32_t
index
)
{
unsigned
int
i
,
k
;
k
=
GIC_CPU_HIGHPRI
(
_gic_table
[
index
].
cpu_hw_base
);
rt_kprintf
(
"--- high pending priority: %d(%08x)
\n
"
,
k
,
k
);
rt_kprintf
(
"--- hw mask ---
\n
"
);
for
(
i
=
0
;
i
<
_gic_max_irq
/
32
;
i
++
)
{
GIC_DIST_IGROUP
(
_gic_table
[
index
].
dist_hw_base
,
vector
)
&=
~
(
1
<<
(
vector
%
32
));
rt_kprintf
(
"0x%08x, "
,
GIC_DIST_ENABLE_SET
(
_gic_table
[
index
].
dist_hw_base
,
i
*
32
));
}
else
if
(
group
==
1
)
rt_kprintf
(
"
\n
--- hw pending ---
\n
"
);
for
(
i
=
0
;
i
<
_gic_max_irq
/
32
;
i
++
)
{
GIC_DIST_IGROUP
(
_gic_table
[
index
].
dist_hw_base
,
vector
)
|=
(
1
<<
(
vector
%
32
));
rt_kprintf
(
"0x%08x, "
,
GIC_DIST_PENDING_SET
(
_gic_table
[
index
].
dist_hw_base
,
i
*
32
));
}
rt_kprintf
(
"
\n
--- hw active ---
\n
"
);
for
(
i
=
0
;
i
<
_gic_max_irq
/
32
;
i
++
)
{
rt_kprintf
(
"0x%08x, "
,
GIC_DIST_ACTIVE_SET
(
_gic_table
[
index
].
dist_hw_base
,
i
*
32
));
}
rt_kprintf
(
"
\n
"
);
}
#ifdef RT_USING_SMP
void
rt_hw_ipi_send
(
int
ipi_vector
,
unsigned
int
cpu_mask
)
{
/* note: ipi_vector maybe different with irq_vector */
GIC_DIST_SOFTINT
(
_gic_table
[
0
].
dist_hw_base
)
=
(
cpu_mask
<<
16
)
|
ipi_vector
;
}
#ifdef RT_USING_FINSH
FINSH_FUNCTION_EXPORT_ALIAS
(
arm_gic_dump
,
gic
,
show
gic
status
);
#endif
#ifdef RT_USING_SMP
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
libcpu/arm/cortex-a/gic.h
浏览文件 @
0b4416f0
...
...
@@ -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
);
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
);
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
);
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
);
...
...
libcpu/arm/cortex-a/gtimer.c
0 → 100644
浏览文件 @
0b4416f0
/*
* 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
());
}
libcpu/arm/cortex-a/gtimer.h
0 → 100644
浏览文件 @
0b4416f0
/*
* 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
libcpu/arm/cortex-a/interrupt.c
浏览文件 @
0b4416f0
...
...
@@ -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
libcpu/arm/cortex-a/interrupt.h
浏览文件 @
0b4416f0
...
...
@@ -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
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录