Changes in / [b6636dc:23c1fae] in mainline


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/arm32/src/mm/page_fault.c

    rb6636dc r23c1fae  
    7777}
    7878
    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 
    12479/** Decides whether read or write into memory is requested.
    12580 *
     
    146101        }
    147102
    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;
    154131                }
    155         }
    156 
    157         /* swap, swpb instruction */
    158         if (is_swap_instruction(instr)) {
    159                 return PF_ACCESS_WRITE;
    160132        }
    161133
     
    163135            "(instr_code: %#0" PRIx32 ", badvaddr:%p).",
    164136            instr_union.pc, (void *) badvaddr);
    165 
    166         return PF_ACCESS_EXEC;
    167137}
    168138
Note: See TracChangeset for help on using the changeset viewer.