- Timestamp:
- Jul 7, 2017, 2:03:01 PM (7 years ago)
- Location:
- trunk/kernel/mm
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/mm/ppm.c
r53 r160 38 38 #include <ppm.h> 39 39 40 41 42 40 //////////////////////////////////////////////// 43 41 inline bool_t ppm_page_is_valid( page_t * page ) 44 42 { 45 43 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 46 44 uint32_t pgnr = (uint32_t)( page - ppm->pages_tbl ); 47 45 return (pgnr <= ppm->pages_nr); … … 49 47 50 48 51 52 49 ///////////////////////////////////////////// 53 50 inline void * ppm_page2vaddr( page_t * page ) … … 64 61 } 65 62 66 67 68 63 ////////////////////////////////////////// 69 64 inline ppn_t ppm_page2ppn( page_t * page ) 70 65 { 71 ppm_t * ppm 66 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 72 67 return (ppn_t)( page - ppm->pages_tbl ); 73 68 } … … 76 71 inline page_t * ppm_ppn2page( ppn_t ppn ) 77 72 { 78 ppm_t * ppm 73 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 79 74 return &ppm->pages_tbl[ppn]; 80 75 } 81 82 83 76 84 77 /////////////////////////////////////// … … 93 86 { 94 87 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 95 return ( (ppm->vaddr_base - vaddr) >> CONFIG_PPM_PAGE_SHIFT ); 96 } 97 88 return ( (ppm->vaddr_base - vaddr) >> CONFIG_PPM_PAGE_SHIFT ); 89 } 98 90 99 91 … … 107 99 uint32_t current_order; // current (merged) page order 108 100 109 110 111 112 101 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 102 page_t * pages_tbl = ppm->pages_tbl; 103 104 // update released page descriptor flags 113 105 page_set_flag( page , PG_FREE ); 114 106 115 116 117 118 119 107 // search the buddy page descriptor 108 // - merge with current page descriptor if found 109 // - exit to release the current page descriptor if not found 110 current = page , 111 current_index = (uint32_t)(page - ppm->pages_tbl); 120 112 for( current_order = page->order ; 121 122 123 113 current_order < CONFIG_PPM_MAX_ORDER ; 114 current_order++ ) 115 { 124 116 buddy_index = current_index ^ (1 << current_order); 125 117 buddy = pages_tbl + buddy_index; … … 127 119 if( !page_is_flag( buddy , PG_FREE ) || (buddy->order != current_order) ) break; 128 120 129 121 // remove buddy from free list 130 122 list_unlink( &buddy->list ); 131 123 ppm->free_pages_nr[current_order] --; 132 124 133 125 // merge buddy with current 134 126 buddy->order = 0; 135 127 current_index &= buddy_index; 136 128 } 137 129 138 130 // update merged page descriptor order 139 131 current = pages_tbl + current_index; 140 132 current->order = current_order; 141 133 142 134 // insert current in free list 143 135 list_add_first( &ppm->free_pages_root[current_order] , ¤t->list ); 144 136 ppm->free_pages_nr[current_order] ++; 145 146 } // end ppm_free_pages_nolock() 137 } 147 138 148 139 //////////////////////////////////////////// 149 140 page_t * ppm_alloc_pages( uint32_t order ) 150 141 { 151 142 uint32_t current_order; 152 143 page_t * remaining_block; 153 144 uint32_t current_size; 154 145 155 146 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 156 147 157 148 assert( (order < CONFIG_PPM_MAX_ORDER) , __FUNCTION__ , "illegal order argument" ); … … 159 150 page_t * block = NULL; 160 151 161 162 163 164 152 ppm_dmsg("\n[INFO] %s : enters / order = %d\n", 153 __FUNCTION__ , order ); 154 155 // take lock protecting free lists 165 156 spinlock_lock( &ppm->free_lock ); 166 157 167 158 // find a free block equal or larger to requested size 168 159 for( current_order = order ; current_order < CONFIG_PPM_MAX_ORDER ; current_order ++ ) 169 160 { … … 178 169 if( block == NULL ) // return failure 179 170 { 180 181 182 183 184 185 186 171 // release lock protecting free lists 172 spinlock_unlock( &ppm->free_lock ); 173 174 return NULL; 175 } 176 177 // update free-lists after removing a block 187 178 ppm->free_pages_nr[current_order] --; 188 179 current_size = (1 << current_order); 189 180 190 191 181 // split the removed block in smaller sub-blocks if required 182 // and update the free-lists accordingly 192 183 while( current_order > order ) 193 184 { … … 202 193 } 203 194 204 205 195 // update page descriptor 196 page_clear_flag( block , PG_FREE ); 206 197 page_refcount_up( block ); 207 198 block->order = order; 208 199 209 200 // release lock protecting free lists 210 201 spinlock_unlock( &ppm->free_lock ); 211 202 212 213 203 ppm_dmsg("\n[INFO] %s : base = %x / order = %d\n", 204 __FUNCTION__ , (uint32_t)ppm_page2base( block ) , order ); 214 205 215 206 return block; 216 } // end pmm_alloc-pages()207 } 217 208 218 209 … … 222 213 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 223 214 224 215 // get lock protecting free_pages[] array 225 216 spinlock_lock( &ppm->free_lock ); 226 217 227 218 ppm_free_pages_nolock( page ); 228 219 229 220 // release lock protecting free_pages[] array 230 221 spinlock_unlock( &ppm->free_lock ); 231 222 } … … 239 230 page_t * page; 240 231 241 232 // get lock protecting free lists 242 233 spinlock_lock( &ppm->free_lock ); 243 234 … … 248 239 { 249 240 printk("- order = %d / free_pages = %d [", 250 241 order , ppm->free_pages_nr[order] ); 251 242 252 243 LIST_FOREACH( &ppm->free_pages_root[order] , iter ) … … 259 250 } 260 251 261 252 // release lock protecting free lists 262 253 spinlock_unlock( &ppm->free_lock ); 263 264 } // end ppm_print() 254 } 265 255 266 256 /////////////////////////////////////// … … 279 269 page = LIST_ELEMENT( iter , page_t , list ); 280 270 281 if( page->order != order ) return -1; 271 if( page->order != order ) return -1; 282 272 } 283 273 } 284 274 285 return 0; 286 287 } // end ppm_assert_order() 288 275 return 0; 276 } 277 -
trunk/kernel/mm/ppm.h
r53 r160 48 48 * architecture specific bootloader. The reserved pages are defined in the boot_info 49 49 * structure. 50 * 50 * 51 51 * The main service provided by the PMM is the dynamic allocation of physical pages 52 52 * from the "kernel_heap" section. … … 64 64 spinlock_t dirty_lock; /*! lock protecting the dirty pages list */ 65 65 list_entry_t dirty_root; /*! root of dirty pages list */ 66 void * vaddr_base; /*! pointer on local physical memory base */ 66 void * vaddr_base; /*! pointer on local physical memory base */ 67 67 } 68 68 ppm_t;
Note: See TracChangeset
for help on using the changeset viewer.