Boyan Karatotev | 05504ba | 2023-02-15 13:21:50 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2023, Arm Limited. All rights reserved. |
| 3 | * |
| 4 | * SPDX-License-Identifier: BSD-3-Clause |
| 5 | */ |
| 6 | |
| 7 | #include <arch.h> |
| 8 | #include <arch_features.h> |
| 9 | #include <arch_helpers.h> |
| 10 | #include <lib/extensions/pmuv3.h> |
| 11 | |
Boyan Karatotev | 677ed8a | 2023-02-16 09:45:29 +0000 | [diff] [blame] | 12 | static u_register_t mtpmu_disable_el3(u_register_t sdcr) |
| 13 | { |
| 14 | if (!is_feat_mtpmu_supported()) { |
| 15 | return sdcr; |
| 16 | } |
| 17 | |
| 18 | /* |
| 19 | * SDCR.MTPME = 0 |
| 20 | * FEAT_MTPMU is disabled. The Effective value of PMEVTYPER<n>.MT is |
| 21 | * zero. |
| 22 | */ |
| 23 | sdcr &= ~SDCR_MTPME_BIT; |
| 24 | |
| 25 | return sdcr; |
| 26 | } |
| 27 | |
Boyan Karatotev | 05504ba | 2023-02-15 13:21:50 +0000 | [diff] [blame] | 28 | /* |
| 29 | * Applies to all PMU versions. Name is PMUv3 for compatibility with aarch64 and |
| 30 | * to not clash with platforms which reuse the PMU name |
| 31 | */ |
Boyan Karatotev | 6468d4a | 2023-02-16 15:12:45 +0000 | [diff] [blame] | 32 | void pmuv3_init_el3(void) |
Boyan Karatotev | 05504ba | 2023-02-15 13:21:50 +0000 | [diff] [blame] | 33 | { |
| 34 | u_register_t sdcr = read_sdcr(); |
| 35 | |
| 36 | /* --------------------------------------------------------------------- |
| 37 | * Initialise SDCR, setting all the fields rather than relying on hw. |
| 38 | * |
| 39 | * SDCR.SCCD: Set to one so that cycle counting by PMCCNTR is prohibited |
| 40 | * in Secure state. This bit is RES0 in versions of the architecture |
| 41 | * earlier than ARMv8.5 |
| 42 | * |
| 43 | * SDCR.SPME: Set to zero so that event counting is prohibited in Secure |
| 44 | * state (and explicitly EL3 with later revisions). If ARMv8.2 Debug is |
| 45 | * not implemented this bit does not have any effect on the counters |
| 46 | * unless there is support for the implementation defined |
| 47 | * authentication interface ExternalSecureNoninvasiveDebugEnabled(). |
| 48 | * --------------------------------------------------------------------- |
| 49 | */ |
| 50 | sdcr = (sdcr | SDCR_SCCD_BIT) & ~SDCR_SPME_BIT; |
Boyan Karatotev | 677ed8a | 2023-02-16 09:45:29 +0000 | [diff] [blame] | 51 | sdcr = mtpmu_disable_el3(sdcr); |
Boyan Karatotev | 05504ba | 2023-02-15 13:21:50 +0000 | [diff] [blame] | 52 | write_sdcr(sdcr); |
| 53 | |
| 54 | /* --------------------------------------------------------------------- |
| 55 | * Initialise PMCR, setting all fields rather than relying |
| 56 | * on hw. Some fields are architecturally UNKNOWN on reset. |
| 57 | * |
| 58 | * PMCR.DP: Set to one to prohibit cycle counting whilst in Secure mode. |
| 59 | * |
| 60 | * PMCR.X: Set to zero to disable export of events. |
| 61 | * |
| 62 | * PMCR.C: Set to one to reset PMCCNTR. |
| 63 | * |
| 64 | * PMCR.P: Set to one to reset each event counter PMEVCNTR<n> to zero. |
| 65 | * |
| 66 | * PMCR.E: Set to zero to disable cycle and event counters. |
| 67 | * --------------------------------------------------------------------- |
| 68 | */ |
| 69 | |
| 70 | write_pmcr(read_pmcr() | PMCR_DP_BIT | PMCR_C_BIT | PMCR_P_BIT | |
| 71 | ~(PMCR_X_BIT | PMCR_E_BIT)); |
| 72 | } |