blob: ef64dd3315050d41294980004d6a4b29877233f3 [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"
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010015
Olivier Deprez96a2a262020-06-11 17:21:38 +020016#include "vmapi/hf/ffa.h"
17
Andrew Scull11a4a0c2018-12-29 11:38:31 +000018/*
19 * A page table entry (PTE) will take one of the following forms:
Andrew Scullc66a04d2018-12-07 13:41:56 +000020 *
21 * 1. absent : There is no mapping.
22 * 2. invalid block : Represents a block that is not in the address space.
23 * 3. valid block : Represents a block that is in the address space.
24 * 4. table : Represents a reference to a table of PTEs.
25 */
Andrew Scull80871322018-08-06 12:04:09 +010026
Andrew Scull11a4a0c2018-12-29 11:38:31 +000027/**
28 * Creates an absent PTE.
Andrew Walbran25133742018-09-28 16:28:02 +010029 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000030pte_t arch_mm_absent_pte(uint8_t level);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000031
32/**
Andrew Scull9a6384b2019-01-02 12:08:40 +000033 * Creates a table PTE.
Andrew Scull11a4a0c2018-12-29 11:38:31 +000034 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000035pte_t arch_mm_table_pte(uint8_t level, paddr_t pa);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000036
37/**
38 * Creates a block PTE.
39 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000040pte_t arch_mm_block_pte(uint8_t level, paddr_t pa, uint64_t attrs);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000041
42/**
Andrew Scull9a6384b2019-01-02 12:08:40 +000043 * Checks whether a block is allowed at the given level of the page table.
Andrew Scull11a4a0c2018-12-29 11:38:31 +000044 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000045bool arch_mm_is_block_allowed(uint8_t level);
Andrew Scullc66a04d2018-12-07 13:41:56 +000046
47/**
48 * Determines if a PTE is present i.e. it contains information and therefore
49 * needs to exist in the page table. Any non-absent PTE is present.
50 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000051bool arch_mm_pte_is_present(pte_t pte, uint8_t level);
Andrew Scullc66a04d2018-12-07 13:41:56 +000052
53/**
54 * Determines if a PTE is valid i.e. it can affect the address space. Tables and
55 * valid blocks fall into this category. Invalid blocks do not as they hold
56 * information about blocks that are not in the address space.
57 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000058bool arch_mm_pte_is_valid(pte_t pte, uint8_t level);
Andrew Scullc66a04d2018-12-07 13:41:56 +000059
60/**
61 * Determines if a PTE is a block and represents an address range, valid or
62 * invalid.
63 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000064bool arch_mm_pte_is_block(pte_t pte, uint8_t level);
Andrew Scullc66a04d2018-12-07 13:41:56 +000065
66/**
67 * Determines if a PTE represents a reference to a table of PTEs.
68 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000069bool arch_mm_pte_is_table(pte_t pte, uint8_t level);
Andrew Scullc66a04d2018-12-07 13:41:56 +000070
Andrew Scull11a4a0c2018-12-29 11:38:31 +000071/**
72 * Clears the bits of an address that are ignored by the page table. In effect,
73 * the address is rounded down to the start of the corresponding PTE range.
74 */
Andrew Scull459d3b52018-12-07 16:37:12 +000075paddr_t arch_mm_clear_pa(paddr_t pa);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000076
77/**
Andrew Scull9a6384b2019-01-02 12:08:40 +000078 * Extracts the start address of the PTE range.
Andrew Scull11a4a0c2018-12-29 11:38:31 +000079 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000080paddr_t arch_mm_block_from_pte(pte_t pte, uint8_t level);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000081
82/**
Andrew Scull9a6384b2019-01-02 12:08:40 +000083 * Extracts the address of the table referenced by the PTE.
Andrew Scull11a4a0c2018-12-29 11:38:31 +000084 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000085paddr_t arch_mm_table_from_pte(pte_t pte, uint8_t level);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000086
87/**
Andrew Scull9a6384b2019-01-02 12:08:40 +000088 * Extracts the attributes of the PTE.
Andrew Scull11a4a0c2018-12-29 11:38:31 +000089 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000090uint64_t arch_mm_pte_attrs(pte_t pte, uint8_t level);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000091
92/**
Andrew Scull9a6384b2019-01-02 12:08:40 +000093 * Merges the attributes of a block into those of its containing table.
Andrew Scull11a4a0c2018-12-29 11:38:31 +000094 */
Andrew Walbran2400ed22018-09-27 14:45:58 +010095uint64_t arch_mm_combine_table_entry_attrs(uint64_t table_attrs,
96 uint64_t block_attrs);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000097
98/**
Andrew Scull9a6384b2019-01-02 12:08:40 +000099 * Invalidates the given range of stage-1 TLB.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000100 */
Raghu Krishnamurthy8fdd6df2021-02-03 18:30:59 -0800101void arch_mm_invalidate_stage1_range(uint16_t asid, vaddr_t va_begin,
102 vaddr_t va_end);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000103
104/**
Andrew Scull9a6384b2019-01-02 12:08:40 +0000105 * Invalidates the given range of stage-2 TLB.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000106 */
Raghu Krishnamurthy8fdd6df2021-02-03 18:30:59 -0800107void arch_mm_invalidate_stage2_range(uint16_t vmid, ipaddr_t va_begin,
108 ipaddr_t va_end);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000109
110/**
Andrew Scullc059fbe2019-09-12 12:58:40 +0100111 * Writes back the given range of virtual memory to such a point that all cores
112 * and devices will see the updated values. The corresponding cache lines are
113 * also invalidated.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000114 */
Andrew Scullc059fbe2019-09-12 12:58:40 +0100115void arch_mm_flush_dcache(void *base, size_t size);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000116
117/**
Andrew Scullda3df7f2019-01-05 17:49:27 +0000118 * Gets the maximum level allowed in the page table for stage-1.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000119 */
Andrew Scullda3df7f2019-01-05 17:49:27 +0000120uint8_t arch_mm_stage1_max_level(void);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000121
122/**
Andrew Scullda3df7f2019-01-05 17:49:27 +0000123 * Gets the maximum level allowed in the page table for stage-2.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000124 */
Andrew Scullda3df7f2019-01-05 17:49:27 +0000125uint8_t arch_mm_stage2_max_level(void);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000126
127/**
Andrew Scullda3df7f2019-01-05 17:49:27 +0000128 * Gets the number of concatenated page tables used at the root for stage-1.
129 *
130 * Tables are concatenated at the root to avoid introducing another level in the
131 * page table meaning the table is shallow and wide. Each level is an extra
132 * memory access when walking the table so keeping it shallow reduces the memory
133 * accesses to aid performance.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000134 */
Andrew Scullda3df7f2019-01-05 17:49:27 +0000135uint8_t arch_mm_stage1_root_table_count(void);
136
137/**
138 * Gets the number of concatenated page tables used at the root for stage-2.
139 */
140uint8_t arch_mm_stage2_root_table_count(void);
141
142/**
143 * Converts the mode into stage-1 attributes for a block PTE.
144 */
Andrew Walbran1281ed42019-10-22 17:23:40 +0100145uint64_t arch_mm_mode_to_stage1_attrs(uint32_t mode);
Andrew Scullda3df7f2019-01-05 17:49:27 +0000146
147/**
148 * Converts the mode into stage-2 attributes for a block PTE.
149 */
Andrew Walbran1281ed42019-10-22 17:23:40 +0100150uint64_t arch_mm_mode_to_stage2_attrs(uint32_t mode);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000151
152/**
Andrew Scull81e85092018-12-12 12:56:20 +0000153 * Converts the stage-2 block attributes back to the corresponding mode.
154 */
Andrew Walbran1281ed42019-10-22 17:23:40 +0100155uint32_t arch_mm_stage2_attrs_to_mode(uint64_t attrs);
Andrew Scull81e85092018-12-12 12:56:20 +0000156
157/**
Raghu Krishnamurthy2323d722021-02-12 22:55:38 -0800158 * Converts the stage-1 block attributes back to the corresponding mode.
159 */
160uint32_t arch_mm_stage1_attrs_to_mode(uint64_t attrs);
161
162/**
Andrew Scullc280bee2019-08-14 11:11:03 +0100163 * Initializes the arch specific memory management.
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000164 */
Andrew Scullb2910562019-09-17 14:08:27 +0100165bool arch_mm_init(paddr_t table);
Olivier Deprez96a2a262020-06-11 17:21:38 +0200166
167/**
168 * Return the arch specific mm mode for send/recv pages of given VM ID.
169 */
170uint32_t arch_mm_extra_attributes_from_vm(ffa_vm_id_t id);
Raghu Krishnamurthyc1012d62021-01-24 19:19:31 -0800171
172/**
173 * Execute any barriers or synchronization that is required
174 * by a given architecture, after page table writes.
175 */
176void arch_mm_sync_table_writes(void);