Ignore:
Timestamp:
2013-03-10T14:56:21Z (11 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
05bab88
Parents:
ea906c29 (diff), 2277e03 (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:

Merge mainline changes

File:
1 edited

Legend:

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

    rea906c29 r850235d  
    3434 */
    3535#include <panic.h>
     36#include <arch/cp15.h>
    3637#include <arch/exception.h>
    3738#include <arch/mm/page_fault.h>
     
    4243#include <print.h>
    4344
    44 /** Returns value stored in fault status register.
    45  *
    46  *  @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 */
    53         asm volatile (
    54                 "mrc p15, 0, %[dummy], c5, c0, 0"
    55                 : [dummy] "=r" (fsu.dummy)
    56         );
    57        
    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
    64  *         fault)
    65  */
    66 static inline uintptr_t read_fault_address_register(void)
    67 {
    68         uintptr_t ret;
    69        
    70         /* fault adress is stored in CP15 register 6 */
    71         asm volatile (
    72                 "mrc p15, 0, %[ret], c6, c0, 0"
    73                 : [ret] "=r" (ret)
    74         );
    75        
    76         return ret;
    77 }
    78 
     45
     46/**
     47 * FSR encoding ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition.
     48 *
     49 * B3.13.3 page B3-1406 (PDF page 1406)
     50 */
     51typedef enum {
     52        DFSR_SOURCE_ALIGN = 0x0001,
     53        DFSR_SOURCE_CACHE_MAINTENANCE = 0x0004,
     54        DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L1 = 0x000c,
     55        DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L2 = 0x000e,
     56        DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L1 = 0x040c,
     57        DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L2 = 0x040e,
     58        DFSR_SOURCE_TRANSLATION_L1 = 0x0005,
     59        DFSR_SOURCE_TRANSLATION_L2 = 0x0007,
     60        DFSR_SOURCE_ACCESS_FLAG_L1 = 0x0003,  /**< @note: This used to be alignment enc. */
     61        DFSR_SOURCE_ACCESS_FLAG_L2 = 0x0006,
     62        DFSR_SOURCE_DOMAIN_L1 = 0x0009,
     63        DFSR_SOURCE_DOMAIN_L2 = 0x000b,
     64        DFSR_SOURCE_PERMISSION_L1 = 0x000d,
     65        DFSR_SOURCE_PERMISSION_L2 = 0x000f,
     66        DFSR_SOURCE_DEBUG = 0x0002,
     67        DFSR_SOURCE_SYNC_EXTERNAL = 0x0008,
     68        DFSR_SOURCE_TLB_CONFLICT = 0x0400,
     69        DFSR_SOURCE_LOCKDOWN = 0x0404, /**< @note: Implementation defined */
     70        DFSR_SOURCE_COPROCESSOR = 0x040a, /**< @note Implementation defined */
     71        DFSR_SOURCE_SYNC_PARITY = 0x0409,
     72        DFSR_SOURCE_ASYNC_EXTERNAL = 0x0406,
     73        DFSR_SOURCE_ASYNC_PARITY = 0x0408,
     74        DFSR_SOURCE_MASK = 0x0000040f,
     75} dfsr_source_t;
     76
     77static inline const char * dfsr_source_to_str(dfsr_source_t source)
     78{
     79        switch (source) {
     80        case DFSR_SOURCE_TRANSLATION_L1:
     81                return "Translation fault L1";
     82        case DFSR_SOURCE_TRANSLATION_L2:
     83                return "Translation fault L2";
     84        case DFSR_SOURCE_PERMISSION_L1:
     85                return "Permission fault L1";
     86        case DFSR_SOURCE_PERMISSION_L2:
     87                return "Permission fault L2";
     88        case DFSR_SOURCE_ALIGN:
     89                return "Alignment fault";
     90        case DFSR_SOURCE_CACHE_MAINTENANCE:
     91                return "Instruction cache maintenance fault";
     92        case DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L1:
     93                return "Synchronous external abort on translation table walk level 1";
     94        case DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L2:
     95                return "Synchronous external abort on translation table walk level 2";
     96        case DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L1:
     97                return "Synchronous parity error on translation table walk level 1";
     98        case DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L2:
     99                return "Synchronous parity error on translation table walk level 2";
     100        case DFSR_SOURCE_ACCESS_FLAG_L1:
     101                return "Access flag fault L1";
     102        case DFSR_SOURCE_ACCESS_FLAG_L2:
     103                return "Access flag fault L2";
     104        case DFSR_SOURCE_DOMAIN_L1:
     105                return "Domain fault L1";
     106        case DFSR_SOURCE_DOMAIN_L2:
     107                return "Domain flault L2";
     108        case DFSR_SOURCE_DEBUG:
     109                return "Debug event";
     110        case DFSR_SOURCE_SYNC_EXTERNAL:
     111                return "Synchronous external abort";
     112        case DFSR_SOURCE_TLB_CONFLICT:
     113                return "TLB conflict abort";
     114        case DFSR_SOURCE_LOCKDOWN:
     115                return "Lockdown (Implementation defined)";
     116        case DFSR_SOURCE_COPROCESSOR:
     117                return "Coprocessor abort (Implementation defined)";
     118        case DFSR_SOURCE_SYNC_PARITY:
     119                return "Synchronous parity error on memory access";
     120        case DFSR_SOURCE_ASYNC_EXTERNAL:
     121                return "Asynchronous external abort";
     122        case DFSR_SOURCE_ASYNC_PARITY:
     123                return "Asynchronous parity error on memory access";
     124        case DFSR_SOURCE_MASK:
     125                break;
     126        }
     127        return "Unknown data abort";
     128}
     129
     130#if defined(PROCESSOR_ARCH_armv4) | defined(PROCESSOR_ARCH_armv5)
    79131/** Decides whether read or write into memory is requested.
    80132 *
     
    97149                panic("page_fault - instruction does not access memory "
    98150                    "(instr_code: %#0" PRIx32 ", badvaddr:%p).",
    99                     instr_union.pc, (void *) badvaddr);
     151                    *(uint32_t*)instr_union.instr, (void *) badvaddr);
    100152                return PF_ACCESS_EXEC;
    101153        }
     
    136188            inst, (void *) badvaddr);
    137189}
     190#endif
    138191
    139192/** Handles "data abort" exception (load or store at invalid address).
     
    145198void data_abort(unsigned int exc_no, istate_t *istate)
    146199{
    147         fault_status_t fsr __attribute__ ((unused)) =
    148             read_fault_status_register();
    149         uintptr_t badvaddr = read_fault_address_register();
    150 
    151         pf_access_t access = get_memory_access_type(istate->pc, badvaddr);
    152 
    153         int ret = as_page_fault(badvaddr, access, istate);
    154 
    155         if (ret == AS_PF_FAULT) {
    156                 fault_if_from_uspace(istate, "Page fault: %#x.", badvaddr);
    157                 panic_memtrap(istate, access, badvaddr, NULL);
    158         }
     200        const uintptr_t badvaddr = DFAR_read();
     201        const fault_status_t fsr = { .raw = DFSR_read() };
     202        const dfsr_source_t source = fsr.raw & DFSR_SOURCE_MASK;
     203
     204        switch (source) {
     205        case DFSR_SOURCE_TRANSLATION_L1:
     206        case DFSR_SOURCE_TRANSLATION_L2:
     207        case DFSR_SOURCE_PERMISSION_L1:
     208        case DFSR_SOURCE_PERMISSION_L2:
     209                /* Page fault is handled further down */
     210                break;
     211        case DFSR_SOURCE_ALIGN:
     212        case DFSR_SOURCE_CACHE_MAINTENANCE:
     213        case DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L1:
     214        case DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L2:
     215        case DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L1:
     216        case DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L2:
     217        case DFSR_SOURCE_ACCESS_FLAG_L1:
     218        case DFSR_SOURCE_ACCESS_FLAG_L2:
     219        case DFSR_SOURCE_DOMAIN_L1:
     220        case DFSR_SOURCE_DOMAIN_L2:
     221        case DFSR_SOURCE_DEBUG:
     222        case DFSR_SOURCE_SYNC_EXTERNAL:
     223        case DFSR_SOURCE_TLB_CONFLICT:
     224        case DFSR_SOURCE_LOCKDOWN:
     225        case DFSR_SOURCE_COPROCESSOR:
     226        case DFSR_SOURCE_SYNC_PARITY:
     227        case DFSR_SOURCE_ASYNC_EXTERNAL:
     228        case DFSR_SOURCE_ASYNC_PARITY:
     229        case DFSR_SOURCE_MASK:
     230                /* Weird abort stuff */
     231                fault_if_from_uspace(istate, "Unhandled abort %s at address: "
     232                    "%#x.", dfsr_source_to_str(source), badvaddr);
     233                panic("Unhandled abort %s at address: %#x.",
     234                    dfsr_source_to_str(source), badvaddr);
     235        }
     236
     237#if defined(PROCESSOR_ARCH_armv6) | defined(PROCESSOR_ARCH_armv7_a)
     238        const pf_access_t access =
     239            fsr.data.wr ? PF_ACCESS_WRITE : PF_ACCESS_READ;
     240#elif defined(PROCESSOR_ARCH_armv4) | defined(PROCESSOR_ARCH_armv5)
     241        const pf_access_t access = get_memory_access_type(istate->pc, badvaddr);
     242#else
     243#error "Unsupported architecture"
     244#endif
     245        as_page_fault(badvaddr, access, istate);
    159246}
    160247
     
    167254void prefetch_abort(unsigned int exc_no, istate_t *istate)
    168255{
    169         int ret = as_page_fault(istate->pc, PF_ACCESS_EXEC, istate);
    170 
    171         if (ret == AS_PF_FAULT) {
    172                 fault_if_from_uspace(istate,
    173                     "Page fault - prefetch_abort: %#x.", istate->pc);
    174                 panic_memtrap(istate, PF_ACCESS_EXEC, istate->pc, NULL);
    175         }
     256        as_page_fault(istate->pc, PF_ACCESS_EXEC, istate);
    176257}
    177258
Note: See TracChangeset for help on using the changeset viewer.