| [160] | 1 | ////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 2 | // File     : boot_handler.c | 
|---|
 | 3 | // Date     : 01/04/2012 | 
|---|
 | 4 | // Author   : alain greiner | 
|---|
 | 5 | // Copyright (c) UPMC-LIP6 | 
|---|
 | 6 | /////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 7 | // The boot_handler.h and boot_handler.c files are part of the GIET nano-kernel. | 
|---|
 | 8 | // This code can be used in the boot phase to build all the pages tables then jumps | 
|---|
 | 9 | // in to the seg_kernel_init segment with an activated MMU.  | 
|---|
 | 10 | // | 
|---|
 | 11 | // It uses the SoCLib generic MMU (paged virtual memory) to provide two services: | 
|---|
 | 12 | // | 
|---|
 | 13 | // 1) classical memory protection, when several independant applications compiled | 
|---|
 | 14 | //    in different virtual spaces are executing on the same hardware platform. | 
|---|
 | 15 | // 2) data placement in NUMA architectures, when we want to control the placement  | 
|---|
 | 16 | //    of the software objects (virtual segments) on the physical memory banks. | 
|---|
 | 17 | // | 
|---|
 | 18 | // It uses the MAPPING_INFO binary data structures, that must be pre-loaded in the  | 
|---|
 | 19 | // boot ROM in the seg_boot_mapping segment (at address seg_mapping_base). | 
|---|
 | 20 | // This MAPPING_INFO data structure defines both the hardware architecture, | 
|---|
 | 21 | // and the mapping: | 
|---|
 | 22 | // - number of clusters,  | 
|---|
 | 23 | // - number of processors in each cluster,  | 
|---|
 | 24 | // - physical segmentation of the physical address space,  | 
|---|
 | 25 | // - number of virtual spaces (one multi-task application per vspace),  | 
|---|
 | 26 | // - static placement of tasks on the processors,  | 
|---|
 | 27 | // - static placement of virtual segments (vseg) in the physical segments (pseg). | 
|---|
 | 28 | // - static placement of virtual objects (vobj) on virtual segments (vseg). | 
|---|
 | 29 | // | 
|---|
 | 30 | // The page table are statically constructed in the boot phase, and they do not  | 
|---|
 | 31 | // change during execution. The GIET uses only 4 Kbytes pages. | 
|---|
 | 32 | // As most applications use only a limited number of segments, the number of PT2s  | 
|---|
 | 33 | // actually used by a given virtual space is generally smaller than 2048, and is | 
|---|
 | 34 | // defined in the MAPPING_INFO_BINARY data structure(using the length field).  | 
|---|
 | 35 | // The value is calculated and put in _max_pte2 indexed by the vspace_id. | 
|---|
 | 36 | // The physical alignment constraints, is ensured by the align flag in the MAPPING_INFO  | 
|---|
 | 37 | // structure. | 
|---|
 | 38 | // The max number of virtual spaces (GIET_NB_VSPACE_MAX) is a configuration parameter. | 
|---|
 | 39 | // | 
|---|
 | 40 | // Each page table (one page table per virtual space) is monolithic: | 
|---|
 | 41 | // - a first 8K aligned PT1[2148] array, indexed by the (ix1) field of VPN.  | 
|---|
 | 42 | //   The PT1 contains 2048 PTD of 4 bytes => 8K bytes. | 
|---|
 | 43 | // - an aray of array PT2[1024][_max_pte2[vspace_id]], indexed by | 
|---|
 | 44 | //   the (ix2) field of the VPN, and by the PT2 index (pt2_id). | 
|---|
 | 45 | //   Each PT2 contains 512 PTE2 of 8bytes => 4Kbytes * _max_pte2[vspace_id] | 
|---|
 | 46 | // The size of each page table is 8K + (_max_pte2[vspace_id])*4K bytes. | 
|---|
 | 47 | // All page tables must be stored in the seg_kernel_pt segment (at address | 
|---|
 | 48 | // seg_kernel_pt_base)  | 
|---|
 | 49 | //////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 50 |  | 
|---|
 | 51 | #include <mips32_registers.h> | 
|---|
 | 52 | #include <boot_handler.h> | 
|---|
 | 53 | #include <mapping_info.h> | 
|---|
 | 54 | #include <mwmr.h> | 
|---|
 | 55 |  | 
|---|
 | 56 | #include <stdarg.h> | 
|---|
 | 57 |  | 
|---|
 | 58 |  | 
|---|
 | 59 | #if !defined(GIET_NB_VSPACE_MAX)  | 
|---|
 | 60 | # error The GIET_NB_VSPACE_MAX value must be defined in the 'giet_config.h' file ! | 
|---|
 | 61 | #endif | 
|---|
 | 62 |  | 
|---|
 | 63 | //////////////////////////////////////////////////////////////////////////// | 
|---|
 | 64 | //  Global variables | 
|---|
 | 65 | //////////////////////////////////////////////////////////////////////////// | 
|---|
 | 66 |  | 
|---|
 | 67 | // Page Tables  | 
|---|
 | 68 | // Next free PT2 index  | 
|---|
 | 69 | unsigned int  _next_free_pt2[GIET_NB_VSPACE_MAX] = | 
|---|
 | 70 |                          { [0 ... GIET_NB_VSPACE_MAX-1] = 0 }; | 
|---|
 | 71 |  | 
|---|
 | 72 | // Max PT2 index  | 
|---|
 | 73 | unsigned int  _max_pte2[GIET_NB_VSPACE_MAX] = | 
|---|
 | 74 |                          { [0 ... GIET_NB_VSPACE_MAX-1] = 0 }; | 
|---|
 | 75 |  | 
|---|
| [162] | 76 | // Page table pointers | 
|---|
| [160] | 77 | page_table_t* _ptabs[GIET_NB_VSPACE_MAX]; | 
|---|
 | 78 |  | 
|---|
 | 79 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 80 | // boot_procid()  | 
|---|
 | 81 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 82 | unsigned int boot_procid() | 
|---|
 | 83 | { | 
|---|
 | 84 |     unsigned int ret; | 
|---|
 | 85 |     asm volatile("mfc0 %0, $15, 1" : "=r"(ret)); | 
|---|
 | 86 |     return (ret & 0x3FF); | 
|---|
 | 87 | } | 
|---|
 | 88 |  | 
|---|
 | 89 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 90 | // boot_time()  | 
|---|
 | 91 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 92 | unsigned int boot_time() | 
|---|
 | 93 | { | 
|---|
 | 94 |     unsigned int ret; | 
|---|
 | 95 |     asm volatile("mfc0 %0, $9" : "=r"(ret)); | 
|---|
 | 96 |     return ret; | 
|---|
 | 97 | } | 
|---|
 | 98 |  | 
|---|
 | 99 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 100 | // boot_exit()  | 
|---|
 | 101 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 102 | void boot_exit() | 
|---|
 | 103 | { | 
|---|
 | 104 |     while(1) asm volatile("nop"); | 
|---|
 | 105 | } | 
|---|
 | 106 |  | 
|---|
 | 107 |  | 
|---|
 | 108 | //////////////////////////////////////////////////////////////////////////// | 
|---|
 | 109 | // boot_tty_puts() | 
|---|
 | 110 | // (it uses TTY0) | 
|---|
 | 111 | //////////////////////////////////////////////////////////////////////////// | 
|---|
 | 112 | void boot_tty_puts(const char *buffer)  | 
|---|
 | 113 | { | 
|---|
 | 114 |     unsigned int* tty_address = (unsigned int*)&seg_tty_base; | 
|---|
 | 115 |     unsigned int n; | 
|---|
 | 116 |  | 
|---|
 | 117 |     for ( n=0; n<100; n++) | 
|---|
 | 118 |     { | 
|---|
 | 119 |         if (buffer[n] == 0) break; | 
|---|
 | 120 |         tty_address[0] = (unsigned int)buffer[n]; | 
|---|
 | 121 |     } | 
|---|
 | 122 |      | 
|---|
 | 123 | }  | 
