Changeset ecd1a0a in mainline


Ignore:
Timestamp:
2012-09-04T10:09:41Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
cc250b3
Parents:
c5b69a5e
Message:

arm32: Use FSR for data aborts on armv6+.

Location:
kernel/arch/arm32
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/arm32/include/mm/page_fault.h

    rc5b69a5e recd1a0a  
    4040
    4141
    42 /** Decribes CP15 "fault status register" (FSR). */
    43 typedef struct {
    44         unsigned status : 3;
    45         unsigned domain : 4;
    46         unsigned zero : 1;
    47         unsigned should_be_zero : 24;
    48 } ATTRIBUTE_PACKED fault_status_t;
    49 
    50 
    51 /** Help union used for casting integer value into #fault_status_t. */
     42/** Decribes CP15 "fault status register" (FSR).
     43 *
     44 * See ARM Architecture Reference Manual ch. B4.9.6 (pdf p.743).
     45 */
    5246typedef union {
    53         fault_status_t fs;
    54         uint32_t dummy;
    55 } fault_status_union_t;
     47        struct {
     48                unsigned status : 4;
     49                unsigned domain : 4;
     50                unsigned zero : 1;
     51                unsigned sbz0 : 1;
     52                unsigned fs : 1; /**< armv6+ mandated, earlier IPLM. DEFINED */
     53                unsigned wr : 1; /**< armv6+ only */
     54                unsigned should_be_zero : 20;
     55        } ATTRIBUTE_PACKED data;
     56        struct {
     57                unsigned status : 4;
     58                unsigned sbz0 : 6;
     59                unsigned fs : 1;
     60                unsigned should_be_zero : 21;
     61        } ATTRIBUTE_PACKED inst;
     62        uint32_t raw;
     63} fault_status_t;
    5664
    5765
  • kernel/arch/arm32/src/mm/page_fault.c

    rc5b69a5e recd1a0a  
    4242#include <print.h>
    4343
    44 /** Returns value stored in fault status register.
     44/** Returns value stored in comnbined/data fault status register.
    4545 *
    4646 *  @return Value stored in CP15 fault status register (FSR).
    47  */
    48 static inline fault_status_t read_fault_status_register(void)
    49 {
    50         fault_status_union_t fsu;
    51        
    52         /* fault status is stored in CP15 register 5 */
     47 *
     48 *  "VMSAv6 added a fifth fault status bit (bit[10]) to both the IFSR and DFSR.
     49 *  It is IMPLEMENTATION DEFINED how this bit is encoded in earlier versions of
     50 *  the architecture. A write flag (bit[11] of the DFSR) has also been
     51 *  introduced."
     52 *  ARM Architecture Reference Manual version i ch. B4.6 (PDF p. 719)
     53 *
     54 *  See ch. B4.9.6 for location of data/instruction FSR.
     55 *
     56 */
     57static inline fault_status_t read_data_fault_status_register(void)
     58{
     59        fault_status_t fsu;
     60       
     61        /* Combined/Data fault status is stored in CP15 register 5, c0. */
    5362        asm volatile (
    5463                "mrc p15, 0, %[dummy], c5, c0, 0"
    55                 : [dummy] "=r" (fsu.dummy)
     64                : [dummy] "=r" (fsu.raw)
    5665        );
    5766       
    58         return fsu.fs;
    59 }
    60 
    61 /** Returns FAR (fault address register) content.
    62  *
    63  * @return FAR (fault address register) content (address that caused a page
     67        return fsu;
     68}
     69
     70/** Returns DFAR (fault address register) content.
     71 *
     72 * This register is equivalent to FAR on pre armv6 machines.
     73 *
     74 * @return DFAR (fault address register) content (address that caused a page
    6475 *         fault)
    6576 */
    66 static inline uintptr_t read_fault_address_register(void)
     77static inline uintptr_t read_data_fault_address_register(void)
    6778{
    6879        uintptr_t ret;
     
    122133}
    123134
     135#if defined(PROCESSOR_armv4) | defined(PROCESSOR_armv5)
    124136/** Decides whether read or write into memory is requested.
    125137 *
     
    166178        return PF_ACCESS_EXEC;
    167179}
     180#endif
    168181
    169182/** Handles "data abort" exception (load or store at invalid address).
     
    175188void data_abort(unsigned int exc_no, istate_t *istate)
    176189{
    177         fault_status_t fsr __attribute__ ((unused)) =
    178             read_fault_status_register();
    179         uintptr_t badvaddr = read_fault_address_register();
    180 
    181         pf_access_t access = get_memory_access_type(istate->pc, badvaddr);
    182 
     190        uintptr_t badvaddr = read_data_fault_address_register();
     191
     192#if defined(PROCESSOR_armv6) | defined(PROCESSOR_armv7_a)
     193        fault_status_t fsr = read_data_fault_status_register();
     194        const pf_access_t access =
     195            fsr.data.wr ? PF_ACCESS_WRITE : PF_ACCESS_READ;
     196#elif defined(PROCESSOR_armv4) | defined(PROCESSOR_armv5)
     197        const pf_access_t access = get_memory_access_type(istate->pc, badvaddr);
     198#else
     199#error "Unsupported architecture"
     200#endif
    183201        int ret = as_page_fault(badvaddr, access, istate);
    184202
     
    197215void prefetch_abort(unsigned int exc_no, istate_t *istate)
    198216{
     217        /* NOTE: We should use IFAR and IFSR here. */
    199218        int ret = as_page_fault(istate->pc, PF_ACCESS_EXEC, istate);
    200219
Note: See TracChangeset for help on using the changeset viewer.