blob: 0ca0170132958d0bb27345f642227a9fbf963255 [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 * Creates an absent PTE.
Andrew Walbran25133742018-09-28 16:28:02 +010021 */
Karl Meakin07a69ab2025-02-07 14:53:19 +000022pte_t arch_mm_absent_pte(mm_level_t level);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000023
24/**
Andrew Scull9a6384b2019-01-02 12:08:40 +000025 * Creates a table PTE.
Andrew Scull11a4a0c2018-12-29 11:38:31 +000026 */
Karl Meakin07a69ab2025-02-07 14:53:19 +000027pte_t arch_mm_table_pte(mm_level_t level, paddr_t pa);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000028
29/**
30 * Creates a block PTE.
31 */
Karl Meakin07a69ab2025-02-07 14:53:19 +000032pte_t arch_mm_block_pte(mm_level_t level, paddr_t pa, mm_attr_t attrs);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000033
Karl Meakin23122e12025-02-05 14:44:20 +000034enum mm_pte_type arch_mm_pte_type(pte_t pte, mm_level_t level);
35
Andrew Scull11a4a0c2018-12-29 11:38:31 +000036/**
Andrew Scull9a6384b2019-01-02 12:08:40 +000037 * Checks whether a block is allowed at the given level of the page table.
Andrew Scull11a4a0c2018-12-29 11:38:31 +000038 */
Karl Meakin07a69ab2025-02-07 14:53:19 +000039bool arch_mm_is_block_allowed(mm_level_t level);
Andrew Scullc66a04d2018-12-07 13:41:56 +000040
Karl Meakin23122e12025-02-05 14:44:20 +000041static inline bool arch_mm_pte_is_absent(pte_t pte, mm_level_t level)
42{
43 return arch_mm_pte_type(pte, level) == PTE_TYPE_ABSENT;
44}
45
Andrew Scullc66a04d2018-12-07 13:41:56 +000046/**
47 * Determines if a PTE is present i.e. it contains information and therefore
48 * needs to exist in the page table. Any non-absent PTE is present.
49 */
Karl Meakin23122e12025-02-05 14:44:20 +000050static inline bool arch_mm_pte_is_present(pte_t pte, mm_level_t level)
51{
52 return !arch_mm_pte_is_absent(pte, level);
53}
Andrew Scullc66a04d2018-12-07 13:41:56 +000054
55/**
56 * Determines if a PTE is valid i.e. it can affect the address space. Tables and
57 * valid blocks fall into this category. Invalid blocks do not as they hold
58 * information about blocks that are not in the address space.
59 */
Karl Meakin23122e12025-02-05 14:44:20 +000060static inline bool arch_mm_pte_is_valid(pte_t pte, mm_level_t level)
61{
62 switch (arch_mm_pte_type(pte, level)) {
63 case PTE_TYPE_ABSENT:
64 case PTE_TYPE_INVALID_BLOCK:
65 return false;
66 case PTE_TYPE_VALID_BLOCK:
67 case PTE_TYPE_TABLE:
68 return true;
69 }
70}
Andrew Scullc66a04d2018-12-07 13:41:56 +000071
72/**
73 * Determines if a PTE is a block and represents an address range, valid or
74 * invalid.
75 */
Karl Meakin23122e12025-02-05 14:44:20 +000076static inline bool arch_mm_pte_is_block(pte_t pte, mm_level_t level)
77{
78 switch (arch_mm_pte_type(pte, level)) {
79 case PTE_TYPE_ABSENT:
80 case PTE_TYPE_TABLE:
81 return false;
82 case PTE_TYPE_INVALID_BLOCK:
83 case PTE_TYPE_VALID_BLOCK:
84 return true;
85 }
86}
Andrew Scullc66a04d2018-12-07 13:41:56 +000087
88/**
89 * Determines if a PTE represents a reference to a table of PTEs.
90 */
Karl Meakin23122e12025-02-05 14:44:20 +000091static inline bool arch_mm_pte_is_table(pte_t pte, mm_level_t level)
92{
93 return arch_mm_pte_type(pte, level) == PTE_TYPE_TABLE;
94}
Andrew Scullc66a04d2018-12-07 13:41:56 +000095
Andrew Scull11a4a0c2018-12-29 11:38:31 +000096/**
Andrew Scull9a6384b2019-01-02 12:08:40 +000097 * Extracts the start address of the PTE range.
Andrew Scull11a4a0c2018-12-29 11:38:31 +000098 */
Karl Meakin07a69ab2025-02-07 14:53:19 +000099paddr_t arch_mm_block_from_pte(pte_t pte, mm_level_t level);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000100
101/**
Andrew Scull9a6384b2019-01-02 12:08:40 +0000102 * Extracts the address of the table referenced by the PTE.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000103 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000104paddr_t arch_mm_table_from_pte(pte_t pte, mm_level_t level);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000105
106/**
Andrew Scull9a6384b2019-01-02 12:08:40 +0000107 * Extracts the attributes of the PTE.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000108 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000109mm_attr_t arch_mm_pte_attrs(pte_t pte, mm_level_t level);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000110
111/**
Karl Meakin23122e12025-02-05 14:44:20 +0000112 * Merges the attributes of a block into those of its parent table.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000113 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000114mm_attr_t arch_mm_combine_table_entry_attrs(mm_attr_t table_attrs,
115 mm_attr_t block_attrs);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000116
117/**
Andrew Scull9a6384b2019-01-02 12:08:40 +0000118 * Invalidates the given range of stage-1 TLB.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000119 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000120void arch_mm_invalidate_stage1_range(ffa_id_t asid, vaddr_t va_begin,
Raghu Krishnamurthy8fdd6df2021-02-03 18:30:59 -0800121 vaddr_t va_end);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000122
123/**
Andrew Scull9a6384b2019-01-02 12:08:40 +0000124 * Invalidates the given range of stage-2 TLB.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000125 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000126void arch_mm_invalidate_stage2_range(ffa_id_t vmid, ipaddr_t va_begin,
Olivier Deprez6f400372022-03-07 09:31:08 +0100127 ipaddr_t va_end, bool non_secure);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000128
129/**
Andrew Scullc059fbe2019-09-12 12:58:40 +0100130 * Writes back the given range of virtual memory to such a point that all cores
131 * and devices will see the updated values. The corresponding cache lines are
132 * also invalidated.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000133 */
Andrew Scullc059fbe2019-09-12 12:58:40 +0100134void arch_mm_flush_dcache(void *base, size_t size);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000135
136/**
Arunachalam Ganapathy0f0f7062022-01-26 17:09:53 +0000137 * Sets the maximum level allowed in the page table for stage-1.
138 */
Karl Meakina3a9f952025-02-08 00:11:16 +0000139void arch_mm_stage1_root_level_set(uint32_t pa_bits);
Arunachalam Ganapathy0f0f7062022-01-26 17:09:53 +0000140
141/**
Andrew Scullda3df7f2019-01-05 17:49:27 +0000142 * Gets the maximum level allowed in the page table for stage-1.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000143 */
Karl Meakina3a9f952025-02-08 00:11:16 +0000144mm_level_t arch_mm_stage1_root_level(void);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000145
146/**
Andrew Scullda3df7f2019-01-05 17:49:27 +0000147 * Gets the maximum level allowed in the page table for stage-2.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000148 */
Karl Meakina3a9f952025-02-08 00:11:16 +0000149mm_level_t arch_mm_stage2_root_level(void);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000150
151/**
Andrew Scullda3df7f2019-01-05 17:49:27 +0000152 * Gets the number of concatenated page tables used at the root for stage-1.
153 *
154 * Tables are concatenated at the root to avoid introducing another level in the
155 * page table meaning the table is shallow and wide. Each level is an extra
156 * memory access when walking the table so keeping it shallow reduces the memory
157 * accesses to aid performance.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000158 */
Andrew Scullda3df7f2019-01-05 17:49:27 +0000159uint8_t arch_mm_stage1_root_table_count(void);
160
161/**
162 * Gets the number of concatenated page tables used at the root for stage-2.
163 */
164uint8_t arch_mm_stage2_root_table_count(void);
165
166/**
167 * Converts the mode into stage-1 attributes for a block PTE.
168 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000169mm_attr_t arch_mm_mode_to_stage1_attrs(mm_mode_t mode);
Andrew Scullda3df7f2019-01-05 17:49:27 +0000170
171/**
172 * Converts the mode into stage-2 attributes for a block PTE.
173 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000174mm_attr_t arch_mm_mode_to_stage2_attrs(mm_mode_t mode);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000175
176/**
Andrew Scull81e85092018-12-12 12:56:20 +0000177 * Converts the stage-2 block attributes back to the corresponding mode.
178 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000179mm_mode_t arch_mm_stage2_attrs_to_mode(mm_attr_t attrs);
Andrew Scull81e85092018-12-12 12:56:20 +0000180
181/**
Raghu Krishnamurthy2323d722021-02-12 22:55:38 -0800182 * Converts the stage-1 block attributes back to the corresponding mode.
183 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000184mm_mode_t arch_mm_stage1_attrs_to_mode(mm_attr_t attrs);
Raghu Krishnamurthy2323d722021-02-12 22:55:38 -0800185
186/**
Andrew Scullc280bee2019-08-14 11:11:03 +0100187 * Initializes the arch specific memory management.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000188 */
Karl Meakine1aeb1d2025-02-08 00:35:14 +0000189bool arch_mm_init(const struct mm_ptable *ptable);
Olivier Deprez96a2a262020-06-11 17:21:38 +0200190
191/**
192 * Return the arch specific mm mode for send/recv pages of given VM ID.
193 */
Karl Meakin07a69ab2025-02-07 14:53:19 +0000194mm_mode_t arch_mm_extra_mode_from_vm(ffa_id_t id);
Raghu Krishnamurthyc1012d62021-01-24 19:19:31 -0800195
196/**
197 * Execute any barriers or synchronization that is required
198 * by a given architecture, after page table writes.
199 */
200void arch_mm_sync_table_writes(void);
Federico Recanati4fd065d2021-12-13 20:06:23 +0100201
202/**
Jens Wiklander4f1880c2022-10-19 17:00:14 +0200203 * Returns the maximum supported PA Range index.
204 */
205uint64_t arch_mm_get_pa_range(void);
206
207/**
Federico Recanati4fd065d2021-12-13 20:06:23 +0100208 * Returns the maximum supported PA Range in bits.
209 */
Jens Wiklander4f1880c2022-10-19 17:00:14 +0200210uint32_t arch_mm_get_pa_bits(uint64_t pa_range);
Olivier Deprezb7f6bd62022-03-08 10:55:52 +0100211
Maksims Svecovs7efb1632022-03-29 17:05:24 +0100212/**
213 * Returns VTCR_EL2 configured in arch_mm_init.
214 */
Olivier Deprezb7f6bd62022-03-08 10:55:52 +0100215uintptr_t arch_mm_get_vtcr_el2(void);
216
Maksims Svecovs7efb1632022-03-29 17:05:24 +0100217/**
218 * Returns VSTCR_EL2 configured in arch_mm_init.
219 */
Olivier Deprezb7f6bd62022-03-08 10:55:52 +0100220uintptr_t arch_mm_get_vstcr_el2(void);