Changes in / [5fcd537:ae86f89] in mainline


Ignore:
Location:
kernel/arch/arm32
Files:
3 deleted
4 edited

Legend:

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

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

    r5fcd537 rae86f89  
    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
    4741 */
    4842#define CS_ENTER_BARRIER()  asm volatile ("" ::: "memory")
     
    9488 */
    9589
    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,
     90/* Available on both all supported arms,
    10191 * invalidates entire ICache so the written value does not matter. */
    102 //TODO might be PL1 only on armv5 -
    10392#define smc_coherence(a) asm volatile ( "mcr p15, 0, r0, c7, c5, 0")
    10493#define smc_coherence_block(a, l) smc_coherence(a)
    105 #endif
    10694
    10795
  • kernel/arch/arm32/include/regutils.h

    r5fcd537 rae86f89  
    6666
    6767/* ARM Processor Operation Modes */
    68 enum {
    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 };
     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
    8076/* [CS]PRS manipulation macros */
    8177#define GEN_STATUS_READ(nm, reg) \
  • kernel/arch/arm32/src/fpu_context.c

    r5fcd537 rae86f89  
    3737#include <arch.h>
    3838#include <arch/types.h>
    39 #include <arch/security_ext.h>
    40 #include <arch/cp15.h>
    4139#include <cpu.h>
    4240
     
    5755};
    5856
    59 extern uint32_t fpsid_read(void);
    60 extern uint32_t mvfr0_read(void);
    61 
    6257enum {
    6358        FPEXC_EX_FLAG = (1 << 31),
    6459        FPEXC_ENABLED_FLAG = (1 << 30),
    6560};
    66 extern uint32_t fpexc_read(void);
    67 extern void fpexc_write(uint32_t);
    6861
    6962/** ARM Architecture Reference Manual ch. B4.1.58, p. B$-1551 */
     
    10194        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,
    10295};
    103 extern uint32_t fpscr_read(void);
    104 extern void fpscr_write(uint32_t);
    105 
    106 extern void fpu_context_save_s32(fpu_context_t *);
    107 extern void fpu_context_restore_s32(fpu_context_t *);
    108 extern void fpu_context_save_d16(fpu_context_t *);
    109 extern void fpu_context_restore_d16(fpu_context_t *);
    110 extern void fpu_context_save_d32(fpu_context_t *);
    111 extern void fpu_context_restore_d32(fpu_context_t *);
     96
     97static 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
     107static inline void fpscr_write(uint32_t val)
     108{
     109        asm volatile (
     110                "vmsr fpscr, %0\n"
     111                ::"r" (val):
     112        );
     113}
     114
     115static 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
     125static inline void fpexc_write(uint32_t val)
     126{
     127        asm volatile (
     128                "vmsr fpexc, %0\n"
     129                ::"r" (val):
     130        );
     131}
    112132
    113133static void (*save_context)(fpu_context_t *ctx);
    114134static void (*restore_context)(fpu_context_t *ctx);
    115135
    116 static 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  */
    145 static 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 
     136/** Saves 32 single precision fpu registers.
     137 * @param ctx FPU context area.
     138 * Used by VFPv1
     139 */
     140static 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 */
     155static 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 */
     170static 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 */
     185static 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 */
     200static 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 */
     217static 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}
    165229
    166230void fpu_init(void)
    167231{
    168         /* Check if we have access */
    169         if (!fpu_have_coprocessor_access())
    170                 return;
    171 
    172232        /* Clear all fpu flags */
    173233        fpexc_write(0);
     
    181241void fpu_setup(void)
    182242{
    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();
     243        uint32_t fpsid = 0;
     244        asm volatile (
     245                "vmrs %0, fpsid\n"
     246                :"=r"(fpsid)::
     247        );
    191248        if (fpsid & FPSID_SW_ONLY_FLAG) {
    192249                printf("No FPU avaiable\n");
     
    208265        case FPU_VFPv3_NO_COMMON:
    209266        case FPU_VFPv3_COMMONv3: {
    210                 const uint32_t mvfr0 = mvfr0_read();
     267                uint32_t mvfr0 = 0;
     268                asm volatile (
     269                        "vmrs %0,mvfr0\n"
     270                        :"=r"(mvfr0)::
     271                );
    211272                /* See page B4-1637 */
    212273                if ((mvfr0 & 0xf) == 0x1) {
     
    227288bool handle_if_fpu_exception(void)
    228289{
    229         /* Check if we have access */
    230         if (!fpu_have_coprocessor_access())
    231                 return false;
    232 
    233290        const uint32_t fpexc = fpexc_read();
    234291        if (fpexc & FPEXC_ENABLED_FLAG) {
     
    248305void fpu_enable(void)
    249306{
    250         /* Check if we have access */
    251         if (!fpu_have_coprocessor_access())
    252                 return;
    253307        /* Enable FPU instructions */
    254308        fpexc_write(fpexc_read() | FPEXC_ENABLED_FLAG);
     
    257311void fpu_disable(void)
    258312{
    259         /* Check if we have access */
    260         if (!fpu_have_coprocessor_access())
    261                 return;
    262313        /* Disable FPU instructions */
    263314        fpexc_write(fpexc_read() & ~FPEXC_ENABLED_FLAG);
     
    266317void fpu_context_save(fpu_context_t *ctx)
    267318{
    268         /* This is only necessary if we enable fpu exceptions. */
    269 #if 0
    270319        const uint32_t fpexc = fpexc_read();
    271320
     
    274323                //TODO implement common subarch context saving
    275324        }
    276 #endif
    277325        if (save_context)
    278326                save_context(ctx);
Note: See TracChangeset for help on using the changeset viewer.