blob: f0e551e52d7e9f652a9578ab493e08515c96a074 [file] [log] [blame]
Furquan Shaikh24869572014-07-17 11:36:08 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2014 Google Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Furquan Shaikh24869572014-07-17 11:36:08 -070014 */
15
16#ifndef __ARCH_ARM64_MMU_H__
17#define __ARCH_ARM64_MMU_H__
18
Julius Wernerfe4cbf12015-10-07 18:38:24 -070019#include <types.h>
Furquan Shaikh24869572014-07-17 11:36:08 -070020
Furquan Shaikh24869572014-07-17 11:36:08 -070021/* Memory attributes for mmap regions
22 * These attributes act as tag values for memrange regions
23 */
24
25/* Normal memory / device */
26#define MA_MEM (1 << 0)
27#define MA_DEV (0 << 0)
28
29/* Secure / non-secure */
30#define MA_NS (1 << 1)
31#define MA_S (0 << 1)
32
33/* Read only / Read-write */
34#define MA_RO (1 << 2)
35#define MA_RW (0 << 2)
36
Aaron Durbin4633dc12014-08-12 17:40:38 -050037/* Non-cacheable memory. */
38#define MA_MEM_NC (1 << 3)
39
Furquan Shaikh24869572014-07-17 11:36:08 -070040/* Descriptor attributes */
41
42#define INVALID_DESC 0x0
43#define BLOCK_DESC 0x1
44#define TABLE_DESC 0x3
45#define PAGE_DESC 0x3
Julius Wernerfe4cbf12015-10-07 18:38:24 -070046#define DESC_MASK 0x3
Furquan Shaikh24869572014-07-17 11:36:08 -070047
48/* Block descriptor */
49#define BLOCK_NS (1 << 5)
50
51#define BLOCK_AP_RW (0 << 7)
52#define BLOCK_AP_RO (1 << 7)
53
54#define BLOCK_ACCESS (1 << 10)
55
Jimmy Huangc159a0e2015-09-15 15:29:10 +080056#define BLOCK_XN (1UL << 54)
57
Furquan Shaikh55aa17b2015-03-27 22:52:18 -070058#define BLOCK_SH_SHIFT (8)
59#define BLOCK_SH_NON_SHAREABLE (0 << BLOCK_SH_SHIFT)
60#define BLOCK_SH_UNPREDICTABLE (1 << BLOCK_SH_SHIFT)
61#define BLOCK_SH_OUTER_SHAREABLE (2 << BLOCK_SH_SHIFT)
62#define BLOCK_SH_INNER_SHAREABLE (3 << BLOCK_SH_SHIFT)
63
Julius Wernerfe4cbf12015-10-07 18:38:24 -070064/* Sentinel descriptor to mark first PTE of an unused table. It must be a value
65 * that cannot occur naturally as part of a page table. (Bits [1:0] = 0b00 makes
66 * this an unmapped page, but some page attribute bits are still set.) */
67#define UNUSED_DESC 0x6EbAAD0BBADbA6E0
68
Furquan Shaikh24869572014-07-17 11:36:08 -070069/* XLAT Table Init Attributes */
70
71#define VA_START 0x0
Patrick Rudolph57afc5e2018-03-05 09:53:47 +010072#define BITS_PER_VA 48
Jimmy Huangdea45972015-04-13 20:28:38 +080073/* Granule size of 4KB is being used */
74#define GRANULE_SIZE_SHIFT 12
Furquan Shaikh24869572014-07-17 11:36:08 -070075#define GRANULE_SIZE (1 << GRANULE_SIZE_SHIFT)
Julius Wernerfe4cbf12015-10-07 18:38:24 -070076#define XLAT_ADDR_MASK ((1UL << BITS_PER_VA) - GRANULE_SIZE)
Jimmy Huangdea45972015-04-13 20:28:38 +080077#define GRANULE_SIZE_MASK ((1 << GRANULE_SIZE_SHIFT) - 1)
Furquan Shaikh24869572014-07-17 11:36:08 -070078
Jimmy Huangdea45972015-04-13 20:28:38 +080079#define BITS_RESOLVED_PER_LVL (GRANULE_SIZE_SHIFT - 3)
Patrick Rudolph57afc5e2018-03-05 09:53:47 +010080#define L0_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 3)
Jimmy Huangdea45972015-04-13 20:28:38 +080081#define L1_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 2)
82#define L2_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 1)
83#define L3_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 0)
Furquan Shaikh24869572014-07-17 11:36:08 -070084
Patrick Rudolph57afc5e2018-03-05 09:53:47 +010085#define L0_ADDR_MASK (((1UL << BITS_RESOLVED_PER_LVL) - 1) << L0_ADDR_SHIFT)
Jimmy Huangdea45972015-04-13 20:28:38 +080086#define L1_ADDR_MASK (((1UL << BITS_RESOLVED_PER_LVL) - 1) << L1_ADDR_SHIFT)
87#define L2_ADDR_MASK (((1UL << BITS_RESOLVED_PER_LVL) - 1) << L2_ADDR_SHIFT)
88#define L3_ADDR_MASK (((1UL << BITS_RESOLVED_PER_LVL) - 1) << L3_ADDR_SHIFT)
Furquan Shaikh24869572014-07-17 11:36:08 -070089
90/* These macros give the size of the region addressed by each entry of a xlat
91 table at any given level */
Jimmy Huangdea45972015-04-13 20:28:38 +080092#define L3_XLAT_SIZE (1UL << L3_ADDR_SHIFT)
93#define L2_XLAT_SIZE (1UL << L2_ADDR_SHIFT)
94#define L1_XLAT_SIZE (1UL << L1_ADDR_SHIFT)
Patrick Rudolph57afc5e2018-03-05 09:53:47 +010095#define L0_XLAT_SIZE (1UL << L0_ADDR_SHIFT)
Furquan Shaikh24869572014-07-17 11:36:08 -070096
97/* Block indices required for MAIR */
98#define BLOCK_INDEX_MEM_DEV_NGNRNE 0
99#define BLOCK_INDEX_MEM_DEV_NGNRE 1
100#define BLOCK_INDEX_MEM_DEV_GRE 2
101#define BLOCK_INDEX_MEM_NORMAL_NC 3
102#define BLOCK_INDEX_MEM_NORMAL 4
103
Julius Werner372d0ff2016-01-26 19:17:53 -0800104#define BLOCK_INDEX_MASK 0x7
Furquan Shaikh24869572014-07-17 11:36:08 -0700105#define BLOCK_INDEX_SHIFT 2
106
107/* MAIR attributes */
108#define MAIR_ATTRIBUTES ((0x00 << (BLOCK_INDEX_MEM_DEV_NGNRNE*8)) | \
109 (0x04 << (BLOCK_INDEX_MEM_DEV_NGNRE*8)) | \
110 (0x0c << (BLOCK_INDEX_MEM_DEV_GRE*8)) | \
111 (0x44 << (BLOCK_INDEX_MEM_NORMAL_NC*8)) | \
112 (0xffUL << (BLOCK_INDEX_MEM_NORMAL*8)))
113
114/* TCR attributes */
115#define TCR_TOSZ (64 - BITS_PER_VA)
116
117#define TCR_IRGN0_SHIFT 8
118#define TCR_IRGN0_NM_NC (0x00 << TCR_IRGN0_SHIFT)
119#define TCR_IRGN0_NM_WBWAC (0x01 << TCR_IRGN0_SHIFT)
120#define TCR_IRGN0_NM_WTC (0x02 << TCR_IRGN0_SHIFT)
121#define TCR_IRGN0_NM_WBNWAC (0x03 << TCR_IRGN0_SHIFT)
122
123#define TCR_ORGN0_SHIFT 10
124#define TCR_ORGN0_NM_NC (0x00 << TCR_ORGN0_SHIFT)
125#define TCR_ORGN0_NM_WBWAC (0x01 << TCR_ORGN0_SHIFT)
126#define TCR_ORGN0_NM_WTC (0x02 << TCR_ORGN0_SHIFT)
127#define TCR_ORGN0_NM_WBNWAC (0x03 << TCR_ORGN0_SHIFT)
128
129#define TCR_SH0_SHIFT 12
130#define TCR_SH0_NC (0x0 << TCR_SH0_SHIFT)
131#define TCR_SH0_OS (0x2 << TCR_SH0_SHIFT)
132#define TCR_SH0_IS (0x3 << TCR_SH0_SHIFT)
133
134#define TCR_TG0_SHIFT 14
135#define TCR_TG0_4KB (0x0 << TCR_TG0_SHIFT)
136#define TCR_TG0_64KB (0x1 << TCR_TG0_SHIFT)
137#define TCR_TG0_16KB (0x2 << TCR_TG0_SHIFT)
138
139#define TCR_PS_SHIFT 16
140#define TCR_PS_4GB (0x0 << TCR_PS_SHIFT)
141#define TCR_PS_64GB (0x1 << TCR_PS_SHIFT)
142#define TCR_PS_1TB (0x2 << TCR_PS_SHIFT)
143#define TCR_PS_4TB (0x3 << TCR_PS_SHIFT)
144#define TCR_PS_16TB (0x4 << TCR_PS_SHIFT)
145#define TCR_PS_256TB (0x5 << TCR_PS_SHIFT)
146
147#define TCR_TBI_SHIFT 20
148#define TCR_TBI_USED (0x0 << TCR_TBI_SHIFT)
149#define TCR_TBI_IGNORED (0x1 << TCR_TBI_SHIFT)
150
Julius Wernerfe4cbf12015-10-07 18:38:24 -0700151/* Initialize MMU registers and page table memory region. */
152void mmu_init(void);
Julius Werner62336812015-05-18 13:11:12 -0700153/* Change a memory type for a range of bytes at runtime. */
154void mmu_config_range(void *start, size_t size, uint64_t tag);
Julius Wernerfe4cbf12015-10-07 18:38:24 -0700155/* Enable the MMU (need previous mmu_init() and configured ranges!). */
156void mmu_enable(void);
157/* Disable the MMU (which also disables dcache but not icache). */
158void mmu_disable(void);
Furquan Shaikh24869572014-07-17 11:36:08 -0700159
Martin Rothfd277d82016-01-11 12:47:30 -0700160#endif /* __ARCH_ARM64_MMU_H__ */