|---|
 | 124 |  | 
|---|
 | 125 | //////////////////////////////////////////////////////////////////////////// | 
|---|
 | 126 | // boot_tty_putw()  | 
|---|
 | 127 | // (it uses TTY0) | 
|---|
 | 128 | //////////////////////////////////////////////////////////////////////////// | 
|---|
 | 129 | void boot_tty_putw(unsigned int val) | 
|---|
 | 130 | { | 
|---|
 | 131 |     static const char   HexaTab[] = "0123456789ABCDEF"; | 
|---|
 | 132 |     char                buf[11]; | 
|---|
 | 133 |     unsigned int        c; | 
|---|
 | 134 |  | 
|---|
 | 135 |     buf[0]  = '0'; | 
|---|
 | 136 |     buf[1]  = 'x'; | 
|---|
 | 137 |     buf[10] = 0; | 
|---|
 | 138 |  | 
|---|
 | 139 |     for ( c = 0 ; c < 8 ; c++ ) | 
|---|
 | 140 |     {  | 
|---|
 | 141 |         buf[9-c] = HexaTab[val&0xF]; | 
|---|
 | 142 |         val = val >> 4; | 
|---|
 | 143 |     } | 
|---|
 | 144 |     boot_tty_puts(buf); | 
|---|
 | 145 | } | 
|---|
 | 146 |  | 
|---|
 | 147 | ///////////////////////////////////////////////////////////////////////////// | 
|---|
 | 148 | // various mapping_info data structure access functions | 
|---|
 | 149 | ///////////////////////////////////////////////////////////////////////////// | 
|---|
 | 150 | mapping_cluster_t* boot_get_cluster_base( mapping_header_t* header ) | 
|---|
 | 151 | { | 
|---|
 | 152 |     return   (mapping_cluster_t*) ((char*)header + | 
|---|
 | 153 |                                   MAPPING_HEADER_SIZE); | 
|---|
 | 154 | } | 
|---|
 | 155 | ///////////////////////////////////////////////////////////////////////////// | 
|---|
 | 156 | mapping_pseg_t* boot_get_pseg_base( mapping_header_t* header ) | 
|---|
 | 157 | { | 
|---|
 | 158 |     return   (mapping_pseg_t*)    ((char*)header + | 
|---|
 | 159 |                                   MAPPING_HEADER_SIZE + | 
|---|
 | 160 |                                   MAPPING_CLUSTER_SIZE*header->clusters); | 
|---|
 | 161 | } | 
|---|
 | 162 | ///////////////////////////////////////////////////////////////////////////// | 
|---|
 | 163 | mapping_vspace_t* boot_get_vspace_base( mapping_header_t* header ) | 
|---|
 | 164 | { | 
|---|
 | 165 |     return   (mapping_vspace_t*)  ((char*)header + | 
|---|
 | 166 |                                   MAPPING_HEADER_SIZE + | 
|---|
 | 167 |                                   MAPPING_CLUSTER_SIZE*header->clusters + | 
|---|
 | 168 |                                   MAPPING_PSEG_SIZE*header->psegs); | 
|---|
 | 169 | } | 
|---|
 | 170 | ///////////////////////////////////////////////////////////////////////////// | 
|---|
 | 171 | mapping_vseg_t* boot_get_vseg_base( mapping_header_t* header ) | 
|---|
 | 172 | { | 
|---|
 | 173 |     return   (mapping_vseg_t*)    ((char*)header + | 
|---|
 | 174 |                                   MAPPING_HEADER_SIZE + | 
|---|
 | 175 |                                   MAPPING_CLUSTER_SIZE*header->clusters + | 
|---|
 | 176 |                                   MAPPING_PSEG_SIZE*header->psegs + | 
|---|
 | 177 |                                   MAPPING_VSPACE_SIZE*header->vspaces); | 
|---|
 | 178 | } | 
|---|
 | 179 | ///////////////////////////////////////////////////////////////////////////// | 
|---|
 | 180 | mapping_vobj_t* boot_get_vobj_base( mapping_header_t* header ) | 
|---|
 | 181 | { | 
|---|
 | 182 |     return   (mapping_vobj_t*)   ((char*)header + | 
|---|
 | 183 |                                   MAPPING_HEADER_SIZE + | 
|---|
 | 184 |                                   MAPPING_CLUSTER_SIZE*header->clusters + | 
|---|
 | 185 |                                   MAPPING_PSEG_SIZE*header->psegs + | 
|---|
 | 186 |                                   MAPPING_VSPACE_SIZE*header->vspaces + | 
|---|
 | 187 |                                   MAPPING_VSEG_SIZE*header->vsegs ); | 
|---|
 | 188 | } | 
|---|
 | 189 | ///////////////////////////////////////////////////////////////////////////// | 
|---|
 | 190 | mapping_task_t* boot_get_task_base( mapping_header_t* header ) | 
|---|
 | 191 | { | 
|---|
 | 192 |     return   (mapping_task_t*)    ((char*)header + | 
|---|
 | 193 |                                   MAPPING_HEADER_SIZE + | 
|---|
 | 194 |                                   MAPPING_CLUSTER_SIZE*header->clusters + | 
|---|
 | 195 |                                   MAPPING_PSEG_SIZE*header->psegs + | 
|---|
 | 196 |                                   MAPPING_VSPACE_SIZE*header->vspaces + | 
|---|
 | 197 |                                   MAPPING_VOBJ_SIZE*header->vobjs + | 
|---|
 | 198 |                                   MAPPING_VSEG_SIZE*header->vsegs); | 
|---|
 | 199 | } | 
|---|
 | 200 |  | 
|---|
 | 201 | ///////////////////////////////////////////////////////////////////////////// | 
|---|
 | 202 | // print the content of the mapping_info data structure  | 
|---|
 | 203 | //////////////////////////////////////////////////////////////////////// | 
|---|
 | 204 | #if BOOT_DEBUG_VIEW | 
|---|
 | 205 | void boot_print_mapping_info() | 
