blob: aff344a0a0c9cd6fa7214cc8d95d022fa86f8e09 [file] [log] [blame]
Andrew Scull18834872018-10-12 11:48:09 +01001/*
Andrew Walbran692b3252019-03-07 15:51:31 +00002 * Copyright 2018 The Hafnium Authors.
Andrew Scull18834872018-10-12 11:48:09 +01003 *
Andrew Walbrane959ec12020-06-17 15:01:09 +01004 * Use of this source code is governed by a BSD-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/BSD-3-Clause.
Andrew Scull18834872018-10-12 11:48:09 +01007 */
8
Andrew Scullfbc938a2018-08-20 14:09:28 +01009#pragma once
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010010
11#include <stdbool.h>
12#include <stddef.h>
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010013
Andrew Scull18c78fc2018-08-20 12:57:41 +010014#include "hf/addr.h"
Karl Meakin07a69ab2025-02-07 14:53:19 +000015#include "hf/mm.h"
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010016
Olivier Deprez96a2a262020-06-11 17:21:38 +020017#include "vmapi/hf/ffa.h"
18
Andrew Scull11a4a0c2018-12-29 11:38:31 +000019/*
20 * A page table entry (PTE) will take one of the following forms:
Andrew Scullc66a04d2018-12-07 13:41:56 +000021 *
22 * 1. absent : There is no mapping.
23 * 2. invalid block : Represents a block that is not in the address space.
24 * 3. valid block : Represents a block that is in the address space.
25 * 4. table : Represents a reference to a table of PTEs.
26 */
Andrew Scull80871322018-08-06 12:04:09 +010027
Andrew Scull11a4a0c2018-12-29 11:38:31 +000028/**
29 * Creates an absent PTE.
Andrew Walbran25133742018-09-28 16:28:02 +010030 */
Karl Meakin07a69ab2025-02-07 14:53:19 +000031pte_t arch_mm_absent_pte(mm_level_t level);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000032
33/**
Andrew Scull9a6384b2019-01-02 12:08:40 +000034 * Creates a table PTE.
Andrew Scull11a4a0c2018-12-29 11:38:31 +000035 */
Karl Meakin07a69ab2025-02-07 14:53:19 +000036pte_t arch_mm_table_pte(mm_level_t level, paddr_t pa);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000037
38/**
39 * Creates a block PTE.
40 */
Karl Meakin07a69ab2025-02-07 14:53:19 +000041pte_t arch_mm_block_pte(mm_level_t level, paddr_t pa, mm_attr_t attrs);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000042
43/**
Andrew Scull9a6384b2019-01-02 12:08:40 +000044 * Checks whether a block is allowed at the given level of the page table.
Andrew Scull11a4a0c2018-12-29 11:38:31 +000045 */
Karl Meakin07a69ab2025-02-07 14:53:19 +000046bool arch_mm_is_block_allowed(mm_level_t level);
Andrew Scullc66a04d2018-12-07 13:41:56 +000047
48/**
49 * Determines if a PTE is present i.e. it contains information and therefore
50 * needs to exist in the page table. Any non-absent PTE is present.
51 */
Karl Meakin07a69ab2025-02-07 14:53:19 +000052bool arch_mm_pte_is_present(pte_t pte, mm_level_t level);
Andrew Scullc66a04d2018-12-07 13:41:56 +000053
54/**
55 * Determines if a PTE is valid i.e. it can affect the address space. Tables and
56 * valid blocks fall into this category. Invalid blocks do not as they hold
57 * information about blocks that are not in the address space.
58 */
Karl Meakin07a69ab2025-02-07 14:53:19 +000059bool arch_mm_pte_is_valid(pte_t pte, mm_level_t level);
Andrew Scullc66a04d2018-12-07 13:41:56 +000060
61/**
62 * Determines if a PTE is a block and represents an address range, valid or
63 * invalid.
64 */
Karl Meakin07a69ab2025-02-07 14:53:19 +000065bool arch_mm_pte_is_block(pte_t pte, mm_level_t level);
Andrew Scullc66a04d2018-12-07 13:41:56 +000066
67/**
68 * Determines if a PTE represents a reference to a table of PTEs.
69 */
Karl Meakin07a69ab2025-02-07 14:53:19 +000070bool arch_mm_pte_is_table(pte_t pte, mm_level_t level);
Andrew Scullc66a04d2018-12-07 13:41:56 +000071
Andrew Scull11a4a0c2018-12-29 11:38:31 +000072/**
73 * Clears the bits of an address that are ignored by the page table. In effect,
74 * the address is rounded down to the start of the corresponding PTE range.
75 */
Andrew Scull459d3b52018-12-07 16:37:12 +000076paddr_t arch_mm_clear_pa(paddr_t pa);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000077
78/**
Andrew Scull9a6384b2019-01-02 12:08:40 +000079 * Extracts the start address of the PTE range.
Andrew Scull11a4a0c2018-12-29 11:38:31 +000080 */
Karl Meakin07a69ab2025-02-07 14:53:19 +000081paddr_t arch_mm_block_from_pte(pte_t pte, mm_level_t level);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000082
83/**
Andrew Scull9a6384b2019-01-02 12:08:40 +000084 * Extracts the address of the table referenced by the PTE.
Andrew Scull11a4a0c2018-12-29 11:38:31 +000085 */
Karl Meakin07a69ab2025-02-07 14:53:19 +000086paddr_t arch_mm_table_from_pte(pte_t pte, mm_level_t level);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000087
88/**
Andrew Scull9a6384b2019-01-02 12:08:40 +000089 * Extracts the attributes of the PTE.
Andrew Scull11a4a0c2018-12-29 11:38:31 +000090 */
Karl Meakin07a69ab2025-02-07 14:53:19 +000091mm_attr_t arch_mm_pte_attrs(pte_t pte, mm_level_t level);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000092
93/**
Andrew Scull9a6384b2019-01-02 12:08:40 +000094 * Merges the attributes of a block into those of its containing table.
Andrew Scull11a4a0c2018-12-29 11:38:31 +000095 */
Karl Meakin07a69ab2025-02-07 14:53:19 +000096mm_attr_t arch_mm_combine_table_entry_attrs(mm_attr_t table_attrs,
97 mm_attr_t block_attrs);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000098
99/**
Andrew Scull9a6384b2019-01-02 12:08:40 +0000100 * Invalidates the given range of stage-1 TLB.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000101 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000102void arch_mm_invalidate_stage1_range(ffa_id_t asid, vaddr_t va_begin,
Raghu Krishnamurthy8fdd6df2021-02-03 18:30:59 -0800103 vaddr_t va_end);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000104
105/**
Andrew Scull9a6384b2019-01-02 12:08:40 +0000106 * Invalidates the given range of stage-2 TLB.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000107 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000108void arch_mm_invalidate_stage2_range(ffa_id_t vmid, ipaddr_t va_begin,
Olivier Deprez6f400372022-03-07 09:31:08 +0100109 ipaddr_t va_end, bool non_secure);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000110
111/**
Andrew Scullc059fbe2019-09-12 12:58:40 +0100112 * Writes back the given range of virtual memory to such a point that all cores
113 * and devices will see the updated values. The corresponding cache lines are
114 * also invalidated.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000115 */
Andrew Scullc059fbe2019-09-12 12:58:40 +0100116void arch_mm_flush_dcache(void *base, size_t size);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000117
118/**
Arunachalam Ganapathy0f0f7062022-01-26 17:09:53 +0000119 * Sets the maximum level allowed in the page table for stage-1.
120 */
121void arch_mm_stage1_max_level_set(uint32_t pa_bits);
122
123/**
Andrew Scullda3df7f2019-01-05 17:49:27 +0000124 * Gets the maximum level allowed in the page table for stage-1.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000125 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000126mm_level_t arch_mm_stage1_max_level(void);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000127
128/**
Andrew Scullda3df7f2019-01-05 17:49:27 +0000129 * Gets the maximum level allowed in the page table for stage-2.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000130 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000131mm_level_t arch_mm_stage2_max_level(void);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000132
133/**
Andrew Scullda3df7f2019-01-05 17:49:27 +0000134 * Gets the number of concatenated page tables used at the root for stage-1.
135 *
136 * Tables are concatenated at the root to avoid introducing another level in the
137 * page table meaning the table is shallow and wide. Each level is an extra
138 * memory access when walking the table so keeping it shallow reduces the memory
139 * accesses to aid performance.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000140 */
Andrew Scullda3df7f2019-01-05 17:49:27 +0000141uint8_t arch_mm_stage1_root_table_count(void);
142
143/**
144 * Gets the number of concatenated page tables used at the root for stage-2.
145 */
146uint8_t arch_mm_stage2_root_table_count(void);
147
148/**
149 * Converts the mode into stage-1 attributes for a block PTE.
150 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000151mm_attr_t arch_mm_mode_to_stage1_attrs(mm_mode_t mode);
Andrew Scullda3df7f2019-01-05 17:49:27 +0000152
153/**
154 * Converts the mode into stage-2 attributes for a block PTE.
155 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000156mm_attr_t arch_mm_mode_to_stage2_attrs(mm_mode_t mode);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000157
158/**
Andrew Scull81e85092018-12-12 12:56:20 +0000159 * Converts the stage-2 block attributes back to the corresponding mode.
160 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000161mm_mode_t arch_mm_stage2_attrs_to_mode(mm_attr_t attrs);
Andrew Scull81e85092018-12-12 12:56:20 +0000162
163/**
Raghu Krishnamurthy2323d722021-02-12 22:55:38 -0800164 * Converts the stage-1 block attributes back to the corresponding mode.
165 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000166mm_mode_t arch_mm_stage1_attrs_to_mode(mm_attr_t attrs);
Raghu Krishnamurthy2323d722021-02-12 22:55:38 -0800167
168/**
Andrew Scullc280bee2019-08-14 11:11:03 +0100169 * Initializes the arch specific memory management.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000170 */
Andrew Scullb2910562019-09-17 14:08:27 +0100171bool arch_mm_init(paddr_t table);
Olivier Deprez96a2a262020-06-11 17:21:38 +0200172
173/**
174 * Return the arch specific mm mode for send/recv pages of given VM ID.
175 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000176mm_mode_t arch_mm_extra_mode_from_vm(ffa_id_t id);
Raghu Krishnamurthyc1012d62021-01-24 19:19:31 -0800177
178/**
179 * Execute any barriers or synchronization that is required
180 * by a given architecture, after page table writes.
181 */
182void arch_mm_sync_table_writes(void);
Federico Recanati4fd065d2021-12-13 20:06:23 +0100183
184/**
Jens Wiklander4f1880c2022-10-19 17:00:14 +0200185 * Returns the maximum supported PA Range index.
186 */
187uint64_t arch_mm_get_pa_range(void);
188
189/**
Federico Recanati4fd065d2021-12-13 20:06:23 +0100190 * Returns the maximum supported PA Range in bits.
191 */
Jens Wiklander4f1880c2022-10-19 17:00:14 +0200192uint32_t arch_mm_get_pa_bits(uint64_t pa_range);
Olivier Deprezb7f6bd62022-03-08 10:55:52 +0100193
Maksims Svecovs7efb1632022-03-29 17:05:24 +0100194/**
195 * Returns VTCR_EL2 configured in arch_mm_init.
196 */
Olivier Deprezb7f6bd62022-03-08 10:55:52 +0100197uintptr_t arch_mm_get_vtcr_el2(void);
198
Maksims Svecovs7efb1632022-03-29 17:05:24 +0100199/**
200 * Returns VSTCR_EL2 configured in arch_mm_init.
201 */
Olivier Deprezb7f6bd62022-03-08 10:55:52 +0100202uintptr_t arch_mm_get_vstcr_el2(void);