| [1] | 1 | /* | 
|---|
|  | 2 | * vseg.c - virtual segment (vseg) related operations | 
|---|
|  | 3 | * | 
|---|
| [657] | 4 | * Authors   Alain Greiner (2016,2017,2018,2019,2020) | 
|---|
| [1] | 5 | * | 
|---|
|  | 6 | * Copyright (c) UPMC Sorbonne Universites | 
|---|
|  | 7 | * | 
|---|
|  | 8 | * This file is part of ALMOS-MKH. | 
|---|
|  | 9 | * | 
|---|
| [184] | 10 | * ALMOS-MKH is free software; you can redistribute it and/or modify it | 
|---|
| [1] | 11 | * under the terms of the GNU General Public License as published by | 
|---|
|  | 12 | * the Free Software Foundation; version 2.0 of the License. | 
|---|
|  | 13 | * | 
|---|
| [184] | 14 | * ALMOS-MKH is distributed in the hope that it will be useful, but | 
|---|
| [1] | 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
|  | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|---|
|  | 17 | * General Public License for more details. | 
|---|
|  | 18 | * | 
|---|
|  | 19 | * You should have received a copy of the GNU General Public License | 
|---|
| [184] | 20 | * along with ALMOS-MKH; if not, write to the Free Software Foundation, | 
|---|
| [1] | 21 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 
|---|
|  | 22 | */ | 
|---|
|  | 23 |  | 
|---|
| [457] | 24 | #include <hal_kernel_types.h> | 
|---|
| [1] | 25 | #include <hal_special.h> | 
|---|
|  | 26 | #include <hal_remote.h> | 
|---|
|  | 27 | #include <list.h> | 
|---|
|  | 28 | #include <errno.h> | 
|---|
|  | 29 | #include <printk.h> | 
|---|
|  | 30 | #include <bits.h> | 
|---|
|  | 31 | #include <thread.h> | 
|---|
|  | 32 | #include <process.h> | 
|---|
|  | 33 | #include <ppm.h> | 
|---|
|  | 34 | #include <mapper.h> | 
|---|
|  | 35 | #include <vfs.h> | 
|---|
|  | 36 | #include <page.h> | 
|---|
|  | 37 | #include <vmm.h> | 
|---|
|  | 38 | #include <kmem.h> | 
|---|
|  | 39 | #include <vseg.h> | 
|---|
|  | 40 |  | 
|---|
|  | 41 | //////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| [18] | 42 | //   global variables for display / must be consistent with enum in "vseg.h" | 
|---|
| [1] | 43 | //////////////////////////////////////////////////////////////////////////////////////// | 
|---|
|  | 44 |  | 
|---|
| [101] | 45 |  | 
|---|
|  | 46 | ////////////////////////////////////////// | 
|---|
| [184] | 47 | char * vseg_type_str( uint32_t vseg_type ) | 
|---|
| [1] | 48 | { | 
|---|
| [101] | 49 | if     ( vseg_type == VSEG_TYPE_CODE   ) return "CODE"; | 
|---|
|  | 50 | else if( vseg_type == VSEG_TYPE_DATA   ) return "DATA"; | 
|---|
| [407] | 51 | else if( vseg_type == VSEG_TYPE_STACK  ) return "STAK"; | 
|---|
| [101] | 52 | else if( vseg_type == VSEG_TYPE_ANON   ) return "ANON"; | 
|---|
|  | 53 | else if( vseg_type == VSEG_TYPE_FILE   ) return "FILE"; | 
|---|
| [407] | 54 | else if( vseg_type == VSEG_TYPE_REMOTE ) return "REMO"; | 
|---|
| [623] | 55 | else if( vseg_type == VSEG_TYPE_KCODE  ) return "KCOD"; | 
|---|
|  | 56 | else if( vseg_type == VSEG_TYPE_KDATA  ) return "KDAT"; | 
|---|
|  | 57 | else if( vseg_type == VSEG_TYPE_KDEV   ) return "KDEV"; | 
|---|
| [101] | 58 | else                                     return "undefined"; | 
|---|
|  | 59 | } | 
|---|
| [1] | 60 |  | 
|---|
| [625] | 61 | /////////////////////////// | 
|---|
| [503] | 62 | vseg_t * vseg_alloc( void ) | 
|---|
| [1] | 63 | { | 
|---|
|  | 64 | kmem_req_t   req; | 
|---|
|  | 65 |  | 
|---|
| [635] | 66 | req.type  = KMEM_KCM; | 
|---|
|  | 67 | req.order = bits_log2( sizeof(vseg_t) ); | 
|---|
|  | 68 | req.flags = AF_KERNEL | AF_ZERO; | 
|---|
| [1] | 69 |  | 
|---|
| [635] | 70 | return kmem_alloc( &req ); | 
|---|
| [1] | 71 | } | 
|---|
|  | 72 |  | 
|---|
|  | 73 | /////////////////////////////// | 
|---|
|  | 74 | void vseg_free( vseg_t * vseg ) | 
|---|
|  | 75 | { | 
|---|
|  | 76 | kmem_req_t  req; | 
|---|
|  | 77 |  | 
|---|
| [635] | 78 | req.type = KMEM_KCM; | 
|---|
| [1] | 79 | req.ptr  = vseg; | 
|---|
|  | 80 | kmem_free( &req ); | 
|---|
|  | 81 | } | 
|---|
|  | 82 |  | 
|---|
| [651] | 83 | ///////////////////////////////////////// | 
|---|
|  | 84 | void vseg_init_flags( vseg_t      * vseg, | 
|---|
|  | 85 | vseg_type_t   type ) | 
|---|
| [1] | 86 | { | 
|---|
|  | 87 | // set vseg flags depending on type | 
|---|
| [651] | 88 | if( type == VSEG_TYPE_CODE ) | 
|---|
| [1] | 89 | { | 
|---|
|  | 90 | vseg->flags = VSEG_USER    | | 
|---|
| [18] | 91 | VSEG_EXEC    | | 
|---|
| [1] | 92 | VSEG_CACHE   | | 
|---|
|  | 93 | VSEG_PRIVATE ; | 
|---|
|  | 94 | } | 
|---|
|  | 95 | else if( type == VSEG_TYPE_STACK ) | 
|---|
|  | 96 | { | 
|---|
|  | 97 | vseg->flags = VSEG_USER    | | 
|---|
|  | 98 | VSEG_WRITE   | | 
|---|
|  | 99 | VSEG_CACHE   | | 
|---|
| [18] | 100 | VSEG_PRIVATE ; | 
|---|
| [1] | 101 | } | 
|---|
| [18] | 102 | else if( type == VSEG_TYPE_DATA ) | 
|---|
| [1] | 103 | { | 
|---|
|  | 104 | vseg->flags = VSEG_USER    | | 
|---|
|  | 105 | VSEG_WRITE   | | 
|---|
| [18] | 106 | VSEG_CACHE   | | 
|---|
| [1] | 107 | VSEG_DISTRIB ; | 
|---|
|  | 108 | } | 
|---|
| [18] | 109 | else if( type == VSEG_TYPE_REMOTE ) | 
|---|
| [1] | 110 | { | 
|---|
|  | 111 | vseg->flags = VSEG_USER    | | 
|---|
| [18] | 112 | VSEG_WRITE   | | 
|---|
|  | 113 | VSEG_CACHE   ; | 
|---|
| [1] | 114 | } | 
|---|
| [18] | 115 | else if( type == VSEG_TYPE_ANON ) | 
|---|
| [1] | 116 | { | 
|---|
|  | 117 | vseg->flags = VSEG_USER    | | 
|---|
|  | 118 | VSEG_WRITE   | | 
|---|
| [407] | 119 | VSEG_CACHE; | 
|---|
| [1] | 120 | } | 
|---|
| [18] | 121 | else if( type == VSEG_TYPE_FILE ) | 
|---|
| [1] | 122 | { | 
|---|
|  | 123 | vseg->flags = VSEG_USER    | | 
|---|
|  | 124 | VSEG_WRITE   | | 
|---|
|  | 125 | VSEG_CACHE   ; | 
|---|
|  | 126 | } | 
|---|
| [623] | 127 | else if( type == VSEG_TYPE_KCODE ) | 
|---|
|  | 128 | { | 
|---|
|  | 129 | vseg->flags = VSEG_EXEC    | | 
|---|
|  | 130 | VSEG_CACHE   | | 
|---|
|  | 131 | VSEG_PRIVATE ; | 
|---|
|  | 132 | } | 
|---|
|  | 133 | else if( type == VSEG_TYPE_KDATA ) | 
|---|
|  | 134 | { | 
|---|
|  | 135 | vseg->flags = VSEG_CACHE   | | 
|---|
|  | 136 | VSEG_WRITE   ; | 
|---|
|  | 137 | } | 
|---|
|  | 138 | else if( type == VSEG_TYPE_KDEV ) | 
|---|
|  | 139 | { | 
|---|
|  | 140 | vseg->flags = VSEG_WRITE   ; | 
|---|
|  | 141 | } | 
|---|
| [18] | 142 | else | 
|---|
| [1] | 143 | { | 
|---|
| [492] | 144 | assert( false , "illegal vseg type\n" ); | 
|---|
| [18] | 145 | } | 
|---|
| [1] | 146 |  | 
|---|
| [315] | 147 | }  // end vseg_init() | 
|---|
|  | 148 |  | 
|---|
| [1] | 149 | ////////////////////////////////////////// | 
|---|
|  | 150 | void vseg_init_from_ref( vseg_t    * vseg, | 
|---|
| [407] | 151 | xptr_t      ref_xp ) | 
|---|
| [1] | 152 | { | 
|---|
|  | 153 | // get remote vseg cluster and pointer | 
|---|
| [407] | 154 | cxy_t    cxy = (cxy_t   )GET_CXY( ref_xp ); | 
|---|
|  | 155 | vseg_t * ptr = (vseg_t *)GET_PTR( ref_xp ); | 
|---|
| [1] | 156 |  | 
|---|
|  | 157 | // initialize vseg with remote_read access | 
|---|
| [623] | 158 | vseg->type        =           hal_remote_l32( XPTR( cxy , &ptr->type        ) ); | 
|---|
| [407] | 159 | vseg->min         = (intptr_t)hal_remote_lpt( XPTR( cxy , &ptr->min         ) ); | 
|---|
|  | 160 | vseg->max         = (intptr_t)hal_remote_lpt( XPTR( cxy , &ptr->max         ) ); | 
|---|
| [623] | 161 | vseg->vpn_base    =           hal_remote_l32( XPTR( cxy , &ptr->vpn_base    ) ); | 
|---|
|  | 162 | vseg->vpn_size    =           hal_remote_l32( XPTR( cxy , &ptr->vpn_size    ) ); | 
|---|
|  | 163 | vseg->flags       =           hal_remote_l32( XPTR( cxy , &ptr->flags       ) ); | 
|---|
|  | 164 | vseg->file_offset =           hal_remote_l32( XPTR( cxy , &ptr->file_offset ) ); | 
|---|
|  | 165 | vseg->file_size   =           hal_remote_l32( XPTR( cxy , &ptr->file_size   ) ); | 
|---|
| [567] | 166 | vseg->mapper_xp   = (xptr_t)  hal_remote_l64( XPTR( cxy , &ptr->mapper_xp   ) ); | 
|---|
| [453] | 167 |  | 
|---|
|  | 168 | switch (vseg->type) | 
|---|
|  | 169 | { | 
|---|
| [623] | 170 | case VSEG_TYPE_DATA:      // unused | 
|---|
| [457] | 171 | { | 
|---|
| [453] | 172 | vseg->cxy = 0xffff; | 
|---|
|  | 173 | break; | 
|---|
|  | 174 | } | 
|---|
| [623] | 175 | case VSEG_TYPE_CODE:      // always local | 
|---|
| [457] | 176 | case VSEG_TYPE_STACK: | 
|---|
| [623] | 177 | case VSEG_TYPE_KCODE: | 
|---|
| [457] | 178 | { | 
|---|
| [453] | 179 | vseg->cxy = local_cxy; | 
|---|
|  | 180 | break; | 
|---|
|  | 181 | } | 
|---|
| [623] | 182 | case VSEG_TYPE_ANON:      // intrinsic | 
|---|
| [453] | 183 | case VSEG_TYPE_FILE: | 
|---|
| [457] | 184 | case VSEG_TYPE_REMOTE: | 
|---|
| [623] | 185 | case VSEG_TYPE_KDEV: | 
|---|
|  | 186 | case VSEG_TYPE_KDATA: | 
|---|
| [457] | 187 | { | 
|---|
| [567] | 188 | vseg->cxy = (cxy_t) hal_remote_l32( XPTR(cxy, &ptr->cxy) ); | 
|---|
| [453] | 189 | break; | 
|---|
|  | 190 | } | 
|---|
| [457] | 191 | default: | 
|---|
|  | 192 | { | 
|---|
| [492] | 193 | assert( false, "Illegal vseg type" ); | 
|---|
| [453] | 194 | break; | 
|---|
|  | 195 | } | 
|---|
|  | 196 | } | 
|---|
| [184] | 197 | } | 
|---|
| [1] | 198 |  | 
|---|
|  | 199 |  | 
|---|