diff options
Diffstat (limited to 'tools/src/proxy.c')
| -rw-r--r-- | tools/src/proxy.c | 575 |
1 files changed, 575 insertions, 0 deletions
diff --git a/tools/src/proxy.c b/tools/src/proxy.c new file mode 100644 index 0000000..3925d7e --- /dev/null +++ b/tools/src/proxy.c @@ -0,0 +1,575 @@ +/* SPDX-License-Identifier: MIT */ + +#include "proxy.h" +#include "dapf.h" +#include "dart.h" +#include "display.h" +#include "exception.h" +#include "fb.h" +#include "gxf.h" +#include "heapblock.h" +#include "hv.h" +#include "iodev.h" +#include "kboot.h" +#include "malloc.h" +#include "mcc.h" +#include "memory.h" +#include "nvme.h" +#include "pcie.h" +#include "pmgr.h" +#include "smp.h" +#include "string.h" +#include "tunables.h" +#include "types.h" +#include "uart.h" +#include "uartproxy.h" +#include "usb.h" +#include "utils.h" +#include "xnuboot.h" + +#include "minilzlib/minlzma.h" +#include "tinf/tinf.h" + +int proxy_process(ProxyRequest *request, ProxyReply *reply) +{ + enum exc_guard_t guard_save = exc_guard; + + reply->opcode = request->opcode; + reply->status = S_OK; + reply->retval = 0; + switch (request->opcode) { + case P_NOP: + break; + case P_EXIT: + if (request->args[0]) + return request->args[0]; + return 1; + case P_CALL: { + generic_func *f = (generic_func *)request->args[0]; + reply->retval = f(request->args[1], request->args[2], request->args[3], + request->args[4], request->args[5]); + break; + } + case P_GET_BOOTARGS: + reply->retval = boot_args_addr; + break; + case P_GET_BASE: + reply->retval = (u64)_base; + break; + case P_SET_BAUD: { + int cnt = request->args[1]; + printf("Changing baud rate to %lu...\n", request->args[0]); + uart_setbaud(request->args[0]); + while (cnt--) { + uart_putbyte(request->args[2]); + uart_putbyte(request->args[2] >> 8); + uart_putbyte(request->args[2] >> 16); + uart_putbyte(request->args[2] >> 24); + } + break; + } + case P_UDELAY: + udelay(request->args[0]); + break; + case P_SET_EXC_GUARD: + exc_count = 0; + guard_save = request->args[0]; + break; + case P_GET_EXC_COUNT: + reply->retval = exc_count; + exc_count = 0; + break; + case P_EL0_CALL: + reply->retval = el0_call((void *)request->args[0], request->args[1], request->args[2], + request->args[3], request->args[4]); + break; + case P_EL1_CALL: + reply->retval = el1_call((void *)request->args[0], request->args[1], request->args[2], + request->args[3], request->args[4]); + break; + case P_VECTOR: + // forcefully restore tps6598x IRQs + usb_hpm_restore_irqs(1); + iodev_console_flush(); + next_stage.entry = (generic_func *)request->args[0]; + memcpy(next_stage.args, &request->args[1], 5 * sizeof(u64)); + next_stage.restore_logo = true; + return 1; + case P_GL1_CALL: + reply->retval = gl1_call((void *)request->args[0], request->args[1], request->args[2], + request->args[3], request->args[4]); + break; + case P_GL2_CALL: + reply->retval = gl2_call((void *)request->args[0], request->args[1], request->args[2], + request->args[3], request->args[4]); + break; + case P_GET_SIMD_STATE: + get_simd_state((void *)request->args[0]); + break; + case P_PUT_SIMD_STATE: + put_simd_state((void *)request->args[0]); + break; + case P_REBOOT: + reboot(); + break; + + case P_WRITE64: + exc_guard = GUARD_SKIP; + write64(request->args[0], request->args[1]); + break; + case P_WRITE32: + exc_guard = GUARD_SKIP; + write32(request->args[0], request->args[1]); + break; + case P_WRITE16: + exc_guard = GUARD_SKIP; + write16(request->args[0], request->args[1]); + break; + case P_WRITE8: + exc_guard = GUARD_SKIP; + write8(request->args[0], request->args[1]); + break; + + case P_READ64: + exc_guard = GUARD_MARK; + reply->retval = read64(request->args[0]); + break; + case P_READ32: + exc_guard = GUARD_MARK; + reply->retval = read32(request->args[0]); + break; + case P_READ16: + exc_guard = GUARD_MARK; + reply->retval = read16(request->args[0]); + break; + case P_READ8: + exc_guard = GUARD_MARK; + reply->retval = read8(request->args[0]); + break; + + case P_SET64: + exc_guard = GUARD_MARK; + reply->retval = set64(request->args[0], request->args[1]); + break; + case P_SET32: + exc_guard = GUARD_MARK; + reply->retval = set32(request->args[0], request->args[1]); + break; + case P_SET16: + exc_guard = GUARD_MARK; + reply->retval = set16(request->args[0], request->args[1]); + break; + case P_SET8: + exc_guard = GUARD_MARK; + reply->retval = set8(request->args[0], request->args[1]); + break; + + case P_CLEAR64: + exc_guard = GUARD_MARK; + reply->retval = clear64(request->args[0], request->args[1]); + break; + case P_CLEAR32: + exc_guard = GUARD_MARK; + reply->retval = clear32(request->args[0], request->args[1]); + break; + case P_CLEAR16: + exc_guard = GUARD_MARK; + reply->retval = clear16(request->args[0], request->args[1]); + break; + case P_CLEAR8: + exc_guard = GUARD_MARK; + reply->retval = clear8(request->args[0], request->args[1]); + break; + + case P_MASK64: + exc_guard = GUARD_MARK; + reply->retval = mask64(request->args[0], request->args[1], request->args[2]); + break; + case P_MASK32: + exc_guard = GUARD_MARK; + reply->retval = mask32(request->args[0], request->args[1], request->args[2]); + break; + case P_MASK16: + exc_guard = GUARD_MARK; + reply->retval = mask16(request->args[0], request->args[1], request->args[2]); + break; + case P_MASK8: + exc_guard = GUARD_MARK; + reply->retval = mask8(request->args[0], request->args[1], request->args[2]); + break; + + case P_WRITEREAD64: + exc_guard = GUARD_MARK; + reply->retval = writeread64(request->args[0], request->args[1]); + break; + case P_WRITEREAD32: + exc_guard = GUARD_MARK; + reply->retval = writeread32(request->args[0], request->args[1]); + break; + case P_WRITEREAD16: + exc_guard = GUARD_MARK; + reply->retval = writeread16(request->args[0], request->args[1]); + break; + case P_WRITEREAD8: + exc_guard = GUARD_MARK; + reply->retval = writeread8(request->args[0], request->args[1]); + break; + + case P_MEMCPY64: + exc_guard = GUARD_RETURN; + memcpy64((void *)request->args[0], (void *)request->args[1], request->args[2]); + break; + case P_MEMCPY32: + exc_guard = GUARD_RETURN; + memcpy32((void *)request->args[0], (void *)request->args[1], request->args[2]); + break; + case P_MEMCPY16: + exc_guard = GUARD_RETURN; + memcpy16((void *)request->args[0], (void *)request->args[1], request->args[2]); + break; + case P_MEMCPY8: + exc_guard = GUARD_RETURN; + memcpy8((void *)request->args[0], (void *)request->args[1], request->args[2]); + break; + + case P_MEMSET64: + exc_guard = GUARD_RETURN; + memset64((void *)request->args[0], request->args[1], request->args[2]); + break; + case P_MEMSET32: + exc_guard = GUARD_RETURN; + memset32((void *)request->args[0], request->args[1], request->args[2]); + break; + case P_MEMSET16: + exc_guard = GUARD_RETURN; + memset16((void *)request->args[0], request->args[1], request->args[2]); + break; + case P_MEMSET8: + exc_guard = GUARD_RETURN; + memset8((void *)request->args[0], request->args[1], request->args[2]); + break; + + case P_IC_IALLUIS: + ic_ialluis(); + break; + case P_IC_IALLU: + ic_iallu(); + break; + case P_IC_IVAU: + ic_ivau_range((void *)request->args[0], request->args[1]); + break; + case P_DC_IVAC: + dc_ivac_range((void *)request->args[0], request->args[1]); + break; + case P_DC_ISW: + dc_isw((void *)request->args[0]); + break; + case P_DC_CSW: + dc_csw((void *)request->args[0]); + break; + case P_DC_CISW: + dc_cisw((void *)request->args[0]); + break; + case P_DC_ZVA: + dc_zva_range((void *)request->args[0], request->args[1]); + break; + case P_DC_CVAC: + dc_cvac_range((void *)request->args[0], request->args[1]); + break; + case P_DC_CVAU: + dc_cvau_range((void *)request->args[0], request->args[1]); + break; + case P_DC_CIVAC: + dc_civac_range((void *)request->args[0], request->args[1]); + break; + case P_MMU_SHUTDOWN: + mmu_shutdown(); + break; + case P_MMU_INIT: + mmu_init(); + break; + case P_MMU_DISABLE: + reply->retval = mmu_disable(); + break; + case P_MMU_RESTORE: + mmu_restore(request->args[0]); + break; + case P_MMU_INIT_SECONDARY: + mmu_init_secondary(request->args[0]); + break; + + case P_XZDEC: { + uint32_t destlen, srclen; + destlen = request->args[3]; + srclen = request->args[1]; + if (XzDecode((void *)request->args[0], &srclen, (void *)request->args[2], &destlen)) + reply->retval = destlen; + else + reply->retval = ~0L; + break; + } + case P_GZDEC: { + unsigned int destlen, srclen; + destlen = request->args[3]; + srclen = request->args[1]; + size_t ret = tinf_gzip_uncompress((void *)request->args[2], &destlen, + (void *)request->args[0], &srclen); + if (ret != TINF_OK) + reply->retval = ret; + else + reply->retval = destlen; + break; + } + + case P_SMP_START_SECONDARIES: + smp_start_secondaries(); + break; + case P_SMP_CALL: + smp_call4(request->args[0], (void *)request->args[1], request->args[2], + request->args[3], request->args[4], request->args[5]); + break; + case P_SMP_CALL_SYNC: + smp_call4(request->args[0], (void *)request->args[1], request->args[2], + request->args[3], request->args[4], request->args[5]); + reply->retval = smp_wait(request->args[0]); + break; + case P_SMP_WAIT: + reply->retval = smp_wait(request->args[0]); + break; + case P_SMP_SET_WFE_MODE: + smp_set_wfe_mode(request->args[0]); + break; + + case P_HEAPBLOCK_ALLOC: + reply->retval = (u64)heapblock_alloc(request->args[0]); + break; + case P_MALLOC: + reply->retval = (u64)malloc(request->args[0]); + break; + case P_MEMALIGN: + reply->retval = (u64)memalign(request->args[0], request->args[1]); + break; + case P_FREE: + free((void *)request->args[0]); + break; + + case P_KBOOT_BOOT: + if (kboot_boot((void *)request->args[0]) == 0) + return 1; + break; + case P_KBOOT_SET_CHOSEN: + reply->retval = kboot_set_chosen((void *)request->args[0], (void *)request->args[1]); + break; + case P_KBOOT_SET_INITRD: + kboot_set_initrd((void *)request->args[0], request->args[1]); + break; + case P_KBOOT_PREPARE_DT: + reply->retval = kboot_prepare_dt((void *)request->args[0]); + break; + + case P_PMGR_POWER_ENABLE: + reply->retval = pmgr_power_enable(request->args[0]); + break; + case P_PMGR_POWER_DISABLE: + reply->retval = pmgr_power_enable(request->args[0]); + break; + case P_PMGR_ADT_POWER_ENABLE: + reply->retval = pmgr_adt_power_enable((const char *)request->args[0]); + break; + case P_PMGR_ADT_POWER_DISABLE: + reply->retval = pmgr_adt_power_disable((const char *)request->args[0]); + break; + case P_PMGR_RESET: + reply->retval = pmgr_reset(request->args[0], (const char *)request->args[1]); + break; + + case P_IODEV_SET_USAGE: + iodev_set_usage(request->args[0], request->args[1]); + break; + case P_IODEV_CAN_READ: + reply->retval = iodev_can_read(request->args[0]); + break; + case P_IODEV_CAN_WRITE: + reply->retval = iodev_can_write(request->args[0]); + break; + case P_IODEV_READ: + reply->retval = + iodev_read(request->args[0], (void *)request->args[1], request->args[2]); + break; + case P_IODEV_WRITE: + reply->retval = + iodev_write(request->args[0], (void *)request->args[1], request->args[2]); + break; + case P_IODEV_WHOAMI: + reply->retval = uartproxy_iodev; + break; + + case P_USB_IODEV_VUART_SETUP: + usb_iodev_vuart_setup(request->args[0]); + break; + + case P_TUNABLES_APPLY_GLOBAL: + reply->retval = tunables_apply_global((const char *)request->args[0], + (const char *)request->args[1]); + break; + case P_TUNABLES_APPLY_LOCAL: + reply->retval = tunables_apply_local((const char *)request->args[0], + (const char *)request->args[1], request->args[2]); + break; + case P_TUNABLES_APPLY_LOCAL_ADDR: + reply->retval = tunables_apply_local_addr( + (const char *)request->args[0], (const char *)request->args[1], request->args[2]); + break; + + case P_DART_INIT: + reply->retval = (u64)dart_init(request->args[0], request->args[1], request->args[2], + request->args[3]); + break; + case P_DART_SHUTDOWN: + dart_shutdown((dart_dev_t *)request->args[0]); + break; + case P_DART_MAP: + reply->retval = dart_map((dart_dev_t *)request->args[0], request->args[1], + (void *)request->args[2], request->args[3]); + break; + case P_DART_UNMAP: + dart_unmap((dart_dev_t *)request->args[0], request->args[1], request->args[2]); + break; + + case P_HV_INIT: + hv_init(); + break; + case P_HV_MAP: + hv_map(request->args[0], request->args[1], request->args[2], request->args[3]); + break; + case P_HV_START: + hv_start((void *)request->args[0], &request->args[1]); + break; + case P_HV_TRANSLATE: + reply->retval = hv_translate(request->args[0], request->args[1], request->args[2], + (void *)request->args[3]); + break; + case P_HV_PT_WALK: + reply->retval = hv_pt_walk(request->args[0]); + break; + case P_HV_MAP_VUART: + hv_map_vuart(request->args[0], request->args[1], request->args[2]); + break; + case P_HV_MAP_VIRTIO: + hv_map_virtio(request->args[0], (void *)request->args[1]); + break; + case P_VIRTIO_PUT_BUFFER: + virtio_put_buffer(request->args[0], request->args[1], request->args[2], + request->args[3]); + break; + case P_HV_TRACE_IRQ: + reply->retval = hv_trace_irq(request->args[0], request->args[1], request->args[2], + request->args[3]); + break; + case P_HV_WDT_START: + hv_wdt_start(request->args[0]); + break; + case P_HV_START_SECONDARY: + hv_start_secondary(request->args[0], (void *)request->args[1], &request->args[2]); + break; + case P_HV_SWITCH_CPU: + reply->retval = hv_switch_cpu(request->args[0]); + break; + case P_HV_SET_TIME_STEALING: + hv_set_time_stealing(request->args[0], request->args[1]); + break; + case P_HV_PIN_CPU: + hv_pin_cpu(request->args[0]); + break; + case P_HV_WRITE_HCR: + hv_write_hcr(request->args[0]); + break; + + case P_FB_INIT: + fb_init(request->args[0]); + break; + case P_FB_SHUTDOWN: + fb_shutdown(request->args[0]); + break; + case P_FB_BLIT: + // HACK: Running out of args, stash pix fmt in high bits of stride... + fb_blit(request->args[0], request->args[1], request->args[2], request->args[3], + (void *)request->args[4], (u32)request->args[5], request->args[5] >> 32); + break; + case P_FB_UNBLIT: + fb_unblit(request->args[0], request->args[1], request->args[2], request->args[3], + (void *)request->args[4], request->args[5]); + break; + case P_FB_FILL: + fb_fill(request->args[0], request->args[1], request->args[2], request->args[3], + int2rgb(request->args[4])); + break; + case P_FB_CLEAR: + fb_clear(int2rgb(request->args[0])); + break; + case P_FB_DISPLAY_LOGO: + fb_display_logo(); + break; + case P_FB_RESTORE_LOGO: + fb_restore_logo(); + break; + case P_FB_IMPROVE_LOGO: + fb_improve_logo(); + break; + + case P_PCIE_INIT: + pcie_init(); + break; + case P_PCIE_SHUTDOWN: + pcie_shutdown(); + break; + + case P_NVME_INIT: + reply->retval = nvme_init(); + break; + case P_NVME_SHUTDOWN: + nvme_shutdown(); + break; + case P_NVME_READ: + reply->retval = nvme_read(request->args[0], request->args[1], (void *)request->args[2]); + break; + case P_NVME_FLUSH: + reply->retval = nvme_flush(request->args[0]); + break; + + case P_MCC_GET_CARVEOUTS: + reply->retval = (u64)mcc_carveouts; + break; + + case P_DISPLAY_INIT: + reply->retval = display_init(); + break; + case P_DISPLAY_CONFIGURE: + reply->retval = display_configure((char *)request->args[0]); + break; + case P_DISPLAY_SHUTDOWN: + display_shutdown(request->args[0]); + break; + case P_DISPLAY_START_DCP: + display_start_dcp(); + break; + case P_DISPLAY_IS_EXTERNAL: + reply->retval = display_is_external; + break; + + case P_DAPF_INIT_ALL: + reply->retval = dapf_init_all(); + break; + case P_DAPF_INIT: + reply->retval = dapf_init((const char *)request->args[0]); + break; + + default: + reply->status = S_BADCMD; + break; + } + sysop("dsb sy"); + sysop("isb"); + exc_guard = guard_save; + return 0; +} |
