xref: /rk3399_ARM-atf/lib/extensions/mpam/mpam.c (revision 19e4312c13d9df5d9e23f6e7cbe98ce636426c97)
1 /*
2  * Copyright (c) 2018-2025, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <stdbool.h>
8 
9 #include <arch.h>
10 #include <arch_features.h>
11 #include <arch_helpers.h>
12 #include <lib/extensions/mpam.h>
13 
mpam_enable_per_world(per_world_context_t * per_world_ctx)14 void mpam_enable_per_world(per_world_context_t *per_world_ctx)
15 {
16 	u_register_t mpam3_el3;
17 
18 	/*
19 	 * Enable MPAM, and disable trapping to EL3 when lower ELs access their
20 	 * own MPAM registers
21 	 */
22 	mpam3_el3 = per_world_ctx->ctx_mpam3_el3;
23 	mpam3_el3 = (mpam3_el3 | MPAM3_EL3_MPAMEN_BIT) &
24 				~(MPAM3_EL3_TRAPLOWER_BIT);
25 
26 	per_world_ctx->ctx_mpam3_el3 = mpam3_el3;
27 }
28 
mpam_init_el3(void)29 void mpam_init_el3(void)
30 {
31 	if (is_feat_mpam_pe_bw_ctrl_supported()) {
32 		u_register_t mpambw3_el3;
33 
34 		/*
35 		 * Disables EL3 trapping of MPAM PE-side bandwidth
36 		 * control registers - MPAMBW2_EL2, MPAMBWCAP_EL2,
37 		 * MPAMBW1_EL1, MPAMBW0_EL1, MPAMBWSM_EL1,
38 		 * MPAMBWIDR_EL1.
39 		 */
40 		mpambw3_el3 = read_mpambw3_el3()	|
41 			MPAMBW3_EL3_NTRAPLOWER_BIT;
42 
43 		/*
44 		 * Disable use of MPAM PE side bandwidth controls in EL3
45 		 * since we don't use it in EL3.
46 		 */
47 		mpambw3_el3 &= ~(MPAMBW3_EL3_HW_SCALE_ENABLE_BIT	|
48 				MPAMBW3_EL3_ENABLED_BIT			|
49 				MPAMBW3_EL3_HARDLIM_BIT);
50 
51 		write_mpambw3_el3(mpambw3_el3);
52 	}
53 }
54 
55 /*
56  * If EL2 is implemented but unused, disable trapping to EL2 when lower ELs
57  * access their own MPAM registers.
58  */
mpam_init_el2_unused(void)59 void mpam_init_el2_unused(void)
60 {
61 	write_mpam2_el2(0ULL);
62 
63 	if ((read_mpamidr_el1() & MPAMIDR_HAS_HCR_BIT) != 0U) {
64 		write_mpamhcr_el2(0ULL);
65 	}
66 
67 	if (is_feat_mpam_pe_bw_ctrl_supported()) {
68 		u_register_t mpambw2_el2;
69 
70 		/*
71 		 * Configure MPAMBW2_EL2 to allow EL1 direct access to
72 		 * specific MPAM bandwidth registers (MPAMBWIDR_EL1,
73 		 * MPAMBW0_EL1, MPAMBW1_EL1, MPAMBWSM_EL1)
74 		 * by disabling traps for these accesses.
75 		 */
76 		mpambw2_el2 = read_mpambw2_el2()			|
77 				MPAMBW2_EL2_NTRAP_MPAMBWIDR_EL1_BIT	|
78 				MPAMBW2_EL2_NTRAP_MPAMBW0_EL1_BIT	|
79 				MPAMBW2_EL2_NTRAP_MPAMBW1_EL1_BIT	|
80 				MPAMBW2_EL2_NTRAP_MPAMBWSM_EL1_BIT;
81 		/*
82 		 * MPAM PE side bandwidth controls are disabled in EL2
83 		 * since NS-EL2 is unused.
84 		 */
85 		mpambw2_el2 &= (MPAMBW2_EL2_HW_SCALE_ENABLE_BIT		|
86 				MPAMBW2_EL2_ENABLED_BIT			|
87 				MPAMBW2_EL2_HARDLIM_BIT);
88 
89 		write_mpambw2_el2(mpambw2_el2);
90 	}
91 }
92