source: mainline/arch/ia64/src/mm/page.c@ 95042fd

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 95042fd was 085434a, checked in by Jakub Vana <jakub.vana@…>, 19 years ago

Itanium kernel page extended to maximum (256M) repaired RR manipulation functions, paging setuping function and added some comments.

  • Property mode set to 100644
File size: 6.3 KB
Line 
1/*
2 * Copyright (C) 2006 Jakub Jermar
3 * Copyright (C) 2006 Jakub Vana
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <arch/mm/page.h>
31#include <genarch/mm/page_ht.h>
32#include <mm/asid.h>
33#include <arch/mm/asid.h>
34#include <arch/types.h>
35#include <typedefs.h>
36#include <print.h>
37#include <mm/page.h>
38#include <mm/frame.h>
39#include <config.h>
40#include <panic.h>
41#include <arch/asm.h>
42#include <arch/barrier.h>
43#include <memstr.h>
44
45static void set_environment(void);
46
47/** Initialize ia64 virtual address translation subsystem. */
48void page_arch_init(void)
49{
50 page_mapping_operations = &ht_mapping_operations;
51 pk_disable();
52 set_environment();
53}
54
55/** Initialize VHPT and region registers. */
56void set_environment(void)
57{
58
59 region_register rr;
60 pta_register pta;
61 int i;
62
63 /*
64 * First set up kernel region register.
65 * This action is redundand (see start.S) but I would to keep it to make sure that
66 *no unexpected changes will be made.
67 */
68 rr.word = rr_read(VRN_KERNEL);
69 rr.map.ve = 0; /* disable VHPT walker */
70 rr.map.ps = PAGE_WIDTH;
71 rr.map.rid = ASID2RID(ASID_KERNEL,VRN_KERNEL);
72 rr_write(VRN_KERNEL, rr.word);
73 srlz_i();
74 srlz_d();
75
76 /*
77 * And invalidate the rest of region register.
78 */
79 for(i = 0; i < REGION_REGISTERS; i++) {
80 /* skip kernel rr */
81 if (i == VRN_KERNEL)
82 continue;
83
84 rr.word == rr_read(i);
85 rr.map.ve = 0; /* disable VHPT walker */
86 rr.map.rid = ASID2RID(ASID_INVALID,i);
87 rr_write(i, rr.word);
88 srlz_i();
89 srlz_d();
90 }
91
92 /*
93 * Set up PTA register.
94 */
95 pta.word = pta_read();
96 pta.map.ve = 0; /* disable VHPT walker */
97 pta.map.vf = 1; /* large entry format */
98 pta.map.size = VHPT_WIDTH;
99 pta.map.base = VHPT_BASE >> PTA_BASE_SHIFT;
100 pta_write(pta.word);
101 srlz_i();
102 srlz_d();
103
104
105 return ;
106
107}
108
109/** Calculate address of collision chain from VPN and ASID.
110 *
111 * Interrupts must be disabled.
112 *
113 * @param page Address of virtual page including VRN bits.
114 * @param asid Address space identifier.
115 *
116 * @return VHPT entry address.
117 */
118vhpt_entry_t *vhpt_hash(__address page, asid_t asid)
119{
120 region_register rr_save, rr;
121 index_t vrn;
122 rid_t rid;
123 vhpt_entry_t *v;
124
125 vrn = page >> VRN_SHIFT;
126 rid = ASID2RID(asid, vrn);
127
128 rr_save.word = rr_read(vrn);
129 if (rr_save.map.rid == rid) {
130 /*
131 * The RID is already in place, compute thash and return.
132 */
133 v = (vhpt_entry_t *) thash(page);
134 return v;
135 }
136
137 /*
138 * The RID must be written to some region register.
139 * To speed things up, register indexed by vrn is used.
140 */
141 rr.word = rr_save.word;
142 rr.map.rid = rid;
143 rr_write(vrn, rr.word);
144 srlz_i();
145 v = (vhpt_entry_t *) thash(page);
146 rr_write(vrn, rr_save.word);
147 srlz_i();
148 srlz_d();
149
150 return v;
151}
152
153/** Compare ASID and VPN against PTE.
154 *
155 * Interrupts must be disabled.
156 *
157 * @param page Address of virtual page including VRN bits.
158 * @param asid Address space identifier.
159 *
160 * @return True if page and asid match the page and asid of t, false otherwise.
161 */
162bool vhpt_compare(__address page, asid_t asid, vhpt_entry_t *v)
163{
164 region_register rr_save, rr;
165 index_t vrn;
166 rid_t rid;
167 bool match;
168
169 ASSERT(v);
170
171 vrn = page >> VRN_SHIFT;
172 rid = ASID2RID(asid, vrn);
173
174 rr_save.word = rr_read(vrn);
175 if (rr_save.map.rid == rid) {
176 /*
177 * The RID is already in place, compare ttag with t and return.
178 */
179 return ttag(page) == v->present.tag.tag_word;
180 }
181
182 /*
183 * The RID must be written to some region register.
184 * To speed things up, register indexed by vrn is used.
185 */
186 rr.word = rr_save.word;
187 rr.map.rid = rid;
188 rr_write(vrn, rr.word);
189 srlz_i();
190 match = (ttag(page) == v->present.tag.tag_word);
191 rr_write(vrn, rr_save.word);
192 srlz_i();
193 srlz_d();
194
195 return match;
196}
197
198/** Set up one VHPT entry.
199 *
200 * @param t VHPT entry to be set up.
201 * @param page Virtual address of the page mapped by the entry.
202 * @param asid Address space identifier of the address space to which page belongs.
203 * @param frame Physical address of the frame to wich page is mapped.
204 * @param flags Different flags for the mapping.
205 */
206void vhpt_set_record(vhpt_entry_t *v, __address page, asid_t asid, __address frame, int flags)
207{
208 region_register rr_save, rr;
209 index_t vrn;
210 rid_t rid;
211 __u64 tag;
212
213 ASSERT(v);
214
215 vrn = page >> VRN_SHIFT;
216 rid = ASID2RID(asid, vrn);
217
218 /*
219 * Compute ttag.
220 */
221 rr_save.word = rr_read(vrn);
222 rr.word = rr_save.word;
223 rr.map.rid = rid;
224 rr_write(vrn, rr.word);
225 srlz_i();
226 tag = ttag(page);
227 rr_write(vrn, rr_save.word);
228 srlz_i();
229 srlz_d();
230
231 /*
232 * Clear the entry.
233 */
234 v->word[0] = 0;
235 v->word[1] = 0;
236 v->word[2] = 0;
237 v->word[3] = 0;
238
239 v->present.p = true;
240 v->present.ma = (flags & PAGE_CACHEABLE) ? MA_WRITEBACK : MA_UNCACHEABLE;
241 v->present.a = false; /* not accessed */
242 v->present.d = false; /* not dirty */
243 v->present.pl = (flags & PAGE_USER) ? PL_USER : PL_KERNEL;
244 v->present.ar = (flags & PAGE_WRITE) ? AR_WRITE : AR_READ;
245 v->present.ar |= (flags & PAGE_EXEC) ? AR_EXECUTE : 0;
246 v->present.ppn = frame >> PPN_SHIFT;
247 v->present.ed = false; /* exception not deffered */
248 v->present.ps = PAGE_WIDTH;
249 v->present.key = 0;
250 v->present.tag.tag_word = tag;
251}
Note: See TracBrowser for help on using the repository browser.