Changes in / [23c1fae:b6636dc] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/arm32/src/mm/page_fault.c
r23c1fae rb6636dc 77 77 } 78 78 79 /** Decides whether the instruction is load/store or not. 80 * 81 * @param instr Instruction 82 * 83 * @return true when instruction is load/store, false otherwise 84 * 85 */ 86 static inline bool is_load_store_instruction(instruction_t instr) 87 { 88 /* load store immediate offset */ 89 if (instr.type == 0x2) 90 return true; 91 92 /* load store register offset */ 93 if ((instr.type == 0x3) && (instr.bit4 == 0)) 94 return true; 95 96 /* load store multiple */ 97 if (instr.type == 0x4) 98 return true; 99 100 /* oprocessor load/store */ 101 if (instr.type == 0x6) 102 return true; 103 104 return false; 105 } 106 107 /** Decides whether the instruction is swap or not. 108 * 109 * @param instr Instruction 110 * 111 * @return true when instruction is swap, false otherwise 112 */ 113 static inline bool is_swap_instruction(instruction_t instr) 114 { 115 /* swap, swapb instruction */ 116 if ((instr.type == 0x0) && 117 ((instr.opcode == 0x8) || (instr.opcode == 0xa)) && 118 (instr.access == 0x0) && (instr.bits567 == 0x4) && (instr.bit4 == 1)) 119 return true; 120 121 return false; 122 } 123 79 124 /** Decides whether read or write into memory is requested. 80 125 * … … 101 146 } 102 147 103 /* See ARM Architecture reference manual ARMv7-A and ARMV7-R edition 104 * A5.3 (PDF p. 206) */ 105 static const struct { 106 uint32_t mask; 107 uint32_t value; 108 pf_access_t access; 109 } ls_inst[] = { 110 /* Store word/byte */ 111 { 0x0e100000, 0x04000000, PF_ACCESS_WRITE }, /*STR(B) imm*/ 112 { 0x0e100010, 0x06000000, PF_ACCESS_WRITE }, /*STR(B) reg*/ 113 /* Load word/byte */ 114 { 0x0e100000, 0x04100000, PF_ACCESS_READ }, /*LDR(B) imm*/ 115 { 0x0e100010, 0x06100000, PF_ACCESS_READ }, /*LDR(B) reg*/ 116 /* Store half-word/dual A5.2.8 */ 117 { 0x0e1000b0, 0x000000b0, PF_ACCESS_WRITE }, /*STRH imm reg*/ 118 /* Load half-word/dual A5.2.8 */ 119 { 0x0e0000f0, 0x000000d0, PF_ACCESS_READ }, /*LDRH imm reg*/ 120 { 0x0e1000b0, 0x001000b0, PF_ACCESS_READ }, /*LDRH imm reg*/ 121 /* Block data transfer, Store */ 122 { 0x0e100000, 0x08000000, PF_ACCESS_WRITE }, /* STM variants */ 123 { 0x0e100000, 0x08100000, PF_ACCESS_READ }, /* LDM variants */ 124 /* Swap */ 125 { 0x0fb00000, 0x01000000, PF_ACCESS_WRITE }, 126 }; 127 uint32_t inst = *(uint32_t*)instr_addr; 128 for (unsigned i = 0; i < sizeof(ls_inst) / sizeof(ls_inst[0]); ++i) { 129 if ((inst & ls_inst[i].mask) == ls_inst[i].value) { 130 return ls_inst[i].access; 148 /* load store instructions */ 149 if (is_load_store_instruction(instr)) { 150 if (instr.access == 1) { 151 return PF_ACCESS_READ; 152 } else { 153 return PF_ACCESS_WRITE; 131 154 } 155 } 156 157 /* swap, swpb instruction */ 158 if (is_swap_instruction(instr)) { 159 return PF_ACCESS_WRITE; 132 160 } 133 161 … … 135 163 "(instr_code: %#0" PRIx32 ", badvaddr:%p).", 136 164 instr_union.pc, (void *) badvaddr); 165 166 return PF_ACCESS_EXEC; 137 167 } 138 168
Note:
See TracChangeset
for help on using the changeset viewer.