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