16 #define USE_OWNTIMER 1
20 #define Timersub timersub
21 #define Timeradd timeradd
22 #define Timercmp timercmp
30 #if __linux__ || __APPLE__ || __OpenBSD__ || __FreeBSD__ || __NetBSD__ || __DragonFly__ || __HAIKU__
31 #include <sys/ioctl.h>
39 #define GPROBE_SIZE (1LL << 32)
40 #define GPROBE_I2C_ADDR 0x6e
42 #define I2C_SLAVE 0x0703
49 COMMTIMEOUTS timeouts;
86 static ut8 gprobe_checksum_i2c(
const ut8 *
p,
unsigned int size,
ut8 initial) {
126 ddc2bi3_len =
buf[1] & ~0x80;
132 checksum = gprobe_checksum_i2c(&
addr, 1, 0);
134 if (gprobe_checksum_i2c(
buf, ddc2bi3_len + 2, checksum) !=
buf[ddc2bi3_len + 2]) {
135 eprintf(
"gprobe rx checksum error\n");
152 static int i2c_open(
struct gport *port) {
154 int i2cbus = strtol(port->
name + 4, &
end, 0);
184 if (CloseHandle(port->hdl) == 0) {
190 #define CLOSE_OVERLAPPED(ovl) \
192 if (port->ovl.hEvent != INVALID_HANDLE_VALUE && \
193 CloseHandle(port->ovl.hEvent) == 0) \
196 CLOSE_OVERLAPPED(read_ovl);
197 CLOSE_OVERLAPPED(write_ovl);
198 CLOSE_OVERLAPPED(wait_ovl);
211 static int restart_wait(
struct gport *port) {
214 if (port->wait_running) {
216 if (GetOverlappedResult(port->hdl, &port->wait_ovl,
217 &wait_result,
FALSE)) {
218 port->wait_running =
FALSE;
219 }
else if (GetLastError() == ERROR_IO_INCOMPLETE) {
224 if (!port->wait_running) {
226 if (WaitCommEvent(port->hdl, &port->events,
228 }
else if (GetLastError() == ERROR_IO_PENDING) {
229 port->wait_running =
TRUE;
241 char *escaped_port_name;
247 if (!(escaped_port_name =
malloc(strlen(port->
name) + 5))) {
250 sprintf(escaped_port_name,
"\\\\.\\%s", port->
name);
252 filename_ = rz_sys_conv_utf8_to_win(escaped_port_name);
254 port->hdl = CreateFile(filename_, GENERIC_READ | GENERIC_WRITE, 0, 0,
256 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0);
258 free(escaped_port_name);
265 port->timeouts.ReadIntervalTimeout = 0;
266 port->timeouts.ReadTotalTimeoutMultiplier = 0;
267 port->timeouts.ReadTotalTimeoutConstant = 0;
268 port->timeouts.WriteTotalTimeoutMultiplier = 0;
269 port->timeouts.WriteTotalTimeoutConstant = 0;
271 if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) {
277 #define INIT_OVERLAPPED(ovl) \
279 memset(&port->ovl, 0, sizeof(port->ovl)); \
280 port->ovl.hEvent = INVALID_HANDLE_VALUE; \
281 if ((port->ovl.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL)) == INVALID_HANDLE_VALUE) { \
287 INIT_OVERLAPPED(read_ovl);
288 INIT_OVERLAPPED(write_ovl);
289 INIT_OVERLAPPED(wait_ovl);
292 if (SetCommMask(port->hdl, EV_RXCHAR | EV_ERR) == 0) {
297 port->writing =
FALSE;
298 port->wait_running =
FALSE;
300 ret = restart_wait(port);
308 dcb.fDsrSensitivity =
FALSE;
309 dcb.fErrorChar =
FALSE;
311 dcb.fAbortOnError =
FALSE;
313 if (ClearCommError(port->hdl, &errors, &
status) == 0) {
317 dcb.BaudRate = CBR_115200;
320 dcb.Parity = NOPARITY;
321 dcb.StopBits = ONESTOPBIT;
322 dcb.fRtsControl = RTS_CONTROL_DISABLE;
323 dcb.fOutxCtsFlow =
FALSE;
324 dcb.fDtrControl = DTR_CONTROL_DISABLE;
325 dcb.fOutxDsrFlow =
FALSE;
329 if (!SetCommState(port->hdl, &dcb)) {
341 if (tcgetattr(port->
fd, &
tty) != 0) {
363 tty.c_cflag &= ~020000000000;
376 static int restart_wait_if_needed(
struct gport *port,
unsigned int bytes_read) {
380 if (bytes_read == 0) {
384 if (ClearCommError(port->hdl, &errors, &comstat) == 0) {
388 if (comstat.cbInQue == 0) {
389 if (restart_wait(port)) {
399 size_t count,
unsigned int timeout_ms) {
401 DWORD bytes_read = 0;
404 if (port->timeouts.ReadIntervalTimeout != 0 ||
405 port->timeouts.ReadTotalTimeoutMultiplier != 0 ||
406 port->timeouts.ReadTotalTimeoutConstant != timeout_ms) {
407 port->timeouts.ReadIntervalTimeout = 0;
408 port->timeouts.ReadTotalTimeoutMultiplier = 0;
409 port->timeouts.ReadTotalTimeoutConstant = timeout_ms;
410 if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) {
416 if (ReadFile(port->hdl,
buf,
count,
NULL, &port->read_ovl)) {
418 }
else if (GetLastError() == ERROR_IO_PENDING) {
419 if (GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read,
TRUE) == 0)
425 if (restart_wait_if_needed(port, bytes_read)) {
431 size_t bytes_read = 0;
432 unsigned char *ptr = (
unsigned char *)
buf;
442 delta.tv_sec = timeout_ms / 1000;
443 delta.tv_usec = (timeout_ms % 1000) * 1000;
452 while (bytes_read <
count) {
458 if (timeout_ms && started) {
469 if (errno ==
EINTR) {
474 }
else if (result == 0) {
495 bytes_read += result;
506 if (PurgeComm(port->hdl, PURGE_RXCLEAR) == 0) {
510 if (restart_wait(port)) {
523 static int await_write_completion(
struct gport *port) {
529 result = GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written,
TRUE);
541 size_t count,
unsigned int timeout_ms) {
543 DWORD bytes_written = 0;
545 if (await_write_completion(port)) {
550 if (port->timeouts.WriteTotalTimeoutConstant != timeout_ms) {
551 port->timeouts.WriteTotalTimeoutConstant = timeout_ms;
552 if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) {
558 if (WriteFile(port->hdl,
buf,
count,
NULL, &port->write_ovl)) {
560 }
else if (GetLastError() == ERROR_IO_PENDING) {
561 if (GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written,
TRUE) == 0) {
562 if (GetLastError() == ERROR_SEM_TIMEOUT)
567 return bytes_written;
572 size_t bytes_written = 0;
573 unsigned char *ptr = (
unsigned char *)
buf;
583 delta.tv_sec = timeout_ms / 1000;
584 delta.tv_usec = (timeout_ms % 1000) * 1000;
593 while (bytes_written <
count) {
599 if (timeout_ms && started) {
610 if (errno ==
EINTR) {
615 }
else if (result == 0) {
633 bytes_written += result;
637 return bytes_written;
691 printf(
"### CHECKSUM FAILED\n");
1009 rz_cons_print(dump);
1027 int has_written = 0;
1029 if (!
fd || !
fd->data || !
buf) {
1039 while (has_written <
count) {
1056 if (!
fd || !
fd->data || !
buf) {
1066 while (has_read <
count) {
1081 if (!
fd || !
fd->data) {
1094 if (!
fd || !
fd->data) {
1134 if (i2c_open(&gprobe->
gport)) {
1164 if (!
fd || !
fd->data) {
1169 if (!
cmd[0] ||
cmd[0] ==
'?' || !strcmp(
cmd,
"help")) {
1170 printf(
"Usage: R!cmd args\n"
1174 " R!runcode address\n"
1176 " R!getinformation\n");
1230 .desc =
"Open gprobe connection",
1232 .uris =
"gprobe://",
1242 #ifndef RZ_PLUGIN_INCORE
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
static static sync static getppid static getegid const char static filename request
static static fork const void static count close
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog gettimeofday
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
static static sync static getppid static getegid const char static filename ioctl
RZ_API void Ht_() free(HtName_(Ht) *ht)
static void gprobe_frame_sp(RzBuffer *frame)
static int gprobe_debugoff(struct gport *port)
static int __read(RzIO *io, RzIODesc *fd, ut8 *buf, int count)
RzIOPlugin rz_io_plugin_gprobe
static int gprobe_getdeviceid(struct gport *port, ut8 index)
static int gprobe_reset(struct gport *port, ut8 code)
static int gprobe_send_request_sp(struct gport *port, RzBuffer *request)
static int gprobe_getinformation(struct gport *port)
static bool __plugin_open(RzIO *io, const char *pathname, bool many)
static int sp_flush(struct gport *port)
static RzIODesc * __open(RzIO *io, const char *pathname, int rw, int mode)
RZ_API RzLibStruct rizin_plugin
static int gprobe_get_reply_sp(struct gport *port, ut8 cmd, RzBuffer *reply)
static int gprobe_debugon(struct gport *port)
static int __write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count)
static int gprobe_runcode(struct gport *port, ut32 addr)
static int sp_blocking_read(struct gport *port, void *buf, size_t count, unsigned int timeout_ms)
static ut64 __lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence)
static int __close(RzIODesc *fd)
static ut8 gprobe_checksum(const ut8 *p, unsigned int size)
static int sp_blocking_write(struct gport *port, const void *buf, size_t count, unsigned int timeout_ms)
static char * __system(RzIO *io, RzIODesc *fd, const char *cmd)
static int sp_close(struct gport *port)
static int sp_open(struct gport *port)
static int gprobe_write(struct gport *port, ut32 addr, const ut8 *buf, ut32 count)
static int gprobe_read(struct gport *port, ut32 addr, ut8 *buf, ut32 count)
#define Timeradd(tvp, uvp, vvp)
#define Timersub(tvp, uvp, vvp)
#define Timercmp(tvp, uvp, cmp)
#define INVALID_HANDLE_VALUE
void * malloc(size_t size)
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char pathname
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz select
static const char struct stat static buf struct stat static buf static vhangup int status
#define header(is_bt, len_min, ret_op)
RZ_API RzPrint * rz_print_new(void)
RZ_API RzPrint * rz_print_free(RzPrint *p)
RZ_API RZ_OWN char * rz_print_hexdump_str(RZ_NONNULL RzPrint *p, ut64 addr, RZ_NONNULL const ut8 *buf, int len, int base, int step, size_t zoomsz)
Prints a hexdump of buf at addr.
RZ_API bool rz_buf_prepend_bytes(RZ_NONNULL RzBuffer *b, RZ_NONNULL const ut8 *buf, ut64 len)
Prepend an array of bytes to the buffer.
RZ_API bool rz_buf_append_bytes(RZ_NONNULL RzBuffer *b, RZ_NONNULL const ut8 *buf, ut64 len)
Append an array of bytes to the buffer.
RZ_API st64 rz_buf_read_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
Read len bytes of the buffer at the specified address.
RZ_API void rz_buf_free(RzBuffer *b)
Free all internal data hold by the buffer and the buffer.
RZ_API RZ_OWN RzBuffer * rz_buf_new_with_bytes(RZ_NULLABLE RZ_BORROW const ut8 *bytes, ut64 len)
Creates a new buffer with a bytes array.
RZ_DEPRECATE RZ_API RZ_BORROW ut8 * rz_buf_data(RZ_NONNULL RzBuffer *b, RZ_NONNULL RZ_OUT ut64 *size)
Return a borrowed array of bytes representing the buffer data.
RZ_API ut64 rz_buf_size(RZ_NONNULL RzBuffer *b)
Return the size of the buffer.
RZ_API RZ_OWN char * rz_buf_to_string(RZ_NONNULL RzBuffer *b)
Stringify the buffer.
static void rz_write_be32(void *dest, ut32 val)
RZ_API RzIODesc * rz_io_desc_new(RzIO *io, RzIOPlugin *plugin, const char *uri, int flags, int mode, void *data)
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
RZ_API int rz_sys_open(const char *path, int perm, int mode)
RZ_API int rz_sys_usleep(int usecs)
Sleep for usecs microseconds.
void(* frame)(RzBuffer *frame)
int(* get_reply)(struct gport *port, ut8 cmd, RzBuffer *reply)
int(* send_request)(struct gport *port, RzBuffer *request)
if(dbg->bits==RZ_SYS_BITS_64)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static const z80_opcode fd[]
int read(izstream &zs, T *x, Items items)