1/* 2 * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230) 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6#include <stdlib.h> 7#include <string.h> 8#include <sel4/types.h> 9 10#include <sel4vm/guest_vm.h> 11#include <sel4vm/guest_memory.h> 12 13#include <sel4vmmplatsupport/guest_memory_util.h> 14#include <sel4vmmplatsupport/plat/usb.h> 15#include <sel4vmmplatsupport/device.h> 16#include <sel4vmmplatsupport/arch/guest_reboot.h> 17#include <utils/io.h> 18 19#define USB2_CONTROLLER_USB2D_USBCMD_0_OFFSET 0x130 20#define USB2D_USB_COMMAND_REGISTER_RESET_BIT BIT(1) 21 22const struct device dev_usb = { 23 .name = "usb", 24 .pstart = 0x7d004000, 25 .size = PAGE_SIZE, 26 .priv = NULL 27}; 28 29static int usb_vm_reboot_hook(vm_t *vm, void *token) 30{ 31 void *usb_cmd_register = token + USB2_CONTROLLER_USB2D_USBCMD_0_OFFSET; 32 uint32_t reg = RAW_READ32(usb_cmd_register); 33 RAW_WRITE32(reg | USB2D_USB_COMMAND_REGISTER_RESET_BIT, usb_cmd_register); 34 return 0; 35} 36 37 38static memory_fault_result_t handle_usb_fault(vm_t *vm, vm_vcpu_t *vcpu, uintptr_t fault_addr, size_t fault_length, 39 void *cookie) 40{ 41 ZF_LOGE("Fault occured on passthrough usb device"); 42 return FAULT_ERROR; 43} 44 45int vm_install_tk1_usb_passthrough_device(vm_t *vm, reboot_hooks_list_t *reboot_hooks) 46{ 47 /* Add the device */ 48 void *vmm_addr = create_device_reservation_frame(vm, dev_usb.pstart, seL4_AllRights, handle_usb_fault, NULL); 49 if (vmm_addr == NULL) { 50 ZF_LOGE("Failed to create passthrough usb device"); 51 return -1; 52 } 53 54 int err = vmm_register_reboot_callback(reboot_hooks, usb_vm_reboot_hook, vmm_addr); 55 if (err) { 56 ZF_LOGE("vm_register_reboot_callback returned error: %d", err); 57 return -1; 58 } 59 60 return 0; 61} 62