Changeset 25d5c96 in mainline


Ignore:
Timestamp:
2012-09-16T17:31:57Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f94b95b1
Parents:
68c2e32
Message:

arm32: Recognize and handle all data abort sources.

File:
1 edited

Legend:

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

    r68c2e32 r25d5c96  
    4141#include <interrupt.h>
    4242#include <print.h>
     43
     44
     45/**
     46 * FSR encoding ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition.
     47 *
     48 * B3.13.3 page B3-1406 (PDF page 1406)
     49 */
     50typedef enum {
     51        DFSR_SOURCE_ALIGN = 0x0001,
     52        DFSR_SOURCE_CACHE_MAINTENANCE = 0x0004,
     53        DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L1 = 0x000c,
     54        DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L2 = 0x000e,
     55        DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L1 = 0x040c,
     56        DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L2 = 0x040e,
     57        DFSR_SOURCE_TRANSLATION_L1 = 0x0005,
     58        DFSR_SOURCE_TRANSLATION_L2 = 0x0007,
     59        DFSR_SOURCE_ACCESS_FLAG_L1 = 0x0003,  /**< @note: This used to be alignment enc. */
     60        DFSR_SOURCE_ACCESS_FLAG_L2 = 0x0006,
     61        DFSR_SOURCE_DOMAIN_L1 = 0x0009,
     62        DFSR_SOURCE_DOMAIN_L2 = 0x000b,
     63        DFSR_SOURCE_PERMISSION_L1 = 0x000d,
     64        DFSR_SOURCE_PERMISSION_L2 = 0x000f,
     65        DFSR_SOURCE_DEBUG = 0x0002,
     66        DFSR_SOURCE_SYNC_EXTERNAL = 0x0008,
     67        DFSR_SOURCE_TLB_CONFLICT = 0x0400,
     68        DFSR_SOURCE_LOCKDOWN = 0x0404, /**< @note: Implementation defined */
     69        DFSR_SOURCE_COPROCESSOR = 0x040a, /**< @note Implementation defined */
     70        DFSR_SOURCE_SYNC_PARITY = 0x0409,
     71        DFSR_SOURCE_ASYNC_EXTERNAL = 0x0406,
     72        DFSR_SOURCE_ASYNC_PARITY = 0x0408,
     73        DFSR_SOURCE_MASK = 0x0000040f,
     74} dfsr_source_t;
     75
     76static inline const char * dfsr_source_to_str(dfsr_source_t source)
     77{
     78        switch (source)
     79        {
     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
    43130
    44131/** Returns value stored in comnbined/data fault status register.
     
    158245void data_abort(unsigned int exc_no, istate_t *istate)
    159246{
    160         uintptr_t badvaddr = read_data_fault_address_register();
     247        const uintptr_t badvaddr = read_data_fault_address_register();
     248        const fault_status_t fsr = read_data_fault_status_register();
     249        const dfsr_source_t source = fsr.raw & DFSR_SOURCE_MASK;
     250
     251        switch (source)
     252        {
     253        case DFSR_SOURCE_TRANSLATION_L1:
     254        case DFSR_SOURCE_TRANSLATION_L2:
     255        case DFSR_SOURCE_PERMISSION_L1:
     256        case DFSR_SOURCE_PERMISSION_L2:
     257                /* Page fault is handled further down */
     258                break;
     259        case DFSR_SOURCE_ALIGN:
     260        case DFSR_SOURCE_CACHE_MAINTENANCE:
     261        case DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L1:
     262        case DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L2:
     263        case DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L1:
     264        case DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L2:
     265        case DFSR_SOURCE_ACCESS_FLAG_L1:
     266        case DFSR_SOURCE_ACCESS_FLAG_L2:
     267        case DFSR_SOURCE_DOMAIN_L1:
     268        case DFSR_SOURCE_DOMAIN_L2:
     269        case DFSR_SOURCE_DEBUG:
     270        case DFSR_SOURCE_SYNC_EXTERNAL:
     271        case DFSR_SOURCE_TLB_CONFLICT:
     272        case DFSR_SOURCE_LOCKDOWN:
     273        case DFSR_SOURCE_COPROCESSOR:
     274        case DFSR_SOURCE_SYNC_PARITY:
     275        case DFSR_SOURCE_ASYNC_EXTERNAL:
     276        case DFSR_SOURCE_ASYNC_PARITY:
     277        case DFSR_SOURCE_MASK:
     278                /* Weird abort stuff */
     279                fault_if_from_uspace(istate, "Unhandled abort %s at address: "
     280                    "%#x.", dfsr_source_to_str(source), badvaddr);
     281                panic("Unhandled abort %s at address: %#x.",
     282                    dfsr_source_to_str(source), badvaddr);
     283        }
    161284
    162285#if defined(PROCESSOR_armv6) | defined(PROCESSOR_armv7_a)
    163         fault_status_t fsr = read_data_fault_status_register();
    164286        const pf_access_t access =
    165287            fsr.data.wr ? PF_ACCESS_WRITE : PF_ACCESS_READ;
     
    169291#error "Unsupported architecture"
    170292#endif
    171         int ret = as_page_fault(badvaddr, access, istate);
     293        const int ret = as_page_fault(badvaddr, access, istate);
    172294
    173295        if (ret == AS_PF_FAULT) {
Note: See TracChangeset for help on using the changeset viewer.