source: mainline/arch/amd64/src/mm/page.c@ 0e00b8a

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 0e00b8a was c7c0b89b, checked in by Ondrej Palkovsky <ondrap@…>, 19 years ago

Added uspace call to enable/disable interrupts.

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/*
2 * Copyright (C) 2001-2004 Jakub Jermar
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#include <arch/mm/page.h>
30#include <genarch/mm/page_pt.h>
31#include <arch/mm/frame.h>
32#include <mm/page.h>
33#include <mm/frame.h>
34#include <mm/as.h>
35#include <arch/interrupt.h>
36#include <arch/asm.h>
37#include <config.h>
38#include <memstr.h>
39#include <interrupt.h>
40#include <print.h>
41#include <panic.h>
42#include <align.h>
43
44/* Definitions for identity page mapper */
45pte_t helper_ptl1[512] __attribute__((aligned (PAGE_SIZE)));
46pte_t helper_ptl2[512] __attribute__((aligned (PAGE_SIZE)));
47pte_t helper_ptl3[512] __attribute__((aligned (PAGE_SIZE)));
48extern pte_t ptl_0; /* From boot.S */
49
50#define PTL1_PRESENT(ptl0, page) (!(GET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page)) & PAGE_NOT_PRESENT))
51#define PTL2_PRESENT(ptl1, page) (!(GET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page)) & PAGE_NOT_PRESENT))
52#define PTL3_PRESENT(ptl2, page) (!(GET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page)) & PAGE_NOT_PRESENT))
53
54#define PTL1_ADDR(ptl0, page) ((pte_t *)PA2KA(GET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page))))
55#define PTL2_ADDR(ptl1, page) ((pte_t *)PA2KA(GET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page))))
56#define PTL3_ADDR(ptl2, page) ((pte_t *)PA2KA(GET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page))))
57
58#define SETUP_PTL1(ptl0, page, tgt) { \
59 SET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page), (__address)KA2PA(tgt)); \
60 SET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
61 }
62#define SETUP_PTL2(ptl1, page, tgt) { \
63 SET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page), (__address)KA2PA(tgt)); \
64 SET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
65 }
66#define SETUP_PTL3(ptl2, page, tgt) { \
67 SET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page), (__address)KA2PA(tgt)); \
68 SET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
69 }
70#define SETUP_FRAME(ptl3, page, tgt) { \
71 SET_FRAME_ADDRESS_ARCH(ptl3, PTL3_INDEX_ARCH(page), (__address)KA2PA(tgt)); \
72 SET_FRAME_FLAGS_ARCH(ptl3, PTL3_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
73 }
74void page_arch_init(void)
75{
76 __address cur;
77 int i;
78 int identity_flags = PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL;
79
80 if (config.cpu_active == 1) {
81 page_mapping_operations = &pt_mapping_operations;
82
83 /*
84 * PA2KA(identity) mapping for all frames.
85 */
86 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
87 /* Standard identity mapping */
88 page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, identity_flags);
89 }
90 /* Upper kernel mapping
91 * - from zero to top of kernel (include bottom addresses
92 * because some are needed for init )
93 */
94 for (cur = PA2KA_CODE(0); cur < config.base+config.kernel_size; cur += FRAME_SIZE) {
95 page_mapping_insert(AS_KERNEL, cur, KA2PA(cur), identity_flags);
96 }
97 for (i=0; i < init.cnt; i++) {
98 for (cur=init.tasks[i].addr;cur < init.tasks[i].size; cur += FRAME_SIZE) {
99 page_mapping_insert(AS_KERNEL, PA2KA_CODE(KA2PA(cur)), KA2PA(cur), identity_flags);
100 }
101 }
102
103 exc_register(14, "page_fault", (iroutine)page_fault);
104 write_cr3((__address) AS_KERNEL->page_table);
105 }
106 else {
107 write_cr3((__address) AS_KERNEL->page_table);
108 }
109}
110
111/** Identity page mapper
112 *
113 * We need to map whole physical memory identically before the page subsystem
114 * is initializaed. This thing clears page table and fills in the specific
115 * items.
116 */
117void ident_page_fault(int n, istate_t *istate)
118{
119 __address page;
120 static __address oldpage = 0;
121 pte_t *aptl_1, *aptl_2, *aptl_3;
122
123 page = read_cr2();
124 if (oldpage) {
125 /* Unmap old address */
126 aptl_1 = PTL1_ADDR(&ptl_0, oldpage);
127 aptl_2 = PTL2_ADDR(aptl_1, oldpage);
128 aptl_3 = PTL3_ADDR(aptl_2, oldpage);
129
130 SET_FRAME_FLAGS_ARCH(aptl_3, PTL3_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
131 if (KA2PA(aptl_3) == KA2PA(helper_ptl3))
132 SET_PTL3_FLAGS_ARCH(aptl_2, PTL2_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
133 if (KA2PA(aptl_2) == KA2PA(helper_ptl2))
134 SET_PTL2_FLAGS_ARCH(aptl_1, PTL1_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
135 if (KA2PA(aptl_1) == KA2PA(helper_ptl1))
136 SET_PTL1_FLAGS_ARCH(&ptl_0, PTL0_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
137 }
138 if (PTL1_PRESENT(&ptl_0, page))
139 aptl_1 = PTL1_ADDR(&ptl_0, page);
140 else {
141 SETUP_PTL1(&ptl_0, page, helper_ptl1);
142 aptl_1 = helper_ptl1;
143 }
144
145 if (PTL2_PRESENT(aptl_1, page))
146 aptl_2 = PTL2_ADDR(aptl_1, page);
147 else {
148 SETUP_PTL2(aptl_1, page, helper_ptl2);
149 aptl_2 = helper_ptl2;
150 }
151
152 if (PTL3_PRESENT(aptl_2, page))
153 aptl_3 = PTL3_ADDR(aptl_2, page);
154 else {
155 SETUP_PTL3(aptl_2, page, helper_ptl3);
156 aptl_3 = helper_ptl3;
157 }
158
159 SETUP_FRAME(aptl_3, page, page);
160
161 oldpage = page;
162}
163
164void page_fault(int n, istate_t *istate)
165{
166 __address page;
167
168 page = read_cr2();
169 if (!as_page_fault(page)) {
170 print_info_errcode(n, istate);
171 printf("Page fault address: %llX\n", page);
172 panic("page fault\n");
173 }
174}
Note: See TracBrowser for help on using the repository browser.