/* * vseg.c - virtual segment (vseg) related operations * * Authors Alain Greiner (2016,2017,2018,2019) * * Copyright (c) UPMC Sorbonne Universites * * This file is part of ALMOS-MKH. * * ALMOS-MKH is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2.0 of the License. * * ALMOS-MKH is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ALMOS-MKH; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //////////////////////////////////////////////////////////////////////////////////////// // global variables for display / must be consistent with enum in "vseg.h" //////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////// char * vseg_type_str( uint32_t vseg_type ) { if ( vseg_type == VSEG_TYPE_CODE ) return "CODE"; else if( vseg_type == VSEG_TYPE_DATA ) return "DATA"; else if( vseg_type == VSEG_TYPE_STACK ) return "STAK"; else if( vseg_type == VSEG_TYPE_ANON ) return "ANON"; else if( vseg_type == VSEG_TYPE_FILE ) return "FILE"; else if( vseg_type == VSEG_TYPE_REMOTE ) return "REMO"; else if( vseg_type == VSEG_TYPE_KCODE ) return "KCOD"; else if( vseg_type == VSEG_TYPE_KDATA ) return "KDAT"; else if( vseg_type == VSEG_TYPE_KDEV ) return "KDEV"; else return "undefined"; } /////////////////////////// vseg_t * vseg_alloc( void ) { kmem_req_t req; req.type = KMEM_KCM; req.order = bits_log2( sizeof(vseg_t) ); req.flags = AF_KERNEL | AF_ZERO; return kmem_alloc( &req ); } /////////////////////////////// void vseg_free( vseg_t * vseg ) { kmem_req_t req; req.type = KMEM_KCM; req.ptr = vseg; kmem_free( &req ); } /////////////////////////////////// void vseg_init( vseg_t * vseg, vseg_type_t type, intptr_t base, uint32_t size, vpn_t vpn_base, vpn_t vpn_size, uint32_t file_offset, uint32_t file_size, xptr_t mapper_xp, cxy_t cxy ) { vseg->type = type; vseg->min = base; vseg->max = base + size; vseg->vpn_base = vpn_base; vseg->vpn_size = vpn_size; vseg->file_offset = file_offset; vseg->file_size = file_size; vseg->mapper_xp = mapper_xp; vseg->cxy = cxy; // set vseg flags depending on type if ( type == VSEG_TYPE_CODE ) { vseg->flags = VSEG_USER | VSEG_EXEC | VSEG_CACHE | VSEG_PRIVATE ; } else if( type == VSEG_TYPE_STACK ) { vseg->flags = VSEG_USER | VSEG_WRITE | VSEG_CACHE | VSEG_PRIVATE ; } else if( type == VSEG_TYPE_DATA ) { vseg->flags = VSEG_USER | VSEG_WRITE | VSEG_CACHE | VSEG_DISTRIB ; } else if( type == VSEG_TYPE_REMOTE ) { vseg->flags = VSEG_USER | VSEG_WRITE | VSEG_CACHE ; } else if( type == VSEG_TYPE_ANON ) { vseg->flags = VSEG_USER | VSEG_WRITE | VSEG_CACHE; } else if( type == VSEG_TYPE_FILE ) { vseg->flags = VSEG_USER | VSEG_WRITE | VSEG_CACHE ; } else if( type == VSEG_TYPE_KCODE ) { vseg->flags = VSEG_EXEC | VSEG_CACHE | VSEG_PRIVATE ; } else if( type == VSEG_TYPE_KDATA ) { vseg->flags = VSEG_CACHE | VSEG_WRITE ; } else if( type == VSEG_TYPE_KDEV ) { vseg->flags = VSEG_WRITE ; } else { assert( false , "illegal vseg type\n" ); } } // end vseg_init() ////////////////////////////////////////// void vseg_init_from_ref( vseg_t * vseg, xptr_t ref_xp ) { // get remote vseg cluster and pointer cxy_t cxy = (cxy_t )GET_CXY( ref_xp ); vseg_t * ptr = (vseg_t *)GET_PTR( ref_xp ); // initialize vseg with remote_read access vseg->type = hal_remote_l32( XPTR( cxy , &ptr->type ) ); vseg->min = (intptr_t)hal_remote_lpt( XPTR( cxy , &ptr->min ) ); vseg->max = (intptr_t)hal_remote_lpt( XPTR( cxy , &ptr->max ) ); vseg->vpn_base = hal_remote_l32( XPTR( cxy , &ptr->vpn_base ) ); vseg->vpn_size = hal_remote_l32( XPTR( cxy , &ptr->vpn_size ) ); vseg->flags = hal_remote_l32( XPTR( cxy , &ptr->flags ) ); vseg->file_offset = hal_remote_l32( XPTR( cxy , &ptr->file_offset ) ); vseg->file_size = hal_remote_l32( XPTR( cxy , &ptr->file_size ) ); vseg->mapper_xp = (xptr_t) hal_remote_l64( XPTR( cxy , &ptr->mapper_xp ) ); switch (vseg->type) { case VSEG_TYPE_DATA: // unused { vseg->cxy = 0xffff; break; } case VSEG_TYPE_CODE: // always local case VSEG_TYPE_STACK: case VSEG_TYPE_KCODE: { vseg->cxy = local_cxy; break; } case VSEG_TYPE_ANON: // intrinsic case VSEG_TYPE_FILE: case VSEG_TYPE_REMOTE: case VSEG_TYPE_KDEV: case VSEG_TYPE_KDATA: { vseg->cxy = (cxy_t) hal_remote_l32( XPTR(cxy, &ptr->cxy) ); break; } default: { assert( false, "Illegal vseg type" ); break; } } }