Changeset 69146b93 in mainline for kernel/arch/arm32/src


Ignore:
Timestamp:
2012-11-26T19:02:45Z (13 years ago)
Author:
Adam Hraska <adam.hraska+hos@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
04552324
Parents:
5d230a30 (diff), 7462674 (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:

Merged mainline,1723.

Location:
kernel/arch/arm32/src
Files:
1 added
6 edited

Legend:

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

    r5d230a30 r69146b93  
    4949#include <str.h>
    5050#include <arch/ras.h>
     51#include <sysinfo/sysinfo.h>
    5152
    5253/** Performs arm32-specific initialization before main_bsp() is called. */
     
    116117{
    117118        machine_input_init();
     119        const char *platform = machine_get_platform_name();
     120
     121        sysinfo_set_item_data("platform", NULL, (void *) platform,
     122            str_size(platform));
    118123}
    119124
  • kernel/arch/arm32/src/cpu/cpu.c

    r5d230a30 r69146b93  
    4444/** Implementators (vendor) names */
    4545static const char *imp_data[] = {
    46         "?",                                    /* IMP_DATA_START_OFFSET */
    47         "ARM Ltd",                              /* 0x41 */
    48         "",                                     /* 0x42 */
    49         "",                                     /* 0x43 */
    50         "Digital Equipment Corporation",        /* 0x44 */
    51         "", "", "", "", "", "", "", "", "", "", /* 0x45 - 0x4e */
    52         "", "", "", "", "", "", "", "", "", "", /* 0x4f - 0x58 */
    53         "", "", "", "", "", "", "", "", "", "", /* 0x59 - 0x62 */
    54         "", "", "", "", "", "",                 /* 0x63 - 0x68 */
    55         "Intel Corporation"                     /* 0x69 */
     46        "?",                                     /* IMP_DATA_START_OFFSET */
     47        "ARM Limited",                           /* 0x41 */
     48        "", "",                                  /* 0x42 - 0x43 */
     49        "Digital Equipment Corporation",         /* 0x44 */
     50        "", "", "", "", "", "", "", "",          /* 0x45 - 0x4c */
     51        "Motorola, Freescale Semicondutor Inc.", /* 0x4d */
     52        "", "", "",                              /* 0x4e - 0x50 */
     53        "Qualcomm Inc.",                         /* 0x51 */
     54        "", "", "", "",                          /* 0x52 - 0x55 */
     55        "Marvell Semiconductor",                 /* 0x56 */
     56        "", "", "", "", "", "", "", "", "", "",  /* 0x57 - 0x60 */
     57        "", "", "", "", "", "", "", "",          /* 0x61 - 0x68 */
     58        "Intel Corporation"                      /* 0x69 */
    5659};
    5760
     
    9497}
    9598
    96 /** Does nothing on ARM. */
     99/** Enables unaligned access and caching for armv6+ */
    97100void cpu_arch_init(void)
    98101{
     102#if defined(PROCESSOR_armv7_a) | defined(PROCESSOR_armv6)
     103        uint32_t control_reg = 0;
     104        asm volatile (
     105                "mrc p15, 0, %[control_reg], c1, c0"
     106                : [control_reg] "=r" (control_reg)
     107        );
     108       
     109        /* Turn off tex remap, RAZ ignores writes prior to armv7 */
     110        control_reg &= ~CP15_R1_TEX_REMAP_EN;
     111        /* Turn off accessed flag, RAZ ignores writes prior to armv7 */
     112        control_reg &= ~(CP15_R1_ACCESS_FLAG_EN | CP15_R1_HW_ACCESS_FLAG_EN);
     113        /* Enable unaligned access, RAZ ignores writes prior to armv6
     114         * switchable on armv6, RAO ignores writes on armv7,
     115         * see ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition
     116         * L.3.1 (p. 2456) */
     117        control_reg |= CP15_R1_UNALIGNED_EN;
     118        /* Disable alignment checks, this turns unaligned access to undefined,
     119         * unless U bit is set. */
     120        control_reg &= ~CP15_R1_ALIGN_CHECK_EN;
     121        /* Enable caching, On arm prior to armv7 there is only one level
     122         * of caches. Data cache is coherent.
     123         * "This means that the behavior of accesses from the same observer to
     124         * different VAs, that are translated to the same PA
     125         * with the same memory attributes, is fully coherent."
     126         *    ARM Architecture Reference Manual ARMv7-A and ARMv7-R Edition
     127         *    B3.11.1 (p. 1383)
     128         * ICache coherency is elaborate on in barrier.h.
     129         * We are safe to turn these on.
     130         */
     131        control_reg |= CP15_R1_CACHE_EN | CP15_R1_INST_CACHE_EN;
     132       
     133        asm volatile (
     134                "mcr p15, 0, %[control_reg], c1, c0"
     135                :: [control_reg] "r" (control_reg)
     136        );
     137#endif
    99138}
    100139
    101140/** Retrieves processor identification and stores it to #CPU.arch */
    102 void cpu_identify(void) 
     141void cpu_identify(void)
    103142{
    104143        arch_cpu_identify(&CPU->arch);
     
    112151        cpu_arch_t * cpu_arch = &m->arch;
    113152
    114         if ((cpu_arch->imp_num) > 0 &&
    115             (cpu_arch->imp_num < (imp_data_length + IMP_DATA_START_OFFSET))) {
     153        const unsigned imp_offset = cpu_arch->imp_num - IMP_DATA_START_OFFSET;
     154
     155        if (imp_offset < imp_data_length) {
    116156                vendor = imp_data[cpu_arch->imp_num - IMP_DATA_START_OFFSET];
    117157        }
    118158
    119         if ((cpu_arch->arch_num) > 0 &&
    120             (cpu_arch->arch_num < arch_data_length)) {
     159        // TODO CPUs with arch_num == 0xf use CPUID scheme for identification
     160        if (cpu_arch->arch_num < arch_data_length) {
    121161                architecture = arch_data[cpu_arch->arch_num];
    122162        }
  • kernel/arch/arm32/src/exception.c

    r5d230a30 r69146b93  
    117117
    118118#ifdef HIGH_EXCEPTION_VECTORS
    119 /** Activates use of high exception vectors addresses. */
     119/** Activates use of high exception vectors addresses.
     120 *
     121 * "High vectors were introduced into some implementations of ARMv4 and are
     122 * required in ARMv6 implementations. High vectors allow the exception vector
     123 * locations to be moved from their normal address range 0x00000000-0x0000001C
     124 * at the bottom of the 32-bit address space, to an alternative address range
     125 * 0xFFFF0000-0xFFFF001C near the top of the address space. These alternative
     126 * locations are known as the high vectors.
     127 *
     128 * Prior to ARMv6, it is IMPLEMENTATION DEFINED whether the high vectors are
     129 * supported. When they are, a hardware configuration input selects whether
     130 * the normal vectors or the high vectors are to be used from
     131 * reset." ARM Architecture Reference Manual A2.6.11 (p. 64 in the PDF).
     132 *
     133 * ARM920T (gta02) TRM A2.3.5 (PDF p. 36) and ARM926EJ-S (icp) 2.3.2 (PDF p. 42)
     134 * say that armv4 an armv5 chips that we support implement this.
     135 */
    120136static void high_vectors(void)
    121137{
    122         uint32_t control_reg;
    123        
     138        uint32_t control_reg = 0;
    124139        asm volatile (
    125140                "mrc p15, 0, %[control_reg], c1, c0"
     
    128143       
    129144        /* switch on the high vectors bit */
    130         control_reg |= CP15_R1_HIGH_VECTORS_BIT;
     145        control_reg |= CP15_R1_HIGH_VECTORS_EN;
    131146       
    132147        asm volatile (
     
    153168void exception_init(void)
    154169{
     170        // TODO check for availability of high vectors for <= armv5
    155171#ifdef HIGH_EXCEPTION_VECTORS
    156172        high_vectors();
  • kernel/arch/arm32/src/machine_func.c

    r5d230a30 r69146b93  
    4242#include <arch/mach/integratorcp/integratorcp.h>
    4343#include <arch/mach/testarm/testarm.h>
     44#include <arch/mach/beagleboardxm/beagleboardxm.h>
    4445
    4546/** Pointer to machine_ops structure being used. */
     
    5556#elif defined(MACHINE_integratorcp)
    5657        machine_ops = &icp_machine_ops;
     58#elif defined(MACHINE_beagleboardxm)
     59        machine_ops = &bbxm_machine_ops;
    5760#else
    5861#error Machine type not defined.
     
    131134}
    132135
     136const char * machine_get_platform_name(void)
     137{
     138        if (machine_ops->machine_get_platform_name)
     139                return machine_ops->machine_get_platform_name();
     140        return NULL;
     141}
    133142/** @}
    134143 */
  • kernel/arch/arm32/src/mm/page.c

    r5d230a30 r69146b93  
    5252void page_arch_init(void)
    5353{
    54         int flags = PAGE_CACHEABLE;
     54        int flags = PAGE_CACHEABLE | PAGE_EXEC;
    5555        page_mapping_operations = &pt_mapping_operations;
    5656
    5757        page_table_lock(AS_KERNEL, true);
    5858       
    59         uintptr_t cur;
    60 
    6159        /* Kernel identity mapping */
    62         for (cur = PHYSMEM_START_ADDR;
    63             cur < min(config.identity_size, config.physmem_end);
     60        //FIXME: We need to consider the possibility that
     61        //identity_base > identity_size and physmem_end.
     62        //This might lead to overflow if identity_size is too big.
     63        for (uintptr_t cur = PHYSMEM_START_ADDR;
     64            cur < min(KA2PA(config.identity_base) +
     65                config.identity_size, config.physmem_end);
    6466            cur += FRAME_SIZE)
    6567                page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
  • kernel/arch/arm32/src/mm/page_fault.c

    r5d230a30 r69146b93  
    4242#include <print.h>
    4343
    44 /** Returns value stored in fault status register.
     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        case DFSR_SOURCE_TRANSLATION_L1:
     80                return "Translation fault L1";
     81        case DFSR_SOURCE_TRANSLATION_L2:
     82                return "Translation fault L2";
     83        case DFSR_SOURCE_PERMISSION_L1:
     84                return "Permission fault L1";
     85        case DFSR_SOURCE_PERMISSION_L2:
     86                return "Permission fault L2";
     87        case DFSR_SOURCE_ALIGN:
     88                return "Alignment fault";
     89        case DFSR_SOURCE_CACHE_MAINTENANCE:
     90                return "Instruction cache maintenance fault";
     91        case DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L1:
     92                return "Synchronous external abort on translation table walk level 1";
     93        case DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L2:
     94                return "Synchronous external abort on translation table walk level 2";
     95        case DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L1:
     96                return "Synchronous parity error on translation table walk level 1";
     97        case DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L2:
     98                return "Synchronous parity error on translation table walk level 2";
     99        case DFSR_SOURCE_ACCESS_FLAG_L1:
     100                return "Access flag fault L1";
     101        case DFSR_SOURCE_ACCESS_FLAG_L2:
     102                return "Access flag fault L2";
     103        case DFSR_SOURCE_DOMAIN_L1:
     104                return "Domain fault L1";
     105        case DFSR_SOURCE_DOMAIN_L2:
     106                return "Domain flault L2";
     107        case DFSR_SOURCE_DEBUG:
     108                return "Debug event";
     109        case DFSR_SOURCE_SYNC_EXTERNAL:
     110                return "Synchronous external abort";
     111        case DFSR_SOURCE_TLB_CONFLICT:
     112                return "TLB conflict abort";
     113        case DFSR_SOURCE_LOCKDOWN:
     114                return "Lockdown (Implementation defined)";
     115        case DFSR_SOURCE_COPROCESSOR:
     116                return "Coprocessor abort (Implementation defined)";
     117        case DFSR_SOURCE_SYNC_PARITY:
     118                return "Synchronous parity error on memory access";
     119        case DFSR_SOURCE_ASYNC_EXTERNAL:
     120                return "Asynchronous external abort";
     121        case DFSR_SOURCE_ASYNC_PARITY:
     122                return "Asynchronous parity error on memory access";
     123        case DFSR_SOURCE_MASK:
     124                break;
     125        }
     126        return "Unknown data abort";
     127}
     128
     129
     130/** Returns value stored in comnbined/data fault status register.
    45131 *
    46132 *  @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;
     133 *
     134 *  "VMSAv6 added a fifth fault status bit (bit[10]) to both the IFSR and DFSR.
     135 *  It is IMPLEMENTATION DEFINED how this bit is encoded in earlier versions of
     136 *  the architecture. A write flag (bit[11] of the DFSR) has also been
     137 *  introduced."
     138 *  ARM Architecture Reference Manual version i ch. B4.6 (PDF p. 719)
     139 *
     140 *  See ch. B4.9.6 for location of data/instruction FSR.
     141 *
     142 */
     143static inline fault_status_t read_data_fault_status_register(void)
     144{
     145        fault_status_t fsu;
    51146       
    52         /* fault status is stored in CP15 register 5 */
     147        /* Combined/Data fault status is stored in CP15 register 5, c0. */
    53148        asm volatile (
    54149                "mrc p15, 0, %[dummy], c5, c0, 0"
    55                 : [dummy] "=r" (fsu.dummy)
     150                : [dummy] "=r" (fsu.raw)
    56151        );
    57152       
    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
     153        return fsu;
     154}
     155
     156/** Returns DFAR (fault address register) content.
     157 *
     158 * This register is equivalent to FAR on pre armv6 machines.
     159 *
     160 * @return DFAR (fault address register) content (address that caused a page
    64161 *         fault)
    65162 */
    66 static inline uintptr_t read_fault_address_register(void)
     163static inline uintptr_t read_data_fault_address_register(void)
    67164{
    68165        uintptr_t ret;
     
    77174}
    78175
     176#if defined(PROCESSOR_armv4) | defined(PROCESSOR_armv5)
    79177/** Decides whether read or write into memory is requested.
    80178 *
     
    97195                panic("page_fault - instruction does not access memory "
    98196                    "(instr_code: %#0" PRIx32 ", badvaddr:%p).",
    99                     instr_union.pc, (void *) badvaddr);
     197                    *(uint32_t*)instr_union.instr, (void *) badvaddr);
    100198                return PF_ACCESS_EXEC;
    101199        }
     
    136234            inst, (void *) badvaddr);
    137235}
     236#endif
    138237
    139238/** Handles "data abort" exception (load or store at invalid address).
     
    145244void data_abort(unsigned int exc_no, istate_t *istate)
    146245{
    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);
     246        const uintptr_t badvaddr = read_data_fault_address_register();
     247        const fault_status_t fsr = read_data_fault_status_register();
     248        const dfsr_source_t source = fsr.raw & DFSR_SOURCE_MASK;
     249
     250        switch (source) {
     251        case DFSR_SOURCE_TRANSLATION_L1:
     252        case DFSR_SOURCE_TRANSLATION_L2:
     253        case DFSR_SOURCE_PERMISSION_L1:
     254        case DFSR_SOURCE_PERMISSION_L2:
     255                /* Page fault is handled further down */
     256                break;
     257        case DFSR_SOURCE_ALIGN:
     258        case DFSR_SOURCE_CACHE_MAINTENANCE:
     259        case DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L1:
     260        case DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L2:
     261        case DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L1:
     262        case DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L2:
     263        case DFSR_SOURCE_ACCESS_FLAG_L1:
     264        case DFSR_SOURCE_ACCESS_FLAG_L2:
     265        case DFSR_SOURCE_DOMAIN_L1:
     266        case DFSR_SOURCE_DOMAIN_L2:
     267        case DFSR_SOURCE_DEBUG:
     268        case DFSR_SOURCE_SYNC_EXTERNAL:
     269        case DFSR_SOURCE_TLB_CONFLICT:
     270        case DFSR_SOURCE_LOCKDOWN:
     271        case DFSR_SOURCE_COPROCESSOR:
     272        case DFSR_SOURCE_SYNC_PARITY:
     273        case DFSR_SOURCE_ASYNC_EXTERNAL:
     274        case DFSR_SOURCE_ASYNC_PARITY:
     275        case DFSR_SOURCE_MASK:
     276                /* Weird abort stuff */
     277                fault_if_from_uspace(istate, "Unhandled abort %s at address: "
     278                    "%#x.", dfsr_source_to_str(source), badvaddr);
     279                panic("Unhandled abort %s at address: %#x.",
     280                    dfsr_source_to_str(source), badvaddr);
    158281        }
     282
     283#if defined(PROCESSOR_armv6) | defined(PROCESSOR_armv7_a)
     284        const pf_access_t access =
     285            fsr.data.wr ? PF_ACCESS_WRITE : PF_ACCESS_READ;
     286#elif defined(PROCESSOR_armv4) | defined(PROCESSOR_armv5)
     287        const pf_access_t access = get_memory_access_type(istate->pc, badvaddr);
     288#else
     289#error "Unsupported architecture"
     290#endif
     291        as_page_fault(badvaddr, access, istate);
    159292}
    160293
     
    167300void prefetch_abort(unsigned int exc_no, istate_t *istate)
    168301{
    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         }
     302        as_page_fault(istate->pc, PF_ACCESS_EXEC, istate);
    176303}
    177304
Note: See TracChangeset for help on using the changeset viewer.