Changeset 3451129 in mainline for kernel/arch/arm32/src/mm/page_fault.c
- Timestamp:
- 2012-09-07T15:05:43Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8776c46
- Parents:
- c6b601b (diff), 60d931d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/arm32/src/mm/page_fault.c
rc6b601b r3451129 88 88 } 89 89 90 /** Decides whether the instruction is load/store or not.91 *92 * @param instr Instruction93 *94 * @return true when instruction is load/store, false otherwise95 *96 */97 static inline bool is_load_store_instruction(instruction_t instr)98 {99 /* load store immediate offset */100 if (instr.type == 0x2)101 return true;102 103 /* load store register offset */104 if ((instr.type == 0x3) && (instr.bit4 == 0))105 return true;106 107 /* load store multiple */108 if (instr.type == 0x4)109 return true;110 111 /* oprocessor load/store */112 if (instr.type == 0x6)113 return true;114 115 return false;116 }117 118 /** Decides whether the instruction is swap or not.119 *120 * @param instr Instruction121 *122 * @return true when instruction is swap, false otherwise123 */124 static inline bool is_swap_instruction(instruction_t instr)125 {126 /* swap, swapb instruction */127 if ((instr.type == 0x0) &&128 ((instr.opcode == 0x8) || (instr.opcode == 0xa)) &&129 (instr.access == 0x0) && (instr.bits567 == 0x4) && (instr.bit4 == 1))130 return true;131 132 return false;133 }134 135 90 #if defined(PROCESSOR_armv4) | defined(PROCESSOR_armv5) 136 91 /** Decides whether read or write into memory is requested. … … 140 95 * 141 96 * @return Type of access into memory, PF_ACCESS_EXEC if no memory access is 142 * 97 * requested. 143 98 */ 144 99 static pf_access_t get_memory_access_type(uint32_t instr_addr, … … 158 113 } 159 114 160 /* load store instructions */ 161 if (is_load_store_instruction(instr)) { 162 if (instr.access == 1) { 163 return PF_ACCESS_READ; 164 } else { 165 return PF_ACCESS_WRITE; 115 /* See ARM Architecture reference manual ARMv7-A and ARMV7-R edition 116 * A5.3 (PDF p. 206) */ 117 static const struct { 118 uint32_t mask; 119 uint32_t value; 120 pf_access_t access; 121 } ls_inst[] = { 122 /* Store word/byte */ 123 { 0x0e100000, 0x04000000, PF_ACCESS_WRITE }, /*STR(B) imm*/ 124 { 0x0e100010, 0x06000000, PF_ACCESS_WRITE }, /*STR(B) reg*/ 125 /* Load word/byte */ 126 { 0x0e100000, 0x04100000, PF_ACCESS_READ }, /*LDR(B) imm*/ 127 { 0x0e100010, 0x06100000, PF_ACCESS_READ }, /*LDR(B) reg*/ 128 /* Store half-word/dual A5.2.8 */ 129 { 0x0e1000b0, 0x000000b0, PF_ACCESS_WRITE }, /*STRH imm reg*/ 130 /* Load half-word/dual A5.2.8 */ 131 { 0x0e0000f0, 0x000000d0, PF_ACCESS_READ }, /*LDRH imm reg*/ 132 { 0x0e1000b0, 0x001000b0, PF_ACCESS_READ }, /*LDRH imm reg*/ 133 /* Block data transfer, Store */ 134 { 0x0e100000, 0x08000000, PF_ACCESS_WRITE }, /* STM variants */ 135 { 0x0e100000, 0x08100000, PF_ACCESS_READ }, /* LDM variants */ 136 /* Swap */ 137 { 0x0fb00000, 0x01000000, PF_ACCESS_WRITE }, 138 }; 139 const uint32_t inst = *(uint32_t*)instr_addr; 140 for (unsigned i = 0; i < sizeof(ls_inst) / sizeof(ls_inst[0]); ++i) { 141 if ((inst & ls_inst[i].mask) == ls_inst[i].value) { 142 return ls_inst[i].access; 166 143 } 167 }168 169 /* swap, swpb instruction */170 if (is_swap_instruction(instr)) {171 return PF_ACCESS_WRITE;172 144 } 173 145 174 146 panic("page_fault - instruction doesn't access memory " 175 147 "(instr_code: %#0" PRIx32 ", badvaddr:%p).", 176 *(uint32_t*)instr_union.instr, (void *) badvaddr); 177 178 return PF_ACCESS_EXEC; 148 inst, (void *) badvaddr); 179 149 } 180 150 #endif
Note:
See TracChangeset
for help on using the changeset viewer.