00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00036 #include <arch/mm/page.h>
00037 #include <genarch/mm/page_ht.h>
00038 #include <mm/asid.h>
00039 #include <arch/mm/asid.h>
00040 #include <arch/mm/vhpt.h>
00041 #include <arch/types.h>
00042 #include <typedefs.h>
00043 #include <print.h>
00044 #include <mm/page.h>
00045 #include <mm/frame.h>
00046 #include <config.h>
00047 #include <panic.h>
00048 #include <arch/asm.h>
00049 #include <arch/barrier.h>
00050 #include <memstr.h>
00051
00052 static void set_environment(void);
00053
00055 void page_arch_init(void)
00056 {
00057 page_mapping_operations = &ht_mapping_operations;
00058 pk_disable();
00059 set_environment();
00060 }
00061
00063 void set_environment(void)
00064 {
00065 region_register rr;
00066 pta_register pta;
00067 int i;
00068 #ifdef CONFIG_VHPT
00069 __address vhpt_base;
00070 #endif
00071
00072
00073
00074
00075
00076 rr.word = rr_read(VRN_KERNEL);
00077 rr.map.ve = 0;
00078 rr.map.ps = PAGE_WIDTH;
00079 rr.map.rid = ASID2RID(ASID_KERNEL, VRN_KERNEL);
00080 rr_write(VRN_KERNEL, rr.word);
00081 srlz_i();
00082 srlz_d();
00083
00084
00085
00086
00087 for(i = 0; i < REGION_REGISTERS; i++) {
00088
00089 if (i == VRN_KERNEL)
00090 continue;
00091
00092 rr.word = rr_read(i);
00093 rr.map.ve = 0;
00094 rr.map.rid = RID_KERNEL;
00095 rr.map.ps = PAGE_WIDTH;
00096 rr_write(i, rr.word);
00097 srlz_i();
00098 srlz_d();
00099 }
00100
00101 #ifdef CONFIG_VHPT
00102 vhpt_base = vhpt_set_up();
00103 #endif
00104
00105
00106
00107 pta.word = pta_read();
00108 #ifndef CONFIG_VHPT
00109 pta.map.ve = 0;
00110 pta.map.base = 0 >> PTA_BASE_SHIFT;
00111 #else
00112 pta.map.ve = 1;
00113 pta.map.base = vhpt_base >> PTA_BASE_SHIFT;
00114 #endif
00115 pta.map.vf = 1;
00116 pta.map.size = VHPT_WIDTH;
00117 pta_write(pta.word);
00118 srlz_i();
00119 srlz_d();
00120 }
00121
00131 vhpt_entry_t *vhpt_hash(__address page, asid_t asid)
00132 {
00133 region_register rr_save, rr;
00134 index_t vrn;
00135 rid_t rid;
00136 vhpt_entry_t *v;
00137
00138 vrn = page >> VRN_SHIFT;
00139 rid = ASID2RID(asid, vrn);
00140
00141 rr_save.word = rr_read(vrn);
00142 if (rr_save.map.rid == rid) {
00143
00144
00145
00146 v = (vhpt_entry_t *) thash(page);
00147 return v;
00148 }
00149
00150
00151
00152
00153
00154 rr.word = rr_save.word;
00155 rr.map.rid = rid;
00156 rr_write(vrn, rr.word);
00157 srlz_i();
00158 v = (vhpt_entry_t *) thash(page);
00159 rr_write(vrn, rr_save.word);
00160 srlz_i();
00161 srlz_d();
00162
00163 return v;
00164 }
00165
00175 bool vhpt_compare(__address page, asid_t asid, vhpt_entry_t *v)
00176 {
00177 region_register rr_save, rr;
00178 index_t vrn;
00179 rid_t rid;
00180 bool match;
00181
00182 ASSERT(v);
00183
00184 vrn = page >> VRN_SHIFT;
00185 rid = ASID2RID(asid, vrn);
00186
00187 rr_save.word = rr_read(vrn);
00188 if (rr_save.map.rid == rid) {
00189
00190
00191
00192 return ttag(page) == v->present.tag.tag_word;
00193 }
00194
00195
00196
00197
00198
00199 rr.word = rr_save.word;
00200 rr.map.rid = rid;
00201 rr_write(vrn, rr.word);
00202 srlz_i();
00203 match = (ttag(page) == v->present.tag.tag_word);
00204 rr_write(vrn, rr_save.word);
00205 srlz_i();
00206 srlz_d();
00207
00208 return match;
00209 }
00210
00219 void vhpt_set_record(vhpt_entry_t *v, __address page, asid_t asid, __address frame, int flags)
00220 {
00221 region_register rr_save, rr;
00222 index_t vrn;
00223 rid_t rid;
00224 __u64 tag;
00225
00226 ASSERT(v);
00227
00228 vrn = page >> VRN_SHIFT;
00229 rid = ASID2RID(asid, vrn);
00230
00231
00232
00233
00234 rr_save.word = rr_read(vrn);
00235 rr.word = rr_save.word;
00236 rr.map.rid = rid;
00237 rr_write(vrn, rr.word);
00238 srlz_i();
00239 tag = ttag(page);
00240 rr_write(vrn, rr_save.word);
00241 srlz_i();
00242 srlz_d();
00243
00244
00245
00246
00247 v->word[0] = 0;
00248 v->word[1] = 0;
00249 v->word[2] = 0;
00250 v->word[3] = 0;
00251
00252 v->present.p = true;
00253 v->present.ma = (flags & PAGE_CACHEABLE) ? MA_WRITEBACK : MA_UNCACHEABLE;
00254 v->present.a = false;
00255 v->present.d = false;
00256 v->present.pl = (flags & PAGE_USER) ? PL_USER : PL_KERNEL;
00257 v->present.ar = (flags & PAGE_WRITE) ? AR_WRITE : AR_READ;
00258 v->present.ar |= (flags & PAGE_EXEC) ? AR_EXECUTE : 0;
00259 v->present.ppn = frame >> PPN_SHIFT;
00260 v->present.ed = false;
00261 v->present.ps = PAGE_WIDTH;
00262 v->present.key = 0;
00263 v->present.tag.tag_word = tag;
00264 }
00265