summaryrefslogtreecommitdiff
path: root/tools/src/proxy.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/src/proxy.c')
-rw-r--r--tools/src/proxy.c575
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;
+}