Changeset 8ff9484 in mainline


Ignore:
Timestamp:
2012-11-24T18:50:02Z (11 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
435c33b
Parents:
04cb6957
Message:

arm32: Implement all variants of FPU context save/restore.

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

Legend:

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

    r04cb6957 r8ff9484  
    3737ifeq ($(CONFIG_FPU),y)
    3838# This is necessary to allow vmsr insn and fpexc manipulation
    39 GCC_CFLAGS += -mfloat-abi=hard
     39# Use vfp32 to allow context save/restore of d16-d31 regs.
     40GCC_CFLAGS += -mfloat-abi=hard -mfpu=vfp3
    4041endif
    4142
     
    5152        arch/$(KARCH)/src/machine_func.c \
    5253        arch/$(KARCH)/src/context.S \
     54        arch/$(KARCH)/src/fpu_context.c \
    5355        arch/$(KARCH)/src/dummy.S \
    5456        arch/$(KARCH)/src/cpu/cpu.c \
  • kernel/arch/arm32/include/cpu.h

    r04cb6957 r8ff9484  
    4343/** Struct representing ARM CPU identification. */
    4444typedef struct {
    45         /** Implementator (vendor) number. */
     45        /** Implementor (vendor) number. */
    4646        uint32_t imp_num;
    4747
  • kernel/arch/arm32/src/cpu/cpu.c

    r04cb6957 r8ff9484  
    3838#include <arch.h>
    3939#include <print.h>
    40 #include <fpu_context.h>
    4140
    42 /** Number of indexes left out in the #imp_data array */
    43 #define IMP_DATA_START_OFFSET 0x40
    44 
    45 /** Implementors (vendor) names */
    46 static const char *imp_data[] = {
    47         "?",                                     /* IMP_DATA_START_OFFSET */
    48         "ARM Limited",                           /* 0x41 */
    49         "", "",                                  /* 0x42 - 0x43 */
    50         "Digital Equipment Corporation",         /* 0x44 */
    51         "", "", "", "", "", "", "", "",          /* 0x45 - 0x4c */
    52         "Motorola, Freescale Semicondutor Inc.", /* 0x4d */
    53         "", "", "",                              /* 0x4e - 0x50 */
    54         "Qualcomm Inc.",                         /* 0x51 */
    55         "", "", "", "",                          /* 0x52 - 0x55 */
    56         "Marvell Semiconductor",                 /* 0x56 */
    57         "", "", "", "", "", "", "", "", "", "",  /* 0x57 - 0x60 */
    58         "", "", "", "", "", "", "", "",          /* 0x61 - 0x68 */
    59         "Intel Corporation"                      /* 0x69 */
    60 };
    61 
    62 /** Length of the #imp_data array */
    63 static const unsigned int imp_data_length = sizeof(imp_data) / sizeof(char *);
     41/** Implementers (vendor) names */
     42static const char * implementer(unsigned id)
     43{
     44        switch (id)
     45        {
     46        case 0x41: return "ARM Limited";
     47        case 0x44: return "Digital Equipment Corporation";
     48        case 0x4d: return "Motorola, Freescale Semiconductor Inc.";
     49        case 0x51: return "Qualcomm Inc.";
     50        case 0x56: return "Marvell Semiconductor Inc.";
     51        case 0x69: return "Intel Corporation";
     52        }
     53        return "Unknown implementer";
     54}
    6455
    6556/** Architecture names */
    66 static const char *arch_data[] = {
    67         "?",       /* 0x0 */
    68         "4",       /* 0x1 */
    69         "4T",      /* 0x2 */
    70         "5",       /* 0x3 */
    71         "5T",      /* 0x4 */
    72         "5TE",     /* 0x5 */
    73         "5TEJ",    /* 0x6 */
    74         "6"        /* 0x7 */
    75 };
    76 
    77 /** Length of the #arch_data array */
    78 static const unsigned int arch_data_length = sizeof(arch_data) / sizeof(char *);
     57static const char * architecture_string(cpu_arch_t *arch)
     58{
     59        static const char *arch_data[] = {
     60                "ARM",       /* 0x0 */
     61                "ARMv4",       /* 0x1 */
     62                "ARMv4T",      /* 0x2 */
     63                "ARMv5",       /* 0x3 */
     64                "ARMv5T",      /* 0x4 */
     65                "ARMv5TE",     /* 0x5 */
     66                "ARMv5TEJ",    /* 0x6 */
     67                "ARMv6"        /* 0x7 */
     68        };
     69        if (arch->arch_num < (sizeof(arch_data) / sizeof(arch_data[0])))
     70                return arch_data[arch->arch_num];
     71        else
     72                return arch_data[0];
     73}
    7974
    8075
     
    8277 *
    8378 * @param cpu Structure for storing CPU identification.
     79 * See page B4-1630 of ARM Architecture Reference Manual.
    8480 */
    8581static void arch_cpu_identify(cpu_arch_t *cpu)
     
    9692        cpu->prim_part_num = (ident << 16) >> 20;
    9793        cpu->rev_num = (ident << 28) >> 28;
     94        // TODO CPUs with arch_num == 0xf use CPUID scheme for identification
    9895}
    9996
     
    139136}
    140137
    141 void fpu_init(void)
    142 {
    143         //TODO: Identify FPU unit
    144         //and set correct functions to save/restore ctx
    145 }
    146 
    147 void fpu_enable(void)
    148 {
    149         /* Enable FPU instructions */
    150         asm volatile (
    151                 "ldr r1, =0x40000000\n"
    152                 "vmsr fpexc, r1\n"
    153                 ::: "r1"
    154         );
    155 }
    156 
    157 void fpu_disable(void)
    158 {
    159         /* Disable FPU instructions */
    160         asm volatile (
    161                 "ldr r1, =0x00000000\n"
    162                 "vmsr fpexc, r1\n"
    163                 ::: "r1"
    164         );
    165 }
    166 
    167 void fpu_context_save(fpu_context_t *ctx)
    168 {
    169         // TODO check and complete. What about fpexc?
    170         asm volatile (
    171                 "vmrs r1, fpscr\n"
    172 //              "vmrs r2, fpexc\n"
    173                 "stm %0, {r1, r2}\n"
    174                 "vstm %0, {d0-d15}\n"
    175                 ::"r" (ctx): "r1","r2","memory"
    176         );
    177 }
    178 
    179 void fpu_context_restore(fpu_context_t *ctx)
    180 {
    181         // TODO check and complete. What about fpexc?
    182         asm volatile (
    183                 "ldm %0, {r1, r2}\n"
    184                 "vmsr fpscr, r1\n"
    185 //              "vmsr fpexc, r2\n"
    186                 "vldm %0, {d0-d15}\n"
    187                 ::"r" (ctx): "r1","r2"
    188         );
    189 }
    190 
    191138/** Retrieves processor identification and stores it to #CPU.arch */
    192139void cpu_identify(void)
     
    198145void cpu_print_report(cpu_t *m)
    199146{
    200         const char *vendor = imp_data[0];
    201         const char *architecture = arch_data[0];
    202         cpu_arch_t * cpu_arch = &m->arch;
    203 
    204         const unsigned imp_offset = cpu_arch->imp_num - IMP_DATA_START_OFFSET;
    205 
    206         if (imp_offset < imp_data_length) {
    207                 vendor = imp_data[cpu_arch->imp_num - IMP_DATA_START_OFFSET];
    208         }
    209 
    210         // TODO CPUs with arch_num == 0xf use CPUID scheme for identification
    211         if (cpu_arch->arch_num < arch_data_length) {
    212                 architecture = arch_data[cpu_arch->arch_num];
    213         }
    214 
    215         printf("cpu%d: vendor=%s, architecture=ARMv%s, part number=%x, "
     147        printf("cpu%d: vendor=%s, architecture=%s, part number=%x, "
    216148            "variant=%x, revision=%x\n",
    217             m->id, vendor, architecture, cpu_arch->prim_part_num,
    218             cpu_arch->variant_num, cpu_arch->rev_num);
     149            m->id, implementer(m->arch.imp_num),
     150            architecture_string(&m->arch), m->arch.prim_part_num,
     151            m->arch.variant_num, m->arch.rev_num);
    219152}
    220153
Note: See TracChangeset for help on using the changeset viewer.