Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
okll00
rt-thread
提交
709e0d57
R
rt-thread
项目概览
okll00
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
709e0d57
编写于
4月 16, 2020
作者:
B
bigmagic
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add bsp/raspi4 gicv2
上级
a120c914
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
299 addition
and
333 deletion
+299
-333
bsp/raspberry-pi/raspi4/driver/board.c
bsp/raspberry-pi/raspi4/driver/board.c
+3
-4
bsp/raspberry-pi/raspi4/driver/iomap.h
bsp/raspberry-pi/raspi4/driver/iomap.h
+1
-0
bsp/raspberry-pi/raspi4/rtconfig.py
bsp/raspberry-pi/raspi4/rtconfig.py
+1
-1
libcpu/aarch64/common/gic/gic_pl400.c
libcpu/aarch64/common/gic/gic_pl400.c
+186
-292
libcpu/aarch64/common/gic/gic_pl400.h
libcpu/aarch64/common/gic/gic_pl400.h
+60
-34
libcpu/aarch64/cortex-a72/interrupt.c
libcpu/aarch64/cortex-a72/interrupt.c
+48
-2
未找到文件。
bsp/raspberry-pi/raspi4/driver/board.c
浏览文件 @
709e0d57
...
...
@@ -75,10 +75,6 @@ void rt_hw_board_init(void)
rt_hw_interrupt_init
();
// in libcpu/interrupt.c. Set some data structures, no operation on device
rt_hw_vector_init
();
// in libcpu/interrupt.c. == rt_cpu_vector_set_base((rt_ubase_t)&system_vectors);
/* initialize timer for os tick */
rt_hw_timer_init
();
rt_thread_idle_sethook
(
idle_wfi
);
/* initialize uart */
rt_hw_uart_init
();
// driver/drv_uart.c
#ifdef RT_USING_CONSOLE
...
...
@@ -91,6 +87,9 @@ void rt_hw_board_init(void)
rt_kprintf
(
"heap: 0x%08x - 0x%08x
\n
"
,
RT_HW_HEAP_BEGIN
,
RT_HW_HEAP_END
);
rt_system_heap_init
(
RT_HW_HEAP_BEGIN
,
RT_HW_HEAP_END
);
#endif
/* initialize timer for os tick */
rt_hw_timer_init
();
rt_thread_idle_sethook
(
idle_wfi
);
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init
();
...
...
bsp/raspberry-pi/raspi4/driver/iomap.h
浏览文件 @
709e0d57
#ifndef __RASPI4_H__
#define __RASPI4_H__
#define ARM_GIC_NR_IRQS 512
#define INTC_BASE 0xff800000
#define GIC_V2_DISTRIBUTOR_BASE (INTC_BASE + 0x00041000)
#define GIC_V2_CPU_INTERFACE_BASE (INTC_BASE + 0x00042000)
...
...
bsp/raspberry-pi/raspi4/rtconfig.py
浏览文件 @
709e0d57
...
...
@@ -32,7 +32,7 @@ if PLATFORM == 'gcc':
OBJDUMP
=
PREFIX
+
'objdump'
OBJCPY
=
PREFIX
+
'objcopy'
DEVICE
=
' -march=armv8-a -mtune=cortex-a
57
'
DEVICE
=
' -march=armv8-a -mtune=cortex-a
72
'
CFLAGS
=
DEVICE
+
' -Wall'
AFLAGS
=
' -c'
+
' -x assembler-with-cpp -D__ASSEMBLY__'
LFLAGS
=
DEVICE
+
' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds'
...
...
libcpu/aarch64/common/gic/gic_pl400.c
浏览文件 @
709e0d57
/*
* Copyright
2014, General Dynamics C4 Systems
* Copyright
(c) 2006-2018, RT-Thread Development Team
*
* This software may be distributed and modified according to the terms of
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
* See "LICENSE_GPLv2.txt" for details.
* SPDX-License-Identifier: Apache-2.0
*
* @TAG(GD_GPL)
* Change Logs:
* Date Author Notes
* 2013-07-20 Bernard first version
* 2014-04-03 Grissiom many enhancements
* 2018-11-22 Jesven add rt_hw_ipi_send()
* add rt_hw_ipi_handler_install()
*/
#include <rtthread.h>
#include "gic_pl400.h"
#include "cp15.h"
#include "iomap.h"
#define BIT(n) (1ul<<(n))
#define MASK(n) (BIT(n)-1ul)
/* Setters/getters helpers */
#define IRQ_REG(IRQ) ((IRQ) / 32)
#define IRQ_BIT(IRQ) BIT((IRQ) % 32)
#define IRQ_MASK MASK(10)
#define IS_IRQ_VALID(X) (((X)&IRQ_MASK) < SPECIAL_IRQ_START)
#define ARM_GIC_MAX_NR 1
struct
arm_gic
{
rt_uint32_t
offset
;
/* the first interrupt index in the vector table */
#define CPU(X) (1<<(X))
#define TARGET_CPU_ALLINT(CPU) ( \
( ((CPU)&0xff)<<0 ) |\
( ((CPU)&0xff)<<8 ) |\
( ((CPU)&0xff)<<16 ) |\
( ((CPU)&0xff)<<24 ) \
)
#define TARGET_CPU0_ALLINT TARGET_CPU_ALLINT(CPU(0))
rt_uint32_t
dist_hw_base
;
/* the base address of the gic distributor */
rt_uint32_t
cpu_hw_base
;
/* the base addrees of the gic cpu interface */
};
/* 'ARM_GIC_MAX_NR' is the number of cores */
static
struct
arm_gic
_gic_table
[
ARM_GIC_MAX_NR
];
#define IRQ_SET_ALL 0xffffffff
;
static
unsigned
int
_gic_max_irq
;
/* Special IRQ's */
#define SPECIAL_IRQ_START 1020
#define IRQ_NONE 1023
int
arm_gic_get_active_irq
(
rt_uint32_t
index
)
{
int
irq
;
/* Memory map for GIC distributor */
struct
gic_dist_map
{
uint32_t
enable
;
/* 0x000 */
uint32_t
ic_type
;
/* 0x004 */
uint32_t
dist_ident
;
/* 0x008 */
uint32_t
res1
[
29
];
/* [0x00C, 0x080) */
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
uint32_t
group
[
32
];
/* [0x080, 0x100) */
irq
=
GIC_CPU_INTACK
(
_gic_table
[
index
].
cpu_hw_base
);
irq
+=
_gic_table
[
index
].
offset
;
return
irq
;
}
uint32_t
enable_set
[
32
];
/* [0x100, 0x180) */
uint32_t
enable_clr
[
32
];
/* [0x180, 0x200) */
uint32_t
pending_set
[
32
];
/* [0x200, 0x280) */
uint32_t
pending_clr
[
32
];
/* [0x280, 0x300) */
uint32_t
active
[
32
];
/* [0x300, 0x380) */
uint32_t
active_clr
[
32
];
/* [0x380, 0x400) */
void
arm_gic_ack
(
rt_uint32_t
index
,
int
irq
)
{
rt_uint32_t
mask
=
1
<<
(
irq
%
32
);
uint32_t
priority
[
255
];
/* [0x400, 0x7FC) */
uint32_t
res2
;
/* 0x7FC */
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
uint32_t
targets
[
255
];
/* [0x800, 0xBFC) */
uint32_t
res3
;
/* 0xBFC */
irq
=
irq
-
_gic_table
[
index
].
offset
;
RT_ASSERT
(
irq
>=
0
);
uint32_t
config
[
64
];
/* [0xC00, 0xD00) */
GIC_DIST_ENABLE_CLEAR
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
=
mask
;
GIC_CPU_EOI
(
_gic_table
[
index
].
cpu_hw_base
)
=
irq
;
GIC_DIST_ENABLE_SET
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
=
mask
;
}
uint32_t
ppi_status
;
/* [0xD00, 0xD04) */
uint32_t
spi_status
[
15
];
/* [0xD04, 0xD40) */
uint32_t
res4
[
112
];
/* [0xD40, 0xF00) */
void
arm_gic_mask
(
rt_uint32_t
index
,
int
irq
)
{
rt_uint32_t
mask
=
1
<<
(
irq
%
32
);
uint32_t
sgi_control
;
/* 0xF00 */
uint32_t
res5
[
3
];
/* [0xF04, 0xF10) */
uint32_t
sgi_pending_clr
[
4
];
/* [0xF10, 0xF20) */
uint32_t
sgi_pending_set
[
4
];
/* [0xF20, 0xF30) */
uint32_t
res10
[
40
];
/* [0xF30, 0xFD0) */
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
uint32_t
periph_id
[
8
];
/* [0xFD0, 0xFF0) */
uint32_t
component_id
[
4
];
/* [0xFF0, 0xFFF] */
};
irq
=
irq
-
_gic_table
[
index
].
offset
;
RT_ASSERT
(
irq
>=
0
);
GIC_DIST_ENABLE_CLEAR
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
=
mask
;
}
/* Memory map for GIC cpu interface */
struct
gic_cpu_iface_map
{
uint32_t
icontrol
;
/* 0x000 */
uint32_t
pri_msk_c
;
/* 0x004 */
uint32_t
bp_c
;
/* 0x008 */
uint32_t
int_ack
;
/* 0x00C */
uint32_t
eoi
;
/* 0x010 */
uint32_t
run_priority
;
/* 0x014 */
uint32_t
hi_pend
;
/* 0x018 */
uint32_t
ns_alias_bp_c
;
/* 0x01C */
uint32_t
ns_alias_ack
;
/* 0x020 GIC_PL400 only */
uint32_t
ns_alias_eoi
;
/* 0x024 GIC_PL400 only */
uint32_t
ns_alias_hi_pend
;
/* 0x028 GIC_PL400 only */
uint32_t
res1
[
41
];
/* [0x02C, 0x0D0) */
uint32_t
active_priority
[
4
];
/* [0x0D0, 0xC0] GIC_PL400 only */
uint32_t
ns_active_priority
[
4
];
/* [0xE0,0xF0] GIC_PL400 only */
uint32_t
res4
[
3
];
/* [0xF0, 0xFC] */
uint32_t
cpu_if_ident
;
/* 0x0FC */
uint32_t
deactive
;
/* [0x1000] */
};
void
arm_gic_clear_pending
(
rt_uint32_t
index
,
int
irq
)
{
rt_uint32_t
mask
=
1
<<
(
irq
%
32
);
volatile
struct
gic_dist_map
*
gic_dist
=
(
volatile
struct
gic_dist_map
*
)(
GIC_PL400_DISTRIBUTOR_PPTR
);
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
volatile
struct
gic_cpu_iface_map
*
gic_cpuiface
=
(
volatile
struct
gic_cpu_iface_map
*
)(
GIC_PL400_CONTROLLER_PPTR
);
irq
=
irq
-
_gic_table
[
index
].
offset
;
RT_ASSERT
(
irq
>=
0
);
/* Helpers */
static
inline
int
is_irq_pending
(
irq_t
irq
)
{
int
word
=
irq
/
32
;
int
bit
=
irq
&
0x1f
;
return
!!
(
gic_dist
->
pending_set
[
word
]
&
BIT
(
bit
));
GIC_DIST_PENDING_CLEAR
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
=
mask
;
}
static
inline
int
is_irq_active
(
irq_t
irq
)
void
arm_gic_clear_active
(
rt_uint32_t
index
,
int
irq
)
{
int
word
=
irq
/
32
;
int
bit
=
irq
&
0x1f
;
return
!!
(
gic_dist
->
active
[
word
]
&
BIT
(
bit
));
}
rt_uint32_t
mask
=
1
<<
(
irq
%
32
);
static
inline
int
is_irq_enabled
(
irq_t
irq
)
{
int
word
=
irq
/
32
;
int
bit
=
irq
&
0x1f
;
return
!!
(
gic_dist
->
enable_set
[
word
]
&
BIT
(
bit
));
}
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
static
inline
int
is_irq_edge_triggered
(
irq_t
irq
)
{
int
word
=
irq
/
16
;
int
bit
=
((
irq
&
0xf
)
*
2
);
return
!!
(
gic_dist
->
config
[
word
]
&
BIT
(
bit
+
1
));
}
irq
=
irq
-
_gic_table
[
index
].
offset
;
RT_ASSERT
(
irq
>=
0
);
static
inline
int
is_irq_1_N
(
irq_t
irq
)
{
int
word
=
irq
/
16
;
int
bit
=
((
irq
&
0xf
)
*
2
);
return
!!
(
gic_dist
->
config
[
word
]
&
BIT
(
bit
+
0
));
GIC_DIST_ACTIVE_CLEAR
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
=
mask
;
}
static
inline
int
is_irq_N_N
(
irq_t
irq
)
/* Set up the cpu mask for the specific interrupt */
void
arm_gic_set_cpu
(
rt_uint32_t
index
,
int
irq
,
unsigned
int
cpumask
)
{
return
!
(
is_irq_1_N
(
irq
));
}
rt_uint32_t
old_tgt
;
static
inline
void
dist_pending_clr
(
irq_t
irq
)
{
int
word
=
irq
/
32
;
int
bit
=
irq
&
0x1f
;
/* Using |= here is detrimental to your health */
gic_dist
->
pending_clr
[
word
]
=
BIT
(
bit
);
}
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
static
inline
void
dist_pending_set
(
irq_t
irq
)
{
int
word
=
irq
/
32
;
int
bit
=
irq
&
0x1f
;
gic_dist
->
pending_set
[
word
]
=
BIT
(
bit
);
irq
=
irq
-
_gic_table
[
index
].
offset
;
RT_ASSERT
(
irq
>=
0
);
old_tgt
=
GIC_DIST_TARGET
(
_gic_table
[
index
].
dist_hw_base
,
irq
);
old_tgt
&=
~
(
0x0FFUL
<<
((
irq
%
4
)
*
8
));
old_tgt
|=
cpumask
<<
((
irq
%
4
)
*
8
);
GIC_DIST_TARGET
(
_gic_table
[
index
].
dist_hw_base
,
irq
)
=
old_tgt
;
}
static
inline
void
dist_enable_clr
(
irq_t
irq
)
void
arm_gic_umask
(
rt_uint32_t
index
,
int
irq
)
{
int
word
=
irq
/
32
;
int
bit
=
irq
&
0x1f
;
/* Using |= here is detrimental to your health */
gic_dist
->
enable_clr
[
word
]
=
BIT
(
bit
);
rt_uint32_t
mask
=
1
<<
(
irq
%
32
);
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
;
}
static
inline
void
dist_enable_set
(
irq_t
irq
)
void
arm_gic_dump_type
(
rt_uint32_t
index
)
{
int
word
=
irq
/
32
;
int
bit
=
irq
&
0x1f
;
gic_dist
->
enable_set
[
word
]
=
BIT
(
bit
);
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
);
}
/**
DONT_TRANSLATE
*/
static
void
dist_init
(
void
)
void
arm_gic_dump
(
rt_uint32_t
index
)
{
int
i
;
int
nirqs
=
32
*
((
gic_dist
->
ic_type
&
0x1f
)
+
1
);
gic_dist
->
enable
=
0
;
#if 0
/* configure to group 0 for security */
for (i = 0; i < nirqs; i += 32) {
gic_dist->group[i / 32] = 0xffffffff;
}
#endif
for
(
i
=
0
;
i
<
nirqs
;
i
+=
32
)
{
/* disable */
gic_dist
->
enable_clr
[
i
/
32
]
=
IRQ_SET_ALL
;
/* clear pending */
gic_dist
->
pending_clr
[
i
/
32
]
=
IRQ_SET_ALL
;
}
/* reset interrupts priority */
for
(
i
=
32
;
i
<
nirqs
;
i
+=
4
)
{
gic_dist
->
priority
[
i
/
4
]
=
0x0
;
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
++
)
{
rt_kprintf
(
"0x%08x, "
,
GIC_DIST_ENABLE_SET
(
_gic_table
[
index
].
dist_hw_base
,
i
*
32
));
}
/*
* reset int target to cpu 0
* (Should really query which processor we're running on and use that)
*/
for
(
i
=
0
;
i
<
nirqs
;
i
+=
4
)
{
gic_dist
->
targets
[
i
/
4
]
=
TARGET_CPU0_ALLINT
;
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
));
}
/* level-triggered, 1-N */
for
(
i
=
64
;
i
<
nirqs
;
i
+=
32
)
{
gic_dist
->
config
[
i
/
32
]
=
0
;
//gic_dist->config[i / 32] = 0x55555555;
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
));
}
/* enable the int controller */
gic_dist
->
enable
=
1
;
rt_kprintf
(
"
\n
"
);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT_ALIAS
(
arm_gic_dump
,
gic
,
show
gic
status
);
#endif
/**
DONT_TRANSLATE
*/
static
void
cpu_iface_init
(
void
)
int
arm_gic_dist_init
(
rt_uint32_t
index
,
rt_uint32_t
dist_base
,
int
irq_start
)
{
uint32_t
i
;
unsigned
int
gic_type
,
i
;
rt_uint32_t
cpumask
=
1
<<
0
;
/* For non-Exynos4, the registers are banked per CPU, need to clear them */
gic_dist
->
enable_clr
[
0
]
=
IRQ_SET_ALL
;
gic_dist
->
pending_clr
[
0
]
=
IRQ_SET_ALL
;
gic_dist
->
priority
[
0
]
=
0x00
;
/* put everything in group 0 */
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
/* clear any software generated interrupts */
for
(
i
=
0
;
i
<
16
;
i
+=
4
)
{
gic_dist
->
sgi_pending_clr
[
i
/
4
]
=
IRQ_SET_ALL
;
}
_gic_table
[
index
].
dist_hw_base
=
dist_base
;
_gic_table
[
index
].
offset
=
irq_start
;
gic_cpuiface
->
icontrol
=
0
;
gic_
cpuiface
->
pri_msk_c
=
0x000000f0
;
gic_cpuiface
->
bp_c
=
0x00000003
;
/* Find out how many interrupts are supported. */
gic_
type
=
GIC_DIST_TYPE
(
dist_base
)
;
_gic_max_irq
=
((
gic_type
&
0x1f
)
+
1
)
*
32
;
while
(((
i
=
gic_cpuiface
->
int_ack
)
&
IRQ_MASK
)
!=
IRQ_NONE
)
{
gic_cpuiface
->
eoi
=
i
;
}
gic_cpuiface
->
icontrol
=
0x1
;
}
/*
* The GIC only supports up to 1020 interrupt sources.
* Limit this to either the architected maximum, or the
* platform maximum.
*/
if
(
_gic_max_irq
>
1020
)
_gic_max_irq
=
1020
;
if
(
_gic_max_irq
>
ARM_GIC_NR_IRQS
)
/* the platform maximum interrupts */
_gic_max_irq
=
ARM_GIC_NR_IRQS
;
/**
DONT_TRANSLATE
*/
void
initIRQController
(
void
)
{
dist_init
();
cpu_iface_init
();
}
cpumask
|=
cpumask
<<
8
;
cpumask
|=
cpumask
<<
16
;
cpumask
|=
cpumask
<<
24
;
GIC_DIST_CTRL
(
dist_base
)
=
0x0
;
/* Set all global interrupts to be level triggered, active low. */
for
(
i
=
32
;
i
<
_gic_max_irq
;
i
+=
16
)
GIC_DIST_CONFIG
(
dist_base
,
i
)
=
0x0
;
/*
* The only sane way to get an GIC IRQ number that can be properly
* ACKED later is through the int_ack register. Unfortunately, reading
* this register changes the interrupt state to pending so future
* reads will not return the same value For this reason, we have a
* global variable to store the IRQ number.
*/
static
uint32_t
active_irq
=
IRQ_NONE
;
/**
DONT_TRANSLATE
*/
interrupt_t
getActiveIRQ
(
void
)
{
uint32_t
irq
;
if
(
!
IS_IRQ_VALID
(
active_irq
))
{
active_irq
=
gic_cpuiface
->
int_ack
;
}
/* Set all global interrupts to this CPU only. */
for
(
i
=
32
;
i
<
_gic_max_irq
;
i
+=
4
)
GIC_DIST_TARGET
(
dist_base
,
i
)
=
cpumask
;
if
(
IS_IRQ_VALID
(
active_irq
))
{
irq
=
active_irq
&
IRQ_MASK
;
}
else
{
irq
=
1023
;
}
/* Set priority on all interrupts. */
for
(
i
=
0
;
i
<
_gic_max_irq
;
i
+=
4
)
GIC_DIST_PRI
(
dist_base
,
i
)
=
0xa0a0a0a0
;
return
irq
;
}
/* Disable all interrupts. */
for
(
i
=
0
;
i
<
_gic_max_irq
;
i
+=
32
)
GIC_DIST_ENABLE_CLEAR
(
dist_base
,
i
)
=
0xffffffff
;
/*
* GIC has 4 states: pending->active(+pending)->inactive
* seL4 expects two states: active->inactive.
* We ignore the active state in GIC to conform
*/
/**
DONT_TRANSLATE
*/
bool_t
isIRQPending
(
void
)
{
return
IS_IRQ_VALID
(
gic_cpuiface
->
hi_pend
);
}
#if 0
/* All interrupts defaults to IGROUP1(IRQ). */
for (i = 0; i < _gic_max_irq; i += 32)
GIC_DIST_IGROUP(dist_base, i) = 0xffffffff;
#endif
for
(
i
=
0
;
i
<
_gic_max_irq
;
i
+=
32
)
GIC_DIST_IGROUP
(
dist_base
,
i
)
=
0
;
/* Enable group0 and group1 interrupt forwarding. */
GIC_DIST_CTRL
(
dist_base
)
=
0x01
;
/**
DONT_TRANSLATE
*/
void
maskInterrupt
(
bool_t
disable
,
interrupt_t
irq
)
{
if
(
disable
)
{
dist_enable_clr
(
irq
);
}
else
{
dist_enable_set
(
irq
);
}
return
0
;
}
/**
DONT_TRANSLATE
*/
void
ackInterrupt
(
irq_t
irq
)
int
arm_gic_cpu_init
(
rt_uint32_t
index
,
rt_uint32_t
cpu_base
)
{
if
(
!
(
IS_IRQ_VALID
(
active_irq
)
&&
(
active_irq
&
IRQ_MASK
)
==
irq
))
{
return
;
}
if
(
is_irq_edge_triggered
(
irq
))
{
dist_pending_clr
(
irq
);
}
gic_cpuiface
->
eoi
=
active_irq
;
active_irq
=
IRQ_NONE
;
}
RT_ASSERT
(
index
<
ARM_GIC_MAX_NR
);
void
handleSpuriousIRQ
(
void
)
{
}
_gic_table
[
index
].
cpu_hw_base
=
cpu_base
;
void
rt_hw_interrupt_mask
(
int
vector
)
{
maskInterrupt
(
1
,
vector
);
}
GIC_CPU_PRIMASK
(
cpu_base
)
=
0xf0
;
GIC_CPU_BINPOINT
(
cpu_base
)
=
0x7
;
/* Enable CPU interrupt */
GIC_CPU_CTRL
(
cpu_base
)
=
0x01
;
void
rt_hw_interrupt_umask
(
int
vector
)
{
maskInterrupt
(
0
,
vector
);
return
0
;
}
int
rt_hw_interrupt_get_irq
(
void
)
void
arm_gic_set_group
(
rt_uint32_t
index
,
int
vector
,
int
group
)
{
return
getActiveIRQ
();
/* As for GICv2, there are only group0 and group1. */
RT_ASSERT
(
group
<=
1
);
RT_ASSERT
(
vector
<
_gic_max_irq
);
if
(
group
==
0
)
{
GIC_DIST_IGROUP
(
_gic_table
[
index
].
dist_hw_base
,
vector
)
&=
~
(
1
<<
(
vector
%
32
));
}
else
if
(
group
==
1
)
{
GIC_DIST_IGROUP
(
_gic_table
[
index
].
dist_hw_base
,
vector
)
|=
(
1
<<
(
vector
%
32
));
}
}
void
rt_hw_interrupt_ack
(
int
fiq_irq
)
{
return
ackInterrupt
(
fiq_irq
);
}
libcpu/aarch64/common/gic/gic_pl400.h
浏览文件 @
709e0d57
#ifndef __ARCH_MACHINE_GIC_PL400_H
#define __ARCH_MACHINE_GIC_PL400_H
#include <stdint.h>
typedef
uint16_t
interrupt_t
;
typedef
uint16_t
irq_t
;
typedef
uint64_t
bool_t
;
/** 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
)
{
}
/** MODIFIES: [*] */
void
initIRQController
(
void
);
void
handleSpuriousIRQ
(
void
);
void
rt_hw_interrupt_umask
(
int
vector
);
int
rt_hw_interrupt_get_irq
(
void
);
void
rt_hw_interrupt_ack
(
int
fiq_irq
);
#endif
/* !__ARCH_MACHINE_GIC400_H */
/*
* 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 __GIC_PL400_H__
#define __GIC_PL400_H__
#include <rthw.h>
#include <board.h>
#define __REG32(x) (*((volatile unsigned int*)((rt_uint64_t)x)))
#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)
#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)
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_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
libcpu/aarch64/cortex-a72/interrupt.c
浏览文件 @
709e0d57
...
...
@@ -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
;
}
\ No newline at end of file
}
/**
* 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
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录