|---|
 | 206 | { | 
|---|
 | 207 |     mapping_header_t*   header = (mapping_header_t*)&seg_mapping_base;  | 
|---|
 | 208 |      | 
|---|
 | 209 |     unsigned int                vspace_id; | 
|---|
 | 210 |     unsigned int                cluster_id; | 
|---|
 | 211 |     unsigned int                pseg_id; | 
|---|
 | 212 |     unsigned int                vseg_id; | 
|---|
 | 213 |     unsigned int                vobj_id; | 
|---|
 | 214 |     unsigned int                task_id; | 
|---|
 | 215 |  | 
|---|
 | 216 |     mapping_cluster_t*  cluster = boot_get_cluster_base( header ); | 
|---|
 | 217 |     mapping_pseg_t*         pseg    = boot_get_pseg_base( header );; | 
|---|
 | 218 |     mapping_vspace_t*   vspace  = boot_get_vspace_base ( header );; | 
|---|
 | 219 |     mapping_vseg_t*         vseg    = boot_get_vseg_base ( header ); | 
|---|
 | 220 |     mapping_task_t*         task    = boot_get_task_base ( header );; | 
|---|
 | 221 |     mapping_vobj_t*    vobj   = boot_get_vobj_base( header ); | 
|---|
 | 222 |  | 
|---|
 | 223 |     // header | 
|---|
 | 224 |     boot_tty_puts("mapping_info"); | 
|---|
 | 225 |  | 
|---|
 | 226 |     boot_tty_puts("\n - signature = "); | 
|---|
 | 227 |     boot_tty_putw(header->signature); | 
|---|
 | 228 |     boot_tty_puts("\n - name      = "); | 
|---|
 | 229 |     boot_tty_puts(header->name); | 
|---|
 | 230 |     boot_tty_puts("\n - clusters  = "); | 
|---|
 | 231 |     boot_tty_putw(header->clusters); | 
|---|
 | 232 |     boot_tty_puts("\n - psegs     = "); | 
|---|
 | 233 |     boot_tty_putw(header->psegs); | 
|---|
 | 234 |     boot_tty_puts("\n - ttys      = "); | 
|---|
 | 235 |     boot_tty_putw(header->ttys); | 
|---|
 | 236 |     boot_tty_puts("\n - vspaces   = "); | 
|---|
 | 237 |     boot_tty_putw(header->vspaces); | 
|---|
 | 238 |     boot_tty_puts("\n - globals   = "); | 
|---|
 | 239 |     boot_tty_putw(header->globals); | 
|---|
 | 240 |     boot_tty_puts("\n - vsegs     = "); | 
|---|
 | 241 |     boot_tty_putw(header->vsegs); | 
|---|
 | 242 |     boot_tty_puts("\n - tasks     = "); | 
|---|
 | 243 |     boot_tty_putw(header->tasks); | 
|---|
 | 244 |     boot_tty_puts("\n\n"); | 
|---|
 | 245 |  | 
|---|
 | 246 |     // clusters | 
|---|
 | 247 |     for ( cluster_id = 0 ; cluster_id < header->clusters ; cluster_id++ ) | 
|---|
 | 248 |     { | 
|---|
 | 249 |         boot_tty_puts("cluster "); | 
|---|
 | 250 |         boot_tty_putw(cluster_id); | 
|---|
 | 251 |  | 
|---|
 | 252 |         boot_tty_puts("\n - procs  = "); | 
|---|
 | 253 |         boot_tty_putw(cluster[cluster_id].procs); | 
|---|
 | 254 |         boot_tty_puts("\n - timers = "); | 
|---|
 | 255 |         boot_tty_putw(cluster[cluster_id].timers); | 
|---|
 | 256 |         boot_tty_puts("\n - dmas   = "); | 
|---|
 | 257 |         boot_tty_putw(cluster[cluster_id].dmas); | 
|---|
 | 258 |         boot_tty_puts("\n\n"); | 
|---|
 | 259 |     } | 
|---|
 | 260 |  | 
|---|
 | 261 |     // psegs | 
|---|
 | 262 |     for ( pseg_id = 0 ; pseg_id < header->psegs ; pseg_id++ ) | 
|---|
 | 263 |     { | 
|---|
 | 264 |         boot_tty_puts("pseg "); | 
|---|
 | 265 |         boot_tty_putw(pseg_id); | 
|---|
 | 266 |  | 
|---|
 | 267 |         boot_tty_puts("\n - name   = "); | 
|---|
 | 268 |         boot_tty_puts( pseg[pseg_id].name ); | 
|---|
 | 269 |         boot_tty_puts("\n - base   = "); | 
|---|
 | 270 |         boot_tty_putw( pseg[pseg_id].base ); | 
|---|
 | 271 |         boot_tty_puts("\n - length = "); | 
|---|
 | 272 |         boot_tty_putw( pseg[pseg_id].length ); | 
|---|
 | 273 |         boot_tty_puts("\n\n"); | 
|---|
 | 274 |     } | 
|---|
 | 275 |  | 
|---|
 | 276 |     // globals | 
|---|
 | 277 |     for ( vseg_id = 0 ; vseg_id < header->globals ; vseg_id++ ) | 
|---|
 | 278 |     { | 
|---|
 | 279 |         boot_tty_puts("global vseg "); | 
|---|
 | 280 |         boot_tty_putw(vseg_id); | 
|---|
 | 281 |  | 
|---|
 | 282 |         boot_tty_puts("\n - name   = "); | 
|---|
 | 283 |         boot_tty_puts( vseg[vseg_id].name ); | 
|---|
 | 284 |         boot_tty_puts("\n - vbase  = "); | 
|---|
 | 285 |         boot_tty_putw( vseg[vseg_id].vbase ); | 
|---|
 | 286 |         boot_tty_puts("\n - length = "); | 
|---|
 | 287 |         boot_tty_putw( vseg[vseg_id].length ); | 
|---|
 | 288 |         boot_tty_puts("\n - mode   = "); | 
|---|
 | 289 |         boot_tty_putw( vseg[vseg_id].mode ); | 
|---|
 | 290 |         boot_tty_puts("\n - ident = "); | 
|---|
 | 291 |         boot_tty_putw( vseg[vseg_id].ident ); | 
|---|
 | 292 |         boot_tty_puts("\n - psegname = "); | 
|---|
 | 293 |         boot_tty_puts( pseg[vseg[vseg_id].psegid].name ); | 
|---|
 | 294 |         boot_tty_puts("\n"); | 
|---|
 | 295 |         for ( vobj_id = vseg[vseg_id].vobj_offset ; vobj_id < vseg[vseg_id].vobj_offset + vseg[vseg_id].vobjs ; vobj_id++ ) | 
|---|
 | 296 |         { | 
|---|
 | 297 |                         boot_tty_puts("vobjs: \n"); | 
|---|
 | 298 |             boot_tty_putw( vobj[vobj_id].name); | 
|---|
 | 299 |             boot_tty_puts("\n"); | 
|---|
 | 300 |             boot_tty_puts("\t name     = "); | 
|---|
 | 301 |                         boot_tty_putw(  vobj[vobj_id].name); | 
|---|
 | 302 |                         boot_tty_puts("\n"); | 
|---|
 | 303 |             boot_tty_puts("\t type     = "); | 
|---|
 | 304 |                         boot_tty_putw( vobj[vobj_id].type); | 
|---|
 | 305 |                         boot_tty_puts("\n"); | 
|---|
 | 306 |             boot_tty_puts("\t length   = "); | 
|---|
 | 307 |                         boot_tty_putw(   vobj[vobj_id].length); | 
|---|
 | 308 |                         boot_tty_puts("\n"); | 
|---|
 | 309 |             boot_tty_puts("\t align    = "); | 
|---|
 | 310 |                         boot_tty_putw(   vobj[vobj_id].align); | 
|---|
 | 311 |                         boot_tty_puts("\n"); | 
|---|
 | 312 |             boot_tty_puts("\t binpath  = "); | 
|---|
 | 313 |                         boot_tty_putw(   vobj[vobj_id].binpath); | 
|---|
 | 314 |                         boot_tty_puts("\n\n"); | 
|---|
 | 315 |         } | 
|---|
 | 316 |     } | 
|---|
 | 317 |  | 
|---|
 | 318 |     // vspaces | 
|---|
 | 319 |     for ( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ ) | 
|---|
 | 320 |     { | 
|---|
 | 321 |         unsigned int func_id = vspace[vspace_id].vobj_offset + vspace[vspace_id].funcs_offset;  | 
|---|
 | 322 |         boot_tty_puts("vspace "); | 
|---|
 | 323 |         boot_tty_putw(vspace_id); | 
|---|
 | 324 |  | 
|---|
 | 325 |         boot_tty_puts("\n - name    = "); | 
|---|
 | 326 |         boot_tty_puts( vspace[vspace_id].name );  | 
|---|
 | 327 |         boot_tty_puts("\n - funcs    = "); | 
|---|
 | 328 |         boot_tty_puts( vobj[func_id].name );  | 
|---|
 | 329 |         boot_tty_puts( vspace[vspace_id].name );  | 
|---|
 | 330 |         boot_tty_puts("\n - ttys    = "); | 
|---|
 | 331 |         boot_tty_putw( vspace[vspace_id].ttys ); | 
|---|
 | 332 |         boot_tty_puts("\n\n"); | 
|---|
 | 333 |  | 
|---|
 | 334 |         for ( vseg_id = vspace[vspace_id].vseg_offset ;  | 
|---|
 | 335 |               vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs) ;  | 
|---|
 | 336 |               vseg_id++ ) | 
|---|
 | 337 |         { | 
|---|
 | 338 |             boot_tty_puts("    private vseg "); | 
|---|
 | 339 |             boot_tty_putw( vseg_id ); | 
|---|
 | 340 |  | 
|---|
 | 341 |             boot_tty_puts("\n    - name   = "); | 
|---|
 | 342 |             boot_tty_puts( vseg[vseg_id].name ); | 
|---|
 | 343 |             boot_tty_puts("\n    - vbase  = "); | 
|---|
 | 344 |             boot_tty_putw( vseg[vseg_id].vbase ); | 
|---|
 | 345 |             boot_tty_puts("\n    - length = "); | 
|---|
 | 346 |             boot_tty_putw( vseg[vseg_id].length ); | 
|---|
 | 347 |             boot_tty_puts("\n    - mode   = "); | 
|---|
 | 348 |             boot_tty_putw( vseg[vseg_id].mode ); | 
|---|
 | 349 |             boot_tty_puts("\n    - ident = "); | 
|---|
 | 350 |             boot_tty_putw( vseg[vseg_id].ident ); | 
|---|
 | 351 |             boot_tty_puts("\n    - psegname = "); | 
|---|
 | 352 |             boot_tty_puts( pseg[vseg[vseg_id].psegid].name ); | 
|---|
 | 353 |             boot_tty_puts("\n"); | 
|---|
 | 354 |             for ( vobj_id = vseg[vseg_id].vobj_offset ; vobj_id < vseg[vseg_id].vobj_offset + vseg[vseg_id].vobjs ; vobj_id++ ) | 
|---|
 | 355 |             { | 
|---|
 | 356 |                 boot_tty_puts("\t\t vobjs     = "); | 
|---|
 | 357 |                                 boot_tty_putw(     vobj[vobj_id].name); | 
|---|
 | 358 |                                 boot_tty_puts("\n"); | 
|---|
 | 359 |                 boot_tty_puts("\t\t name     = "); | 
|---|
 | 360 |                                 boot_tty_putw(     vobj[vobj_id].name); | 
|---|
 | 361 |                                 boot_tty_puts("\n"); | 
|---|
 | 362 |                 boot_tty_puts("\t\t type     = "); | 
|---|
 | 363 |                                 boot_tty_putw( vobj[vobj_id].type); | 
|---|
 | 364 |                                 boot_tty_puts("\n"); | 
|---|
 | 365 |                 boot_tty_puts("\t\t length   = "); | 
|---|
 | 366 |                                 boot_tty_putw(   vobj[vobj_id].length); | 
|---|
 | 367 |                                 boot_tty_puts("\n"); | 
|---|
 | 368 |                 boot_tty_puts("\t\t align    = "); | 
|---|
 | 369 |                                 boot_tty_putw(   vobj[vobj_id].align); | 
|---|
 | 370 |                                 boot_tty_puts("\n"); | 
|---|
 | 371 |                 boot_tty_puts("\t\t binpath  = "); | 
|---|
 | 372 |                                 boot_tty_putw(   vobj[vobj_id].binpath); | 
|---|
 | 373 |                                 boot_tty_puts("\n"); | 
|---|
 | 374 |             } | 
|---|
 | 375 |         } | 
|---|
 | 376 |  | 
|---|
 | 377 |         for ( task_id = vspace[vspace_id].vseg_offset ;  | 
|---|
 | 378 |               task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks) ;  | 
|---|
 | 379 |               task_id++ ) | 
