123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- /*
- * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #include <arch.h>
- #include <assert_macros.S>
- #include <asm_macros.S>
- .globl amu_group0_cnt_read_internal
- .globl amu_group0_cnt_write_internal
- .globl amu_group1_cnt_read_internal
- .globl amu_group1_cnt_write_internal
- .globl amu_group1_set_evtype_internal
- /* FEAT_AMUv1p1 virtualisation offset register functions */
- .globl amu_group0_voffset_read_internal
- .globl amu_group0_voffset_write_internal
- .globl amu_group1_voffset_read_internal
- .globl amu_group1_voffset_write_internal
- /*
- * uint64_t amu_group0_cnt_read_internal(int idx);
- *
- * Given `idx`, read the corresponding AMU counter
- * and return it in `x0`.
- */
- func amu_group0_cnt_read_internal
- adr x1, 1f
- #if ENABLE_ASSERTIONS
- /*
- * It can be dangerous to call this function with an
- * out of bounds index. Ensure `idx` is valid.
- */
- tst x0, #~3
- ASM_ASSERT(eq)
- #endif
- /*
- * Given `idx` calculate address of mrs/ret instruction pair
- * in the table below.
- */
- add x1, x1, x0, lsl #3 /* each mrs/ret sequence is 8 bytes */
- #if ENABLE_BTI
- add x1, x1, x0, lsl #2 /* + "bti j" instruction */
- #endif
- br x1
- 1: read AMEVCNTR00_EL0 /* index 0 */
- read AMEVCNTR01_EL0 /* index 1 */
- read AMEVCNTR02_EL0 /* index 2 */
- read AMEVCNTR03_EL0 /* index 3 */
- endfunc amu_group0_cnt_read_internal
- /*
- * void amu_group0_cnt_write_internal(int idx, uint64_t val);
- *
- * Given `idx`, write `val` to the corresponding AMU counter.
- */
- func amu_group0_cnt_write_internal
- adr x2, 1f
- #if ENABLE_ASSERTIONS
- /*
- * It can be dangerous to call this function with an
- * out of bounds index. Ensure `idx` is valid.
- */
- tst x0, #~3
- ASM_ASSERT(eq)
- #endif
- /*
- * Given `idx` calculate address of mrs/ret instruction pair
- * in the table below.
- */
- add x2, x2, x0, lsl #3 /* each msr/ret sequence is 8 bytes */
- #if ENABLE_BTI
- add x2, x2, x0, lsl #2 /* + "bti j" instruction */
- #endif
- br x2
- 1: write AMEVCNTR00_EL0 /* index 0 */
- write AMEVCNTR01_EL0 /* index 1 */
- write AMEVCNTR02_EL0 /* index 2 */
- write AMEVCNTR03_EL0 /* index 3 */
- endfunc amu_group0_cnt_write_internal
- #if ENABLE_AMU_AUXILIARY_COUNTERS
- /*
- * uint64_t amu_group1_cnt_read_internal(int idx);
- *
- * Given `idx`, read the corresponding AMU counter
- * and return it in `x0`.
- */
- func amu_group1_cnt_read_internal
- adr x1, 1f
- #if ENABLE_ASSERTIONS
- /*
- * It can be dangerous to call this function with an
- * out of bounds index. Ensure `idx` is valid.
- */
- tst x0, #~0xF
- ASM_ASSERT(eq)
- #endif
- /*
- * Given `idx` calculate address of mrs/ret instruction pair
- * in the table below.
- */
- add x1, x1, x0, lsl #3 /* each mrs/ret sequence is 8 bytes */
- #if ENABLE_BTI
- add x1, x1, x0, lsl #2 /* + "bti j" instruction */
- #endif
- br x1
- 1: read AMEVCNTR10_EL0 /* index 0 */
- read AMEVCNTR11_EL0 /* index 1 */
- read AMEVCNTR12_EL0 /* index 2 */
- read AMEVCNTR13_EL0 /* index 3 */
- read AMEVCNTR14_EL0 /* index 4 */
- read AMEVCNTR15_EL0 /* index 5 */
- read AMEVCNTR16_EL0 /* index 6 */
- read AMEVCNTR17_EL0 /* index 7 */
- read AMEVCNTR18_EL0 /* index 8 */
- read AMEVCNTR19_EL0 /* index 9 */
- read AMEVCNTR1A_EL0 /* index 10 */
- read AMEVCNTR1B_EL0 /* index 11 */
- read AMEVCNTR1C_EL0 /* index 12 */
- read AMEVCNTR1D_EL0 /* index 13 */
- read AMEVCNTR1E_EL0 /* index 14 */
- read AMEVCNTR1F_EL0 /* index 15 */
- endfunc amu_group1_cnt_read_internal
- /*
- * void amu_group1_cnt_write_internal(int idx, uint64_t val);
- *
- * Given `idx`, write `val` to the corresponding AMU counter.
- */
- func amu_group1_cnt_write_internal
- adr x2, 1f
- #if ENABLE_ASSERTIONS
- /*
- * It can be dangerous to call this function with an
- * out of bounds index. Ensure `idx` is valid.
- */
- tst x0, #~0xF
- ASM_ASSERT(eq)
- #endif
- /*
- * Given `idx` calculate address of mrs/ret instruction pair
- * in the table below.
- */
- add x2, x2, x0, lsl #3 /* each msr/ret sequence is 8 bytes */
- #if ENABLE_BTI
- add x2, x2, x0, lsl #2 /* + "bti j" instruction */
- #endif
- br x2
- 1: write AMEVCNTR10_EL0 /* index 0 */
- write AMEVCNTR11_EL0 /* index 1 */
- write AMEVCNTR12_EL0 /* index 2 */
- write AMEVCNTR13_EL0 /* index 3 */
- write AMEVCNTR14_EL0 /* index 4 */
- write AMEVCNTR15_EL0 /* index 5 */
- write AMEVCNTR16_EL0 /* index 6 */
- write AMEVCNTR17_EL0 /* index 7 */
- write AMEVCNTR18_EL0 /* index 8 */
- write AMEVCNTR19_EL0 /* index 9 */
- write AMEVCNTR1A_EL0 /* index 10 */
- write AMEVCNTR1B_EL0 /* index 11 */
- write AMEVCNTR1C_EL0 /* index 12 */
- write AMEVCNTR1D_EL0 /* index 13 */
- write AMEVCNTR1E_EL0 /* index 14 */
- write AMEVCNTR1F_EL0 /* index 15 */
- endfunc amu_group1_cnt_write_internal
- /*
- * void amu_group1_set_evtype_internal(int idx, unsigned int val);
- *
- * Program the AMU event type register indexed by `idx`
- * with the value `val`.
- */
- func amu_group1_set_evtype_internal
- adr x2, 1f
- #if ENABLE_ASSERTIONS
- /*
- * It can be dangerous to call this function with an
- * out of bounds index. Ensure `idx` is valid.
- */
- tst x0, #~0xF
- ASM_ASSERT(eq)
- /* val should be between [0, 65535] */
- tst x1, #~0xFFFF
- ASM_ASSERT(eq)
- #endif
- /*
- * Given `idx` calculate address of msr/ret instruction pair
- * in the table below.
- */
- add x2, x2, x0, lsl #3 /* each msr/ret sequence is 8 bytes */
- #if ENABLE_BTI
- add x2, x2, x0, lsl #2 /* + "bti j" instruction */
- #endif
- br x2
- 1: write AMEVTYPER10_EL0 /* index 0 */
- write AMEVTYPER11_EL0 /* index 1 */
- write AMEVTYPER12_EL0 /* index 2 */
- write AMEVTYPER13_EL0 /* index 3 */
- write AMEVTYPER14_EL0 /* index 4 */
- write AMEVTYPER15_EL0 /* index 5 */
- write AMEVTYPER16_EL0 /* index 6 */
- write AMEVTYPER17_EL0 /* index 7 */
- write AMEVTYPER18_EL0 /* index 8 */
- write AMEVTYPER19_EL0 /* index 9 */
- write AMEVTYPER1A_EL0 /* index 10 */
- write AMEVTYPER1B_EL0 /* index 11 */
- write AMEVTYPER1C_EL0 /* index 12 */
- write AMEVTYPER1D_EL0 /* index 13 */
- write AMEVTYPER1E_EL0 /* index 14 */
- write AMEVTYPER1F_EL0 /* index 15 */
- endfunc amu_group1_set_evtype_internal
- #endif
- /*
- * Accessor functions for virtual offset registers added with FEAT_AMUv1p1
- */
- /*
- * uint64_t amu_group0_voffset_read_internal(int idx);
- *
- * Given `idx`, read the corresponding AMU virtual offset register
- * and return it in `x0`.
- */
- func amu_group0_voffset_read_internal
- adr x1, 1f
- #if ENABLE_ASSERTIONS
- /*
- * It can be dangerous to call this function with an
- * out of bounds index. Ensure `idx` is valid.
- */
- tst x0, #~3
- ASM_ASSERT(eq)
- /* Make sure idx != 1 since AMEVCNTVOFF01_EL2 does not exist */
- cmp x0, #1
- ASM_ASSERT(ne)
- #endif
- /*
- * Given `idx` calculate address of mrs/ret instruction pair
- * in the table below.
- */
- add x1, x1, x0, lsl #3 /* each mrs/ret sequence is 8 bytes */
- #if ENABLE_BTI
- add x1, x1, x0, lsl #2 /* + "bti j" instruction */
- #endif
- br x1
- 1: read AMEVCNTVOFF00_EL2 /* index 0 */
- .skip 8 /* AMEVCNTVOFF01_EL2 does not exist */
- #if ENABLE_BTI
- .skip 4
- #endif
- read AMEVCNTVOFF02_EL2 /* index 2 */
- read AMEVCNTVOFF03_EL2 /* index 3 */
- endfunc amu_group0_voffset_read_internal
- /*
- * void amu_group0_voffset_write_internal(int idx, uint64_t val);
- *
- * Given `idx`, write `val` to the corresponding AMU virtual offset register.
- */
- func amu_group0_voffset_write_internal
- adr x2, 1f
- #if ENABLE_ASSERTIONS
- /*
- * It can be dangerous to call this function with an
- * out of bounds index. Ensure `idx` is valid.
- */
- tst x0, #~3
- ASM_ASSERT(eq)
- /* Make sure idx != 1 since AMEVCNTVOFF01_EL2 does not exist */
- cmp x0, #1
- ASM_ASSERT(ne)
- #endif
- /*
- * Given `idx` calculate address of mrs/ret instruction pair
- * in the table below.
- */
- add x2, x2, x0, lsl #3 /* each msr/ret sequence is 8 bytes */
- #if ENABLE_BTI
- add x2, x2, x0, lsl #2 /* + "bti j" instruction */
- #endif
- br x2
- 1: write AMEVCNTVOFF00_EL2 /* index 0 */
- .skip 8 /* AMEVCNTVOFF01_EL2 does not exist */
- #if ENABLE_BTI
- .skip 4
- #endif
- write AMEVCNTVOFF02_EL2 /* index 2 */
- write AMEVCNTVOFF03_EL2 /* index 3 */
- endfunc amu_group0_voffset_write_internal
- #if ENABLE_AMU_AUXILIARY_COUNTERS
- /*
- * uint64_t amu_group1_voffset_read_internal(int idx);
- *
- * Given `idx`, read the corresponding AMU virtual offset register
- * and return it in `x0`.
- */
- func amu_group1_voffset_read_internal
- adr x1, 1f
- #if ENABLE_ASSERTIONS
- /*
- * It can be dangerous to call this function with an
- * out of bounds index. Ensure `idx` is valid.
- */
- tst x0, #~0xF
- ASM_ASSERT(eq)
- #endif
- /*
- * Given `idx` calculate address of mrs/ret instruction pair
- * in the table below.
- */
- add x1, x1, x0, lsl #3 /* each mrs/ret sequence is 8 bytes */
- #if ENABLE_BTI
- add x1, x1, x0, lsl #2 /* + "bti j" instruction */
- #endif
- br x1
- 1: read AMEVCNTVOFF10_EL2 /* index 0 */
- read AMEVCNTVOFF11_EL2 /* index 1 */
- read AMEVCNTVOFF12_EL2 /* index 2 */
- read AMEVCNTVOFF13_EL2 /* index 3 */
- read AMEVCNTVOFF14_EL2 /* index 4 */
- read AMEVCNTVOFF15_EL2 /* index 5 */
- read AMEVCNTVOFF16_EL2 /* index 6 */
- read AMEVCNTVOFF17_EL2 /* index 7 */
- read AMEVCNTVOFF18_EL2 /* index 8 */
- read AMEVCNTVOFF19_EL2 /* index 9 */
- read AMEVCNTVOFF1A_EL2 /* index 10 */
- read AMEVCNTVOFF1B_EL2 /* index 11 */
- read AMEVCNTVOFF1C_EL2 /* index 12 */
- read AMEVCNTVOFF1D_EL2 /* index 13 */
- read AMEVCNTVOFF1E_EL2 /* index 14 */
- read AMEVCNTVOFF1F_EL2 /* index 15 */
- endfunc amu_group1_voffset_read_internal
- /*
- * void amu_group1_voffset_write_internal(int idx, uint64_t val);
- *
- * Given `idx`, write `val` to the corresponding AMU virtual offset register.
- */
- func amu_group1_voffset_write_internal
- adr x2, 1f
- #if ENABLE_ASSERTIONS
- /*
- * It can be dangerous to call this function with an
- * out of bounds index. Ensure `idx` is valid.
- */
- tst x0, #~0xF
- ASM_ASSERT(eq)
- #endif
- /*
- * Given `idx` calculate address of mrs/ret instruction pair
- * in the table below.
- */
- add x2, x2, x0, lsl #3 /* each msr/ret sequence is 8 bytes */
- #if ENABLE_BTI
- add x2, x2, x0, lsl #2 /* + "bti j" instruction */
- #endif
- br x2
- 1: write AMEVCNTVOFF10_EL2 /* index 0 */
- write AMEVCNTVOFF11_EL2 /* index 1 */
- write AMEVCNTVOFF12_EL2 /* index 2 */
- write AMEVCNTVOFF13_EL2 /* index 3 */
- write AMEVCNTVOFF14_EL2 /* index 4 */
- write AMEVCNTVOFF15_EL2 /* index 5 */
- write AMEVCNTVOFF16_EL2 /* index 6 */
- write AMEVCNTVOFF17_EL2 /* index 7 */
- write AMEVCNTVOFF18_EL2 /* index 8 */
- write AMEVCNTVOFF19_EL2 /* index 9 */
- write AMEVCNTVOFF1A_EL2 /* index 10 */
- write AMEVCNTVOFF1B_EL2 /* index 11 */
- write AMEVCNTVOFF1C_EL2 /* index 12 */
- write AMEVCNTVOFF1D_EL2 /* index 13 */
- write AMEVCNTVOFF1E_EL2 /* index 14 */
- write AMEVCNTVOFF1F_EL2 /* index 15 */
- endfunc amu_group1_voffset_write_internal
- #endif
|