Changeset 0237380 in mainline


Ignore:
Timestamp:
2012-11-25T16:37:57Z (11 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
37bb3e1
Parents:
e5c8bc6
Message:

arm32,fpu: Save FPEXC in fpu context. Fix VFP detection.

Move FPU exception handling code to fpu_context.c.

Location:
kernel/arch/arm32
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/arm32/include/fpu_context.h

    re5c8bc6 r0237380  
    4444
    4545/* ARM Architecture reference manual, p B-1529.
    46  * We don't enable EX bit so max 32 64bit regs are stored (+2 control regs)
    4746 */
    4847typedef struct {
     48        uint32_t fpexc;
    4949        uint32_t fpuscr;
    50         uint32_t fpuexc;
    5150        uint32_t s[64];
    5251} fpu_context_t;
     
    5453void fpu_setup(void);
    5554
     55bool handle_if_fpu_exception(void);
     56
    5657#endif
    5758
  • kernel/arch/arm32/src/exception.c

    re5c8bc6 r0237380  
    167167static void undef_insn_exception(unsigned int exc_no, istate_t *istate)
    168168{
    169 #ifdef CONFIG_FPU_LAZY
    170         scheduler_fpu_lazy_request();
    171 #else
    172         fault_if_from_uspace(istate, "Undefined instruction.");
    173         panic_badtrap(istate, exc_no, "Undefined instruction.");
    174 #endif
     169        if (!handle_if_fpu_exception()) {
     170                fault_if_from_uspace(istate, "Undefined instruction.");
     171                panic_badtrap(istate, exc_no, "Undefined instruction.");
     172        }
    175173}
    176174
  • kernel/arch/arm32/src/fpu_context.c

    re5c8bc6 r0237380  
    4747        FPU_VFPv1 = 0x00,
    4848        FPU_VFPv2_COMMONv1 = 0x01,
    49         FPU_VFPv3_COMMONv2 = 0x02, /* Check MVFR0 and MVFR 1*/
    50         FPU_VFPv3_NOTRAP = 0x3, /* Does not support trap */
    51         FPU_VFPv3 = 0x4,
     49        FPU_VFPv3_COMMONv2 = 0x02,
     50        FPU_VFPv3_NO_COMMON = 0x3, /* Does not support trap */
     51        FPU_VFPv3_COMMONv3 = 0x4,
    5252};
     53
     54enum {
     55        FPEXC_ENABLED_FLAG = 0x40000000,
     56        FPEXC_EX_FLAG = 0x80000000,
     57};
     58
     59static inline uint32_t fpexc_read()
     60{
     61        uint32_t reg;
     62        asm volatile (
     63                "vmrs %0, fpexc\n"
     64                :"=r" (reg)::
     65        );
     66        return reg;
     67}
     68
     69static inline void fpexc_write(uint32_t val)
     70{
     71        asm volatile (
     72                "vmsr fpexc, %0\n"
     73                ::"r" (val):
     74        );
     75}
    5376
    5477static void (*save_context)(fpu_context_t *ctx);
     
    6285{
    6386        asm volatile (
     87                "vmrs r1, fpexc\n"
     88                "stmia %0!, {r1}\n"
    6489                "vmrs r1, fpscr\n"
    6590                "stmia %0!, {r1}\n"
     
    76101{
    77102        asm volatile (
     103                "ldmia %0!, {r1}\n"
     104                "vmsr fpexc, r1\n"
    78105                "ldmia %0!, {r1}\n"
    79106                "vmsr fpscr, r1\n"
     
    90117{
    91118        asm volatile (
     119                "vmrs r1, fpexc\n"
     120                "stmia %0!, {r1}\n"
    92121                "vmrs r1, fpscr\n"
    93122                "stmia %0!, {r1}\n"
     
    104133{
    105134        asm volatile (
     135                "ldmia %0!, {r1}\n"
     136                "vmsr fpexc, r1\n"
    106137                "ldmia %0!, {r1}\n"
    107138                "vmsr fpscr, r1\n"
     
    118149{
    119150        asm volatile (
     151                "vmrs r1, fpexc\n"
     152                "stmia %0!, {r1}\n"
    120153                "vmrs r1, fpscr\n"
    121154                "stmia %0!, {r1}\n"
     
    133166{
    134167        asm volatile (
     168                "ldmia %0!, {r1}\n"
     169                "vmsr fpexc, r1\n"
    135170                "ldmia %0!, {r1}\n"
    136171                "vmsr fpscr, r1\n"
     
    143178void fpu_init(void)
    144179{
     180        /* Clear all fpu flags */
     181        fpexc_write(0);
    145182        fpu_enable();
    146183}
     
    150187        uint32_t fpsid = 0;
    151188        asm volatile (
    152                 "vmrs %0,fpsid\n"
     189                "vmrs %0, fpsid\n"
    153190                :"=r"(fpsid)::
    154191        );
     
    170207                break;
    171208        case FPU_VFPv3_COMMONv2:
    172         case FPU_VFPv3_NOTRAP:
    173         case FPU_VFPv3: {
     209        case FPU_VFPv3_NO_COMMON:
     210        case FPU_VFPv3_COMMONv3: {
    174211                uint32_t mvfr0 = 0;
    175212                asm volatile (
     
    179216                /* See page B4-1637 */
    180217                if ((mvfr0 & 0xf) == 0x1) {
     218                        printf("Detected VFPv3+ with 16 regs\n");
     219                        save_context = fpu_context_save_d16;
     220                        restore_context = fpu_context_restore_d16;
     221                } else {
    181222                        printf("Detected VFPv3+ with 32 regs\n");
    182223                        save_context = fpu_context_save_d32;
    183224                        restore_context = fpu_context_restore_d32;
    184                 } else {
    185                         printf("Detected VFPv3+ with 16 regs\n");
    186                         save_context = fpu_context_save_d16;
    187                         restore_context = fpu_context_restore_d16;
    188225                }
    189226                break;
     
    193230}
    194231
     232bool handle_if_fpu_exception(void)
     233{
     234        const uint32_t fpexc = fpexc_read();
     235        if (fpexc & FPEXC_ENABLED_FLAG) {
     236                printf("FPU exception with FPU on\n");
     237                return false;
     238        }
     239#ifdef CONFIG_FPU_LAZY
     240        scheduler_fpu_lazy_request();
     241        return true;
     242#else
     243        return false;
     244#endif
     245}
     246
    195247void fpu_enable(void)
    196248{
    197249        /* Enable FPU instructions */
    198         asm volatile (
    199                 "ldr r1, =0x40000000\n"
    200                 "vmsr fpexc, r1\n"
    201                 ::: "r1"
    202         );
     250        fpexc_write(fpexc_read() | FPEXC_ENABLED_FLAG);
    203251}
    204252
     
    206254{
    207255        /* Disable FPU instructions */
    208         asm volatile (
    209                 "ldr r1, =0x00000000\n"
    210                 "vmsr fpexc, r1\n"
    211                 ::: "r1"
    212         );
     256        fpexc_write(fpexc_read() & ~FPEXC_ENABLED_FLAG);
    213257}
    214258
Note: See TracChangeset for help on using the changeset viewer.