|  | 
| 18 | 18 | #include "context.h" | 
| 19 | 19 | #include "debug.h" | 
| 20 | 20 | #include "vmpu.h" | 
|  | 21 | +#include "vmpu_mpu.h" | 
| 21 | 22 | #include "vmpu_unpriv_access.h" | 
| 22 | 23 | #include <stdbool.h> | 
| 23 | 24 | 
 | 
|  | 
| 54 | 55 | #define TT_RESP_MREGION_Pos     0U | 
| 55 | 56 | #define TT_RESP_MREGION_Msk     (0xFFUL << TT_RESP_MREGION_Pos) | 
| 56 | 57 | 
 | 
| 57 |  | - | 
| 58 |  | -static uint32_t vmpu_unpriv_test_range(uint32_t addr, uint32_t size) | 
| 59 |  | -{ | 
| 60 |  | -    if (!size) size = 1; | 
| 61 |  | -    uint32_t response_lower, response_upper; | 
| 62 |  | -    uint32_t test_addr_lower = addr & ~31UL; | 
| 63 |  | -    uint32_t test_addr_upper = (addr + size - 1) & ~31UL; | 
| 64 |  | - | 
| 65 |  | -    /* Test lower address. */ | 
| 66 |  | -    asm volatile ( | 
| 67 |  | -        "tta %[response], %[addr]" | 
| 68 |  | -        : [response] "=r" (response_lower) | 
| 69 |  | -        : [addr] "r" (test_addr_lower) | 
| 70 |  | -    ); | 
| 71 |  | -    if (test_addr_lower != test_addr_upper) { | 
| 72 |  | -        /* Test upper address. */ | 
| 73 |  | -        asm volatile ( | 
| 74 |  | -            "tta %[response], %[addr]" | 
| 75 |  | -            : [response] "=r" (response_upper) | 
| 76 |  | -            : [addr] "r" (test_addr_upper) | 
| 77 |  | -        ); | 
| 78 |  | -        /* If lower and upper do not have the same S|SRVALID|SREGION, then it's definitely not the same region. */ | 
| 79 |  | -        if (((response_lower ^ response_upper) & (TT_RESP_S_Msk | TT_RESP_SRVALID_Msk | TT_RESP_SREGION_Msk))) { | 
| 80 |  | -            /* Upper memory region has different SAU region than lower memory region! */ | 
| 81 |  | -            return 0; | 
| 82 |  | -        } | 
| 83 |  | -        /* Both memory locations have the same non-secure SAU region and therefore same properties. | 
| 84 |  | -         * No Secure SAU region can be inbetween due to SAU region overlap rules. */ | 
| 85 |  | -        response_lower &= response_upper; | 
| 86 |  | -    } | 
| 87 |  | - | 
| 88 |  | -    return response_lower & (TT_RESP_NSRW_Msk | TT_RESP_NSR_Msk | TT_RESP_RW_Msk | TT_RESP_R_Msk | | 
| 89 |  | -                             TT_RESP_S_Msk | TT_RESP_SRVALID_Msk | TT_RESP_SREGION_Msk); | 
| 90 |  | -} | 
| 91 |  | - | 
| 92 |  | -extern int vmpu_fault_recovery_mpu(uint32_t pc, uint32_t sp, uint32_t fault_addr, uint32_t fault_status); | 
| 93 |  | - | 
| 94 | 58 | uint32_t vmpu_unpriv_access(uint32_t addr, uint32_t size, uint32_t data) | 
| 95 | 59 | { | 
| 96 |  | -    unsigned int tries = 0; | 
| 97 |  | -    while(1) { | 
| 98 |  | -        //if ((vmpu_unpriv_test_range(addr, UVISOR_UNPRIV_ACCESS_SIZE(size)) & (TT_RESP_NSRW_Msk | TT_RESP_SRVALID_Msk)) == (TT_RESP_NSRW_Msk | TT_RESP_SRVALID_Msk)) { | 
| 99 |  | -        //this should be slower substantualy | 
| 100 |  | -        if (vmpu_buffer_access_is_ok(g_active_box, addr, UVISOR_UNPRIV_ACCESS_SIZE(size))){ | 
| 101 |  | -            switch(size) { | 
| 102 |  | -                case UVISOR_UNPRIV_ACCESS_READ(1): | 
| 103 |  | -                    return *((uint8_t *) addr); | 
| 104 |  | -                case UVISOR_UNPRIV_ACCESS_READ(2): | 
| 105 |  | -                    return *((uint16_t *) addr); | 
| 106 |  | -                case UVISOR_UNPRIV_ACCESS_READ(4): | 
| 107 |  | -                    return *((uint32_t *) addr); | 
| 108 |  | -                case UVISOR_UNPRIV_ACCESS_WRITE(1): | 
| 109 |  | -                    *((uint8_t *) addr) = (uint8_t) data; | 
| 110 |  | -                    return 0; | 
| 111 |  | -                case UVISOR_UNPRIV_ACCESS_WRITE(2): | 
| 112 |  | -                    *((uint16_t *) addr) = (uint16_t) data; | 
| 113 |  | -                    return 0; | 
| 114 |  | -                case UVISOR_UNPRIV_ACCESS_WRITE(4): | 
| 115 |  | -                    *((uint32_t *) addr) = data; | 
| 116 |  | -                    return 0; | 
| 117 |  | -                default: | 
| 118 |  | -                    break; | 
| 119 |  | -            } | 
| 120 |  | -            break; | 
| 121 |  | -        } | 
| 122 |  | -        if (++tries > 1 || !vmpu_fault_recovery_mpu(0, 0, addr, 0)) { | 
| 123 |  | -            break; | 
|  | 60 | +    //if ((vmpu_unpriv_test_range(addr, UVISOR_UNPRIV_ACCESS_SIZE(size)) & (TT_RESP_NSRW_Msk | TT_RESP_SRVALID_Msk)) == (TT_RESP_NSRW_Msk | TT_RESP_SRVALID_Msk)) { | 
|  | 61 | +    //this should be slower substantualy | 
|  | 62 | +    if (vmpu_buffer_access_is_ok(g_active_box, (const void *) addr, UVISOR_UNPRIV_ACCESS_SIZE(size))){ | 
|  | 63 | +        switch(size) { | 
|  | 64 | +            case UVISOR_UNPRIV_ACCESS_READ(1): | 
|  | 65 | +                return *((uint8_t *) addr); | 
|  | 66 | +            case UVISOR_UNPRIV_ACCESS_READ(2): | 
|  | 67 | +                return *((uint16_t *) addr); | 
|  | 68 | +            case UVISOR_UNPRIV_ACCESS_READ(4): | 
|  | 69 | +                return *((uint32_t *) addr); | 
|  | 70 | +            case UVISOR_UNPRIV_ACCESS_WRITE(1): | 
|  | 71 | +                *((uint8_t *) addr) = (uint8_t) data; | 
|  | 72 | +                return 0; | 
|  | 73 | +            case UVISOR_UNPRIV_ACCESS_WRITE(2): | 
|  | 74 | +                *((uint16_t *) addr) = (uint16_t) data; | 
|  | 75 | +                return 0; | 
|  | 76 | +            case UVISOR_UNPRIV_ACCESS_WRITE(4): | 
|  | 77 | +                *((uint32_t *) addr) = data; | 
|  | 78 | +                return 0; | 
|  | 79 | +            default: | 
|  | 80 | +                break; | 
| 124 | 81 |         } | 
| 125 | 82 |     } | 
|  | 83 | +     | 
| 126 | 84 |     HALT_ERROR(PERMISSION_DENIED, "Access to restricted resource denied"); | 
| 127 | 85 |     return 0; | 
| 128 | 86 | } | 
0 commit comments