#include #include #include #include #include #include #include "hook/iobuf.h" #include "hook/iohook.h" #include "hooklib/uart.h" #include "hooklib/fdshark.h" #include "util/dprintf.h" #include "util/dump.h" #include "platform/jvs.h" static HRESULT jvs_handle_irp(struct irp *irp); static HRESULT jvs_handle_irp_locked(struct irp *irp); static struct uart jvs_uart; static CRITICAL_SECTION jvs_lock; static uint8_t jvs_written_bytes[520]; static uint8_t jvs_readable_bytes[520]; static struct jvs_node *jvs_root; static jvs_provider_t jvs_provider; HRESULT jvs_hook_init(const struct jvs_config *cfg, jvs_provider_t provider) { if (!cfg->enable || provider == NULL) { dprintf("JVS I/O: Disabled\n"); return S_OK; } InitializeCriticalSection(&jvs_lock); dprintf("JVS I/O: init\n"); uart_init(&jvs_uart, cfg->port); jvs_uart.written.bytes = jvs_written_bytes; jvs_uart.written.nbytes = sizeof(jvs_written_bytes); jvs_uart.readable.bytes = jvs_readable_bytes; jvs_uart.readable.nbytes = sizeof(jvs_readable_bytes); jvs_provider = provider; return iohook_push_handler(jvs_handle_irp); } static HRESULT jvs_handle_irp(struct irp *irp) { HRESULT hr; assert(irp != NULL); if (uart_match_irp(&jvs_uart, irp)) { EnterCriticalSection(&jvs_lock); hr = jvs_handle_irp_locked(irp); LeaveCriticalSection(&jvs_lock); } else { return iohook_invoke_next(irp); } return hr; } static HRESULT jvs_handle_irp_locked(struct irp *irp) { HRESULT hr; struct jvs_node *root; if (irp->op == IRP_OP_OPEN) { dprintf("JVS I/O: Starting backend\n"); if (jvs_provider != NULL) { hr = jvs_provider(&root); if (SUCCEEDED(hr)) { jvs_root = root; } } } hr = uart_handle_irp(&jvs_uart, irp); if (FAILED(hr) || irp->op != IRP_OP_WRITE) { return hr; } for (;;) { #if 0 dprintf("JVS I/O: Written\n"); dump_iobuf(&jvs_uart.written); #endif jvs_bus_transact(jvs_root, jvs_uart.written.bytes, jvs_uart.written.pos, &jvs_uart.readable); jvs_uart.written.pos = 0; return S_OK; } }