Changes in / [b6636dc:23c1fae] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/arm32/src/mm/page_fault.c
rb6636dc r23c1fae 77 77 } 78 78 79 /** Decides whether the instruction is load/store or not.80 *81 * @param instr Instruction82 *83 * @return true when instruction is load/store, false otherwise84 *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 Instruction110 *111 * @return true when instruction is swap, false otherwise112 */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 124 79 /** Decides whether read or write into memory is requested. 125 80 * … … 146 101 } 147 102 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; 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; 154 131 } 155 }156 157 /* swap, swpb instruction */158 if (is_swap_instruction(instr)) {159 return PF_ACCESS_WRITE;160 132 } 161 133 … … 163 135 "(instr_code: %#0" PRIx32 ", badvaddr:%p).", 164 136 instr_union.pc, (void *) badvaddr); 165 166 return PF_ACCESS_EXEC;167 137 } 168 138
Note:
See TracChangeset
for help on using the changeset viewer.