Changeset 457d18a in mainline
- Timestamp:
- 2006-01-28T16:47:39Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d0780b4c
- Parents:
- 849386a
- Location:
- arch/ia64
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
arch/ia64/include/mm/asid.h
r849386a r457d18a 43 43 #define RID_OVERFLOW 16777216 /* 2^24 */ 44 44 45 #define ASID2RID(asid, vrn) (((asid)*RIDS_PER_ASID)+(vrn)) 46 #define RID2ASID(rid) ((rid)/RIDS_PER_ASID) 47 48 typedef __u32 rid_t; 49 45 50 /** 46 51 * This macro is needed only to compile the kernel. -
arch/ia64/include/mm/page.h
r849386a r457d18a 33 33 #include <arch/mm/frame.h> 34 34 #include <genarch/mm/page_ht.h> 35 #include <arch/mm/asid.h> 35 36 #include <arch/types.h> 36 37 #include <typedefs.h> … … 47 48 48 49 /** Implementation of page hash table interface. */ 49 #define HT_ENTRIES_ARCH (VHPT_SIZE/sizeof(pte_t)) 50 #define HT_HASH_ARCH(page, asid) vhpt_hash((page), (asid)) 51 #define HT_COMPARE_ARCH(page, asid, t) 0 52 #define HT_SLOT_EMPTY_ARCH(t) 1 53 #define HT_INVALIDATE_SLOT_ARCH(t) 54 #define HT_GET_NEXT_ARCH(t) 0 55 #define HT_SET_NEXT_ARCH(t, s) 56 #define HT_SET_RECORD_ARCH(t, page, asid, frame, flags) 50 #define HT_ENTRIES_ARCH (VHPT_SIZE/sizeof(pte_t)) 51 #define HT_HASH_ARCH(page, asid) vhpt_hash((page), (asid)) 52 #define HT_COMPARE_ARCH(page, asid, t) vhpt_compare((page), (asid), (t)) 53 #define HT_SLOT_EMPTY_ARCH(t) ((t)->present.tag.tag_info.ti) 54 #define HT_INVALIDATE_SLOT_ARCH(t) (t)->present.tag.tag_info.ti = true 55 #define HT_GET_NEXT_ARCH(t) (t)->present.next 56 #define HT_SET_NEXT_ARCH(t, s) (t)->present.next = (s) 57 #define HT_SET_RECORD_ARCH(t, page, asid, frame, flags) vhpt_set_record(t, page, asid, frame, flags) 58 59 #define PPN_SHIFT 12 57 60 58 61 #define VRN_SHIFT 61 … … 60 63 61 64 #define VRN_KERNEL 0 62 #define VRN_WORK 1LL63 65 #define REGION_REGISTERS 8 64 66 … … 67 69 68 70 #define VHPT_BASE page_ht /* Must be aligned to VHPT_SIZE */ 71 72 /** Memory Attributes. */ 73 #define MA_WRITEBACK 0x0 74 #define MA_UNCACHEABLE 0x4 75 76 /** Privilege Levels. Only the most and the least privileged ones are ever used. */ 77 #define PL_KERNEL 0x0 78 #define PL_USER 0x3 79 80 /* Access Rigths. Only certain combinations are used by the kernel. */ 81 #define AR_READ 0x0 82 #define AR_EXECUTE 0x1 83 #define AR_WRITE 0x2 69 84 70 85 struct vhpt_tag_info { … … 102 117 103 118 /* Word 3 */ 104 unsigned long long next : 64;/**< Collision chain next pointer. */119 pte_t *next; /**< Collision chain next pointer. */ 105 120 } __attribute__ ((packed)); 106 121 … … 120 135 121 136 /* Word 3 */ 122 unsigned long long next : 64;/**< Collision chain next pointer. */137 pte_t *next; /**< Collision chain next pointer. */ 123 138 124 139 } __attribute__ ((packed)); … … 127 142 struct vhpt_entry_present present; 128 143 struct vhpt_entry_not_present not_present; 144 __u64 word[4]; 129 145 } vhpt_entry; 130 146 … … 244 260 extern void page_arch_init(void); 245 261 extern pte_t *vhpt_hash(__address page, asid_t asid); 262 extern bool vhpt_compare(__address page, asid_t asid, pte_t *t); 263 extern void vhpt_set_record(pte_t *t, __address page, asid_t asid, __address frame, int flags); 246 264 247 265 #endif -
arch/ia64/src/mm/asid.c
r849386a r457d18a 50 50 #include <mm/asid.h> 51 51 #include <mm/as.h> 52 #include <genarch/mm/page_ht.h> 52 53 #include <mm/tlb.h> 53 54 #include <list.h> … … 105 106 spinlock_unlock(&as->lock); 106 107 } 108 109 /* 110 * The page hash table uses VHPT long format PTE's. 111 * Unfortunatelly, this format has no space to 112 * store as_t pointer, so it is necessary to 113 * invalidate the whole structure after all ASIDs 114 * have been reassigned. The information swept out 115 * from the page hash table can be later reconstructed 116 * from as_t structures on demand. 117 */ 118 ht_invalidate_all(); 107 119 108 120 /* -
arch/ia64/src/mm/page.c
r849386a r457d18a 31 31 #include <genarch/mm/page_ht.h> 32 32 #include <mm/asid.h> 33 #include <arch/mm/asid.h> 33 34 #include <arch/types.h> 35 #include <typedefs.h> 34 36 #include <print.h> 35 37 #include <mm/page.h> … … 41 43 #include <memstr.h> 42 44 45 static void set_vhpt_environment(void); 46 47 /** Initialize ia64 virtual address translation subsystem. */ 48 void page_arch_init(void) 49 { 50 page_operations = &page_ht_operations; 51 pk_disable(); 52 set_vhpt_environment(); 53 } 54 43 55 /** Initialize VHPT and region registers. */ 44 staticvoid set_vhpt_environment(void)56 void set_vhpt_environment(void) 45 57 { 46 58 region_register rr; … … 95 107 } 96 108 97 /** Initialize ia64 virtual address translation subsystem. */98 void page_arch_init(void)99 {100 page_operations = &page_ht_operations;101 pk_disable();102 set_vhpt_environment();103 }104 105 109 /** Calculate address of collision chain from VPN and ASID. 106 110 * 107 * This is rather non-trivial function. 108 * First, it has to translate ASID to RID. 109 * This is achieved by taking VRN bits of 110 * page into account. 111 * Second, it must preserve the region register 112 * it writes the RID to. 111 * Interrupts must be disabled. 113 112 * 114 113 * @param page Address of virtual page including VRN bits. … … 120 119 { 121 120 region_register rr_save, rr; 121 index_t vrn; 122 rid_t rid; 122 123 pte_t *t; 123 124 124 rr_save.word = rr_read(VRN_WORK); 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 t = (pte_t *) thash(page); 134 return t; 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 */ 125 141 rr.word = rr_save.word; 126 if ((page >> VRN_SHIFT) != VRN_KERNEL) 127 rr.map.rid = (asid * RIDS_PER_ASID) + (page >> VRN_SHIFT); 128 else 129 rr.map.rid = ASID_KERNEL; 130 rr_write(VRN_WORK, rr.word); 131 srlz_i(); 132 t = (pte_t *) thash((VRN_WORK << VRN_SHIFT) | (~(VRN_MASK) & page)); 133 rr_write(VRN_WORK, rr_save.word); 142 rr.map.rid = rid; 143 rr_write(vrn, rr.word); 144 srlz_i(); 145 t = (pte_t *) thash(page); 146 rr_write(vrn, rr_save.word); 134 147 srlz_i(); 135 148 srlz_d(); … … 137 150 return t; 138 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 */ 162 bool vhpt_compare(__address page, asid_t asid, pte_t *t) 163 { 164 region_register rr_save, rr; 165 index_t vrn; 166 rid_t rid; 167 bool match; 168 169 ASSERT(t); 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) == t->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) == t->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 */ 206 void vhpt_set_record(pte_t *t, __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(t); 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 t->word[0] = 0; 235 t->word[1] = 0; 236 t->word[2] = 0; 237 t->word[3] = 0; 238 239 t->present.p = true; 240 t->present.ma = (flags & PAGE_CACHEABLE) ? MA_WRITEBACK : MA_UNCACHEABLE; 241 t->present.a = false; /* not accessed */ 242 t->present.d = false; /* not dirty */ 243 t->present.pl = (flags & PAGE_USER) ? PL_USER : PL_KERNEL; 244 t->present.ar = (flags & PAGE_WRITE) ? AR_WRITE : AR_READ; 245 t->present.ar |= (flags & PAGE_EXEC) ? AR_EXECUTE : 0; 246 t->present.ppn = frame >> PPN_SHIFT; 247 t->present.ed = false; /* exception not deffered */ 248 t->present.ps = PAGE_WIDTH; 249 t->present.key = 0; 250 t->present.tag.tag_word = tag; 251 t->present.next = NULL; 252 }
Note:
See TracChangeset
for help on using the changeset viewer.