|---|
 | 380 |         { | 
|---|
 | 381 |             boot_tty_puts("     task"); | 
|---|
 | 382 |             boot_tty_putw( task_id ); | 
|---|
 | 383 |  | 
|---|
 | 384 |             boot_tty_puts("\n     - name = "); | 
|---|
 | 385 |             boot_tty_puts( task[task_id].name ); | 
|---|
 | 386 |             boot_tty_puts("\n     - clusterid = "); | 
|---|
 | 387 |             boot_tty_putw( task[task_id].clusterid ); | 
|---|
 | 388 |             boot_tty_puts("\n     - proclocid = "); | 
|---|
 | 389 |             boot_tty_putw( task[task_id].proclocid ); | 
|---|
 | 390 |             boot_tty_puts("\n     - vobjlocid = "); | 
|---|
 | 391 |             boot_tty_putw( task[task_id].vobjlocid ); | 
|---|
 | 392 |             boot_tty_puts("\n     - startid   = "); | 
|---|
 | 393 |             boot_tty_putw( task[task_id].startid ); | 
|---|
 | 394 |             boot_tty_puts("\n     - ttylocid  = "); | 
|---|
 | 395 |             boot_tty_putw( task[task_id].ttylocid ); | 
|---|
 | 396 |             boot_tty_puts("\n\n"); | 
|---|
 | 397 |         } | 
|---|
 | 398 |     } | 
|---|
 | 399 | } // end boot_print_mapping_info() | 
|---|
 | 400 | #endif | 
|---|
 | 401 |  | 
|---|
 | 402 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 403 | // boot_pseg_get()  | 
|---|
 | 404 | // This function returns the pointer on a physical segment | 
|---|
 | 405 | // identified  by the segment index. | 
|---|
 | 406 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 407 | mapping_pseg_t* boot_pseg_get( unsigned int seg_id) | 
|---|
 | 408 | { | 
|---|
 | 409 |     mapping_header_t* header = (mapping_header_t*)&seg_mapping_base; | 
|---|
 | 410 |     mapping_pseg_t*   pseg   = boot_get_pseg_base( header ); | 
|---|
 | 411 |  | 
|---|
 | 412 |     // checking argument | 
|---|
 | 413 |     if ( seg_id >= header->psegs ) | 
|---|
 | 414 |     { | 
|---|
 | 415 |         boot_tty_puts("\n[BOOT ERROR] : seg_id argument too large\n"); | 
|---|
 | 416 |         boot_tty_puts("               in function boot_pseg_get()\n"); | 
|---|
 | 417 |         boot_exit(); | 
|---|
 | 418 |     } | 
|---|
 | 419 |  | 
|---|
 | 420 |     return &pseg[seg_id];                                     | 
|---|
 | 421 | } // end boot_pseg_get() | 
|---|
 | 422 |  | 
|---|
 | 423 |  | 
|---|
 | 424 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 425 | // boot_add_pte()  | 
|---|
 | 426 | // This function registers a new PTE in the page table pointed | 
|---|
 | 427 | // by the vspace_id argument, and updates both PT1 and PT2. | 
|---|
 | 428 | // A new PT2 is used when required. | 
|---|
 | 429 | // As the set of PT2s is implemented as a fixed size array (no dynamic  | 
|---|
 | 430 | // allocation), this function checks a possible overflow of the PT2 array. | 
|---|
| [163] | 431 | // | 
|---|
 | 432 | // The parametre global is a boolean taht indicate wether a global vseg is | 
|---|
 | 433 | // being mapped. | 
|---|
| [160] | 434 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 435 | void boot_add_pte( unsigned int    vspace_id,     | 
|---|
| [163] | 436 |                    unsigned int    vpn,            | 
|---|
 | 437 |                    unsigned int    flags, | 
|---|
 | 438 |                    unsigned int    ppn, | 
|---|
 | 439 |                    unsigned char   global ) | 
