khypervisor  v1
trap_dabort.c
Go to the documentation of this file.
00001 #include <arch_types.h>
00002 #include <armv7_p15.h>
00003 #include <vdev.h>
00004 #include <hvmm_trace.h>
00005 #include "context.h"
00006 #include "trap_dabort.h"
00007 
00008 #define DEBUG
00009 #include <log/print.h>
00010 
00011 /*
00012  * ISS encoding for Data Abort exceptions taken to Hyp mode as beloww
00013  * ISS[24] : instruction syndrome valid. 0 is invalid information in ISS. 1 is valid information in ISS
00014  * when ISS[24] is 0, we don't need to extract information from the rest of ISS field
00015  * when ISS[24] is 1, we need to extract information from ISS[26:13]
00016  *
00017  * ISS[26:13] is consist of 10 parts. Details as below
00018  *
00019  * - ISS[23:22] is an access size.
00020  * - e.g. byte, hardword, word
00021  * - ISS[21] is a sign extend
00022  * - e.g. 1 is not sign, 1 is sign
00023  * - ISS[20] is reserved
00024  * - ISS[19:16] is for register transfer ?
00025  * - ISS[15:10] is reserved
00026  * - ISS[9] is an external abort type. It is IMPLEMENTATION_DEFINED
00027  * - ISS[8] is a cache maintenance. For synchronous fault, it should need a cache maintenance.
00028  * - ISS[7] is a stage 2 fault for a stage 1 translation table walk
00029  * - ISS[6] is synchronous abort that was caused by a write or read operation
00030  * - ISS[5:0] is a data fault status code(DFSC) 
00031  * Additional register we should reference a DFSR 
00032  */
00033 
00034 #define ISS_VALID                       0x01000000
00035 
00036 #define ISS_FSR_MASK                    0x0000003F
00037 #define ISS_TRANS_FAULT_MASK            0x07
00038 #define TRANS_FAULT_LEVEL1              0x05
00039 #define TRANS_FAULT_LEVEL2              0x06
00040 #define TRANS_FAULT_LEVEL3              0x07
00041 #define ACCESS_FAULT_LEVEL0             0x08
00042 #define ACCESS_FAULT_LEVEL1             0x09
00043 #define ACCESS_FAULT_LEVEL2             0x0A
00044 #define ACCESS_FAULT_LEVEL3             0x0B
00045 
00046 #define ISS_WNR_SHIFT                   6
00047 #define ISS_WNR                         (1 << ISS_WNR_SHIFT)
00048 
00049 #define ISS_SAS_SHIFT                   22
00050 #define ISS_SAS_MASK                    (0x3 << ISS_SAS_SHIFT)
00051 #define ISS_SAS_BYTE                    0x0
00052 #define ISS_SAS_HWORD                   0x1
00053 #define ISS_SAS_WORD                    0x2
00054 #define ISS_SAS_RESERVED                0x3
00055 
00056 #define ISS_SSE_SHIFT                   21
00057 #define ISS_SSE_MASK                    (0x1 << ISS_SSE_SHIFT)
00058 
00059 #define ISS_SRT_SHIFT                   16
00060 #define ISS_SRT_MASK                    (0xf << ISS_SRT_SHIFT)
00061 
00062 /* HPFAR */
00063 #define HPFAR_INITVAL                   0x00000000
00064 #define HPFAR_FIPA_MASK                 0xFFFFFFF0
00065 #define HPFAR_FIPA_SHIFT                4
00066 #define HPFAR_FIPA_PAGE_MASK                0x00000FFF
00067 #define HPFAR_FIPA_PAGE_SHIFT               12
00068 
00069 /*
00070    Handles data abort case trapped into hvc, not dabort
00071  */
00072 hvmm_status_t trap_hvc_dabort(unsigned int iss, struct arch_regs *regs)
00073 {
00074     hvmm_status_t result = HVMM_STATUS_UNKNOWN_ERROR;
00075     //far, fipa, il
00076     uint32_t far = read_hdfar();
00077     uint32_t fipa;
00078     uint32_t sas, srt, wnr;
00079 
00080     HVMM_TRACE_ENTER();
00081 
00082     printh( "trap_hvc_dabort: hdfar:%x hpfar:%x\n", far, read_hpfar() );
00083     fipa = (read_hpfar() & HPFAR_FIPA_MASK) >> HPFAR_FIPA_SHIFT;
00084     fipa = fipa << HPFAR_FIPA_PAGE_SHIFT;
00085     fipa = fipa | (far & HPFAR_FIPA_PAGE_MASK);
00086     sas = (iss & ISS_SAS_MASK) >> ISS_SAS_SHIFT;
00087     srt = (iss & ISS_SRT_MASK) >> ISS_SRT_SHIFT;
00088     wnr = (iss & ISS_WNR) ? 1 : 0;
00089 
00090     if ( (iss & ISS_VALID) && ((iss & ISS_FSR_MASK) < 8) ) {
00091         /*
00092            vdev emulates read/write, update pc, update destination register
00093          */
00094         result = vdev_emulate(fipa, wnr, (vdev_access_size_t) sas, srt, regs );
00095         if ( result != HVMM_STATUS_SUCCESS ) {
00096             printh( "trap_dabort: emulation failed guest pc:%x\n", regs->pc );
00097 
00098             /* Let the guest continue by increasing pc */
00099             regs->pc += 4;
00100         }
00101     } else {
00102         printh( "trap_dboart: fipa=0x%x\n", fipa );
00103         result = HVMM_STATUS_BAD_ACCESS;
00104     }
00105     if ( result != HVMM_STATUS_SUCCESS ) {
00106         printh( "- INSTR: %s[%d] r%d [%x]\n", wnr ? "str" : "ldr", (sas + 1) * 8, srt, fipa );
00107     }
00108 
00109     switch (iss & ISS_FSR_MASK) {
00110         case TRANS_FAULT_LEVEL1:
00111         case TRANS_FAULT_LEVEL2:
00112         case TRANS_FAULT_LEVEL3:
00113             break;
00114 
00115         case ACCESS_FAULT_LEVEL1:
00116         case ACCESS_FAULT_LEVEL2:
00117         case ACCESS_FAULT_LEVEL3:
00118             {
00119                 printh("ACCESS fault %d\n", iss & ISS_FSR_MASK);
00120             }
00121             break;
00122         default:
00123         break;
00124     }
00125     HVMM_TRACE_EXIT();
00126 
00127     return result;
00128 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines