Changeset 5fcd537 in mainline


Ignore:
Timestamp:
2013-01-19T02:25:08Z (11 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
bad1f53
Parents:
ae86f89 (diff), 660e8fa (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.

Includes bbxm fpu fix and other arm changes.
Merge fix: arch defines in fpu_context.c

Location:
kernel/arch/arm32
Files:
3 added
4 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/arm32/Makefile.inc

    rae86f89 r5fcd537  
    3535GCC_CFLAGS += -fno-omit-frame-pointer -mapcs-frame -march=$(subst _,-,$(PROCESSOR_ARCH)) -mno-unaligned-access
    3636
     37ifeq ($(MACHINE),beagleboardxm)
     38GCC_CFLAGS += -mcpu=cortex-a8
     39endif
     40
    3741ifeq ($(CONFIG_FPU),y)
    3842# This is necessary to allow vmsr insn and fpexc manipulation
    3943# Use vfp32 to allow context save/restore of d16-d31 regs.
    40 GCC_CFLAGS += -mfloat-abi=hard -mfpu=vfp3
     44AFLAGS += -mfloat-abi=hard -mfpu=vfp3
    4145endif
    4246
     
    7074ifeq ($(CONFIG_FPU),y)
    7175        ARCH_SOURCES += arch/$(KARCH)/src/fpu_context.c
     76        ARCH_SOURCES += arch/$(KARCH)/src/fpu.s
    7277endif
    7378
  • kernel/arch/arm32/include/barrier.h

    rae86f89 r5fcd537  
    3939/*
    4040 * TODO: implement true ARM memory barriers for macros below.
     41 * ARMv6 introduced user access of the following commands:
     42 * • Prefetch flush
     43 * • Data synchronization barrier
     44 * • Data memory barrier
     45 * • Clean and prefetch range operations.
     46 * ARM Architecture Reference Manual version I ch. B.3.2.1 p. B3-4
    4147 */
    4248#define CS_ENTER_BARRIER()  asm volatile ("" ::: "memory")
     
    8894 */
    8995
    90 /* Available on both all supported arms,
     96#ifdef PROCESSOR_ARCH_armv7_a
     97#define smc_coherence(a) asm volatile ( "isb" ::: "memory")
     98#define smc_coherence_block(a, l) smc_coherence(a)
     99#else
     100/* Available on all supported arms,
    91101 * invalidates entire ICache so the written value does not matter. */
     102//TODO might be PL1 only on armv5 -
    92103#define smc_coherence(a) asm volatile ( "mcr p15, 0, r0, c7, c5, 0")
    93104#define smc_coherence_block(a, l) smc_coherence(a)
     105#endif
    94106
    95107
  • kernel/arch/arm32/include/regutils.h

    rae86f89 r5fcd537  
    6666
    6767/* ARM Processor Operation Modes */
    68 #define USER_MODE        0x10
    69 #define FIQ_MODE         0x11
    70 #define IRQ_MODE         0x12
    71 #define SUPERVISOR_MODE  0x13
    72 #define ABORT_MODE       0x17
    73 #define UNDEFINED_MODE   0x1b
    74 #define SYSTEM_MODE      0x1f
    75 
     68enum {
     69        USER_MODE = 0x10,
     70        FIQ_MODE = 0x11,
     71        IRQ_MODE = 0x12,
     72        SUPERVISOR_MODE = 0x13,
     73        MONITOR_MODE = 0x16,
     74        ABORT_MODE = 0x17,
     75        HYPERVISOR_MODE = 0x1a,
     76        UNDEFINED_MODE = 0x1b,
     77        SYSTEM_MODE = 0x1f,
     78        MODE_MASK = 0x1f,
     79};
    7680/* [CS]PRS manipulation macros */
    7781#define GEN_STATUS_READ(nm, reg) \
  • kernel/arch/arm32/src/fpu_context.c

    rae86f89 r5fcd537  
    3737#include <arch.h>
    3838#include <arch/types.h>
     39#include <arch/security_ext.h>
     40#include <arch/cp15.h>
    3941#include <cpu.h>
    4042
     
    5557};
    5658
     59extern uint32_t fpsid_read(void);
     60extern uint32_t mvfr0_read(void);
     61
    5762enum {
    5863        FPEXC_EX_FLAG = (1 << 31),
    5964        FPEXC_ENABLED_FLAG = (1 << 30),
    6065};
     66extern uint32_t fpexc_read(void);
     67extern void fpexc_write(uint32_t);
    6168
    6269/** ARM Architecture Reference Manual ch. B4.1.58, p. B$-1551 */
     
    94101        FPSCR_EN_ALL = FPSCR_DENORMAL_EN_FLAG | FPSCR_INEXACT_EN_FLAG | FPSCR_UNDERFLOW_EN_FLAG | FPSCR_OVERFLOW_EN_FLAG | FPSCR_ZERO_DIV_EN_FLAG | FPSCR_INVALID_OP_EN_FLAG,
    95102};
    96 
    97 static inline uint32_t fpscr_read()
    98 {
    99         uint32_t reg;
    100         asm volatile (
    101                 "vmrs %0, fpscr\n"
    102                 :"=r" (reg)::
    103         );
    104         return reg;
    105 }
    106 
    107 static inline void fpscr_write(uint32_t val)
    108 {
    109         asm volatile (
    110                 "vmsr fpscr, %0\n"
    111                 ::"r" (val):
    112         );
    113 }
    114 
    115 static inline uint32_t fpexc_read()
    116 {
    117         uint32_t reg;
    118         asm volatile (
    119                 "vmrs %0, fpexc\n"
    120                 :"=r" (reg)::
    121         );
    122         return reg;
    123 }
    124 
    125 static inline void fpexc_write(uint32_t val)
    126 {
    127         asm volatile (
    128                 "vmsr fpexc, %0\n"
    129                 ::"r" (val):
    130         );
    131 }
     103extern uint32_t fpscr_read(void);
     104extern void fpscr_write(uint32_t);
     105
     106extern void fpu_context_save_s32(fpu_context_t *);
     107extern void fpu_context_restore_s32(fpu_context_t *);
     108extern void fpu_context_save_d16(fpu_context_t *);
     109extern void fpu_context_restore_d16(fpu_context_t *);
     110extern void fpu_context_save_d32(fpu_context_t *);
     111extern void fpu_context_restore_d32(fpu_context_t *);
    132112
    133113static void (*save_context)(fpu_context_t *ctx);
    134114static void (*restore_context)(fpu_context_t *ctx);
    135115
    136 /** Saves 32 single precision fpu registers.
    137  * @param ctx FPU context area.
    138  * Used by VFPv1
    139  */
    140 static void fpu_context_save_s32(fpu_context_t *ctx)
    141 {
    142         asm volatile (
    143                 "vmrs r1, fpexc\n"
    144                 "vmrs r2, fpscr\n"
    145                 "stmia %0!, {r1, r2}\n"
    146                 "vstmia %0!, {s0-s31}\n"
    147                 ::"r" (ctx): "r1","r2","memory"
    148         );
    149 }
    150 
    151 /** Restores 32 single precision fpu registers.
    152  * @param ctx FPU context area.
    153  * Used by VFPv1
    154  */
    155 static void fpu_context_restore_s32(fpu_context_t *ctx)
    156 {
    157         asm volatile (
    158                 "ldmia %0!, {r1, r2}\n"
    159                 "vmsr fpexc, r1\n"
    160                 "vmsr fpscr, r2\n"
    161                 "vldmia %0!, {s0-s31}\n"
    162                 ::"r" (ctx): "r1","r2"
    163         );
    164 }
    165 
    166 /** Saves 16 double precision fpu registers.
    167  * @param ctx FPU context area.
    168  * Used by VFPv2, VFPv3-d16, and VFPv4-d16.
    169  */
    170 static void fpu_context_save_d16(fpu_context_t *ctx)
    171 {
    172         asm volatile (
    173                 "vmrs r1, fpexc\n"
    174                 "vmrs r2, fpscr\n"
    175                 "stmia %0!, {r1, r2}\n"
    176                 "vstmia %0!, {d0-d15}\n"
    177                 ::"r" (ctx): "r1","r2","memory"
    178         );
    179 }
    180 
    181 /** Restores 16 double precision fpu registers.
    182  * @param ctx FPU context area.
    183  * Used by VFPv2, VFPv3-d16, and VFPv4-d16.
    184  */
    185 static void fpu_context_restore_d16(fpu_context_t *ctx)
    186 {
    187         asm volatile (
    188                 "ldmia %0!, {r1, r2}\n"
    189                 "vmsr fpexc, r1\n"
    190                 "vmsr fpscr, r2\n"
    191                 "vldmia %0!, {d0-d15}\n"
    192                 ::"r" (ctx): "r1","r2"
    193         );
    194 }
    195 
    196 /** Saves 32 double precision fpu registers.
    197  * @param ctx FPU context area.
    198  * Used by VFPv3-d32, VFPv4-d32, and advanced SIMD.
    199  */
    200 static void fpu_context_save_d32(fpu_context_t *ctx)
    201 {
    202         asm volatile (
    203                 "vmrs r1, fpexc\n"
    204                 "stmia %0!, {r1}\n"
    205                 "vmrs r1, fpscr\n"
    206                 "stmia %0!, {r1}\n"
    207                 "vstmia %0!, {d0-d15}\n"
    208                 "vstmia %0!, {d16-d31}\n"
    209                 ::"r" (ctx): "r1","memory"
    210         );
    211 }
    212 
    213 /** Restores 32 double precision fpu registers.
    214  * @param ctx FPU context area.
    215  * Used by VFPv3-d32, VFPv4-d32, and advanced SIMD.
    216  */
    217 static void fpu_context_restore_d32(fpu_context_t *ctx)
    218 {
    219         asm volatile (
    220                 "ldmia %0!, {r1}\n"
    221                 "vmsr fpexc, r1\n"
    222                 "ldmia %0!, {r1}\n"
    223                 "vmsr fpscr, r1\n"
    224                 "vldmia %0!, {d0-d15}\n"
    225                 "vldmia %0!, {d16-d31}\n"
    226                 ::"r" (ctx): "r1"
    227         );
    228 }
     116static int fpu_have_coprocessor_access()
     117{
     118/* The register containing the information (CPACR) is not available on armv6-
     119 * rely on user decision to use CONFIG_FPU.
     120 */
     121#ifdef PROCESSOR_ARC_armv7_a
     122        const uint32_t cpacr = CPACR_read();
     123        /* FPU needs access to coprocessor 10 and 11.
     124         * Moreover they need to have same access enabledd */
     125        if (((cpacr & CPACR_CP_MASK(10)) != CPACR_CP_FULL_ACCESS(10)) &&
     126           ((cpacr & CPACR_CP_MASK(11)) != CPACR_CP_FULL_ACCESS(11))) {
     127                printf("No access to CP10 and CP11: %" PRIx32 "\n", cpacr);
     128                return 0;
     129        }
     130#endif
     131        return 1;
     132}
     133
     134/** Enable coprocessor access. Turn both non-secure mode bit and generic access.
     135 * Cortex A8 Manual says:
     136 * "You must execute an Instruction Memory Barrier (IMB) sequence immediately
     137 * after an update of the Coprocessor Access Control Register, see Memory
     138 * Barriers in the ARM Architecture Reference Manual. You must not attempt to
     139 * execute any instructions that are affected by the change of access rights
     140 * between the IMB sequence and the register update."
     141 * Cortex a8 TRM ch. 3.2.27. c1, Coprocessor Access Control Register
     142 *
     143 * @note do we need to call secure monitor here?
     144 */
     145static void fpu_enable_coprocessor_access()
     146{
     147/* The register containing the information (CPACR) is not available on armv6-
     148 * rely on user decision to use CONFIG_FPU.
     149 */
     150#ifndef PROCESSOR_ARCH_armv7_a
     151        return;
     152#endif
     153
     154        /* Allow coprocessor access */
     155        uint32_t cpacr = CPACR_read();
     156        /* FPU needs access to coprocessor 10 and 11.
     157         * Moreover, they need to have same access enabled */
     158        cpacr &= ~(CPACR_CP_MASK(10) | CPACR_CP_MASK(11));
     159        cpacr |= (CPACR_CP_FULL_ACCESS(10) | CPACR_CP_FULL_ACCESS(11));
     160        CPACR_write(cpacr);
     161
     162        smc_coherence(0);
     163}
     164
    229165
    230166void fpu_init(void)
    231167{
     168        /* Check if we have access */
     169        if (!fpu_have_coprocessor_access())
     170                return;
     171
    232172        /* Clear all fpu flags */
    233173        fpexc_write(0);
     
    241181void fpu_setup(void)
    242182{
    243         uint32_t fpsid = 0;
    244         asm volatile (
    245                 "vmrs %0, fpsid\n"
    246                 :"=r"(fpsid)::
    247         );
     183        /* Enable coprocessor access*/
     184        fpu_enable_coprocessor_access();
     185
     186        /* Check if we succeeded */
     187        if (!fpu_have_coprocessor_access())
     188                return;
     189
     190        const uint32_t fpsid = fpsid_read();
    248191        if (fpsid & FPSID_SW_ONLY_FLAG) {
    249192                printf("No FPU avaiable\n");
     
    265208        case FPU_VFPv3_NO_COMMON:
    266209        case FPU_VFPv3_COMMONv3: {
    267                 uint32_t mvfr0 = 0;
    268                 asm volatile (
    269                         "vmrs %0,mvfr0\n"
    270                         :"=r"(mvfr0)::
    271                 );
     210                const uint32_t mvfr0 = mvfr0_read();
    272211                /* See page B4-1637 */
    273212                if ((mvfr0 & 0xf) == 0x1) {
     
    288227bool handle_if_fpu_exception(void)
    289228{
     229        /* Check if we have access */
     230        if (!fpu_have_coprocessor_access())
     231                return false;
     232
    290233        const uint32_t fpexc = fpexc_read();
    291234        if (fpexc & FPEXC_ENABLED_FLAG) {
     
    305248void fpu_enable(void)
    306249{
     250        /* Check if we have access */
     251        if (!fpu_have_coprocessor_access())
     252                return;
    307253        /* Enable FPU instructions */
    308254        fpexc_write(fpexc_read() | FPEXC_ENABLED_FLAG);
     
    311257void fpu_disable(void)
    312258{
     259        /* Check if we have access */
     260        if (!fpu_have_coprocessor_access())
     261                return;
    313262        /* Disable FPU instructions */
    314263        fpexc_write(fpexc_read() & ~FPEXC_ENABLED_FLAG);
     
    317266void fpu_context_save(fpu_context_t *ctx)
    318267{
     268        /* This is only necessary if we enable fpu exceptions. */
     269#if 0
    319270        const uint32_t fpexc = fpexc_read();
    320271
     
    323274                //TODO implement common subarch context saving
    324275        }
     276#endif
    325277        if (save_context)
    326278                save_context(ctx);
Note: See TracChangeset for help on using the changeset viewer.