|---|
| [160] | 440 | { | 
|---|
 | 441 |     unsigned int    ix1; | 
|---|
 | 442 |     unsigned int    ix2; | 
|---|
 | 443 |     unsigned int    ptba;       // PT2 base address | 
|---|
 | 444 |     unsigned int    pt2_id;     // PT2 index | 
|---|
 | 445 |     unsigned int*   pt_flags;   // pointer on the pte_flags = &PT2[2*ix2]     | 
|---|
 | 446 |     unsigned int*   pt_ppn;     // pointer on the pte_ppn   = &PT2[2*ix2+1]   | 
|---|
 | 447 |  | 
|---|
 | 448 |     ix1 = vpn >> 9;             // 11 bits | 
|---|
 | 449 |     ix2 = vpn  & 0x1FF;         //  9 bits | 
|---|
 | 450 |  | 
|---|
 | 451 |          | 
|---|
 | 452 |     unsigned int max_pte2   = _max_pte2[vspace_id]; | 
|---|
 | 453 |     if(max_pte2 == 0) | 
|---|
 | 454 |     { | 
|---|
 | 455 |         boot_tty_puts("Unfound page table for vspace "); | 
|---|
 | 456 |         boot_tty_putw(vspace_id); | 
|---|
 | 457 |         boot_tty_puts("\n"); | 
|---|
 | 458 |         boot_exit(); | 
|---|
 | 459 |     } | 
|---|
 | 460 |  | 
|---|
 | 461 |     page_table_t* pt    = (page_table_t *)_ptabs[vspace_id]; | 
|---|
 | 462 |     if ( (pt->pt1[ix1] & PTE_V) == 0 )   // set a new PTD in PT1  | 
|---|
 | 463 |     { | 
|---|
 | 464 |         pt2_id = _next_free_pt2[vspace_id]; | 
|---|
 | 465 |         if ( pt2_id == max_pte2 ) | 
|---|
 | 466 |         { | 
|---|
 | 467 |             boot_tty_puts("\n[BOOT ERROR] in boot_add_pte() function\n"); | 
|---|
 | 468 |             boot_tty_puts("the length of the ptab vobj is too small\n");  | 
|---|
 | 469 |             boot_exit(); | 
|---|
 | 470 |         } | 
|---|
 | 471 |         else | 
|---|
 | 472 |         { | 
|---|
 | 473 |             ptba = (unsigned int)pt + PT1_SIZE + PT2_SIZE*pt2_id; | 
|---|
 | 474 |             pt->pt1[ix1] = PTE_V | PTE_T | (ptba >> 12);     | 
|---|
 | 475 |             _next_free_pt2[vspace_id] = pt2_id + 1; | 
|---|
 | 476 |         } | 
|---|
 | 477 |     } | 
|---|
 | 478 |     else | 
|---|
 | 479 |     { | 
|---|
 | 480 |         ptba = pt->pt1[ix1] << 12; | 
|---|
 | 481 |     } | 
|---|
 | 482 |  | 
|---|
 | 483 |     // set PTE2 after checking double mapping error | 
|---|
 | 484 |     pt_flags = (unsigned int*)(ptba + 8*ix2); | 
|---|
 | 485 |     pt_ppn   = (unsigned int*)(ptba + 8*ix2 + 4); | 
|---|
 | 486 |  | 
|---|
 | 487 |     if ( ( *pt_flags & PTE_V) != 0 )    // page already mapped | 
|---|
 | 488 |     { | 
|---|
| [163] | 489 |         if(global) | 
|---|
 | 490 |         { | 
|---|
 | 491 |             boot_tty_puts("\n[BOOT ERROR] in boot_add_pte() function\n"); | 
|---|
 | 492 |             boot_tty_puts("page already mapped\n"); | 
|---|
 | 493 |             boot_exit(); | 
|---|
 | 494 |         }else | 
|---|
 | 495 |         { | 
|---|
 | 496 |             /** | 
|---|
 | 497 |              * The case where a global vseg is already mapped as private vseg of a | 
|---|
 | 498 |              * vspace_id. Typically used when a vseg is being replicated. | 
|---|
 | 499 |              */   | 
|---|
 | 500 |             boot_tty_puts("\n[BOOT] global PTE for vspace "); | 
|---|
 | 501 |             boot_tty_putw(vspace_id); | 
|---|
 | 502 |             boot_tty_puts(" already mapped, vpn = "); | 
|---|
 | 503 |             boot_tty_putw(vpn); | 
|---|
 | 504 |             boot_tty_puts("\n"); | 
|---|
 | 505 |             return; | 
|---|
 | 506 |         } | 
|---|
| [160] | 507 |     } | 
|---|
| [163] | 508 |  | 
|---|
 | 509 |     // set PTE2 | 
|---|
 | 510 |     *pt_flags = flags; | 
|---|
 | 511 |     *pt_ppn   = ppn; | 
|---|
 | 512 |  | 
|---|
| [160] | 513 | } // end boot_add_pte() | 
|---|
 | 514 |                  | 
|---|
 | 515 | ///////////////////////////////////////////////////////////////////// | 
|---|
 | 516 | // This function build the page table for a given vspace.  | 
|---|
 | 517 | // The physical base addresses for all vsegs (global and private) | 
|---|
 | 518 | // must have been previously computed. | 
|---|
 | 519 | // It initializes the MWMR channels. | 
|---|
 | 520 | ///////////////////////////////////////////////////////////////////// | 
|---|
 | 521 | void boot_vspace_pt_build( unsigned int vspace_id ) | 
|---|
 | 522 | { | 
|---|
 | 523 |     unsigned int    vseg_id; | 
|---|
 | 524 |     unsigned int    npages; | 
|---|
 | 525 |     unsigned int    ppn; | 
|---|
 | 526 |     unsigned int    vpn; | 
|---|
 | 527 |     unsigned int    flags; | 
|---|
 | 528 |     unsigned int    page_id; | 
|---|
 | 529 |  | 
|---|
 | 530 |     mapping_header_t*  header = (mapping_header_t*)&seg_mapping_base;   | 
|---|
 | 531 |     mapping_vspace_t*  vspace = boot_get_vspace_base( header ); | 
|---|
 | 532 |     mapping_vseg_t*    vseg   = boot_get_vseg_base( header ); | 
|---|
| [163] | 533 |      | 
|---|
 | 534 |     // private segments | 
|---|
 | 535 |     for ( vseg_id = vspace[vspace_id].vseg_offset ;  | 
|---|
 | 536 |           vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs) ;  | 
|---|
 | 537 |           vseg_id++ ) | 
|---|
| [160] | 538 |     { | 
|---|
 | 539 |         vpn       = vseg[vseg_id].vbase >> 12; | 
|---|
 | 540 |         ppn       = vseg[vseg_id].pbase >> 12; | 
|---|
 | 541 |         npages    = vseg[vseg_id].length >> 12; | 
|---|
 | 542 |         if ( (vseg[vseg_id].length & 0xFFF) != 0 ) npages++; | 
|---|
 | 543 |  | 
|---|
 | 544 |         flags = PTE_V; | 
|---|
 | 545 |         if ( vseg[vseg_id].mode & C_MODE_MASK )  flags = flags | PTE_C; | 
|---|
 | 546 |         if ( vseg[vseg_id].mode & X_MODE_MASK )  flags = flags | PTE_X; | 
|---|
 | 547 |         if ( vseg[vseg_id].mode & W_MODE_MASK )  flags = flags | PTE_W; | 
|---|
 | 548 |         if ( vseg[vseg_id].mode & U_MODE_MASK )  flags = flags | PTE_U; | 
|---|
 | 549 |  | 
|---|
 | 550 | #if BOOT_DEBUG_PT | 
|---|
 | 551 | boot_tty_puts("- vseg "); | 
|---|
 | 552 | boot_tty_puts( vseg[vseg_id].name ); | 
|---|
 | 553 | boot_tty_puts(" / flags = "); | 
|---|
 | 554 | boot_tty_putw( flags ); | 
|---|
 | 555 | boot_tty_puts("\n"); | 
|---|
 | 556 | #endif         | 
|---|
 | 557 |         // loop on 4K pages | 
|---|
 | 558 |         for ( page_id = 0 ; page_id < npages ; page_id++ ) | 
|---|
 | 559 |         { | 
|---|
 | 560 |             boot_add_pte( vspace_id, | 
|---|
 | 561 |                           vpn, | 
|---|
 | 562 |                           flags, | 
|---|
| [163] | 563 |                           ppn, | 
|---|
 | 564 |                           0 ); | 
|---|
| [160] | 565 |             vpn++; | 
|---|
 | 566 |             ppn++; | 
|---|
 | 567 |         } | 
|---|
 | 568 |     } | 
