blob: 09394987329a91506c5a795d2956226a0045d5b4 [file] [log] [blame]
Andrew Scull18834872018-10-12 11:48:09 +01001/*
2 * Copyright 2018 Google LLC
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andrew Scullfbc938a2018-08-20 14:09:28 +010017#pragma once
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010018
19#include <stdbool.h>
20#include <stddef.h>
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010021
Andrew Scull18c78fc2018-08-20 12:57:41 +010022#include "hf/addr.h"
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010023
Andrew Scull11a4a0c2018-12-29 11:38:31 +000024/*
25 * A page table entry (PTE) will take one of the following forms:
Andrew Scullc66a04d2018-12-07 13:41:56 +000026 *
27 * 1. absent : There is no mapping.
28 * 2. invalid block : Represents a block that is not in the address space.
29 * 3. valid block : Represents a block that is in the address space.
30 * 4. table : Represents a reference to a table of PTEs.
31 */
Andrew Scull80871322018-08-06 12:04:09 +010032
Andrew Scull11a4a0c2018-12-29 11:38:31 +000033/**
34 * Creates an absent PTE.
Andrew Walbran25133742018-09-28 16:28:02 +010035 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000036pte_t arch_mm_absent_pte(uint8_t level);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000037
38/**
39 * Createa a table PTE.
40 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000041pte_t arch_mm_table_pte(uint8_t level, paddr_t pa);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000042
43/**
44 * Creates a block PTE.
45 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000046pte_t arch_mm_block_pte(uint8_t level, paddr_t pa, uint64_t attrs);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000047
48/**
49 * Chceks whether a block is allowed at the given level of the page table.
50 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000051bool arch_mm_is_block_allowed(uint8_t level);
Andrew Scullc66a04d2018-12-07 13:41:56 +000052
53/**
54 * Determines if a PTE is present i.e. it contains information and therefore
55 * needs to exist in the page table. Any non-absent PTE is present.
56 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000057bool arch_mm_pte_is_present(pte_t pte, uint8_t level);
Andrew Scullc66a04d2018-12-07 13:41:56 +000058
59/**
60 * Determines if a PTE is valid i.e. it can affect the address space. Tables and
61 * valid blocks fall into this category. Invalid blocks do not as they hold
62 * information about blocks that are not in the address space.
63 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000064bool arch_mm_pte_is_valid(pte_t pte, uint8_t level);
Andrew Scullc66a04d2018-12-07 13:41:56 +000065
66/**
67 * Determines if a PTE is a block and represents an address range, valid or
68 * invalid.
69 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000070bool arch_mm_pte_is_block(pte_t pte, uint8_t level);
Andrew Scullc66a04d2018-12-07 13:41:56 +000071
72/**
73 * Determines if a PTE represents a reference to a table of PTEs.
74 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000075bool arch_mm_pte_is_table(pte_t pte, uint8_t level);
Andrew Scullc66a04d2018-12-07 13:41:56 +000076
Andrew Scull11a4a0c2018-12-29 11:38:31 +000077/**
78 * Clears the bits of an address that are ignored by the page table. In effect,
79 * the address is rounded down to the start of the corresponding PTE range.
80 */
Andrew Scull459d3b52018-12-07 16:37:12 +000081paddr_t arch_mm_clear_pa(paddr_t pa);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000082
83/**
84 * Extracts the start address if the PTE range.
85 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000086paddr_t arch_mm_block_from_pte(pte_t pte, uint8_t level);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000087
88/**
89 * Extracts the address of the table referenced by the PTE/.
90 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000091paddr_t arch_mm_table_from_pte(pte_t pte, uint8_t level);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000092
93/**
94 * Extracts the atrobutes of the PTE.
95 */
Andrew Scull3681b8d2018-12-12 14:22:59 +000096uint64_t arch_mm_pte_attrs(pte_t pte, uint8_t level);
Andrew Scull11a4a0c2018-12-29 11:38:31 +000097
98/**
99 * Merge the attributes of a block into those of its containing table.
100 */
Andrew Walbran2400ed22018-09-27 14:45:58 +0100101uint64_t arch_mm_combine_table_entry_attrs(uint64_t table_attrs,
102 uint64_t block_attrs);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000103
104/**
105 * Invalidates hte given range of stage-1 TLB.
106 */
Andrew Scull459d3b52018-12-07 16:37:12 +0000107void arch_mm_invalidate_stage1_range(vaddr_t va_begin, vaddr_t va_end);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000108
109/**
110 * Invalidates hte given range of stage-2 TLB.
111 */
Andrew Scull459d3b52018-12-07 16:37:12 +0000112void arch_mm_invalidate_stage2_range(ipaddr_t va_begin, ipaddr_t va_end);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000113
114/**
115 * Writes the given range of virtual memory back to the point of unification so
116 * all cores and devices will see the updated values.
117 */
Andrew Scull459d3b52018-12-07 16:37:12 +0000118void arch_mm_write_back_dcache(void *base, size_t size);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000119
120/**
121 * Gets teh maximum level allowed in the page table for the given mode.
122 */
Andrew Scull459d3b52018-12-07 16:37:12 +0000123uint8_t arch_mm_max_level(int mode);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000124
125/**
126 * Gets the number of concatenated page tables used at the root for the given
127 * mode.
128 */
Andrew Scull459d3b52018-12-07 16:37:12 +0000129uint8_t arch_mm_root_table_count(int mode);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000130
131/**
132 * Converts the mode into attributes for a block PTE.
133 */
Andrew Scull459d3b52018-12-07 16:37:12 +0000134uint64_t arch_mm_mode_to_attrs(int mode);
Andrew Scull11a4a0c2018-12-29 11:38:31 +0000135
136/**
137 * Initialized the arch specific memory management state.
138 */
Andrew Scull459d3b52018-12-07 16:37:12 +0000139bool arch_mm_init(paddr_t table, bool first);