source: mainline/kernel/arch/ia64/src/mm/page.c@ 3e5a814

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

make hw_area API more generic
this allows mapping of EGA VRAM on ia32/amd64

  • Property mode set to 100644
File size: 7.0 KB
RevLine 
[6d7ffa65]1/*
[df4ed85]2 * Copyright (c) 2006 Jakub Jermar
3 * Copyright (c) 2006 Jakub Vana
[6d7ffa65]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
[9979acb]30/** @addtogroup ia64mm
[b45c443]31 * @{
32 */
33/** @file
34 */
35
[6d7ffa65]36#include <arch/mm/page.h>
37#include <genarch/mm/page_ht.h>
[c2b95d3]38#include <mm/asid.h>
[457d18a]39#include <arch/mm/asid.h>
[68091bd]40#include <arch/mm/vhpt.h>
[c2b95d3]41#include <arch/types.h>
[6461d67c]42#include <print.h>
[6d7ffa65]43#include <mm/page.h>
[c2b95d3]44#include <mm/frame.h>
[6d7ffa65]45#include <config.h>
46#include <panic.h>
[2a003d5b]47#include <arch/asm.h>
[c2b95d3]48#include <arch/barrier.h>
[849386a]49#include <memstr.h>
[59e4864]50#include <align.h>
[9979acb]51#include <ddi/ddi.h>
52
53/** Physical memory area for devices. */
54static parea_t dev_area;
[6d7ffa65]55
[c7ec94a4]56static void set_environment(void);
[457d18a]57
58/** Initialize ia64 virtual address translation subsystem. */
59void page_arch_init(void)
60{
[f5935ed]61 page_mapping_operations = &ht_mapping_operations;
[457d18a]62 pk_disable();
[c7ec94a4]63 set_environment();
[457d18a]64}
65
[c2b95d3]66/** Initialize VHPT and region registers. */
[c7ec94a4]67void set_environment(void)
[fd537a0]68{
[c2b95d3]69 region_register rr;
70 pta_register pta;
[fd537a0]71 int i;
[68091bd]72#ifdef CONFIG_VHPT
[7f1c620]73 uintptr_t vhpt_base;
[68091bd]74#endif
[5ac2e61]75
[c2b95d3]76 /*
77 * First set up kernel region register.
[a0d74fd]78 * This is redundant (see start.S) but we keep it here just for sure.
[c2b95d3]79 */
80 rr.word = rr_read(VRN_KERNEL);
81 rr.map.ve = 0; /* disable VHPT walker */
82 rr.map.ps = PAGE_WIDTH;
[a0d74fd]83 rr.map.rid = ASID2RID(ASID_KERNEL, VRN_KERNEL);
[c2b95d3]84 rr_write(VRN_KERNEL, rr.word);
85 srlz_i();
86 srlz_d();
[a0d74fd]87
[c2b95d3]88 /*
[9ad03fe]89 * And setup the rest of region register.
[c2b95d3]90 */
91 for(i = 0; i < REGION_REGISTERS; i++) {
92 /* skip kernel rr */
93 if (i == VRN_KERNEL)
94 continue;
[6461d67c]95
[9459255]96 rr.word = rr_read(i);
[849386a]97 rr.map.ve = 0; /* disable VHPT walker */
[9ad03fe]98 rr.map.rid = RID_KERNEL;
99 rr.map.ps = PAGE_WIDTH;
[c2b95d3]100 rr_write(i, rr.word);
101 srlz_i();
102 srlz_d();
103 }
[6461d67c]104
[68091bd]105#ifdef CONFIG_VHPT
106 vhpt_base = vhpt_set_up();
107#endif
[c2b95d3]108 /*
109 * Set up PTA register.
110 */
111 pta.word = pta_read();
[68091bd]112#ifndef CONFIG_VHPT
[c2b95d3]113 pta.map.ve = 0; /* disable VHPT walker */
[68091bd]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
[c2b95d3]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}
[fd537a0]125
[849386a]126/** Calculate address of collision chain from VPN and ASID.
127 *
[457d18a]128 * Interrupts must be disabled.
[849386a]129 *
[666773c]130 * @param page Address of virtual page including VRN bits.
131 * @param asid Address space identifier.
[849386a]132 *
[666773c]133 * @return VHPT entry address.
[849386a]134 */
[7f1c620]135vhpt_entry_t *vhpt_hash(uintptr_t page, asid_t asid)
[849386a]136{
137 region_register rr_save, rr;
[457d18a]138 index_t vrn;
139 rid_t rid;
[c7ec94a4]140 vhpt_entry_t *v;
[849386a]141
[457d18a]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 */
[c7ec94a4]150 v = (vhpt_entry_t *) thash(page);
151 return v;
[457d18a]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 */
[849386a]158 rr.word = rr_save.word;
[457d18a]159 rr.map.rid = rid;
160 rr_write(vrn, rr.word);
[849386a]161 srlz_i();
[c7ec94a4]162 v = (vhpt_entry_t *) thash(page);
[457d18a]163 rr_write(vrn, rr_save.word);
[849386a]164 srlz_i();
165 srlz_d();
166
[c7ec94a4]167 return v;
[849386a]168}
[457d18a]169
170/** Compare ASID and VPN against PTE.
171 *
172 * Interrupts must be disabled.
173 *
[666773c]174 * @param page Address of virtual page including VRN bits.
175 * @param asid Address space identifier.
[457d18a]176 *
[666773c]177 * @return True if page and asid match the page and asid of t,
178 * false otherwise.
[457d18a]179 */
[7f1c620]180bool vhpt_compare(uintptr_t page, asid_t asid, vhpt_entry_t *v)
[457d18a]181{
182 region_register rr_save, rr;
183 index_t vrn;
184 rid_t rid;
185 bool match;
186
[c7ec94a4]187 ASSERT(v);
[457d18a]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 */
[c7ec94a4]197 return ttag(page) == v->present.tag.tag_word;
[457d18a]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();
[c7ec94a4]208 match = (ttag(page) == v->present.tag.tag_word);
[457d18a]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 *
[abbc16e]218 * @param v VHPT entry to be set up.
[666773c]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.
[457d18a]224 */
[666773c]225void
226vhpt_set_record(vhpt_entry_t *v, uintptr_t page, asid_t asid, uintptr_t frame,
227 int flags)
[457d18a]228{
229 region_register rr_save, rr;
230 index_t vrn;
231 rid_t rid;
[7f1c620]232 uint64_t tag;
[457d18a]233
[c7ec94a4]234 ASSERT(v);
[457d18a]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 */
[c7ec94a4]255 v->word[0] = 0;
256 v->word[1] = 0;
257 v->word[2] = 0;
258 v->word[3] = 0;
[457d18a]259
[c7ec94a4]260 v->present.p = true;
[666773c]261 v->present.ma = (flags & PAGE_CACHEABLE) ?
262 MA_WRITEBACK : MA_UNCACHEABLE;
[c7ec94a4]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;
[457d18a]273}
[b45c443]274
[38f6add]275uintptr_t hw_map(uintptr_t physaddr, size_t size __attribute__ ((unused)))
[59e4864]276{
[38f6add]277 /* This is a dirty hack. */
278 return PA2KA(physaddr);
[59e4864]279}
280
[9979acb]281void hw_area(void)
[ae318d3]282{
[9979acb]283 dev_area.pbase = end_frame;
284 dev_area.frames = SIZE2FRAMES(0x7fffffffffffffffUL - end_frame);
285 ddi_parea_register(&dev_area);
[ae318d3]286}
287
[06e1e95]288/** @}
[b45c443]289 */
Note: See TracBrowser for help on using the repository browser.