|---|
| [163] | 569 |  | 
|---|
 | 570 |     // global segments | 
|---|
 | 571 |     for ( vseg_id = 0 ; vseg_id < header->globals ; vseg_id++ ) | 
|---|
| [160] | 572 |     { | 
|---|
 | 573 |         vpn       = vseg[vseg_id].vbase >> 12; | 
|---|
 | 574 |         ppn       = vseg[vseg_id].pbase >> 12; | 
|---|
 | 575 |         npages    = vseg[vseg_id].length >> 12; | 
|---|
 | 576 |         if ( (vseg[vseg_id].length & 0xFFF) != 0 ) npages++; | 
|---|
 | 577 |  | 
|---|
 | 578 |         flags = PTE_V; | 
|---|
 | 579 |         if ( vseg[vseg_id].mode & C_MODE_MASK )  flags = flags | PTE_C; | 
|---|
 | 580 |         if ( vseg[vseg_id].mode & X_MODE_MASK )  flags = flags | PTE_X; | 
|---|
 | 581 |         if ( vseg[vseg_id].mode & W_MODE_MASK )  flags = flags | PTE_W; | 
|---|
 | 582 |         if ( vseg[vseg_id].mode & U_MODE_MASK )  flags = flags | PTE_U; | 
|---|
 | 583 |  | 
|---|
 | 584 | #if BOOT_DEBUG_PT | 
|---|
 | 585 | boot_tty_puts("- vseg "); | 
|---|
 | 586 | boot_tty_puts( vseg[vseg_id].name ); | 
|---|
 | 587 | boot_tty_puts(" / flags = "); | 
|---|
 | 588 | boot_tty_putw( flags ); | 
|---|
| [163] | 589 | boot_tty_puts(" / npages = "); | 
|---|
 | 590 | boot_tty_putw( npages ); | 
|---|
| [160] | 591 | boot_tty_puts("\n"); | 
|---|
 | 592 | #endif         | 
|---|
 | 593 |         // loop on 4K pages | 
|---|
 | 594 |         for ( page_id = 0 ; page_id < npages ; page_id++ ) | 
|---|
 | 595 |         { | 
|---|
 | 596 |             boot_add_pte( vspace_id, | 
|---|
 | 597 |                           vpn, | 
|---|
 | 598 |                           flags, | 
|---|
| [163] | 599 |                           ppn, | 
|---|
 | 600 |                           1 ); | 
|---|
| [160] | 601 |             vpn++; | 
|---|
 | 602 |             ppn++; | 
|---|
 | 603 |         } | 
|---|
 | 604 |     } | 
|---|
 | 605 |  | 
|---|
 | 606 | } // end boot_vspace_pt_build() | 
|---|
 | 607 |  | 
|---|
 | 608 |  | 
|---|
 | 609 | /////////////////////////////////////////////////////////////////////////// | 
|---|
 | 610 | // Align the value "toAlign" to the required alignement indicated by | 
|---|
 | 611 | // alignPow2 ( the logarithme of 2 the alignement). | 
|---|
 | 612 | /////////////////////////////////////////////////////////////////////////// | 
|---|
 | 613 | unsigned int align_to( unsigned toAlign, unsigned alignPow2) | 
|---|
 | 614 | { | 
|---|
 | 615 |     unsigned mask = (1 << alignPow2) - 1; | 
|---|
 | 616 |     return ((toAlign + mask ) & ~mask );//page aligned  | 
|---|
 | 617 | } | 
|---|
 | 618 |  | 
|---|
 | 619 | /////////////////////////////////////////////////////////////////////////// | 
|---|
 | 620 | // Initialise vobjs | 
|---|
| [162] | 621 | // For now only one type is initialised the: PTAB | 
|---|
 | 622 | // | 
|---|
| [160] | 623 | // param: | 
|---|
| [162] | 624 | //  vobj: the vobj to initialise | 
|---|
 | 625 | //  region_id: the vspace in wich the vobj is located or the global space(-1). | 
|---|
| [160] | 626 | /////////////////////////////////////////////////////////////////////////// | 
|---|
| [162] | 627 | void initailise_vobj(mapping_vobj_t* vobj, unsigned int region_id) | 
|---|
| [160] | 628 | { | 
|---|
 | 629 |     if(vobj->type == PTAB) | 
|---|
 | 630 |     { | 
|---|
 | 631 |         if(region_id == ((unsigned int) -1)) | 
|---|
 | 632 |         { | 
|---|
 | 633 |             boot_tty_puts( "No PTAB vobjs are allowed in the global region" ); | 
|---|
 | 634 |             boot_exit(); | 
|---|
 | 635 |         } | 
|---|
 | 636 |         if(vobj->length < (PT1_SIZE + PT2_SIZE) ) //at least one pt2 => ( max_pt2 >= 1) | 
|---|
 | 637 |         { | 
|---|
 | 638 |             boot_tty_puts("PTAB too small, minumum size is "); | 
|---|
 | 639 |             boot_tty_putw( PT1_SIZE + PT2_SIZE); | 
|---|
 | 640 |             boot_exit(); | 
|---|
 | 641 |         } | 
|---|
 | 642 |  | 
|---|
 | 643 |         _ptabs[region_id]        = (page_table_t*) vobj->paddr; | 
|---|
 | 644 |         _max_pte2[region_id]    = (vobj->length - PT1_SIZE) / PT2_SIZE; | 
|---|
 | 645 |  | 
|---|
| [163] | 646 | #if BOOT_DEBUG_VIEW | 
|---|
| [160] | 647 |         boot_tty_puts("ptabs for vspace "); | 
|---|
 | 648 |         boot_tty_putw(region_id); | 
|---|
| [163] | 649 |         boot_tty_puts(" address: "); | 
|---|
| [160] | 650 |         boot_tty_putw((unsigned)_ptabs[region_id]); | 
|---|
 | 651 |         boot_tty_puts("\n"); | 
|---|
| [163] | 652 | #endif | 
|---|
| [160] | 653 |     }  | 
|---|
 | 654 | } | 
|---|
 | 655 |  | 
|---|
 | 656 | /////////////////////////////////////////////////////////////////////////// | 
|---|
 | 657 | // This function compute the physical base address for a vseg | 
|---|
 | 658 | // as specified in the mapping info data structure. | 
|---|
 | 659 | // It updates the pbase field of the vseg. | 
|---|
 | 660 | // It updates the page allocator (nextfreepage field of the pseg), | 
|---|
 | 661 | // and checks a possible pseg overflow. | 
|---|
 | 662 | // region_id: the vspace in wich the vseg is located or the global space(-1). | 
|---|
 | 663 | /////////////////////////////////////////////////////////////////////////// | 
|---|
 | 664 | void boot_vseg_map( mapping_vseg_t* vseg, unsigned int region_id )  | 
