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
RevLine 
[1141c1a]1/*
[d9f81af3]2 * Copyright (C) 2001-2004 Jakub Jermar
[1141c1a]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
[95498e5]29#include <arch/mm/page.h>
[6d7ffa65]30#include <genarch/mm/page_pt.h>
[95498e5]31#include <arch/mm/frame.h>
[d9f81af3]32#include <mm/page.h>
[db3341e]33#include <mm/frame.h>
[fc1e4f6]34#include <mm/as.h>
[db3341e]35#include <arch/interrupt.h>
36#include <arch/asm.h>
37#include <config.h>
38#include <memstr.h>
[fcfac420]39#include <interrupt.h>
[1ee9ced]40#include <print.h>
41#include <panic.h>
[93165be]42#include <align.h>
[1ee9ced]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 }
[d9f81af3]74void page_arch_init(void)
75{
[95498e5]76 __address cur;
[93165be]77 int i;
78 int identity_flags = PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL;
[db3341e]79
80 if (config.cpu_active == 1) {
[f5935ed]81 page_mapping_operations = &pt_mapping_operations;
[085d973]82
[db3341e]83 /*
84 * PA2KA(identity) mapping for all frames.
85 */
[95498e5]86 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
[93165be]87 /* Standard identity mapping */
[5fceec7]88 page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, identity_flags);
[93165be]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);
[db3341e]96 }
[93165be]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
[49a39c2]103 exc_register(14, "page_fault", (iroutine)page_fault);
[ef67bab]104 write_cr3((__address) AS_KERNEL->page_table);
[db3341e]105 }
106 else {
[ef67bab]107 write_cr3((__address) AS_KERNEL->page_table);
[db3341e]108 }
[d9f81af3]109}
[1ee9ced]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);
[5fceec7]131 if (KA2PA(aptl_3) == KA2PA(helper_ptl3))
[1ee9ced]132 SET_PTL3_FLAGS_ARCH(aptl_2, PTL2_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
[5fceec7]133 if (KA2PA(aptl_2) == KA2PA(helper_ptl2))
[1ee9ced]134 SET_PTL2_FLAGS_ARCH(aptl_1, PTL1_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
[5fceec7]135 if (KA2PA(aptl_1) == KA2PA(helper_ptl1))
[1ee9ced]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);
[c7c0b89b]171 printf("Page fault address: %llX\n", page);
[1ee9ced]172 panic("page fault\n");
173 }
174}
Note: See TracBrowser for help on using the repository browser.