Ignore:
Timestamp:
2012-09-07T15:05:43Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
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.
Message:

Mainline changes.

File:
1 edited

Legend:

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

    rc6b601b r3451129  
    8888}
    8989
    90 /** Decides whether the instruction is load/store or not.
    91  *
    92  * @param instr Instruction
    93  *
    94  * @return true when instruction is load/store, false otherwise
    95  *
    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 Instruction
    121  *
    122  * @return true when instruction is swap, false otherwise
    123  */
    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 
    13590#if defined(PROCESSOR_armv4) | defined(PROCESSOR_armv5)
    13691/** Decides whether read or write into memory is requested.
     
    14095 *
    14196 * @return Type of access into memory, PF_ACCESS_EXEC if no memory access is
    142  *         requested.
     97 *         requested.
    14398 */
    14499static pf_access_t get_memory_access_type(uint32_t instr_addr,
     
    158113        }
    159114
    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;
    166143                }
    167         }
    168 
    169         /* swap, swpb instruction */
    170         if (is_swap_instruction(instr)) {
    171                 return PF_ACCESS_WRITE;
    172144        }
    173145
    174146        panic("page_fault - instruction doesn't access memory "
    175147            "(instr_code: %#0" PRIx32 ", badvaddr:%p).",
    176             *(uint32_t*)instr_union.instr, (void *) badvaddr);
    177 
    178         return PF_ACCESS_EXEC;
     148            inst, (void *) badvaddr);
    179149}
    180150#endif
Note: See TracChangeset for help on using the changeset viewer.