|---|
 | 665 | { | 
|---|
 | 666 |     unsigned pages; | 
|---|
 | 667 |     unsigned vobj_id; | 
|---|
 | 668 |     unsigned cur_vaddr; | 
|---|
 | 669 |     unsigned cur_paddr; | 
|---|
 | 670 |     mapping_header_t*   header = (mapping_header_t*)&seg_mapping_base;   | 
|---|
 | 671 |     mapping_vobj_t*     vobj   = boot_get_vobj_base( header ); | 
|---|
 | 672 |   | 
|---|
 | 673 |     // get physical segment pointer | 
|---|
 | 674 |     mapping_pseg_t*  pseg = boot_pseg_get( vseg->psegid ); | 
|---|
 | 675 |  | 
|---|
 | 676 |     // compute physical base address | 
|---|
 | 677 |     if ( vseg->ident != 0 )            // identity mapping required | 
|---|
 | 678 |     { | 
|---|
 | 679 |         // check physical segment overflow   | 
|---|
 | 680 |         if ( (vseg->vbase < pseg->base) ||  | 
|---|
 | 681 |              ((vseg->vbase + vseg->length) > (pseg->base + pseg->length)) ) | 
|---|
 | 682 |         { | 
|---|
 | 683 |             boot_tty_puts("\n[BOOT ERROR] in boot_vseg_map() function\n"); | 
|---|
 | 684 |             boot_tty_puts("impossible identity mapping for virtual segment: "); | 
|---|
 | 685 |             boot_tty_puts( vseg->name );  | 
|---|
 | 686 |             boot_tty_puts("\n");  | 
|---|
 | 687 |             boot_exit(); | 
|---|
 | 688 |         } | 
|---|
 | 689 |         vseg->pbase = vseg->vbase; | 
|---|
 | 690 |     } | 
|---|
 | 691 |     else                                // unconstrained mapping | 
|---|
 | 692 |     { | 
|---|
 | 693 |         // check physical segment overflow | 
|---|
 | 694 |         if ( (vseg->vbase + vseg->length) > (pseg->base + pseg->length) ) | 
|---|
 | 695 |         { | 
|---|
 | 696 |             boot_tty_puts("\n[BOOT ERROR] in boot_vseg_map() function\n"); | 
|---|
 | 697 |             boot_tty_puts("physical segment "); | 
|---|
 | 698 |             boot_tty_puts( pseg->name );  | 
|---|
 | 699 |             boot_tty_puts(" is too small to map virtual segment"); | 
|---|
 | 700 |             boot_tty_puts( vseg->name );  | 
|---|
 | 701 |             boot_tty_puts("\n"); | 
|---|
 | 702 |             boot_exit(); | 
|---|
 | 703 |         } | 
|---|
 | 704 |         vseg->pbase = pseg->base + (pseg->next_free_page<<12); | 
|---|
 | 705 |     } | 
|---|
 | 706 |      | 
|---|
 | 707 |  | 
|---|
 | 708 |     //loop on vobj: | 
|---|
 | 709 |     // + to computes the length of the current vseg | 
|---|
 | 710 |     // + Align vobjs | 
|---|
| [162] | 711 |     // + Initialise the vobj | 
|---|
| [160] | 712 |     cur_vaddr = vseg->vbase; | 
|---|
 | 713 |     cur_paddr = vseg->pbase; | 
|---|
 | 714 |     for(vobj_id= vseg->vobj_offset; vobj_id < (vseg->vobj_offset + vseg->vobjs); vobj_id++) | 
|---|
 | 715 |     { | 
|---|
 | 716 |         if(vobj[vobj_id].align) | 
|---|
 | 717 |         { | 
|---|
 | 718 |             cur_paddr = align_to(cur_paddr, vobj[vobj_id].align); | 
|---|
 | 719 |         } | 
|---|
 | 720 |  | 
|---|
 | 721 |         //set vaddr/paddr | 
|---|
 | 722 |         vobj[vobj_id].vaddr = cur_vaddr;         | 
|---|
 | 723 |         vobj[vobj_id].paddr = cur_paddr;   | 
|---|
 | 724 |        | 
|---|
 | 725 |         //set next vaddr/paddr | 
|---|
 | 726 |         cur_vaddr += vobj[vobj_id].length; | 
|---|
 | 727 |         cur_paddr += vobj[vobj_id].length;  | 
|---|
| [162] | 728 |         initailise_vobj(&vobj[vobj_id], region_id); | 
|---|
| [160] | 729 |     }  | 
|---|
 | 730 |      | 
|---|
 | 731 |     //set the length | 
|---|
 | 732 |     vseg->length = align_to((cur_paddr - vseg->pbase), 12); | 
|---|
 | 733 |  | 
|---|
 | 734 |     // computes number of pages | 
|---|
 | 735 |     pages = vseg->length >> 12; | 
|---|
 | 736 |     if ( (vseg->length & 0xFFF) != 0 ) pages++; | 
|---|
 | 737 |  | 
|---|
 | 738 |     // set the next free physical address | 
|---|
 | 739 |     if ( vseg->ident != 0 ) | 
|---|
 | 740 |             ;            // nothing to do | 
|---|
 | 741 |     else                                 | 
|---|
 | 742 |         pseg->next_free_page = pseg->next_free_page + pages; | 
|---|
 | 743 |  | 
|---|
 | 744 | #if BOOT_DEBUG_PT | 
|---|
 | 745 | boot_tty_puts("- vseg "); | 
|---|
 | 746 | boot_tty_puts( vseg->name ); | 
|---|
 | 747 | boot_tty_puts(" : vbase = "); | 
|---|
 | 748 | boot_tty_putw( vseg->vbase ); | 
|---|
 | 749 | boot_tty_puts(" / pbase = "); | 
|---|
 | 750 | boot_tty_putw( vseg->pbase ); | 
|---|
 | 751 | boot_tty_puts("\n"); | 
|---|
 | 752 | #endif   | 
|---|
 | 753 |  | 
|---|
 | 754 | } // end boot_vseg_map() | 
|---|
 | 755 |  | 
|---|
 | 756 | ///////////////////////////////////////////////////////////////////// | 
|---|
 | 757 | // This function cheks the mapping_info data structure  | 
|---|
 | 758 | ///////////////////////////////////////////////////////////////////// | 
|---|
 | 759 | void boot_check_mapping() | 
