Changeset c7ec94a4 in mainline
- Timestamp:
- 2006-02-06T14:18:28Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f5935ed
- Parents:
- 214f5bb
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
arch/ia64/include/mm/page.h
r214f5bb rc7ec94a4 46 46 #define SET_PTL0_ADDRESS_ARCH(x) /**< To be removed as situation permits. */ 47 47 48 /** Implementation of page hash table interface. */49 #define HT_WIDTH_ARCH 20 /* 1M */50 #define HT_HASH_ARCH(page, asid) vhpt_hash((page), (asid))51 #define HT_COMPARE_ARCH(page, asid, t) vhpt_compare((page), (asid), (t))52 #define HT_SLOT_EMPTY_ARCH(t) ((t)->present.tag.tag_info.ti)53 #define HT_INVALIDATE_SLOT_ARCH(t) (t)->present.tag.tag_info.ti = true54 #define HT_GET_NEXT_ARCH(t) (t)->present.next55 #define HT_SET_NEXT_ARCH(t, s) (t)->present.next = (s)56 #define HT_SET_RECORD_ARCH(t, page, asid, frame, flags) vhpt_set_record(t, page, asid, frame, flags)57 58 48 #define PPN_SHIFT 12 59 49 … … 64 54 65 55 #define VHPT_WIDTH 20 /* 1M */ 66 #define VHPT_SIZE (1 <<VHPT_WIDTH)67 #define VHPT_BASE page_ht/* Must be aligned to VHPT_SIZE */56 #define VHPT_SIZE (1 << VHPT_WIDTH) 57 #define VHPT_BASE 0 /* Must be aligned to VHPT_SIZE */ 68 58 69 59 #define PTA_BASE_SHIFT 15 … … 116 106 117 107 /* Word 3 */ 118 pte_t *next; /**< Collision chain next pointer. */108 __u64 ig3 : 64; 119 109 } __attribute__ ((packed)); 120 110 … … 134 124 135 125 /* Word 3 */ 136 pte_t *next; /**< Collision chain next pointer. */ 137 126 __u64 ig3 : 64; 138 127 } __attribute__ ((packed)); 139 128 … … 142 131 struct vhpt_entry_not_present not_present; 143 132 __u64 word[4]; 144 } vhpt_entry ;133 } vhpt_entry_t; 145 134 146 135 struct region_register_map { … … 258 247 259 248 extern void page_arch_init(void); 260 extern pte_t *vhpt_hash(__address page, asid_t asid); 261 extern bool vhpt_compare(__address page, asid_t asid, pte_t *t); 262 extern void vhpt_set_record(pte_t *t, __address page, asid_t asid, __address frame, int flags); 249 250 extern vhpt_entry_t *vhpt_hash(__address page, asid_t asid); 251 extern bool vhpt_compare(__address page, asid_t asid, vhpt_entry_t *v); 252 extern void vhpt_set_record(vhpt_entry_t *v, __address page, asid_t asid, __address frame, int flags); 263 253 264 254 #endif -
arch/ia64/include/types.h
r214f5bb rc7ec94a4 48 48 typedef __u64 __native; 49 49 50 typedef union vhpt_entrypte_t;50 typedef struct pte pte_t; 51 51 52 52 #endif -
arch/ia64/src/mm/page.c
r214f5bb rc7ec94a4 43 43 #include <memstr.h> 44 44 45 static void set_ vhpt_environment(void);45 static void set_environment(void); 46 46 47 47 /** Initialize ia64 virtual address translation subsystem. */ … … 50 50 page_operations = &page_ht_operations; 51 51 pk_disable(); 52 set_ vhpt_environment();52 set_environment(); 53 53 } 54 54 55 55 /** Initialize VHPT and region registers. */ 56 void set_ vhpt_environment(void)56 void set_environment(void) 57 57 { 58 58 region_register rr; … … 88 88 89 89 /* 90 * Allocate VHPT and invalidate all its entries.91 */92 page_ht = (pte_t *) frame_alloc(VHPT_WIDTH - FRAME_WIDTH, FRAME_KA);93 memsetb((__address) page_ht, VHPT_SIZE, 0);94 ht_invalidate_all();95 96 /*97 90 * Set up PTA register. 98 91 */ … … 101 94 pta.map.vf = 1; /* large entry format */ 102 95 pta.map.size = VHPT_WIDTH; 103 pta.map.base = ((__address) page_ht)>> PTA_BASE_SHIFT;96 pta.map.base = VHPT_BASE >> PTA_BASE_SHIFT; 104 97 pta_write(pta.word); 105 98 srlz_i(); … … 114 107 * @param asid Address space identifier. 115 108 * 116 * @return Head of VHPT collision chain for page and asid.117 */ 118 pte_t *vhpt_hash(__address page, asid_t asid)109 * @return VHPT entry address. 110 */ 111 vhpt_entry_t *vhpt_hash(__address page, asid_t asid) 119 112 { 120 113 region_register rr_save, rr; 121 114 index_t vrn; 122 115 rid_t rid; 123 pte_t *t;116 vhpt_entry_t *v; 124 117 125 118 vrn = page >> VRN_SHIFT; … … 131 124 * The RID is already in place, compute thash and return. 132 125 */ 133 t = (pte_t *) thash(page);134 return t;126 v = (vhpt_entry_t *) thash(page); 127 return v; 135 128 } 136 129 … … 143 136 rr_write(vrn, rr.word); 144 137 srlz_i(); 145 t = (pte_t *) thash(page);138 v = (vhpt_entry_t *) thash(page); 146 139 rr_write(vrn, rr_save.word); 147 140 srlz_i(); 148 141 srlz_d(); 149 142 150 return t;143 return v; 151 144 } 152 145 … … 160 153 * @return True if page and asid match the page and asid of t, false otherwise. 161 154 */ 162 bool vhpt_compare(__address page, asid_t asid, pte_t *t)155 bool vhpt_compare(__address page, asid_t asid, vhpt_entry_t *v) 163 156 { 164 157 region_register rr_save, rr; … … 167 160 bool match; 168 161 169 ASSERT( t);162 ASSERT(v); 170 163 171 164 vrn = page >> VRN_SHIFT; … … 177 170 * The RID is already in place, compare ttag with t and return. 178 171 */ 179 return ttag(page) == t->present.tag.tag_word;172 return ttag(page) == v->present.tag.tag_word; 180 173 } 181 174 … … 188 181 rr_write(vrn, rr.word); 189 182 srlz_i(); 190 match = (ttag(page) == t->present.tag.tag_word);183 match = (ttag(page) == v->present.tag.tag_word); 191 184 rr_write(vrn, rr_save.word); 192 185 srlz_i(); … … 204 197 * @param flags Different flags for the mapping. 205 198 */ 206 void vhpt_set_record( pte_t *t, __address page, asid_t asid, __address frame, int flags)199 void vhpt_set_record(vhpt_entry_t *v, __address page, asid_t asid, __address frame, int flags) 207 200 { 208 201 region_register rr_save, rr; … … 211 204 __u64 tag; 212 205 213 ASSERT( t);206 ASSERT(v); 214 207 215 208 vrn = page >> VRN_SHIFT; … … 232 225 * Clear the entry. 233 226 */ 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 } 227 v->word[0] = 0; 228 v->word[1] = 0; 229 v->word[2] = 0; 230 v->word[3] = 0; 231 232 v->present.p = true; 233 v->present.ma = (flags & PAGE_CACHEABLE) ? MA_WRITEBACK : MA_UNCACHEABLE; 234 v->present.a = false; /* not accessed */ 235 v->present.d = false; /* not dirty */ 236 v->present.pl = (flags & PAGE_USER) ? PL_USER : PL_KERNEL; 237 v->present.ar = (flags & PAGE_WRITE) ? AR_WRITE : AR_READ; 238 v->present.ar |= (flags & PAGE_EXEC) ? AR_EXECUTE : 0; 239 v->present.ppn = frame >> PPN_SHIFT; 240 v->present.ed = false; /* exception not deffered */ 241 v->present.ps = PAGE_WIDTH; 242 v->present.key = 0; 243 v->present.tag.tag_word = tag; 244 } -
arch/sparc64/include/mm/page.h
r214f5bb rc7ec94a4 42 42 #define SET_PTL0_ADDRESS_ARCH(x) /**< To be removed as situation permits. */ 43 43 44 /** Implementation of page hash table interface. */45 #define HT_WIDTH_ARCH 20 /* 1M */46 #define HT_HASH_ARCH(page, asid) 047 #define HT_COMPARE_ARCH(page, asid, t) 048 #define HT_SLOT_EMPTY_ARCH(t) 149 #define HT_INVALIDATE_SLOT_ARCH(t)50 #define HT_GET_NEXT_ARCH(t) 051 #define HT_SET_NEXT_ARCH(t, s)52 #define HT_SET_RECORD_ARCH(t, page, asid, frame, flags)53 54 44 union page_address { 55 45 __address address; -
arch/sparc64/include/types.h
r214f5bb rc7ec94a4 45 45 typedef __u64 __native; 46 46 47 typedef __u64pte_t;47 typedef struct pte pte_t; 48 48 49 49 typedef __u8 asi_t; -
arch/sparc64/src/mm/frame.c
r214f5bb rc7ec94a4 33 33 void frame_arch_init(void) 34 34 { 35 /* 36 * Workaround to prevent slab allocator from allocating fram 0, 37 * which is not, at that time, mapped. 38 */ 39 frame_region_not_free(0, FRAME_SIZE); 40 35 41 zone_create_in_region(0, config.memory_size & ~(FRAME_SIZE - 1)); 36 42 } -
genarch/include/mm/page_ht.h
r214f5bb rc7ec94a4 29 29 /* 30 30 * This is the generic page hash table interface. 31 * Architectures that use single page hash table for32 * storing page translations must implement it.33 31 */ 34 32 … … 38 36 #include <mm/page.h> 39 37 #include <typedefs.h> 38 #include <arch/types.h> 39 #include <adt/list.h> 40 #include <adt/hash_table.h> 40 41 41 /** Page hash table size. */ 42 #define HT_WIDTH HT_WIDTH_ARCH 43 #define HT_SIZE (1<<HT_WIDTH) 44 #define HT_ENTRIES (HT_SIZE/sizeof(pte_t)) 42 #define PAGE_HT_KEYS 2 43 #define KEY_AS 0 44 #define KEY_PAGE 1 45 45 46 /** Hash function. 47 * 48 * @param page Virtual address. Only vpn bits will be used. 49 * @param asid Address space identifier. 50 * 51 * @return Pointer to hash table typed pte_t *. 52 */ 53 #define HT_HASH(page, asid) HT_HASH_ARCH(page, asid) 46 #define PAGE_HT_ENTRIES_BITS 13 47 #define PAGE_HT_ENTRIES (1<<PAGE_HT_ENTRIES_BITS) 54 48 55 /** Compare PTE with page and asid. 56 * 57 * @param page Virtual address. Only vpn bits will be used. 58 * @param asid Address space identifier. 59 * @param t PTE. 60 * 61 * @return 1 on match, 0 otherwise. 62 */ 63 #define HT_COMPARE(page, asid, t) HT_COMPARE_ARCH(page, asid, t) 64 65 /** Identify empty page hash table slots. 66 * 67 * @param t Pointer ro hash table typed pte_t *. 68 * 69 * @return 1 if the slot is empty, 0 otherwise. 70 */ 71 #define HT_SLOT_EMPTY(t) HT_SLOT_EMPTY_ARCH(t) 72 73 /** Invalidate/empty page hash table slot. 74 * 75 * @param t Address of the slot to be invalidated. 76 */ 77 #define HT_INVALIDATE_SLOT(t) HT_INVALIDATE_SLOT_ARCH(t) 78 79 /** Return next record in collision chain. 80 * 81 * @param t PTE. 82 * 83 * @return Successor of PTE or NULL. 84 */ 85 #define HT_GET_NEXT(t) HT_GET_NEXT_ARCH(t) 86 87 /** Set successor in collision chain. 88 * 89 * @param t PTE. 90 * @param s Successor or NULL. 91 */ 92 #define HT_SET_NEXT(t, s) HT_SET_NEXT_ARCH(t, s) 93 94 /** Set page hash table record. 95 * 96 * @param t PTE. 97 * @param page Virtual address. Only vpn bits will be used. 98 * @param asid Address space identifier. 99 * @param frame Physical address. Only pfn bits will be used. 100 * @param flags Flags. See mm/page.h. 101 */ 102 #define HT_SET_RECORD(t, page, asid, frame, flags) HT_SET_RECORD_ARCH(t, page, asid, frame, flags) 49 struct pte { 50 link_t link; /**< Page hash table link. */ 51 as_t *as; /**< Address space. */ 52 __address page; /**< Virtual memory page. */ 53 __address frame; /**< Physical memory frame. */ 54 int flags; 55 unsigned a : 1; /**< Accessed. */ 56 unsigned d : 1; /**< Dirty. */ 57 unsigned p : 1; /**< Present. */ 58 }; 103 59 104 60 extern page_operations_t page_ht_operations; 105 61 extern spinlock_t page_ht_lock; 106 62 107 extern pte_t *page_ht; 108 109 extern void ht_invalidate_all(void); 63 extern hash_table_t page_ht; 64 extern hash_table_operations_t ht_operations; 110 65 111 66 #endif -
genarch/src/mm/as_ht.c
r214f5bb rc7ec94a4 34 34 #include <typedefs.h> 35 35 #include <memstr.h> 36 #include <adt/hash_table.h> 36 37 37 38 static pte_t *ht_create(int flags); … … 49 50 * @param flags Ignored. 50 51 * 51 * @return Address of global page hash table.52 * @return Returns NULL. 52 53 */ 53 54 pte_t *ht_create(int flags) 54 55 { 55 if (!page_ht) { 56 page_ht = (pte_t *) frame_alloc(HT_WIDTH - FRAME_WIDTH, FRAME_KA | FRAME_PANIC); 57 memsetb((__address) page_ht, HT_SIZE, 0); 56 if (flags & FLAG_AS_KERNEL) { 57 hash_table_create(&page_ht, PAGE_HT_ENTRIES, 2, &ht_operations); 58 58 } 59 return page_ht;59 return NULL; 60 60 } -
genarch/src/mm/page_ht.c
r214f5bb rc7ec94a4 29 29 #include <genarch/mm/page_ht.h> 30 30 #include <mm/page.h> 31 #include <arch/mm/page.h> 31 32 #include <mm/frame.h> 32 33 #include <mm/heap.h> … … 40 41 #include <debug.h> 41 42 #include <memstr.h> 43 #include <adt/hash_table.h> 44 45 static index_t hash(__native key[]); 46 static bool compare(__native key[], count_t keys, link_t *item); 47 static void remove_callback(link_t *item); 48 49 static void ht_mapping_insert(as_t *as, __address page, __address frame, int flags); 50 static pte_t *ht_mapping_find(as_t *as, __address page); 42 51 43 52 /** … … 47 56 48 57 /** 49 * Page hash table pointer.58 * Page hash table. 50 59 * The page hash table may be accessed only when page_ht_lock is held. 51 60 */ 52 pte_t *page_ht = NULL; 53 54 static void ht_mapping_insert(as_t *as, __address page, __address frame, int flags); 55 static pte_t *ht_mapping_find(as_t *as, __address page); 61 hash_table_t page_ht; 62 63 /** Hash table operations for page hash table. */ 64 hash_table_operations_t ht_operations = { 65 .hash = hash, 66 .compare = compare, 67 .remove_callback = remove_callback 68 }; 56 69 57 70 page_operations_t page_ht_operations = { … … 60 73 }; 61 74 75 /** Compute page hash table index. 76 * 77 * @param key Array of two keys (i.e. page and address space). 78 * 79 * @return Index into page hash table. 80 */ 81 index_t hash(__native key[]) 82 { 83 as_t *as = (as_t *) key[KEY_AS]; 84 __address page = (__address) key[KEY_PAGE]; 85 index_t index; 86 87 /* 88 * Virtual page addresses have roughly the same probability 89 * of occurring. Least significant bits of VPN compose the 90 * hash index. 91 */ 92 index = ((page >> PAGE_WIDTH) & (PAGE_HT_ENTRIES-1)); 93 94 /* 95 * Address space structures are likely to be allocated from 96 * similar addresses. Least significant bits compose the 97 * hash index. 98 */ 99 index |= ((__native) as) & (PAGE_HT_ENTRIES-1); 100 101 return index; 102 } 103 104 /** Compare page hash table item with page and/or address space. 105 * 106 * @param key Array of one or two keys (i.e. page and/or address space). 107 * @param keys Number of keys passed. 108 * @param item Item to compare the keys with. 109 * 110 * @return true on match, false otherwise. 111 */ 112 bool compare(__native key[], count_t keys, link_t *item) 113 { 114 pte_t *t; 115 116 ASSERT(item); 117 ASSERT((keys > 0) && (keys <= PAGE_HT_KEYS)); 118 119 /* 120 * Convert item to PTE. 121 */ 122 t = list_get_instance(item, pte_t, link); 123 124 if (keys == PAGE_HT_KEYS) { 125 return (key[KEY_AS] == (__address) t->as) && (key[KEY_PAGE] == t->page); 126 } else { 127 return (key[KEY_AS] == (__address) t->as); 128 } 129 } 130 131 /** Callback on page hash table item removal. 132 * 133 * @param item Page hash table item being removed. 134 */ 135 void remove_callback(link_t *item) 136 { 137 pte_t *t; 138 139 ASSERT(item); 140 141 /* 142 * Convert item to PTE. 143 */ 144 t = list_get_instance(item, pte_t, link); 145 146 free(t); 147 } 148 62 149 /** Map page to frame using page hash table. 63 150 * … … 74 161 void ht_mapping_insert(as_t *as, __address page, __address frame, int flags) 75 162 { 76 pte_t *t , *u;163 pte_t *t; 77 164 ipl_t ipl; 165 __native key[2] = { (__address) as, page }; 78 166 79 167 ipl = interrupts_disable(); 80 168 spinlock_lock(&page_ht_lock); 81 169 82 t = HT_HASH(page, as->asid); 83 if (!HT_SLOT_EMPTY(t)) { 84 85 /* 86 * The slot is occupied. 87 * Walk through the collision chain and append the mapping to its end. 88 */ 89 90 do { 91 u = t; 92 if (HT_COMPARE(page, as->asid, t)) { 93 /* 94 * Nothing to do, 95 * the record is already there. 96 */ 97 spinlock_unlock(&page_ht_lock); 98 interrupts_restore(ipl); 99 return; 100 } 101 } while ((t = HT_GET_NEXT(t))); 102 103 t = (pte_t *) malloc(sizeof(pte_t)); /* FIXME: use slab allocator for this */ 104 if (!t) 105 panic("could not allocate memory\n"); 106 107 HT_SET_NEXT(u, t); 170 if (!hash_table_find(&page_ht, key)) { 171 t = (pte_t *) malloc(sizeof(pte_t)); 172 ASSERT(t != NULL); 173 174 hash_table_insert(&page_ht, key, &t->link); 108 175 } 109 110 HT_SET_RECORD(t, page, as->asid, frame, flags);111 HT_SET_NEXT(t, NULL);112 176 113 177 spinlock_unlock(&page_ht_lock); … … 128 192 pte_t *ht_mapping_find(as_t *as, __address page) 129 193 { 130 pte_t *t; 194 link_t *hlp; 195 pte_t *t = NULL; 196 __native key[2] = { (__address) as, page }; 131 197 132 198 spinlock_lock(&page_ht_lock); 133 t = HT_HASH(page, as->asid); 134 if (!HT_SLOT_EMPTY(t)) { 135 while (!HT_COMPARE(page, as->asid, t) && HT_GET_NEXT(t)) 136 t = HT_GET_NEXT(t); 137 t = HT_COMPARE(page, as->asid, t) ? t : NULL; 138 } else { 139 t = NULL; 140 } 199 200 hlp = hash_table_find(&page_ht, key); 201 if (hlp) 202 t = list_get_instance(hlp, pte_t, link); 203 141 204 spinlock_unlock(&page_ht_lock); 142 205 return t; 143 206 } 144 145 /** Invalidate page hash table.146 *147 * Interrupts must be disabled.148 */149 void ht_invalidate_all(void)150 {151 pte_t *t, *u;152 int i;153 154 spinlock_lock(&page_ht_lock);155 for (i = 0; i < HT_ENTRIES; i++) {156 if (!HT_SLOT_EMPTY(&page_ht[i])) {157 t = HT_GET_NEXT(&page_ht[i]);158 while (t) {159 u = t;160 t = HT_GET_NEXT(t);161 free(u); /* FIXME: use slab allocator for this */162 }163 HT_INVALIDATE_SLOT(&page_ht[i]);164 }165 }166 spinlock_unlock(&page_ht_lock);167 } -
generic/include/adt/hash_table.h
r214f5bb rc7ec94a4 30 30 #define __HASH_TABLE_H__ 31 31 32 #include <adt/list.h> 32 33 #include <arch/types.h> 33 34 #include <typedefs.h> 34 #include <adt/list.h>35 35 36 36 /** Hash table structure. */ … … 54 54 /** Hash table item comparison function. 55 55 * 56 * @param key Array of keys that will be compared againstitem. It is not necessary to pass all keys.56 * @param key Array of keys that will be compared with item. It is not necessary to pass all keys. 57 57 * 58 58 * @return true if the keys match, false otherwise. … … 67 67 }; 68 68 69 #define hash_table_get_instance(item, type, member) list_get_instance((item), (type),(member))69 #define hash_table_get_instance(item,type,member) list_get_instance((item),(type),(member)) 70 70 71 71 extern void hash_table_create(hash_table_t *h, count_t m, count_t max_keys, hash_table_operations_t *op); 72 extern boolhash_table_insert(hash_table_t *h, __native key[], link_t *item);72 extern void hash_table_insert(hash_table_t *h, __native key[], link_t *item); 73 73 extern link_t *hash_table_find(hash_table_t *h, __native key[]); 74 74 extern void hash_table_remove(hash_table_t *h, __native key[], count_t keys); -
generic/src/adt/hash_table.c
r214f5bb rc7ec94a4 68 68 * @param hey Array of all keys necessary to compute hash index. 69 69 * @param item Item to be inserted into the hash table. 70 *71 * @return true on success, false if the keys were already present in the hash table.72 70 */ 73 boolhash_table_insert(hash_table_t *h, __native key[], link_t *item)71 void hash_table_insert(hash_table_t *h, __native key[], link_t *item) 74 72 { 75 73 index_t chain; … … 81 79 ASSERT(chain < h->entries); 82 80 83 if (hash_table_find(h, key)) {84 /*85 * The hash table is not redundant.86 * Signal failure on return.87 */88 return false;89 }90 91 81 list_append(item, &h->entry[chain]); 92 return true;93 82 } 94 83 -
generic/src/mm/as.c
r214f5bb rc7ec94a4 282 282 ipl = interrupts_disable(); 283 283 spinlock_lock(&as->lock); 284 ASSERT(as->page_table);285 284 SET_PTL0_ADDRESS(as->page_table); 286 285 spinlock_unlock(&as->lock);
Note:
See TracChangeset
for help on using the changeset viewer.