forked from Solo5/solo5
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathukvm_cpu_aarch64.h
154 lines (133 loc) · 4.88 KB
/
ukvm_cpu_aarch64.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
* Copyright (c) 2015-2017 Contributors as noted in the AUTHORS file
*
* This file is part of ukvm, a unikernel monitor.
*
* Permission to use, copy, modify, and/or distribute this software
* for any purpose with or without fee is hereby granted, provided
* that the above copyright notice and this permission notice appear
* in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* ukvm_cpu_aarch64.h: CPU constants and initialisation data common to aarch64
* backend implementations.
*/
#ifndef UKVM_CPU_AARCH64_H
#define UKVM_CPU_AARCH64_H
#ifndef _BITUL
#ifdef __ASSEMBLY__
#define _AC(X,Y) X
#define _AT(T,X) X
#else
#define __AC(X,Y) (X##Y)
#define _AC(X,Y) __AC(X,Y)
#define _AT(T,X) ((T)(X))
#endif
#define _BITUL(x) (_AC(1,UL) << (x))
#define _BITULL(x) (_AC(1,ULL) << (x))
#endif
/*
* As the design of ukvm_do_hypercall, the guest memory has been limited
* to the area of 0 ~ 4GB. So we can design an address space layout for
* guest as follow:
*
* Guest address space layout
* ---------------------------------------------------------------
* | 0 ~ 0xFFFFFFFF for RAM | 0x100000000 ~ 0x13FFFFFFF for MMIO |
* ---------------------------------------------------------------
* 0x100000000 MMIO space start
* 0x0FFFFFFFF End of RAM space
* 0x100000 loaded elf file (linker script dictates location)
* ... unused ram
* 0x012000 PMD
* 0x011000 PUD
* 0x010000 PGD, memory start for page table
* ... command line arguments
* 0x002000 ukvm_boot_info
* 0x001000 non-cacheable page
* 0x000000 unused ram
*/
#define AARCH64_MMIO_BASE _AC(0x100000000, UL)
#define AARCH64_MMIO_SZ _AC(0x40000000, UL)
#define AARCH64_GUEST_MIN_BASE _AC(0x100000, UL)
#define AARCH64_PAGE_TABLE _AC(0x10000, UL)
#define AARCH64_CMDLINE_BASE _AC(0xC000, UL)
#define AARCH64_CMDLINE_SZ (AARCH64_PAGE_TABLE - AARCH64_CMDLINE_BASE)
#define AARCH64_BOOT_INFO _AC(0x1000, UL)
#define AARCH64_BOOT_INFO_SZ (AARCH64_CMDLINE_BASE - AARCH64_BOOT_INFO)
#define GENMASK32(h, l) \
(((~0U) << (l)) & (~0U >> (31 - (h))))
#define GENMASK64(h, l) \
(((~0UL) << (l)) & (~0UL >> (63 - (h))))
/* Definitions of Page tables */
#define PAGE_SHIFT 12
#define PAGE_SIZE (1 << (PAGE_SHIFT))
/*
* Hardware page table definitions.
*
* Descriptor type for (PGD, PUD and PMD).
*/
#define PGT_DESC_TYPE_TABLE (_AC(3, UL) << 0)
#define PGT_DESC_TYPE_SECT (_AC(1, UL) << 0)
/*
* Bit definition for section type descriptor
*/
#define SECT_VALID (_AC(1, UL) << 0)
#define SECT_USER (_AC(1, UL) << 6) /* AP[1] */
#define SECT_RDONLY (_AC(1, UL) << 7) /* AP[2] */
#define SECT_S (_AC(3, UL) << 8)
#define SECT_AF (_AC(1, UL) << 10)
#define SECT_NG (_AC(1, UL) << 11)
#define SECT_CONT (_AC(1, UL) << 52)
#define SECT_PXN (_AC(1, UL) << 53)
#define SECT_UXN (_AC(1, UL) << 54)
/*
* AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
*/
#define ATTRINDX(t) (_AC(t, UL) << 2)
/* Memory types available. */
#define MT_DEVICE_nGnRnE 0
#define MT_DEVICE_nGnRE 1
#define MT_DEVICE_GRE 2
#define MT_NORMAL_NC 3
#define MT_NORMAL 4
#define MT_NORMAL_WT 5
#define PROT_SECT_DEFAULT (PGT_DESC_TYPE_SECT | SECT_AF | SECT_S)
#define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | SECT_PXN | SECT_UXN | ATTRINDX(MT_NORMAL))
#define PROT_SECT_NORMAL_EXEC (PROT_SECT_DEFAULT | SECT_UXN | ATTRINDX(MT_NORMAL))
#define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | SECT_PXN | SECT_UXN | ATTRINDX(MT_DEVICE_nGnRE))
/*
* Define the MMU transfer block size:
* PGD entry size: 512GB -- Translation Level 0
* PUD entry size: 1GB -- Translation Level 1
* PMD entry size: 2MB -- Translation Level 2
* PTE entry size: 64KB -- Translation Level 3
*/
#define PGD_SIZE (_AC(1, UL) << 39)
#define PGD_MASK (~(PGD_SIZE-1))
#define PUD_SIZE (_AC(1, UL) << 30)
#define PUD_MASK (~(PUD_SIZE-1))
#define PMD_SIZE (_AC(1, UL) << 21)
#define PMD_MASK (~(PMD_SIZE-1))
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
struct pmd {
uint64_t entry[1];
};
struct pud {
uint64_t entry[1];
};
struct pgd {
uint64_t entry[1];
};
void aarch64_setup_memory_mapping(uint8_t *va_addr, uint64_t mem_size, uint64_t space_size);
void aarch64_mem_size(size_t *mem_size);
#endif /* UKVM_CPU_AARCH64_H */