source: mainline/kernel/arch/abs32le/include/mm/page.h@ 50fda24

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 50fda24 was 50fda24, checked in by Martin Decky <martin@…>, 15 years ago

add Abstract32 Little Endian architecture (abs32le)

the purpose of this special architecture is code verification and checking
(some tools cannot parse code with platform specific constructs or assembler),
it can be also used as a simple description of arch/genarch/generic kernel
interface and a starting point for new ports

(still work-in-progress: kernel compiles, but does not link due to several
missing symbols)

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/*
2 * Copyright (c) 2010 Martin Decky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup abs32lemm
30 * @{
31 */
32/** @file
33 */
34
35#ifndef KERN_abs32le_PAGE_H_
36#define KERN_abs32le_PAGE_H_
37
38#include <arch/mm/frame.h>
39
40#define PAGE_WIDTH FRAME_WIDTH
41#define PAGE_SIZE FRAME_SIZE
42
43#ifdef KERNEL
44
45#ifndef __ASM__
46 #define KA2PA(x) (((uintptr_t) (x)) - 0x80000000)
47 #define PA2KA(x) (((uintptr_t) (x)) + 0x80000000)
48#else
49 #define KA2PA(x) ((x) - 0x80000000)
50 #define PA2KA(x) ((x) + 0x80000000)
51#endif
52
53/*
54 * This is an example of 2-level page tables (PTL1 and PTL2 are left out)
55 * on top of the generic 4-level page table interface.
56 */
57
58/* Number of entries in each level. */
59#define PTL0_ENTRIES_ARCH 1024
60#define PTL1_ENTRIES_ARCH 0
61#define PTL2_ENTRIES_ARCH 0
62#define PTL3_ENTRIES_ARCH 1024
63
64/* Page table sizes for each level. */
65#define PTL0_SIZE_ARCH ONE_FRAME
66#define PTL1_SIZE_ARCH 0
67#define PTL2_SIZE_ARCH 0
68#define PTL3_SIZE_ARCH ONE_FRAME
69
70/* Macros calculating indices for each level. */
71#define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 22) & 0x3ff)
72#define PTL1_INDEX_ARCH(vaddr) 0
73#define PTL2_INDEX_ARCH(vaddr) 0
74#define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x3ff)
75
76/* Get PTE address accessors for each level. */
77#define GET_PTL1_ADDRESS_ARCH(ptl0, i) \
78 ((pte_t *) ((((pte_t *) (ptl0))[(i)].frame_address) << 12))
79#define GET_PTL2_ADDRESS_ARCH(ptl1, i) \
80 (ptl1)
81#define GET_PTL3_ADDRESS_ARCH(ptl2, i) \
82 (ptl2)
83#define GET_FRAME_ADDRESS_ARCH(ptl3, i) \
84 ((uintptr_t) ((((pte_t *) (ptl3))[(i)].frame_address) << 12))
85
86/* Set PTE address accessors for each level. */
87#define SET_PTL0_ADDRESS_ARCH(ptl0)
88#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
89 (((pte_t *) (ptl0))[(i)].frame_address = (a) >> 12)
90#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
91#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
92#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \
93 (((pte_t *) (ptl3))[(i)].frame_address = (a) >> 12)
94
95/* Get PTE flags accessors for each level. */
96#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
97 get_pt_flags((pte_t *) (ptl0), (size_t) (i))
98#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
99 PAGE_PRESENT
100#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
101 PAGE_PRESENT
102#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
103 get_pt_flags((pte_t *) (ptl3), (size_t) (i))
104
105/* Set PTE flags accessors for each level. */
106#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
107 set_pt_flags((pte_t *) (ptl0), (size_t) (i), (x))
108#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
109#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
110#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
111 set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x))
112
113/* Macros for querying the last level entries. */
114#define PTE_VALID_ARCH(p) \
115 (*((uint32_t *) (p)) != 0)
116#define PTE_PRESENT_ARCH(p) \
117 ((p)->present != 0)
118#define PTE_GET_FRAME_ARCH(p) \
119 ((p)->frame_address << FRAME_WIDTH)
120#define PTE_WRITABLE_ARCH(p) \
121 ((p)->writeable != 0)
122#define PTE_EXECUTABLE_ARCH(p) 1
123
124#ifndef __ASM__
125
126#include <mm/mm.h>
127#include <arch/interrupt.h>
128#include <arch/types.h>
129#include <typedefs.h>
130
131/* Page fault error codes. */
132
133/** When bit on this position is 0, the page fault was caused by a not-present
134 * page.
135 */
136#define PFERR_CODE_P (1 << 0)
137
138/** When bit on this position is 1, the page fault was caused by a write. */
139#define PFERR_CODE_RW (1 << 1)
140
141/** When bit on this position is 1, the page fault was caused in user mode. */
142#define PFERR_CODE_US (1 << 2)
143
144/** When bit on this position is 1, a reserved bit was set in page directory. */
145#define PFERR_CODE_RSVD (1 << 3)
146
147/** Page Table Entry. */
148typedef struct {
149 unsigned present : 1;
150 unsigned writeable : 1;
151 unsigned uaccessible : 1;
152 unsigned page_write_through : 1;
153 unsigned page_cache_disable : 1;
154 unsigned accessed : 1;
155 unsigned dirty : 1;
156 unsigned pat : 1;
157 unsigned global : 1;
158 unsigned soft_valid : 1; /**< Valid content even if the present bit is not set. */
159 unsigned avl : 2;
160 unsigned frame_address : 20;
161} __attribute__ ((packed)) pte_t;
162
163static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
164{
165 pte_t *p = &pt[i];
166
167 return ((!p->page_cache_disable) << PAGE_CACHEABLE_SHIFT |
168 (!p->present) << PAGE_PRESENT_SHIFT |
169 p->uaccessible << PAGE_USER_SHIFT |
170 1 << PAGE_READ_SHIFT |
171 p->writeable << PAGE_WRITE_SHIFT |
172 1 << PAGE_EXEC_SHIFT |
173 p->global << PAGE_GLOBAL_SHIFT);
174}
175
176static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
177{
178 pte_t *p = &pt[i];
179
180 p->page_cache_disable = !(flags & PAGE_CACHEABLE);
181 p->present = !(flags & PAGE_NOT_PRESENT);
182 p->uaccessible = (flags & PAGE_USER) != 0;
183 p->writeable = (flags & PAGE_WRITE) != 0;
184 p->global = (flags & PAGE_GLOBAL) != 0;
185
186 /*
187 * Ensure that there is at least one bit set even if the present bit is
188 * cleared.
189 */
190 p->soft_valid = true;
191}
192
193extern void page_arch_init(void);
194extern void page_fault(int n, istate_t *istate);
195
196#endif /* __ASM__ */
197
198#endif /* KERNEL */
199
200#endif
201
202/** @}
203 */
Note: See TracBrowser for help on using the repository browser.