Changes in / [23c1fae:b6636dc] in mainline


Ignore:
File:
1 edited

Legend:

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

    r23c1fae rb6636dc  
    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 */
     86static 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 */
     113static 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
    79124/** Decides whether read or write into memory is requested.
    80125 *
     
    101146        }
    102147
    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;
    131154                }
     155        }
     156
     157        /* swap, swpb instruction */
     158        if (is_swap_instruction(instr)) {
     159                return PF_ACCESS_WRITE;
    132160        }
    133161
     
    135163            "(instr_code: %#0" PRIx32 ", badvaddr:%p).",
    136164            instr_union.pc, (void *) badvaddr);
     165
     166        return PF_ACCESS_EXEC;
    137167}
    138168
Note: See TracChangeset for help on using the changeset viewer.