1 /*
2  * Copyright (c) 2011-2014 Wind River Systems, Inc.
3  * Copyright (c) 2020 Intel Corporation
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #ifndef ZEPHYR_INCLUDE_ARCH_X86_MMU_H
9 #define ZEPHYR_INCLUDE_ARCH_X86_MMU_H
10 
11 #include <zephyr/sys/util.h>
12 
13 /*
14  * K_MEM_PARTITION_* defines
15  *
16  * Slated for removal when virtual memory is implemented, memory
17  * mapping APIs will replace memory domains.
18  */
19 #define Z_X86_MMU_RW		BIT64(1)	/** Read-Write */
20 #define Z_X86_MMU_US		BIT64(2)	/** User-Supervisor */
21 #if defined(CONFIG_X86_PAE) || defined(CONFIG_X86_64)
22 #define Z_X86_MMU_XD		BIT64(63)	/** Execute Disable */
23 #else
24 #define Z_X86_MMU_XD		0
25 #endif
26 
27 /* For these we'll just use the same bits in the PTE */
28 #define ARCH_DATA_PAGE_DIRTY		((uintptr_t)BIT(6))
29 #define ARCH_DATA_PAGE_LOADED		((uintptr_t)BIT(0))
30 #define ARCH_DATA_PAGE_ACCESSED		((uintptr_t)BIT(5))
31 
32 /* Use an PAT bit for this one since it's never set in a mapped PTE */
33 #define ARCH_DATA_PAGE_NOT_MAPPED	((uintptr_t)BIT(7))
34 
35 /*
36  * Special unpaged "location" tags. These are defined as the highest possible
37  * PTE address values unlikely to conflict with backing store locations.
38  * As noted in arch_page_info_get(), those values on PAE systems, whose
39  * pentry_t is larger than uintptr_t get truncated.
40  */
41 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
42 #define ARCH_UNPAGED_ANON_ZERO		((uintptr_t)0x07FFFFFFFFFFF000ULL)
43 #define ARCH_UNPAGED_ANON_UNINIT	((uintptr_t)0x07FFFFFFFFFFE000ULL)
44 #else
45 #define ARCH_UNPAGED_ANON_ZERO		((uintptr_t)0xFFFFF000U)
46 #define ARCH_UNPAGED_ANON_UNINIT	((uintptr_t)0xFFFFE000U)
47 #endif
48 
49 /* Always true with 32-bit page tables, don't enable
50  * CONFIG_EXECUTE_XOR_WRITE and expect it to work for you
51  */
52 #define K_MEM_PARTITION_IS_EXECUTABLE(attr)	(((attr) & Z_X86_MMU_XD) == 0)
53 #define K_MEM_PARTITION_IS_WRITABLE(attr)	(((attr) & Z_X86_MMU_RW) != 0)
54 
55 /* memory partition arch/soc independent attribute */
56 #define K_MEM_PARTITION_P_RW_U_RW	(Z_X86_MMU_RW | Z_X86_MMU_US | \
57 					 Z_X86_MMU_XD)
58 #define K_MEM_PARTITION_P_RW_U_NA	(Z_X86_MMU_RW | Z_X86_MMU_XD)
59 #define K_MEM_PARTITION_P_RO_U_RO	(Z_X86_MMU_US | Z_X86_MMU_XD)
60 #define K_MEM_PARTITION_P_RO_U_NA	Z_X86_MMU_XD
61 /* Execution-allowed attributes */
62 #define K_MEM_PARTITION_P_RWX_U_RWX	(Z_X86_MMU_RW | Z_X86_MMU_US)
63 #define K_MEM_PARTITION_P_RWX_U_NA	Z_X86_MMU_RW
64 #define K_MEM_PARTITION_P_RX_U_RX	Z_X86_MMU_US
65 #define K_MEM_PARTITION_P_RX_U_NA	(0)
66  /* memory partition access permission mask */
67 #define K_MEM_PARTITION_PERM_MASK	(Z_X86_MMU_RW | Z_X86_MMU_US | \
68 					 Z_X86_MMU_XD)
69 
70 #ifndef _ASMLANGUAGE
71 #include <zephyr/sys/slist.h>
72 
73 /* Page table entry data type at all levels. Defined here due to
74  * k_mem_partition_attr_t, eventually move to private x86_mmu.h
75  */
76 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
77 typedef uint64_t pentry_t;
78 #else
79 typedef uint32_t pentry_t;
80 #endif
81 typedef pentry_t k_mem_partition_attr_t;
82 
83 struct arch_mem_domain {
84 #ifdef CONFIG_X86_PAE
85 	/* 4-entry, 32-byte top-level PDPT */
86 	pentry_t pdpt[4];
87 #endif
88 	/* Pointer to top-level structure, either a PML4, PDPT, PD */
89 	pentry_t *ptables;
90 
91 	/* Linked list of all active memory domains */
92 	sys_snode_t node;
93 #ifdef CONFIG_X86_PAE
94 } __aligned(32);
95 #else
96 };
97 #endif /* CONFIG_X86_PAE */
98 #endif /* _ASMLANGUAGE */
99 #endif /* ZEPHYR_INCLUDE_ARCH_X86_MMU_H */
100