1 /*
2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7 #include <config.h>
8 #include <types.h>
9 #include <object.h>
10 #include <kernel/vspace.h>
11 #include <api/faults.h>
12 #include <api/syscall.h>
13
Arch_handleFaultReply(tcb_t * receiver,tcb_t * sender,word_t faultType)14 bool_t Arch_handleFaultReply(tcb_t *receiver, tcb_t *sender, word_t faultType)
15 {
16 switch (faultType) {
17 case seL4_Fault_VMFault:
18 return true;
19
20 #ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
21 case seL4_Fault_VGICMaintenance:
22 return true;
23 case seL4_Fault_VCPUFault:
24 return true;
25 case seL4_Fault_VPPIEvent:
26 return true;
27 #endif
28 default:
29 fail("Invalid fault");
30 }
31 }
32
Arch_setMRs_fault(tcb_t * sender,tcb_t * receiver,word_t * receiveIPCBuffer,word_t faultType)33 word_t Arch_setMRs_fault(tcb_t *sender, tcb_t *receiver, word_t *receiveIPCBuffer, word_t faultType)
34 {
35 switch (faultType) {
36 case seL4_Fault_VMFault: {
37 if (config_set(CONFIG_ARM_HYPERVISOR_SUPPORT)) {
38 word_t ipa, va;
39 va = getRestartPC(sender);
40 ipa = (addressTranslateS1CPR(va) & ~MASK(PAGE_BITS)) | (va & MASK(PAGE_BITS));
41 setMR(receiver, receiveIPCBuffer, seL4_VMFault_IP, ipa);
42 } else {
43 setMR(receiver, receiveIPCBuffer, seL4_VMFault_IP, getRestartPC(sender));
44 }
45 setMR(receiver, receiveIPCBuffer, seL4_VMFault_Addr,
46 seL4_Fault_VMFault_get_address(sender->tcbFault));
47 setMR(receiver, receiveIPCBuffer, seL4_VMFault_PrefetchFault,
48 seL4_Fault_VMFault_get_instructionFault(sender->tcbFault));
49 return setMR(receiver, receiveIPCBuffer, seL4_VMFault_FSR,
50 seL4_Fault_VMFault_get_FSR(sender->tcbFault));
51 }
52
53 #ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
54 case seL4_Fault_VGICMaintenance:
55 if (seL4_Fault_VGICMaintenance_get_idxValid(sender->tcbFault)) {
56 return setMR(receiver, receiveIPCBuffer, seL4_VGICMaintenance_IDX,
57 seL4_Fault_VGICMaintenance_get_idx(sender->tcbFault));
58 } else {
59 return setMR(receiver, receiveIPCBuffer, seL4_VGICMaintenance_IDX, -1);
60 }
61 case seL4_Fault_VCPUFault:
62 return setMR(receiver, receiveIPCBuffer, seL4_VCPUFault_HSR, seL4_Fault_VCPUFault_get_hsr(sender->tcbFault));
63 case seL4_Fault_VPPIEvent:
64 return setMR(receiver, receiveIPCBuffer, seL4_VPPIEvent_IRQ, seL4_Fault_VPPIEvent_get_irq_w(sender->tcbFault));
65 #endif
66
67 default:
68 fail("Invalid fault");
69 }
70 }
71