summaryrefslogtreecommitdiff
path: root/usr/src/uts/i86pc/sys/mach_mmu.h
blob: 22c7aac422c16c124678b55a7af272848a175159 (plain)
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright 2018 Joyent, Inc.
 */

#ifndef _SYS_MACH_MMU_H
#define	_SYS_MACH_MMU_H

#ifdef __cplusplus
extern "C" {
#endif

#ifndef _ASM

#include <sys/types.h>
#include <sys/systm.h>

/*
 * Platform-dependent MMU routines and types.
 *
 * WARNING: this header file is used by both dboot and i86pc, so don't go using
 * normal kernel headers.
 */

#define	TWO_MEG		(2 * 1024 * 1024)

/*
 * This is:
 *	The kernel nucleus pagesizes, ie: bi->bi_kseg_size
 *	The grub 64 bit file load address (see multiboot header in dboot_grub.s)
 *	The grub 32 bit and hypervisor physical load addresses of
 *	    the kernel text/data (see Mapfile.unix)
 */
#define	FOUR_MEG	(4 * 1024 * 1024)

#define	ONE_GIG		(1024 * 1024 * 1024)
#define	FOUR_GIG	((uint64_t)4 * ONE_GIG)

#define	MMU_STD_PAGESIZE	4096
#ifdef __amd64
#define	MMU_STD_PAGEMASK	0xFFFFFFFFFFFFF000ULL
#else
#define	MMU_STD_PAGEMASK	0xFFFFF000UL
#endif

/*
 * Defines for the bits in X86 and AMD64 Page Tables
 *
 * Notes:
 *
 * Largepages and PAT bits:
 *
 * bit 7 at level 0 is the PAT bit
 * bit 7 above level 0 is the Pagesize bit (set for large page)
 * bit 12 (when a large page) is the PAT bit
 *
 * In Solaris the PAT/PWT/PCD values are set up so that:
 *
 * PAT & PWT -> Write Protected
 * PAT & PCD -> Write Combining
 * PAT by itself (PWT == 0 && PCD == 0) yields uncacheable (same as PCD == 1)
 *
 *
 * Permission bits:
 *
 * - PT_USER must be set in all levels for user pages
 * - PT_WRITE must be set in all levels for user writable pages
 * - PT_NX applies if set at any level
 *
 * For these, we use the "allow" settings in all tables above level 0 and only
 * ever disable things in PTEs.
 *
 * The use of PT_GLOBAL and PT_NX depend on being enabled in processor
 * control registers. Hence, we use a variable to reference these bit
 * masks. During hat_kern_setup() if the feature isn't enabled we
 * clear out the variables.
 */
#define	PT_VALID	(0x001)	/* a valid translation is present */
#define	PT_WRITABLE	(0x002)	/* the page is writable */
#define	PT_USER		(0x004)	/* the page is accessible by user mode */
#define	PT_WRITETHRU	(0x008)	/* write back caching is disabled (non-PAT) */
#define	PT_NOCACHE	(0x010)	/* page is not cacheable (non-PAT) */
#define	PT_REF		(0x020)	/* page was referenced */
#define	PT_MOD		(0x040)	/* page was modified */
#define	PT_PAGESIZE	(0x080)	/* above level 0, indicates a large page */
#define	PT_PAT_4K	(0x080) /* at level 0, used for write combining */
#define	PT_GLOBAL	(0x100)	/* the mapping is global */
#define	PT_SOFTWARE	(0xe00)	/* software bits */

#define	PT_PAT_LARGE	(0x1000)	/* PAT bit for large pages */

#define	PT_PTPBITS	(PT_VALID | PT_USER | PT_WRITABLE | PT_REF)
#define	PT_FLAGBITS	(0xfff)	/* for masking off flag bits */

/*
 * The software bits are used by the HAT to track attributes.
 * Note that the attributes are inclusive as the values increase.
 *
 * PT_NOSYNC - The PT_REF/PT_MOD bits are not sync'd to page_t.
 *             The hat will install them as always set.
 *
 * PT_NOCONSIST - There is no hment entry for this mapping.
 *
 * PT_FOREIGN - used for the hypervisor, check via
 *		(pte & PT_SOFTWARE) >= PT_FOREIGN
 *		as it might set	0x800 for foreign grant table mappings.
 */
#define	PT_NOSYNC	(0x200)	/* PTE was created with HAT_NOSYNC */
#define	PT_NOCONSIST	(0x400)	/* PTE was created with HAT_LOAD_NOCONSIST */
#define	PT_FOREIGN	(0x600)	/* MFN mapped on the hypervisor has no PFN */

#ifndef _BOOT

extern ulong_t getcr3(void);
extern void setcr3(ulong_t);

#define	getcr3_pa() (getcr3() & MMU_PAGEMASK)
#define	getpcid() ((getcr4() & CR4_PCIDE) ? \
	(getcr3() & MMU_PAGEOFFSET) : PCID_NONE)

extern void mmu_invlpg(caddr_t);

#endif

#ifdef __xpv
#include <sys/xen_mmu.h>
#else
#include <sys/pc_mmu.h>
#endif

/*
 * The software extraction for a single Page Table Entry will always
 * be a 64 bit unsigned int. If running a non-PAE hat, the page table
 * access routines know to extend/shorten it to 32 bits.
 */
typedef uint64_t x86pte_t;
typedef uint32_t x86pte32_t;

x86pte_t get_pteval(paddr_t, uint_t);
void set_pteval(paddr_t, uint_t, uint_t, x86pte_t);
paddr_t make_ptable(x86pte_t *, uint_t);
x86pte_t *find_pte(uint64_t, paddr_t *, uint_t, uint_t);
x86pte_t *map_pte(paddr_t, uint_t);

extern uint_t *shift_amt;
extern uint_t ptes_per_table;
extern paddr_t top_page_table;
extern uint_t top_level;
extern uint_t pte_size;
extern uint_t shift_amt_nopae[];
extern uint_t shift_amt_pae[];
extern uint32_t lpagesize;

#ifdef __cplusplus
}
#endif

#endif /* _ASM */

#endif	/* _SYS_MACH_MMU_H */