@ -520,6 +520,21 @@ static void host_gettimeofday(CPUState *cs, gdb_syscall_complete_cb complete,
unlock_user ( p , tv_addr , sizeof ( struct gdb_timeval ) ) ;
}
# ifndef CONFIG_USER_ONLY
static void host_poll_one ( CPUState * cs , gdb_syscall_complete_cb complete ,
GuestFD * gf , GIOCondition cond , int timeout )
{
/*
* Since this is only used by xtensa in system mode , and stdio is
* handled through GuestFDConsole , and there are no semihosting
* system calls for sockets and the like , that means this descriptor
* must be a normal file . Normal files never block and are thus
* always ready .
*/
complete ( cs , cond & ( G_IO_IN | G_IO_OUT ) , 0 ) ;
}
# endif
/*
* Static file semihosting syscall implementations .
*/
@ -628,6 +643,34 @@ static void console_fstat(CPUState *cs, gdb_syscall_complete_cb complete,
complete ( cs , ret ? - 1 : 0 , ret ? - ret : 0 ) ;
}
# ifndef CONFIG_USER_ONLY
static void console_poll_one ( CPUState * cs , gdb_syscall_complete_cb complete ,
GuestFD * gf , GIOCondition cond , int timeout )
{
/* The semihosting console does not support urgent data or errors. */
cond & = G_IO_IN | G_IO_OUT ;
/*
* Since qemu_semihosting_console_write never blocks , we can
* consider output always ready - - leave G_IO_OUT alone .
* All that remains is to conditionally signal input ready .
* Since output ready causes an immediate return , only block
* for G_IO_IN alone .
*
* TODO : Implement proper timeout . For now , only support
* indefinite wait or immediate poll .
*/
if ( cond = = G_IO_IN & & timeout < 0 ) {
qemu_semihosting_console_block_until_ready ( cs ) ;
/* We returned -- input must be ready. */
} else if ( ( cond & G_IO_IN ) & & ! qemu_semihosting_console_ready ( ) ) {
cond & = ~ G_IO_IN ;
}
complete ( cs , cond , 0 ) ;
}
# endif
/*
* Syscall entry points .
*/
@ -906,3 +949,30 @@ void semihost_sys_gettimeofday(CPUState *cs, gdb_syscall_complete_cb complete,
host_gettimeofday ( cs , complete , tv_addr , tz_addr ) ;
}
}
# ifndef CONFIG_USER_ONLY
void semihost_sys_poll_one ( CPUState * cs , gdb_syscall_complete_cb complete ,
int fd , GIOCondition cond , int timeout )
{
GuestFD * gf = get_guestfd ( fd ) ;
if ( ! gf ) {
complete ( cs , G_IO_NVAL , 1 ) ;
return ;
}
switch ( gf - > type ) {
case GuestFDGDB :
complete ( cs , G_IO_NVAL , 1 ) ;
break ;
case GuestFDHost :
host_poll_one ( cs , complete , gf , cond , timeout ) ;
break ;
case GuestFDConsole :
console_poll_one ( cs , complete , gf , cond , timeout ) ;
break ;
case GuestFDStatic :
default :
g_assert_not_reached ( ) ;
}
}
# endif