blob: c59225ca22d379dc270022744a663624d809bfc6 [file]
/* SPDX-License-Identifier: MIT */
#include "proxy.h"
#include "cpufreq.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_SLEEP:
cpu_sleep(request->args[0]);
break;
case P_EL3_CALL:
reply->retval = el3_call((void *)request->args[0], request->args[1], request->args[2],
request->args[3], request->args[4]);
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_STOP_SECONDARIES:
smp_stop_secondaries(request->args[0]);
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_SMP_IS_ALIVE:
reply->retval = smp_is_alive(request->args[0]);
break;
case P_SMP_CALL_EL1:
smp_call4(request->args[0], el1_call, request->args[1], request->args[2],
request->args[3], request->args[4]);
break;
case P_SMP_CALL_EL1_SYNC:
smp_call4(request->args[0], el1_call, request->args[1], request->args[2],
request->args[3], request->args[4]);
reply->retval = smp_wait(request->args[0]);
break;
case P_SMP_CALL_EL0:
smp_call4(request->args[0], el0_call, request->args[1], request->args[2],
request->args[3], request->args[4]);
break;
case P_SMP_CALL_EL0_SYNC:
smp_call4(request->args[0], el0_call, request->args[1], request->args[2],
request->args[3], request->args[4]);
reply->retval = smp_wait(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_HV_EXIT_CPU:
hv_exit_cpu(request->args[0]);
break;
case P_HV_ADD_TIME:
hv_add_time(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], 1);
break;
case P_CPUFREQ_INIT:
reply->retval = cpufreq_init();
break;
default:
reply->status = S_BADCMD;
break;
}
sysop("dsb sy");
sysop("isb");
exc_guard = guard_save;
return 0;
}