Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
623c4377
Commit
623c4377
authored
Oct 21, 2017
by
davidcunado-arm
Committed by
GitHub
Oct 21, 2017
Browse files
Merge pull request #1130 from jeenu-arm/gic-patches
New GIC APIs and specifying interrupt propertes
parents
6de7c00c
c639e8eb
Changes
27
Hide whitespace changes
Inline
Side-by-side
include/lib/aarch64/arch.h
View file @
623c4377
...
...
@@ -68,6 +68,7 @@
#define ICC_CTLR_EL1 S3_0_C12_C12_4
#define ICC_CTLR_EL3 S3_6_C12_C12_4
#define ICC_PMR_EL1 S3_0_C4_C6_0
#define ICC_RPR_EL1 S3_0_C12_C11_3
#define ICC_IGRPEN1_EL3 S3_6_c12_c12_7
#define ICC_IGRPEN0_EL1 S3_0_c12_c12_6
#define ICC_HPPIR0_EL1 S3_0_c12_c8_2
...
...
@@ -76,6 +77,7 @@
#define ICC_IAR1_EL1 S3_0_c12_c12_0
#define ICC_EOIR0_EL1 S3_0_c12_c8_1
#define ICC_EOIR1_EL1 S3_0_c12_c12_1
#define ICC_SGI0R_EL1 S3_0_c12_c11_7
/*******************************************************************************
* Generic timer memory mapped registers & offsets
...
...
include/lib/aarch64/arch_helpers.h
View file @
623c4377
...
...
@@ -198,6 +198,7 @@ DEFINE_SYSOP_TYPE_FUNC(dmb, ld)
DEFINE_SYSOP_TYPE_FUNC
(
dsb
,
ish
)
DEFINE_SYSOP_TYPE_FUNC
(
dsb
,
ishst
)
DEFINE_SYSOP_TYPE_FUNC
(
dmb
,
ish
)
DEFINE_SYSOP_TYPE_FUNC
(
dmb
,
ishst
)
DEFINE_SYSOP_FUNC
(
isb
)
uint32_t
get_afflvl_shift
(
uint32_t
);
...
...
@@ -307,6 +308,7 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el1, ICC_SRE_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS
(
icc_sre_el2
,
ICC_SRE_EL2
)
DEFINE_RENAME_SYSREG_RW_FUNCS
(
icc_sre_el3
,
ICC_SRE_EL3
)
DEFINE_RENAME_SYSREG_RW_FUNCS
(
icc_pmr_el1
,
ICC_PMR_EL1
)
DEFINE_RENAME_SYSREG_READ_FUNC
(
icc_rpr_el1
,
ICC_RPR_EL1
)
DEFINE_RENAME_SYSREG_RW_FUNCS
(
icc_igrpen1_el3
,
ICC_IGRPEN1_EL3
)
DEFINE_RENAME_SYSREG_RW_FUNCS
(
icc_igrpen0_el1
,
ICC_IGRPEN0_EL1
)
DEFINE_RENAME_SYSREG_READ_FUNC
(
icc_hppir0_el1
,
ICC_HPPIR0_EL1
)
...
...
@@ -315,6 +317,7 @@ DEFINE_RENAME_SYSREG_READ_FUNC(icc_iar0_el1, ICC_IAR0_EL1)
DEFINE_RENAME_SYSREG_READ_FUNC
(
icc_iar1_el1
,
ICC_IAR1_EL1
)
DEFINE_RENAME_SYSREG_WRITE_FUNC
(
icc_eoir0_el1
,
ICC_EOIR0_EL1
)
DEFINE_RENAME_SYSREG_WRITE_FUNC
(
icc_eoir1_el1
,
ICC_EOIR1_EL1
)
DEFINE_RENAME_SYSREG_WRITE_FUNC
(
icc_sgi0r_el1
,
ICC_SGI0R_EL1
)
#define IS_IN_EL(x) \
...
...
include/plat/common/platform.h
View file @
623c4377
...
...
@@ -69,6 +69,26 @@ void plat_ic_end_of_interrupt(uint32_t id);
uint32_t
plat_interrupt_type_to_line
(
uint32_t
type
,
uint32_t
security_state
);
/*******************************************************************************
* Optional interrupt management functions, depending on chosen EL3 components.
******************************************************************************/
unsigned
int
plat_ic_get_running_priority
(
void
);
int
plat_ic_is_spi
(
unsigned
int
id
);
int
plat_ic_is_ppi
(
unsigned
int
id
);
int
plat_ic_is_sgi
(
unsigned
int
id
);
unsigned
int
plat_ic_get_interrupt_active
(
unsigned
int
id
);
void
plat_ic_disable_interrupt
(
unsigned
int
id
);
void
plat_ic_enable_interrupt
(
unsigned
int
id
);
int
plat_ic_has_interrupt_type
(
unsigned
int
type
);
void
plat_ic_set_interrupt_type
(
unsigned
int
id
,
unsigned
int
type
);
void
plat_ic_set_interrupt_priority
(
unsigned
int
id
,
unsigned
int
priority
);
void
plat_ic_raise_el3_sgi
(
int
sgi_num
,
u_register_t
target
);
void
plat_ic_set_spi_routing
(
unsigned
int
id
,
unsigned
int
routing_mode
,
u_register_t
mpidr
);
void
plat_ic_set_interrupt_pending
(
unsigned
int
id
);
void
plat_ic_clear_interrupt_pending
(
unsigned
int
id
);
unsigned
int
plat_ic_set_priority_mask
(
unsigned
int
mask
);
/*******************************************************************************
* Optional common functions (may be overridden)
******************************************************************************/
...
...
make_helpers/defaults.mk
View file @
623c4377
...
...
@@ -77,6 +77,10 @@ FWU_FIP_NAME := fwu_fip.bin
# For Chain of Trust
GENERATE_COT
:=
0
# Hint platform interrupt control layer that Group 0 interrupts are for EL3. By
# default, they are for Secure EL1.
GICV2_G0_FOR_EL3
:=
0
# Whether system coherency is managed in hardware, without explicit software
# operations.
HW_ASSISTED_COHERENCY
:=
0
...
...
plat/arm/common/arm_gicv2.c
View file @
623c4377
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015
-2017
, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
@@ -28,11 +28,15 @@ static const unsigned int g0_interrupt_array[] = {
PLAT_ARM_G0_IRQS
};
static
unsigned
int
target_mask_array
[
PLATFORM_CORE_COUNT
];
static
const
gicv2_driver_data_t
arm_gic_data
=
{
.
gicd_base
=
PLAT_ARM_GICD_BASE
,
.
gicc_base
=
PLAT_ARM_GICC_BASE
,
.
g0_interrupt_num
=
ARRAY_SIZE
(
g0_interrupt_array
),
.
g0_interrupt_array
=
g0_interrupt_array
,
.
target_masks
=
target_mask_array
,
.
target_masks_num
=
ARRAY_SIZE
(
target_mask_array
),
};
/******************************************************************************
...
...
@@ -72,6 +76,7 @@ void plat_arm_gic_cpuif_disable(void)
void
plat_arm_gic_pcpu_init
(
void
)
{
gicv2_pcpu_distif_init
();
gicv2_set_pe_target_mask
(
plat_my_core_pos
());
}
/******************************************************************************
...
...
plat/common/plat_gicv2.c
View file @
623c4377
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015
-2017
, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
@@ -7,6 +7,7 @@
#include <gic_common.h>
#include <gicv2.h>
#include <interrupt_mgmt.h>
#include <platform.h>
/*
* The following platform GIC functions are weakly defined. They
...
...
@@ -20,6 +21,18 @@
#pragma weak plat_ic_end_of_interrupt
#pragma weak plat_interrupt_type_to_line
#pragma weak plat_ic_get_running_priority
#pragma weak plat_ic_is_spi
#pragma weak plat_ic_is_ppi
#pragma weak plat_ic_is_sgi
#pragma weak plat_ic_get_interrupt_active
#pragma weak plat_ic_enable_interrupt
#pragma weak plat_ic_disable_interrupt
#pragma weak plat_ic_set_interrupt_priority
#pragma weak plat_ic_set_interrupt_type
#pragma weak plat_ic_raise_el3_sgi
#pragma weak plat_ic_set_spi_routing
/*
* This function returns the highest priority pending interrupt at
* the Interrupt controller
...
...
@@ -53,8 +66,13 @@ uint32_t plat_ic_get_pending_interrupt_type(void)
id
=
gicv2_get_pending_interrupt_type
();
/* Assume that all secure interrupts are S-EL1 interrupts */
if
(
id
<
PENDING_G1_INTID
)
if
(
id
<
PENDING_G1_INTID
)
{
#if GICV2_G0_FOR_EL3
return
INTR_TYPE_EL3
;
#else
return
INTR_TYPE_S_EL1
;
#endif
}
if
(
id
==
GIC_SPURIOUS_INTERRUPT
)
return
INTR_TYPE_INVAL
;
...
...
@@ -83,7 +101,12 @@ uint32_t plat_ic_get_interrupt_type(uint32_t id)
type
=
gicv2_get_interrupt_group
(
id
);
/* Assume that all secure interrupts are S-EL1 interrupts */
return
(
type
)
?
INTR_TYPE_NS
:
INTR_TYPE_S_EL1
;
return
type
==
GICV2_INTR_GROUP1
?
INTR_TYPE_NS
:
#if GICV2_G0_FOR_EL3
INTR_TYPE_EL3
;
#else
INTR_TYPE_S_EL1
;
#endif
}
/*
...
...
@@ -122,3 +145,135 @@ uint32_t plat_interrupt_type_to_line(uint32_t type,
return
((
gicv2_is_fiq_enabled
())
?
__builtin_ctz
(
SCR_FIQ_BIT
)
:
__builtin_ctz
(
SCR_IRQ_BIT
));
}
unsigned
int
plat_ic_get_running_priority
(
void
)
{
return
gicv2_get_running_priority
();
}
int
plat_ic_is_spi
(
unsigned
int
id
)
{
return
(
id
>=
MIN_SPI_ID
)
&&
(
id
<=
MAX_SPI_ID
);
}
int
plat_ic_is_ppi
(
unsigned
int
id
)
{
return
(
id
>=
MIN_PPI_ID
)
&&
(
id
<
MIN_SPI_ID
);
}
int
plat_ic_is_sgi
(
unsigned
int
id
)
{
return
(
id
>=
MIN_SGI_ID
)
&&
(
id
<
MIN_PPI_ID
);
}
unsigned
int
plat_ic_get_interrupt_active
(
unsigned
int
id
)
{
return
gicv2_get_interrupt_active
(
id
);
}
void
plat_ic_enable_interrupt
(
unsigned
int
id
)
{
gicv2_enable_interrupt
(
id
);
}
void
plat_ic_disable_interrupt
(
unsigned
int
id
)
{
gicv2_disable_interrupt
(
id
);
}
void
plat_ic_set_interrupt_priority
(
unsigned
int
id
,
unsigned
int
priority
)
{
gicv2_set_interrupt_priority
(
id
,
priority
);
}
int
plat_ic_has_interrupt_type
(
unsigned
int
type
)
{
switch
(
type
)
{
#if GICV2_G0_FOR_EL3
case
INTR_TYPE_EL3
:
#else
case
INTR_TYPE_S_EL1
:
#endif
case
INTR_TYPE_NS
:
return
1
;
default:
return
0
;
}
}
void
plat_ic_set_interrupt_type
(
unsigned
int
id
,
unsigned
int
type
)
{
int
gicv2_type
=
0
;
/* Map canonical interrupt type to GICv2 type */
switch
(
type
)
{
#if GICV2_G0_FOR_EL3
case
INTR_TYPE_EL3
:
#else
case
INTR_TYPE_S_EL1
:
#endif
gicv2_type
=
GICV2_INTR_GROUP0
;
break
;
case
INTR_TYPE_NS
:
gicv2_type
=
GICV2_INTR_GROUP1
;
break
;
default:
assert
(
0
);
}
gicv2_set_interrupt_type
(
id
,
gicv2_type
);
}
void
plat_ic_raise_el3_sgi
(
int
sgi_num
,
u_register_t
target
)
{
#if GICV2_G0_FOR_EL3
int
id
;
/* Target must be a valid MPIDR in the system */
id
=
plat_core_pos_by_mpidr
(
target
);
assert
(
id
>=
0
);
/* Verify that this is a secure SGI */
assert
(
plat_ic_get_interrupt_type
(
sgi_num
)
==
INTR_TYPE_EL3
);
gicv2_raise_sgi
(
sgi_num
,
id
);
#else
assert
(
0
);
#endif
}
void
plat_ic_set_spi_routing
(
unsigned
int
id
,
unsigned
int
routing_mode
,
u_register_t
mpidr
)
{
int
proc_num
=
0
;
switch
(
routing_mode
)
{
case
INTR_ROUTING_MODE_PE
:
proc_num
=
plat_core_pos_by_mpidr
(
mpidr
);
assert
(
proc_num
>=
0
);
break
;
case
INTR_ROUTING_MODE_ANY
:
/* Bit mask selecting all 8 CPUs as candidates */
proc_num
=
-
1
;
break
;
default:
assert
(
0
);
}
gicv2_set_spi_routing
(
id
,
proc_num
);
}
void
plat_ic_set_interrupt_pending
(
unsigned
int
id
)
{
gicv2_set_interrupt_pending
(
id
);
}
void
plat_ic_clear_interrupt_pending
(
unsigned
int
id
)
{
gicv2_clear_interrupt_pending
(
id
);
}
unsigned
int
plat_ic_set_priority_mask
(
unsigned
int
mask
)
{
return
gicv2_set_pmr
(
mask
);
}
plat/common/plat_gicv3.c
View file @
623c4377
/*
* Copyright (c) 2015-201
6
, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-201
7
, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
...
...
@@ -26,6 +26,20 @@
#pragma weak plat_ic_end_of_interrupt
#pragma weak plat_interrupt_type_to_line
#pragma weak plat_ic_get_running_priority
#pragma weak plat_ic_is_spi
#pragma weak plat_ic_is_ppi
#pragma weak plat_ic_is_sgi
#pragma weak plat_ic_get_interrupt_active
#pragma weak plat_ic_enable_interrupt
#pragma weak plat_ic_disable_interrupt
#pragma weak plat_ic_set_interrupt_priority
#pragma weak plat_ic_set_interrupt_type
#pragma weak plat_ic_raise_el3_sgi
#pragma weak plat_ic_set_spi_routing
#pragma weak plat_ic_set_interrupt_pending
#pragma weak plat_ic_clear_interrupt_pending
CASSERT
((
INTR_TYPE_S_EL1
==
INTR_GROUP1S
)
&&
(
INTR_TYPE_NS
==
INTR_GROUP1NS
)
&&
(
INTR_TYPE_EL3
==
INTR_GROUP0
),
assert_interrupt_type_mismatch
);
...
...
@@ -155,6 +169,108 @@ uint32_t plat_interrupt_type_to_line(uint32_t type,
return
__builtin_ctz
(
SCR_FIQ_BIT
);
}
}
unsigned
int
plat_ic_get_running_priority
(
void
)
{
return
gicv3_get_running_priority
();
}
int
plat_ic_is_spi
(
unsigned
int
id
)
{
return
(
id
>=
MIN_SPI_ID
)
&&
(
id
<=
MAX_SPI_ID
);
}
int
plat_ic_is_ppi
(
unsigned
int
id
)
{
return
(
id
>=
MIN_PPI_ID
)
&&
(
id
<
MIN_SPI_ID
);
}
int
plat_ic_is_sgi
(
unsigned
int
id
)
{
return
(
id
>=
MIN_SGI_ID
)
&&
(
id
<
MIN_PPI_ID
);
}
unsigned
int
plat_ic_get_interrupt_active
(
unsigned
int
id
)
{
return
gicv3_get_interrupt_active
(
id
,
plat_my_core_pos
());
}
void
plat_ic_enable_interrupt
(
unsigned
int
id
)
{
gicv3_enable_interrupt
(
id
,
plat_my_core_pos
());
}
void
plat_ic_disable_interrupt
(
unsigned
int
id
)
{
gicv3_disable_interrupt
(
id
,
plat_my_core_pos
());
}
void
plat_ic_set_interrupt_priority
(
unsigned
int
id
,
unsigned
int
priority
)
{
gicv3_set_interrupt_priority
(
id
,
plat_my_core_pos
(),
priority
);
}
int
plat_ic_has_interrupt_type
(
unsigned
int
type
)
{
assert
((
type
==
INTR_TYPE_EL3
)
||
(
type
==
INTR_TYPE_S_EL1
)
||
(
type
==
INTR_TYPE_NS
));
return
1
;
}
void
plat_ic_set_interrupt_type
(
unsigned
int
id
,
unsigned
int
type
)
{
gicv3_set_interrupt_type
(
id
,
plat_my_core_pos
(),
type
);
}
void
plat_ic_raise_el3_sgi
(
int
sgi_num
,
u_register_t
target
)
{
/* Target must be a valid MPIDR in the system */
assert
(
plat_core_pos_by_mpidr
(
target
)
>=
0
);
/* Verify that this is a secure EL3 SGI */
assert
(
plat_ic_get_interrupt_type
(
sgi_num
)
==
INTR_TYPE_EL3
);
gicv3_raise_secure_g0_sgi
(
sgi_num
,
target
);
}
void
plat_ic_set_spi_routing
(
unsigned
int
id
,
unsigned
int
routing_mode
,
u_register_t
mpidr
)
{
unsigned
int
irm
=
0
;
switch
(
routing_mode
)
{
case
INTR_ROUTING_MODE_PE
:
assert
(
plat_core_pos_by_mpidr
(
mpidr
)
>=
0
);
irm
=
GICV3_IRM_PE
;
break
;
case
INTR_ROUTING_MODE_ANY
:
irm
=
GICV3_IRM_ANY
;
break
;
default:
assert
(
0
);
}
gicv3_set_spi_routing
(
id
,
irm
,
mpidr
);
}
void
plat_ic_set_interrupt_pending
(
unsigned
int
id
)
{
/* Disallow setting SGIs pending */
assert
(
id
>=
MIN_PPI_ID
);
gicv3_set_interrupt_pending
(
id
,
plat_my_core_pos
());
}
void
plat_ic_clear_interrupt_pending
(
unsigned
int
id
)
{
/* Disallow setting SGIs pending */
assert
(
id
>=
MIN_PPI_ID
);
gicv3_clear_interrupt_pending
(
id
,
plat_my_core_pos
());
}
unsigned
int
plat_ic_set_priority_mask
(
unsigned
int
mask
)
{
return
gicv3_set_pmr
(
mask
);
}
#endif
#ifdef IMAGE_BL32
...
...
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment