| 1 | // ### -------------------------------------------------------------- ###
|
|---|
| 2 | // # #
|
|---|
| 3 | // # File : sim2os.h #
|
|---|
| 4 | // # Authors : Rosière Mathieu #
|
|---|
| 5 | // # Date : 12/06/2006 #
|
|---|
| 6 | // # Modif. : dd/mm/yyyy #
|
|---|
| 7 | // # Version : 1.0 #
|
|---|
| 8 | // # #
|
|---|
| 9 | // # Origin : this description has been developed by CAO-VLSI team #
|
|---|
| 10 | // # at ASIM laboratory, University Pierre et Marie Curie #
|
|---|
| 11 | // # 4 Place Jussieu 75252 Paris Cedex 05 - France #
|
|---|
| 12 | // # #
|
|---|
| 13 | // ### -------------------------------------------------------------- ###
|
|---|
| 14 |
|
|---|
| 15 | /*
|
|---|
| 16 | * WARNING :
|
|---|
| 17 | * This bridge can be use, if :
|
|---|
| 18 | * - sizeof between the host's cpu and the simulation's cpu is the same
|
|---|
| 19 | * -
|
|---|
| 20 | */
|
|---|
| 21 |
|
|---|
| 22 | #ifndef SIM2OS_H
|
|---|
| 23 | #define SIM2OS_H
|
|---|
| 24 |
|
|---|
| 25 | #include "service.h"
|
|---|
| 26 | #include "service_conversion.h"
|
|---|
| 27 | #include <iostream>
|
|---|
| 28 | #include <map>
|
|---|
| 29 | using namespace std;
|
|---|
| 30 | #include <sys/types.h>
|
|---|
| 31 | #include <sys/stat.h>
|
|---|
| 32 | #include <fcntl.h>
|
|---|
| 33 | #include <errno.h>
|
|---|
| 34 | #include <stdarg.h>
|
|---|
| 35 | #include "shared/soclib_segment_table.h"
|
|---|
| 36 | #include "../endianness/endianness.h"
|
|---|
| 37 | using namespace std;
|
|---|
| 38 | using namespace hierarchy_memory::sim2os::service;
|
|---|
| 39 |
|
|---|
| 40 | namespace hierarchy_memory {
|
|---|
| 41 | namespace sim2os {
|
|---|
| 42 |
|
|---|
| 43 |
|
|---|
| 44 |
|
|---|
| 45 | //******************************************************************************************
|
|---|
| 46 | // Interface
|
|---|
| 47 | //******************************************************************************************
|
|---|
| 48 |
|
|---|
| 49 |
|
|---|
| 50 |
|
|---|
| 51 | class param_t
|
|---|
| 52 | {
|
|---|
| 53 | public : char * name ;
|
|---|
| 54 | public : SOCLIB_SEGMENT_TABLE * segment_table ;
|
|---|
| 55 |
|
|---|
| 56 | public : param_t () {};
|
|---|
| 57 |
|
|---|
| 58 | public : param_t (char * name ,
|
|---|
| 59 | SOCLIB_SEGMENT_TABLE * segment_table )
|
|---|
| 60 | {
|
|---|
| 61 | this->name = name ;
|
|---|
| 62 | this->segment_table = segment_table ;
|
|---|
| 63 | }
|
|---|
| 64 | }; //end param_t
|
|---|
| 65 |
|
|---|
| 66 | class Sim2os
|
|---|
| 67 | {
|
|---|
| 68 | //=====[ Private ]==========================================================================
|
|---|
| 69 | //-----[ Champ ]----------------------------------------------------------------------------
|
|---|
| 70 | private : const char * NAME;
|
|---|
| 71 | private : service_t num_service; // number of service
|
|---|
| 72 | private : map<unsigned int,void *> arguments;
|
|---|
| 73 | private : SOCLIB_SEGMENT_TABLE * segment_table;
|
|---|
| 74 | private : unsigned long long nb_cycle;
|
|---|
| 75 |
|
|---|
| 76 | //-----[ Methods ]--------------------------------------------------------------------------
|
|---|
| 77 | private : bool have_all_arguments (unsigned int);
|
|---|
| 78 | private : void * convert_address (void *);
|
|---|
| 79 |
|
|---|
| 80 | private : void * service_open ();
|
|---|
| 81 | private : void * service_close ();
|
|---|
| 82 | private : void * service_read ();
|
|---|
| 83 | private : void * service_write ();
|
|---|
| 84 | private : void * service_time ();
|
|---|
| 85 | private : void * service_clock ();
|
|---|
| 86 | private : void * service_lseek ();
|
|---|
| 87 |
|
|---|
| 88 | //=====[ Public ]===========================================================================
|
|---|
| 89 | public : void * result;
|
|---|
| 90 | public : int error; // It's errno
|
|---|
| 91 |
|
|---|
| 92 | //-----[ Methods ]--------------------------------------------------------------------------
|
|---|
| 93 | public : Sim2os (param_t);
|
|---|
| 94 | public : ~Sim2os ();
|
|---|
| 95 | public : void * execute ();
|
|---|
| 96 | public : void * execute (service_t);
|
|---|
| 97 | public : void * execute (service_t, void *, ...);
|
|---|
| 98 | public : void parameter (unsigned int, void *);
|
|---|
| 99 | public : void transition ();
|
|---|
| 100 |
|
|---|
| 101 | //=====[ Friend ]===========================================================================
|
|---|
| 102 | //-----[ Methods ]--------------------------------------------------------------------------
|
|---|
| 103 | friend ostream& operator<< (ostream&, Sim2os);
|
|---|
| 104 | };
|
|---|
| 105 |
|
|---|
| 106 |
|
|---|
| 107 |
|
|---|
| 108 | //******************************************************************************************
|
|---|
| 109 | // Implementation
|
|---|
| 110 | //******************************************************************************************
|
|---|
| 111 |
|
|---|
| 112 |
|
|---|
| 113 |
|
|---|
| 114 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[ Sim2os ]~~~~~
|
|---|
| 115 | Sim2os ::
|
|---|
| 116 | Sim2os (param_t param) :
|
|---|
| 117 | NAME (param.name)
|
|---|
| 118 | {
|
|---|
| 119 | segment_table = param.segment_table;
|
|---|
| 120 | result = (void *)-1;
|
|---|
| 121 | error = 1;
|
|---|
| 122 | nb_cycle = 0;
|
|---|
| 123 | cout << "<" << NAME << "> Successful Instanciation" << endl;
|
|---|
| 124 | };
|
|---|
| 125 |
|
|---|
| 126 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[ ~Sim2os ]~~~~~
|
|---|
| 127 | Sim2os ::
|
|---|
| 128 | ~Sim2os ()
|
|---|
| 129 | {
|
|---|
| 130 | cout << "<" << NAME << "> Destructor" << endl;
|
|---|
| 131 | };
|
|---|
| 132 |
|
|---|
| 133 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[ have_all_arguments ]~~~~~
|
|---|
| 134 | /*
|
|---|
| 135 | * Test if all arguments is here
|
|---|
| 136 | * (don't test the coherencies of this)
|
|---|
| 137 | */
|
|---|
| 138 | bool
|
|---|
| 139 | Sim2os ::
|
|---|
| 140 | have_all_arguments (unsigned int nb_val)
|
|---|
| 141 | {
|
|---|
| 142 | // while ((nb_val > 0) &&
|
|---|
| 143 | // (arguments.find(nb_val) != arguments.end()))
|
|---|
| 144 | // nb_val --;
|
|---|
| 145 |
|
|---|
| 146 | unsigned int val = nb_val;
|
|---|
| 147 | while (nb_val > 0)
|
|---|
| 148 | if (arguments.find(nb_val) != arguments.end())
|
|---|
| 149 | nb_val --;
|
|---|
| 150 | else
|
|---|
| 151 | {
|
|---|
| 152 | cerr << "argument[" << nb_val << "] on " << val << ", is not find." << endl;
|
|---|
| 153 | break;
|
|---|
| 154 | }
|
|---|
| 155 |
|
|---|
| 156 | return (nb_val == 0);
|
|---|
| 157 | };
|
|---|
| 158 |
|
|---|
| 159 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[ convert_address ]~~~~~
|
|---|
| 160 | /*
|
|---|
| 161 | * convert a address in the simulator on a address in OS
|
|---|
| 162 | */
|
|---|
| 163 | void *
|
|---|
| 164 | Sim2os ::
|
|---|
| 165 | convert_address (void * address)
|
|---|
| 166 | {
|
|---|
| 167 | void * result = segment_table->getAddrAlloc((unsigned int)address);
|
|---|
| 168 |
|
|---|
| 169 | if (result == NULL)
|
|---|
| 170 | {
|
|---|
| 171 | cerr << "<" << NAME << "> address don't match : " << hex << (unsigned int)address << dec << endl;
|
|---|
| 172 | exit(0);
|
|---|
| 173 | }
|
|---|
| 174 |
|
|---|
| 175 | return result;
|
|---|
| 176 | }
|
|---|
| 177 |
|
|---|
| 178 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[ transition ]~~~~~
|
|---|
| 179 | /*
|
|---|
| 180 | * have a new cycle : update register cycle's depend
|
|---|
| 181 | */
|
|---|
| 182 | void
|
|---|
| 183 | Sim2os ::
|
|---|
| 184 | transition ()
|
|---|
| 185 | {
|
|---|
| 186 | nb_cycle ++;
|
|---|
| 187 | }
|
|---|
| 188 |
|
|---|
| 189 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[ execute ]~~~~~
|
|---|
| 190 | /*
|
|---|
| 191 | * execute the service with num_service in argument
|
|---|
| 192 | */
|
|---|
| 193 | void *
|
|---|
| 194 | Sim2os ::
|
|---|
| 195 | execute (service_t num)
|
|---|
| 196 | {
|
|---|
| 197 | num_service = num;
|
|---|
| 198 |
|
|---|
| 199 | return execute();
|
|---|
| 200 | }
|
|---|
| 201 |
|
|---|
| 202 | /*
|
|---|
| 203 | * execute the service with all
|
|---|
| 204 | * the list of arg must be finish by "NULL"
|
|---|
| 205 | * also the list can't have a NULL as param
|
|---|
| 206 | */
|
|---|
| 207 | void *
|
|---|
| 208 | Sim2os ::
|
|---|
| 209 | execute (service_t num, void * arg, ...)
|
|---|
| 210 | {
|
|---|
| 211 |
|
|---|
| 212 | num_service = num;
|
|---|
| 213 |
|
|---|
| 214 | va_list ap;
|
|---|
| 215 | va_start (ap,arg);
|
|---|
| 216 | unsigned int it = 1;
|
|---|
| 217 | while (arg != NULL)
|
|---|
| 218 | {
|
|---|
| 219 | arguments[it] = arg;
|
|---|
| 220 | it ++;
|
|---|
| 221 | arg = va_arg(ap,void *);
|
|---|
| 222 | }
|
|---|
| 223 |
|
|---|
| 224 | va_end(ap);
|
|---|
| 225 | return execute();
|
|---|
| 226 | }
|
|---|
| 227 |
|
|---|
| 228 | /*
|
|---|
| 229 | * execute the service without argument
|
|---|
| 230 | */
|
|---|
| 231 | void *
|
|---|
| 232 | Sim2os ::
|
|---|
| 233 | execute ()
|
|---|
| 234 | {
|
|---|
| 235 | result = NULL;
|
|---|
| 236 |
|
|---|
| 237 | switch (num_service)
|
|---|
| 238 | {
|
|---|
| 239 | case SERVICE_OPEN : {result = service_open (); break;}
|
|---|
| 240 | case SERVICE_CLOSE : {result = service_close (); break;}
|
|---|
| 241 | case SERVICE_READ : {result = service_read (); break;}
|
|---|
| 242 | case SERVICE_WRITE : {result = service_write (); break;}
|
|---|
| 243 | case SERVICE_TIME : {result = service_time (); break;}
|
|---|
| 244 | case SERVICE_CLOCK : {result = service_clock (); break;}
|
|---|
| 245 | case SERVICE_LSEEK : {result = service_lseek (); break;}
|
|---|
| 246 | case SERVICE_UNIMPLEMENTED :
|
|---|
| 247 | {
|
|---|
| 248 | cerr << "<" << NAME << "> service Unimplemented : " << num_service << endl;
|
|---|
| 249 | break;
|
|---|
| 250 | }
|
|---|
| 251 |
|
|---|
| 252 | case SERVICE_UNDEFINED :
|
|---|
| 253 | default :
|
|---|
| 254 | {
|
|---|
| 255 | cerr << "<" << NAME << "> service Undefine : " << num_service << endl;
|
|---|
| 256 | break;
|
|---|
| 257 | }
|
|---|
| 258 | }//end switch
|
|---|
| 259 |
|
|---|
| 260 | // Erase all elt;
|
|---|
| 261 | arguments.erase(arguments.begin(),arguments.end());
|
|---|
| 262 | return result;
|
|---|
| 263 | };
|
|---|
| 264 |
|
|---|
| 265 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[ parameter ]~~~~~
|
|---|
| 266 | /*
|
|---|
| 267 | * Add a new parameter
|
|---|
| 268 | * if num_reg == 0, it's the number of service
|
|---|
| 269 | * else it's a arguments
|
|---|
| 270 | */
|
|---|
| 271 | void
|
|---|
| 272 | Sim2os ::
|
|---|
| 273 | parameter (unsigned int num_reg,
|
|---|
| 274 | void * val)
|
|---|
| 275 | {
|
|---|
| 276 | if (num_reg == 0)
|
|---|
| 277 | num_service = int2service((int) val);
|
|---|
| 278 | else
|
|---|
| 279 | arguments[num_reg] = val;
|
|---|
| 280 | };
|
|---|
| 281 |
|
|---|
| 282 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[ operator<< ]~~~~~
|
|---|
| 283 | ostream& operator<< (ostream& output, Sim2os input)
|
|---|
| 284 | {
|
|---|
| 285 | // output << "<" << input.NAME << ">" << endl;
|
|---|
| 286 | // output << "num_service : " << input.num_service << endl;
|
|---|
| 287 |
|
|---|
| 288 | // for (map<unsigned int,void *>::iterator it = input.arguments.begin();
|
|---|
| 289 | // it != input.arguments.end();
|
|---|
| 290 | // it ++)
|
|---|
| 291 | // output << "[" << it.first << "] : " << it.second << endl;
|
|---|
| 292 | return output;
|
|---|
| 293 | };
|
|---|
| 294 |
|
|---|
| 295 | };};
|
|---|
| 296 |
|
|---|
| 297 | // Include all service !!!
|
|---|
| 298 | #include "service/service_open.h"
|
|---|
| 299 | #include "service/service_close.h"
|
|---|
| 300 | #include "service/service_read.h"
|
|---|
| 301 | #include "service/service_write.h"
|
|---|
| 302 | #include "service/service_time.h"
|
|---|
| 303 | #include "service/service_clock.h"
|
|---|
| 304 | #include "service/service_lseek.h"
|
|---|
| 305 |
|
|---|
| 306 |
|
|---|
| 307 | #endif //!SIM2OS_H
|
|---|