| 1 | /* |
| 2 | * ARM MemTag operation helpers. |
| 3 | * |
| 4 | * This code is licensed under the GNU GPL v2 or later. |
| 5 | * |
| 6 | * SPDX-License-Identifier: LGPL-2.1-or-later |
| 7 | */ |
| 8 | |
| 9 | #ifndef TARGET_ARM_MTE_H |
| 10 | #define TARGET_ARM_MTE_H |
| 11 | |
| 12 | #include "exec/mmu-access-type.h" |
| 13 | |
| 14 | /** |
| 15 | * allocation_tag_mem_probe: |
| 16 | * @env: the cpu environment |
| 17 | * @ptr_mmu_idx: the addressing regime to use for the virtual address |
| 18 | * @ptr: the virtual address for which to look up tag memory |
| 19 | * @ptr_access: the access to use for the virtual address |
| 20 | * @ptr_size: the number of bytes in the normal memory access |
| 21 | * @tag_access: the access to use for the tag memory |
| 22 | * @probe: true to merely probe, never taking an exception |
| 23 | * @ra: the return address for exception handling |
| 24 | * |
| 25 | * Our tag memory is formatted as a sequence of little-endian nibbles. |
| 26 | * That is, the byte at (addr >> (LOG2_TAG_GRANULE + 1)) contains two |
| 27 | * tags, with the tag at [3:0] for the lower addr and the tag at [7:4] |
| 28 | * for the higher addr. |
| 29 | * |
| 30 | * Here, resolve the physical address from the virtual address, and return |
| 31 | * a pointer to the corresponding tag byte. |
| 32 | * |
| 33 | * If there is no tag storage corresponding to @ptr, return NULL. |
| 34 | * |
| 35 | * If the page is inaccessible for @ptr_access, or has a watchpoint, there are |
| 36 | * three options: |
| 37 | * (1) probe = true, ra = 0 : pure probe -- we return NULL if the page is not |
| 38 | * accessible, and do not take watchpoint traps. The calling code must |
| 39 | * handle those cases in the right priority compared to MTE traps. |
| 40 | * (2) probe = false, ra = 0 : probe, no fault expected -- the caller guarantees |
| 41 | * that the page is going to be accessible. We will take watchpoint traps. |
| 42 | * (3) probe = false, ra != 0 : non-probe -- we will take both memory access |
| 43 | * traps and watchpoint traps. |
| 44 | * (probe = true, ra != 0 is invalid and will assert.) |
| 45 | */ |
| 46 | uint8_t *allocation_tag_mem_probe(CPUARMState *env, int ptr_mmu_idx, |
| 47 | uint64_t ptr, MMUAccessType ptr_access, |
| 48 | int ptr_size, MMUAccessType tag_access, |
| 49 | bool probe, uintptr_t ra); |
| 50 | |
| 51 | /** |
| 52 | * load_tag1 - Load 1 tag (nibble) from byte |
| 53 | * @ptr: The tagged address |
| 54 | * @mem: The tag address (packed, 2 tags in byte) |
| 55 | */ |
| 56 | int load_tag1(uint64_t ptr, uint8_t *mem); |
| 57 | |
| 58 | /** |
| 59 | * store_tag1 - Store 1 tag (nibble) into byte |
| 60 | * @ptr: The tagged address |
| 61 | * @mem: The tag address (packed, 2 tags in byte) |
| 62 | * @tag: The tag to be stored in the nibble |
| 63 | */ |
| 64 | void store_tag1(uint64_t ptr, uint8_t *mem, int tag); |
| 65 | |
| 66 | #endif /* TARGET_ARM_MTE_H */ |