source: mainline/kernel/arch/ia64/src/mm/page.c@ 6b1de7a

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

Fix I/O access to identicaly mapped space

  • Property mode set to 100644
File size: 7.0 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/** @addtogroup ia64mm
31 * @{
32 */
33/** @file
34 */
35
36#include <arch/mm/page.h>
37#include <genarch/mm/page_ht.h>
38#include <mm/asid.h>
39#include <arch/mm/asid.h>
40#include <arch/mm/vhpt.h>
41#include <arch/types.h>
42#include <print.h>
43#include <mm/page.h>
44#include <mm/frame.h>
45#include <config.h>
46#include <panic.h>
47#include <arch/asm.h>
48#include <arch/barrier.h>
49#include <memstr.h>
50#include <align.h>
51#include <ddi/ddi.h>
52
53/** Physical memory area for devices. */
54static parea_t dev_area;
55
56static void set_environment(void);
57
58/** Initialize ia64 virtual address translation subsystem. */
59void page_arch_init(void)
60{
61 page_mapping_operations = &ht_mapping_operations;
62 pk_disable();
63 set_environment();
64}
65
66/** Initialize VHPT and region registers. */
67void set_environment(void)
68{
69 region_register rr;
70 pta_register pta;
71 int i;
72#ifdef CONFIG_VHPT
73 uintptr_t vhpt_base;
74#endif
75
76 /*
77 * First set up kernel region register.
78 * This is redundant (see start.S) but we keep it here just for sure.
79 */
80 rr.word = rr_read(VRN_KERNEL);
81 rr.map.ve = 0; /* disable VHPT walker */
82 rr.map.ps = PAGE_WIDTH;
83 rr.map.rid = ASID2RID(ASID_KERNEL, VRN_KERNEL);
84 rr_write(VRN_KERNEL, rr.word);
85 srlz_i();
86 srlz_d();
87
88 /*
89 * And setup the rest of region register.
90 */
91 for(i = 0; i < REGION_REGISTERS; i++) {
92 /* skip kernel rr */
93 if (i == VRN_KERNEL)
94 continue;
95
96 rr.word = rr_read(i);
97 rr.map.ve = 0; /* disable VHPT walker */
98 rr.map.rid = RID_KERNEL;
99 rr.map.ps = PAGE_WIDTH;
100 rr_write(i, rr.word);
101 srlz_i();
102 srlz_d();
103 }
104
105#ifdef CONFIG_VHPT
106 vhpt_base = vhpt_set_up();
107#endif
108 /*
109 * Set up PTA register.
110 */
111 pta.word = pta_read();
112#ifndef CONFIG_VHPT
113 pta.map.ve = 0; /* disable VHPT walker */
114 pta.map.base = 0 >> PTA_BASE_SHIFT;
115#else
116 pta.map.ve = 1; /* enable VHPT walker */
117 pta.map.base = vhpt_base >> PTA_BASE_SHIFT;
118#endif
119 pta.map.vf = 1; /* large entry format */
120 pta.map.size = VHPT_WIDTH;
121 pta_write(pta.word);
122 srlz_i();
123 srlz_d();
124}
125
126/** Calculate address of collision chain from VPN and ASID.
127 *
128 * Interrupts must be disabled.
129 *
130 * @param page Address of virtual page including VRN bits.
131 * @param asid Address space identifier.
132 *
133 * @return VHPT entry address.
134 */
135vhpt_entry_t *vhpt_hash(uintptr_t page, asid_t asid)
136{
137 region_register rr_save, rr;
138 index_t vrn;
139 rid_t rid;
140 vhpt_entry_t *v;
141
142 vrn = page >> VRN_SHIFT;
143 rid = ASID2RID(asid, vrn);
144
145 rr_save.word = rr_read(vrn);
146 if (rr_save.map.rid == rid) {
147 /*
148 * The RID is already in place, compute thash and return.
149 */
150 v = (vhpt_entry_t *) thash(page);
151 return v;
152 }
153
154 /*
155 * The RID must be written to some region register.
156 * To speed things up, register indexed by vrn is used.
157 */
158 rr.word = rr_save.word;
159 rr.map.rid = rid;
160 rr_write(vrn, rr.word);
161 srlz_i();
162 v = (vhpt_entry_t *) thash(page);
163 rr_write(vrn, rr_save.word);
164 srlz_i();
165 srlz_d();
166
167 return v;
168}
169
170/** Compare ASID and VPN against PTE.
171 *
172 * Interrupts must be disabled.
173 *
174 * @param page Address of virtual page including VRN bits.
175 * @param asid Address space identifier.
176 *
177 * @return True if page and asid match the page and asid of t,
178 * false otherwise.
179 */
180bool vhpt_compare(uintptr_t page, asid_t asid, vhpt_entry_t *v)
181{
182 region_register rr_save, rr;
183 index_t vrn;
184 rid_t rid;
185 bool match;
186
187 ASSERT(v);
188
189 vrn = page >> VRN_SHIFT;
190 rid = ASID2RID(asid, vrn);
191
192 rr_save.word = rr_read(vrn);
193 if (rr_save.map.rid == rid) {
194 /*
195 * The RID is already in place, compare ttag with t and return.
196 */
197 return ttag(page) == v->present.tag.tag_word;
198 }
199
200 /*
201 * The RID must be written to some region register.
202 * To speed things up, register indexed by vrn is used.
203 */
204 rr.word = rr_save.word;
205 rr.map.rid = rid;
206 rr_write(vrn, rr.word);
207 srlz_i();
208 match = (ttag(page) == v->present.tag.tag_word);
209 rr_write(vrn, rr_save.word);
210 srlz_i();
211 srlz_d();
212
213 return match;
214}
215
216/** Set up one VHPT entry.
217 *
218 * @param v VHPT entry to be set up.
219 * @param page Virtual address of the page mapped by the entry.
220 * @param asid Address space identifier of the address space to which
221 * page belongs.
222 * @param frame Physical address of the frame to wich page is mapped.
223 * @param flags Different flags for the mapping.
224 */
225void
226vhpt_set_record(vhpt_entry_t *v, uintptr_t page, asid_t asid, uintptr_t frame,
227 int flags)
228{
229 region_register rr_save, rr;
230 index_t vrn;
231 rid_t rid;
232 uint64_t tag;
233
234 ASSERT(v);
235
236 vrn = page >> VRN_SHIFT;
237 rid = ASID2RID(asid, vrn);
238
239 /*
240 * Compute ttag.
241 */
242 rr_save.word = rr_read(vrn);
243 rr.word = rr_save.word;
244 rr.map.rid = rid;
245 rr_write(vrn, rr.word);
246 srlz_i();
247 tag = ttag(page);
248 rr_write(vrn, rr_save.word);
249 srlz_i();
250 srlz_d();
251
252 /*
253 * Clear the entry.
254 */
255 v->word[0] = 0;
256 v->word[1] = 0;
257 v->word[2] = 0;
258 v->word[3] = 0;
259
260 v->present.p = true;
261 v->present.ma = (flags & PAGE_CACHEABLE) ?
262 MA_WRITEBACK : MA_UNCACHEABLE;
263 v->present.a = false; /* not accessed */
264 v->present.d = false; /* not dirty */
265 v->present.pl = (flags & PAGE_USER) ? PL_USER : PL_KERNEL;
266 v->present.ar = (flags & PAGE_WRITE) ? AR_WRITE : AR_READ;
267 v->present.ar |= (flags & PAGE_EXEC) ? AR_EXECUTE : 0;
268 v->present.ppn = frame >> PPN_SHIFT;
269 v->present.ed = false; /* exception not deffered */
270 v->present.ps = PAGE_WIDTH;
271 v->present.key = 0;
272 v->present.tag.tag_word = tag;
273}
274
275uintptr_t hw_map(uintptr_t physaddr, size_t size __attribute__ ((unused)))
276{
277 /* THIS is a dirty hack. */
278 return (uintptr_t)((uint64_t)(PA2KA(physaddr)) + VIO_OFFSET);
279}
280
281void hw_area(void)
282{
283 dev_area.pbase = end_frame;
284 dev_area.frames = SIZE2FRAMES(0x7fffffffffffffffUL - end_frame);
285 ddi_parea_register(&dev_area);
286}
287
288/** @}
289 */
Note: See TracBrowser for help on using the repository browser.