/* Poll for input on the console, and if there's any, deliver it to the tty driver. */ void simcons_poll_tty (struct tty_struct *tty) { char buf[32]; /* Not the nicest way to do it but I need it correct first */ int flip = 0, send_break = 0; struct pollfd pfd; pfd.fd = 0; pfd.events = POLLIN; if (V850_SIM_SYSCALL (poll, &pfd, 1, 0) > 0) { if (pfd.revents & POLLIN) { /* Real block hardware knows the transfer size before transfer so the new tty buffering doesn't try to handle this rather weird simulator specific case well */ int rd = V850_SIM_SYSCALL (read, 0, buf, 32); if (rd > 0) { tty_insert_flip_string(tty, buf, rd); flip = 1; } else send_break = 1; } else if (pfd.revents & POLLERR) send_break = 1; } if (send_break) { tty_insert_flip_char (tty, 0, TTY_BREAK); flip = 1; } if (flip) tty_schedule_flip (tty); }
/* Load data from a file called NAME into ram. The address and length of the data image are returned in ADDR and LEN. */ static int __init read_file (const char *name, unsigned long *addr, unsigned long *len, const char **err) { int rval, fd; unsigned long cur, left; /* Note this is not a normal stat buffer, it's an ad-hoc structure defined by the simulator. */ unsigned long stat_buf[10]; /* Stat the file to find out the length. */ rval = V850_SIM_SYSCALL (stat, name, stat_buf); if (rval < 0) { if (err) *err = "stat"; return 0; } *len = stat_buf[4]; /* Open the file; `0' is O_RDONLY. */ fd = V850_SIM_SYSCALL (open, name, 0); if (fd < 0) { if (err) *err = "open"; return 0; } *addr = (unsigned long)alloc_bootmem(*len); if (! *addr) { V850_SIM_SYSCALL (close, fd); if (err) *err = "alloc_bootmem"; return 0; } cur = *addr; left = *len; while (left > 0) { int chunk = V850_SIM_SYSCALL (read, fd, cur, left); if (chunk <= 0) break; cur += chunk; left -= chunk; } V850_SIM_SYSCALL (close, fd); if (left > 0) { /* Some read failed. */ free_bootmem (*addr, *len); if (err) *err = "read"; return 0; } return 1; }
void mach_gettimeofday (struct timespec *tv) { long timeval[2], timezone[2]; int rval = V850_SIM_SYSCALL (gettimeofday, timeval, timezone); if (rval == 0) { tv->tv_sec = timeval[0]; tv->tv_nsec = timeval[1] * 1000; } }
/* Poll for input on the console, and if there's any, deliver it to the tty driver. */ void simcons_poll_tty (struct tty_struct *tty) { int flip = 0, send_break = 0; struct pollfd pfd; pfd.fd = 0; pfd.events = POLLIN; if (V850_SIM_SYSCALL (poll, &pfd, 1, 0) > 0) { if (pfd.revents & POLLIN) { int left = TTY_FLIPBUF_SIZE - tty->flip.count; if (left > 0) { unsigned char *buf = tty->flip.char_buf_ptr; int rd = V850_SIM_SYSCALL (read, 0, buf, left); if (rd > 0) { tty->flip.count += rd; tty->flip.char_buf_ptr += rd; memset (tty->flip.flag_buf_ptr, 0, rd); tty->flip.flag_buf_ptr += rd; flip = 1; } else send_break = 1; } } else if (pfd.revents & POLLERR) send_break = 1; } if (send_break) { tty_insert_flip_char (tty, 0, TTY_BREAK); flip = 1; } if (flip) tty_schedule_flip (tty); }
int simcons_tty_write (struct tty_struct *tty, const unsigned char *buf, int count) { return V850_SIM_SYSCALL (write, 1, buf, count); }
static int simcons_read (struct console *co, char *buf, unsigned len) { return V850_SIM_SYSCALL (read, 0, buf, len); }
static void simcons_write (struct console *co, const char *buf, unsigned len) { V850_SIM_SYSCALL (write, 1, buf, len); }
void simcons_setup (void) { V850_SIM_SYSCALL (make_raw, 0); register_console (&simcons); printk (KERN_INFO "Console: GDB V850E simulator stdio\n"); }
void machine_power_off (void) { V850_SIM_SYSCALL (write, 1, "POWER OFF\n", 10); V850_SIM_SYSCALL (exit, 0); }
void machine_halt (void) { V850_SIM_SYSCALL (write, 1, "HALT\n", 5); V850_SIM_SYSCALL (exit, 0); }
void machine_restart (char *__unused) { V850_SIM_SYSCALL (write, 1, "RESTART\n", 8); V850_SIM_SYSCALL (exit, 0); }