1 /* emulos.c -- Small OS emulation 2 Copyright 1999, 2000, 2007, 2008, 2009, 2010, 2011 3 Free Software Foundation, Inc. 4 Written by Stephane Carrez (stcarrez@worldnet.fr) 5 6 This file is part of GDB, GAS, and the GNU binutils. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 21 #include "sim-main.h" 22 #ifdef HAVE_UNISTD_H 23 #include <unistd.h> 24 #endif 25 26 #ifndef WIN32 27 #include <sys/types.h> 28 #include <sys/time.h> 29 30 /* This file emulates some OS system calls. 31 It's basically used to give access to the host OS facilities 32 like: stdin, stdout, files, time of day. */ 33 static int bench_mode = -1; 34 static struct timeval bench_start; 35 static struct timeval bench_stop; 36 37 void 38 emul_bench (struct _sim_cpu* cpu) 39 { 40 int op; 41 42 op = cpu_get_d (cpu); 43 switch (op) 44 { 45 case 0: 46 bench_mode = 0; 47 gettimeofday (&bench_start, 0); 48 break; 49 50 case 1: 51 gettimeofday (&bench_stop, 0); 52 if (bench_mode != 0) 53 printf ("bench start not called...\n"); 54 bench_mode = 1; 55 break; 56 57 case 2: 58 { 59 int sz = 0; 60 int addr = cpu_get_x (cpu); 61 double t_start, t_stop, t; 62 char buf[1024]; 63 64 op = cpu_get_y (cpu); 65 t_start = (double) (bench_start.tv_sec) * 1.0e6; 66 t_start += (double) (bench_start.tv_usec); 67 t_stop = (double) (bench_stop.tv_sec) * 1.0e6; 68 t_stop += (double) (bench_stop.tv_usec); 69 70 while (sz < 1024) 71 { 72 buf[sz] = memory_read8 (cpu, addr); 73 if (buf[sz] == 0) 74 break; 75 76 sz ++; 77 addr++; 78 } 79 buf[1023] = 0; 80 81 if (bench_mode != 1) 82 printf ("bench_stop not called"); 83 84 bench_mode = -1; 85 t = t_stop - t_start; 86 printf ("%-40.40s [%6d] %3.3f us\n", buf, 87 op, t / (double) (op)); 88 break; 89 } 90 } 91 } 92 #endif 93 94 void 95 emul_write(struct _sim_cpu* state) 96 { 97 int addr = cpu_get_x (state) & 0x0FFFF; 98 int size = cpu_get_d (state) & 0x0FFFF; 99 100 if (addr + size > 0x0FFFF) { 101 size = 0x0FFFF - addr; 102 } 103 state->cpu_running = 0; 104 while (size) 105 { 106 uint8 val = memory_read8 (state, addr); 107 108 write(0, &val, 1); 109 addr ++; 110 size--; 111 } 112 } 113 114 /* emul_exit () is used by the default startup code of GCC to implement 115 the exit (). For a real target, this will create an ILLEGAL fault. 116 But doing an exit () on a real target is really a non-sense. 117 exit () is important for the validation of GCC. The exit status 118 is passed in 'D' register. */ 119 void 120 emul_exit (sim_cpu *cpu) 121 { 122 sim_engine_halt (CPU_STATE (cpu), cpu, 123 NULL, NULL_CIA, sim_exited, 124 cpu_get_d (cpu)); 125 } 126 127 void 128 emul_os (int code, sim_cpu *proc) 129 { 130 proc->cpu_current_cycle = 8; 131 switch (code) 132 { 133 case 0x0: 134 break; 135 136 /* 0xCD 0x01 */ 137 case 0x01: 138 emul_write (proc); 139 break; 140 141 /* 0xCD 0x02 */ 142 case 0x02: 143 break; 144 145 /* 0xCD 0x03 */ 146 case 0x03: 147 emul_exit (proc); 148 break; 149 150 /* 0xCD 0x04 */ 151 case 0x04: 152 #ifndef WIN32 153 emul_bench (proc); 154 #endif 155 break; 156 157 default: 158 break; 159 } 160 } 161 162