|---|
 | 760 | { | 
|---|
 | 761 |     mapping_header_t*   header = (mapping_header_t*)&seg_mapping_base;   | 
|---|
 | 762 |  | 
|---|
 | 763 |     // checking mapping availability | 
|---|
 | 764 |     if ( header->signature != IN_MAPPING_SIGNATURE ) | 
|---|
 | 765 |     { | 
|---|
 | 766 |         boot_tty_puts("\n[BOOT ERROR] Illegal mapping signature: "); | 
|---|
 | 767 |         boot_tty_putw(header->signature); | 
|---|
 | 768 |         boot_tty_puts("\n"); | 
|---|
 | 769 |         boot_exit(); | 
|---|
 | 770 |     } | 
|---|
 | 771 |  | 
|---|
 | 772 | #if BOOT_DEBUG_VIEW | 
|---|
 | 773 | boot_print_mapping_info(); | 
|---|
 | 774 | #endif | 
|---|
 | 775 |  | 
|---|
 | 776 |     // checking double definition of NB_CLUSTERS | 
|---|
 | 777 |     if ( header->clusters != NB_CLUSTERS ) | 
|---|
 | 778 |     { | 
|---|
 | 779 |         boot_tty_puts("\n[BOOT ERROR] Incoherent NB_CLUSTERS"); | 
|---|
 | 780 |         boot_tty_puts("\n             - In giet_config,  value = "); | 
|---|
 | 781 |         boot_tty_putw ( NB_CLUSTERS ); | 
|---|
 | 782 |         boot_tty_puts("\n             - In mapping_info, value = "); | 
|---|
 | 783 |         boot_tty_putw ( header->clusters ); | 
|---|
 | 784 |         boot_tty_puts("\n"); | 
|---|
 | 785 |         boot_exit(); | 
|---|
 | 786 |     } | 
|---|
 | 787 |  | 
|---|
 | 788 |     // checking double definition of NB_TTYS | 
|---|
 | 789 |     if ( header->ttys != NB_TTYS ) | 
|---|
 | 790 |     { | 
|---|
 | 791 |         boot_tty_puts("\n[BOOT ERROR] Incoherent NB_TTYS"); | 
|---|
 | 792 |         boot_tty_puts("\n             - In giet_config,  value = "); | 
|---|
 | 793 |         boot_tty_putw ( NB_TTYS ); | 
|---|
 | 794 |         boot_tty_puts("\n             - In mapping_info, value = "); | 
|---|
 | 795 |         boot_tty_putw ( header->ttys ); | 
|---|
 | 796 |         boot_tty_puts("\n"); | 
|---|
 | 797 |         boot_exit(); | 
|---|
 | 798 |     } | 
|---|
 | 799 |  | 
|---|
 | 800 |     // number of virtual spaces no larger than GIET_NB_VSPACE_MAX | 
|---|
 | 801 |     if ( header->vspaces > GIET_NB_VSPACE_MAX ) | 
|---|
 | 802 |     { | 
|---|
 | 803 |         boot_tty_puts("\n[BOOT ERROR] : number of vspaces > GIET_NB_VSPACE_MAX\n"); | 
|---|
 | 804 |         boot_tty_puts("\n"); | 
|---|
 | 805 |         boot_exit(); | 
|---|
 | 806 |     } | 
|---|
 | 807 | } // end boot_check_mapping() | 
|---|
 | 808 |  | 
|---|
 | 809 | ///////////////////////////////////////////////////////////////////// | 
|---|
 | 810 | // This function builds the page tables for all virtual spaces  | 
|---|
 | 811 | // defined in the mapping_info data structure. | 
|---|
 | 812 | // For each virtual space, it maps both the global virtual segments  | 
|---|
 | 813 | // (replicated in all vspaces), and the private virtuals segments. | 
|---|
 | 814 | ///////////////////////////////////////////////////////////////////// | 
|---|
 | 815 | void boot_pt_init() | 
|---|
 | 816 | { | 
|---|
 | 817 |     mapping_header_t*   header = (mapping_header_t*)&seg_mapping_base;   | 
|---|
 | 818 |  | 
|---|
 | 819 |     mapping_vspace_t*   vspace = boot_get_vspace_base( header );      | 
|---|
 | 820 |     mapping_pseg_t*     pseg   = boot_get_pseg_base( header );  | 
|---|
 | 821 |     mapping_vseg_t*     vseg   = boot_get_vseg_base( header ); | 
|---|
 | 822 |  | 
|---|
 | 823 |     unsigned int        vspace_id;   | 
|---|
 | 824 |     unsigned int        vseg_id; | 
|---|
 | 825 |     unsigned int        pseg_id; | 
|---|
 | 826 |  | 
|---|
 | 827 |     // first loop on virtual spaces to map global vsegs | 
|---|
 | 828 |  | 
|---|
 | 829 | #if BOOT_DEBUG_PT | 
|---|
 | 830 | boot_tty_puts("\n******* mapping global vsegs ********"); | 
|---|
 | 831 | #endif | 
|---|
 | 832 |              | 
|---|
 | 833 |     // physical page allocators must be initialised ??? | 
|---|
 | 834 |     for ( pseg_id = 0 ; pseg_id < header->psegs ; pseg_id++ ) | 
|---|
 | 835 |     { | 
|---|
 | 836 |         pseg[pseg_id].next_free_page = 0; | 
|---|
 | 837 |     } | 
|---|
 | 838 |  | 
|---|
 | 839 |     for ( vseg_id = 0 ; vseg_id < header->globals ; vseg_id++ ) | 
|---|
 | 840 |     { | 
|---|
 | 841 |         boot_vseg_map( &vseg[vseg_id], ((unsigned int)(-1)) ); | 
|---|
 | 842 |     } | 
|---|
 | 843 |  | 
|---|
 | 844 |     // loop on virtual vspaces to map private vsegs | 
|---|
 | 845 |     for ( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ ) | 
|---|
 | 846 |     { | 
|---|
 | 847 |  | 
|---|
 | 848 | #if BOOT_DEBUG_PT | 
|---|
 | 849 | boot_tty_puts("\n******* mapping private vsegs in vspace "); | 
|---|
 | 850 | boot_tty_puts(vspace[vspace_id].name); | 
|---|
 | 851 | boot_tty_puts(" ********\n"); | 
|---|
 | 852 | #endif | 
|---|
 | 853 |              | 
|---|
 | 854 |         for ( vseg_id = vspace[vspace_id].vseg_offset ;  | 
|---|
 | 855 |               vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs) ;  | 
|---|
 | 856 |               vseg_id++ ) | 
|---|
 | 857 |         { | 
|---|
 | 858 |             boot_vseg_map( &vseg[vseg_id], vspace_id );  | 
|---|
 | 859 |         } | 
|---|
 | 860 |     }  | 
|---|
 | 861 |  | 
|---|
 | 862 |     // loop on the vspaces to build the page tables | 
|---|
 | 863 |     for ( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ ) | 
|---|
 | 864 |     { | 
|---|
 | 865 |  | 
|---|
 | 866 | #if BOOT_DEBUG_PT | 
|---|
 | 867 | boot_tty_puts("\n******* building page table for vspace "); | 
|---|
 | 868 | boot_tty_puts(vspace[vspace_id].name); | 
|---|
 | 869 | boot_tty_puts(" ********\n"); | 
|---|
 | 870 | #endif | 
|---|
 | 871 |              | 
|---|
 | 872 |         boot_vspace_pt_build( vspace_id ); | 
|---|
 | 873 |     }  | 
|---|
 | 874 | } // end boot_pt_init() | 
|---|
 | 875 |  | 
|---|
 | 876 |  | 
|---|
 | 877 |  | 
|---|
 | 878 | //////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 879 | // boot_init() | 
|---|
 | 880 | // This function is executed by one single processor to initialize the page | 
|---|
 | 881 | // tables, the tasks contexts and the peripherals, for all applications. | 
|---|
 | 882 | //////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 883 | void boot_init() | 
|---|
 | 884 | { | 
|---|
 | 885 |     // checking mapping_info | 
|---|
 | 886 |     boot_check_mapping(); | 
|---|
 | 887 |  | 
|---|
 | 888 |     // building page tables | 
|---|
 | 889 |     boot_pt_init(); | 
|---|
 | 890 |     boot_tty_puts("\n[BOOT] Page Tables completed at cycle "); | 
|---|
 | 891 |     boot_tty_putw( boot_time() ); | 
|---|
 | 892 |     boot_tty_puts("\n"); | 
|---|
 | 893 |  | 
|---|
 | 894 | } // end boot_init() | 
|---|
 | 895 |  | 
|---|
 | 896 | // Local Variables: | 
|---|
 | 897 | // tab-width: 4 | 
|---|
 | 898 | // c-basic-offset: 4 | 
|---|
 | 899 | // c-file-offsets:((innamespace . 0)(inline-open . 0)) | 
|---|
 | 900 | // indent-tabs-mode: nil | 
|---|
 | 901 | // End: | 
|---|
 | 902 | // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 | 
|---|
 | 903 |  | 
|---|