Changeset b1011dae in mainline


Ignore:
Timestamp:
2013-01-24T21:18:18Z (12 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
077b9172
Parents:
5e761f3 (diff), c124dce3 (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 changes from jan.vesely/helenos/arm

Files:
10 added
25 edited
1 moved

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    r5e761f3 rb1011dae  
    8888
    8989% CPU type
     90@ "cortex_a8" ARM Cortex A-8
     91! [PLATFORM=arm32&(MACHINE=beagleboardxm|MACHINE=beaglebone)] PROCESSOR (choice)
     92
     93% CPU type
     94@ "arm920t" ARM920T
     95! [PLATFORM=arm32&MACHINE=gta02] PROCESSOR (choice)
     96
     97% CPU type
     98@ "arm926ej_s" ARM926EJ-S
     99! [PLATFORM=arm32&MACHINE=integratorcp] PROCESSOR (choice)
     100
     101
     102# Add more ARMv4 CPUs
     103% CPU arch
    90104@ "armv4" ARMv4
    91 ! [PLATFORM=arm32&(MACHINE=gta02)] PROCESSOR (choice)
    92 
    93 % CPU type
     105! [PLATFORM=arm32&(PROCESSOR=arm920t)] PROCESSOR_ARCH (choice)
     106
     107# Add more ARMv5 CPUs
     108% CPU arch
    94109@ "armv5" ARMv5
    95 ! [PLATFORM=arm32&MACHINE=integratorcp] PROCESSOR (choice)
    96 
    97 % CPU type
     110! [PLATFORM=arm32&(PROCESSOR=arm926ej_s)] PROCESSOR_ARCH (choice)
     111
     112# Add more ARMv7-A CPUs
     113% CPU arch
    98114@ "armv7_a" ARMv7-A
    99 ! [PLATFORM=arm32&(MACHINE=beagleboardxm|MACHINE=beaglebone)] PROCESSOR (choice)
     115! [PLATFORM=arm32&(PROCESSOR=cortex_a8)] PROCESSOR_ARCH (choice)
    100116
    101117% RAM disk format
     
    349365## armv7 made fpu hardware compulsory
    350366% FPU support
    351 ! [PLATFORM=arm32&PROCESSOR=armv7_a] CONFIG_FPU (y)
     367! [PLATFORM=arm32&PROCESSOR_ARCH=armv7_a] CONFIG_FPU (y)
    352368
    353369% FPU support
  • boot/arch/arm32/Makefile.inc

    r5e761f3 rb1011dae  
    4949BITS = 32
    5050ENDIANESS = LE
    51 EXTRA_CFLAGS = -march=$(subst _,-,$(PROCESSOR)) -mno-unaligned-access
     51EXTRA_CFLAGS = -march=$(subst _,-,$(PROCESSOR_ARCH)) -mno-unaligned-access
    5252
    5353ifeq ($(MACHINE), gta02)
     
    5959RD_DRVS += \
    6060        infrastructure/rootamdm37x \
     61        fb/amdm37x_dispc \
    6162        bus/usb/ehci \
    6263        bus/usb/ohci \
  • boot/arch/arm32/_link.ld.in

    r5e761f3 rb1011dae  
    1111        . = BOOT_BASE + 0x8000;
    1212        .data : {
     13                bdata_start = .;
    1314                *(BOOTPT);      /* bootstrap page table */
    1415                *(BOOTSTACK);   /* bootstrap stack */
     
    2425[[COMPONENTS]]
    2526        }
    26        
     27        bdata_end = .;
     28
    2729        /DISCARD/ : {
    2830                *(.gnu.*);
  • boot/arch/arm32/include/mm.h

    r5e761f3 rb1011dae  
    5858#define GTA02_IOMEM_END  0x60000000
    5959
     60/** Start of ram memory on BBxM */
     61#define BBXM_RAM_START   0x80000000
     62/** Start of ram memory on BBxM */
     63#define BBXM_RAM_END   0xc0000000
     64
     65
    6066/* Page table level 0 entry - "section" format is used
    6167 * (one-level paging, 1 MB sized pages). Used only while booting the kernel.
  • boot/arch/arm32/src/asm.S

    r5e761f3 rb1011dae  
    6161        #
    6262
    63 #if defined(MACHINE_gta02)
     63        #
     64        # r0 is kernel entry point
     65        # r1 is pointer to the bootinfo structure
    6466
    6567#define CP15_C1_IC              12
     68#define CP15_C1_BP              11
    6669#define CP15_C1_DC              2
    67 #define CP15_C7_SEG_SHIFT       5
    68 #define CP15_C7_SEG_SIZE        3
    69 #define CP15_C7_IDX_SHIFT       26
    70 
    7170        # Disable I-cache and D-cache before the kernel is started.
    7271        mrc     p15, 0, r4, c1, c0, 0
    7372        bic     r4, r4, #(1 << CP15_C1_DC)
    7473        bic     r4, r4, #(1 << CP15_C1_IC)
     74        bic     r4, r4, #(1 << CP15_C1_BP)
    7575        mcr     p15, 0, r4, c1, c0, 0
     76
     77       
     78        #Wait for the operations to complete
     79#ifdef PROCESSOR_ARCH_armv7_a
     80        dsb
     81#else
     82        #cp15 dsb, r4 is ignored (should be zero)
     83        mcr p15, 0, r4, c7, c10, 4
     84#endif
     85       
     86        # Clean ICache and BPredictors, r4 ignored (SBZ)
     87        mcr p15, 0, r4, c7, c5, 0
     88        nop
     89
     90        #Wait for the operations to complete
     91#ifdef PROCESSOR_ARCH_armv7_a
     92        isb
     93        nop
     94#else
     95        # cp15 isb
     96        mcr p15, 0, r4, c7, c5, 4
     97        nop
     98#endif
     99       
     100#TODO:This should not be necessary
     101
     102#if defined(MACHINE_gta02)
     103
     104#define CP15_C7_SEG_SHIFT       5
     105#define CP15_C7_SEG_SIZE        3
     106#define CP15_C7_IDX_SHIFT       26
    76107
    77108        # Now clean D-cache to guarantee coherency between I-cache and D-cache.
  • boot/arch/arm32/src/main.c

    r5e761f3 rb1011dae  
    5050#define TOP2ADDR(top)  (((void *) PA2KA(BOOT_OFFSET)) + (top))
    5151
     52extern void *bdata_start;
     53extern void *bdata_end;
     54
     55
     56static inline void invalidate_icache(void)
     57{
     58        /* ICIALLU Invalidate entire ICache */
     59        asm volatile ("mov r0, #0\n" "mcr p15, 0, r0, c7, c5, 0\n" ::: "r0" );
     60}
     61
     62static inline void invalidate_dcache(void *address, size_t size)
     63{
     64        const uintptr_t addr = (uintptr_t)address;
     65        /* DCIMVAC - invalidate by address to the point of coherence */
     66        for (uintptr_t a = addr; a < addr + size; a += 4) {
     67                asm volatile ("mcr p15, 0, %[a], c7, c6, 1\n" :: [a]"r"(a) : );
     68        }
     69}
     70
     71static inline void clean_dcache_poc(void *address, size_t size)
     72{
     73        const uintptr_t addr = (uintptr_t)address;
     74        /* DCCMVAC - clean by address to the point of coherence */
     75        for (uintptr_t a = addr; a < addr + size; a += 4) {
     76                asm volatile ("mcr p15, 0, %[a], c7, c10, 1\n" :: [a]"r"(a) : );
     77        }
     78}
     79
    5280static bootinfo_t bootinfo;
    5381
    5482void bootstrap(void)
    5583{
     84        /* Make sure  we run in memory code when caches are enabled,
     85         * make sure we read memory data too. This part is ARMv7 specific as
     86         * ARMv7 no longer invalidates caches on restart.
     87         * See chapter B2.2.2 of ARM Architecture Reference Manual p. B2-1263*/
     88        invalidate_icache();
     89        invalidate_dcache(&bdata_start, &bdata_end - &bdata_start);
     90
     91        /* Enable MMU and caches */
    5692        mmu_start();
    5793        version_print();
    5894       
     95        printf("Boot data: %p -> %p\n", &bdata_start, &bdata_end);
    5996        printf("\nMemory statistics\n");
    6097        printf(" %p|%p: bootstrap stack\n", &boot_stack, &boot_stack);
     
    64101            (void *) PA2KA(BOOT_OFFSET), (void *) BOOT_OFFSET);
    65102       
    66         size_t i;
    67         for (i = 0; i < COMPONENTS; i++)
     103        for (size_t i = 0; i < COMPONENTS; i++) {
    68104                printf(" %p|%p: %s image (%u/%u bytes)\n", components[i].start,
    69105                    components[i].start, components[i].name, components[i].inflated,
    70106                    components[i].size);
     107                invalidate_dcache(components[i].start, components[i].size);
     108        }
    71109       
    72110        void *dest[COMPONENTS];
     
    74112        size_t cnt = 0;
    75113        bootinfo.cnt = 0;
    76         for (i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) {
     114        for (size_t i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) {
    77115                top = ALIGN_UP(top, PAGE_SIZE);
    78116               
     
    94132        printf("\nInflating components ... ");
    95133       
    96         for (i = cnt; i > 0; i--) {
     134        for (size_t i = cnt; i > 0; i--) {
    97135                void *tail = components[i - 1].start + components[i - 1].size;
    98136                if (tail >= dest[i - 1]) {
     
    106144                int err = inflate(components[i - 1].start, components[i - 1].size,
    107145                    dest[i - 1], components[i - 1].inflated);
    108                
    109146                if (err != EOK) {
    110147                        printf("\n%s: Inflating error %d\n", components[i - 1].name, err);
    111148                        halt();
    112149                }
     150                clean_dcache_poc(dest[i - 1], components[i - 1].inflated);
    113151        }
    114152       
    115153        printf(".\n");
    116154       
    117         printf("Booting the kernel... \n");
     155        void *kernel_end = (void *) PA2KA(BOOT_OFFSET + components[0].inflated);
     156        printf("Booting the kernel...\n");
    118157        jump_to_kernel((void *) PA2KA(BOOT_OFFSET), &bootinfo);
    119158}
  • boot/arch/arm32/src/mm.c

    r5e761f3 rb1011dae  
    6666        else
    6767                return 1;
    68 #else
     68#elif defined MACHINE_beagleboardxm
     69        const unsigned long address = section << PTE_SECTION_SHIFT;
     70        if (address >= BBXM_RAM_START && address < BBXM_RAM_END)
     71                return 1;
     72#endif
    6973        return 0;
    70 #endif
    7174}
    7275
     
    129132                "mrc p15, 0, r0, c1, c0, 0\n"
    130133               
    131 #ifdef PROCESSOR_armv7_a
    132                 /* Mask to enable paging, caching */
    133                 "ldr r1, =0x00000005\n"
    134 #else
    135 #ifdef MACHINE_gta02
    136                 /* Mask to enable paging (bit 0),
    137                    D-cache (bit 2), I-cache (bit 12) */
    138                 "ldr r1, =0x00001005\n"
    139 #else
    140                 /* Mask to enable paging */
    141                 "ldr r1, =0x00000001\n"
    142 #endif
    143 #endif
     134                /* Enable ICache, DCache, BPredictors and MMU,
     135                 * we disable caches before jumping to kernel
     136                 * so this is safe for all archs.
     137                 */
     138                "ldr r1, =0x00001805\n"
     139               
    144140                "orr r0, r0, r1\n"
    145141
  • kernel/arch/arm32/Makefile.inc

    r5e761f3 rb1011dae  
    3333ATSIGN = %
    3434
    35 GCC_CFLAGS += -fno-omit-frame-pointer -mapcs-frame -march=$(subst _,-,$(PROCESSOR)) -mno-unaligned-access
     35GCC_CFLAGS += -fno-omit-frame-pointer -mapcs-frame -march=$(subst _,-,$(PROCESSOR_ARCH)) -mno-unaligned-access
    3636
    3737ifeq ($(CONFIG_FPU),y)
    3838# This is necessary to allow vmsr insn and fpexc manipulation
    3939# Use vfp32 to allow context save/restore of d16-d31 regs.
    40 GCC_CFLAGS += -mfloat-abi=hard -mfpu=vfp3
     40AFLAGS += -mfloat-abi=hard -mfpu=vfp3
    4141endif
    4242
     
    7070ifeq ($(CONFIG_FPU),y)
    7171        ARCH_SOURCES += arch/$(KARCH)/src/fpu_context.c
     72        ARCH_SOURCES += arch/$(KARCH)/src/fpu.s
    7273endif
    7374
  • kernel/arch/arm32/include/asm.h

    r5e761f3 rb1011dae  
    4343#include <trace.h>
    4444
    45 /** No such instruction on old ARM to sleep CPU.
     45/** CPU specific way to sleep cpu.
    4646 *
    4747 * ARMv7 introduced wait for event and wait for interrupt (wfe/wfi).
    4848 * ARM920T has custom coprocessor action to do the same. See ARM920T Technical
    4949 * Reference Manual ch 4.9 p. 4-23 (103 in the PDF)
     50 * ARM926EJ-S uses the same coprocessor instruction as ARM920T. See ARM926EJ-S
     51 * chapter 2.3.8 p.2-22 (52 in the PDF)
     52 *
     53 * @note Although mcr p15, 0, R0, c7, c0, 4 is defined in ARM Architecture
     54 * reference manual for armv4/5 CP15 implementation is mandatory only for
     55 * armv6+.
    5056 */
    5157NO_TRACE static inline void cpu_sleep(void)
    5258{
    53 #ifdef PROCESSOR_armv7_a
    54         asm volatile ( "wfe" :: );
    55 #elif defined(MACHINE_gta02)
    56         asm volatile ( "mcr p15,0,R0,c7,c0,4" :: );
     59#ifdef PROCESSOR_ARCH_armv7_a
     60        asm volatile ( "wfe" );
     61#elif defined(PROCESSOR_ARCH_armv6) | defined(PROCESSOR_arm926ej_s) | defined(PROCESSOR_arm920t)
     62        asm volatile ( "mcr p15, 0, R0, c7, c0, 4" );
    5763#endif
    5864}
  • kernel/arch/arm32/include/barrier.h

    r5e761f3 rb1011dae  
    3737#define KERN_arm32_BARRIER_H_
    3838
    39 /*
    40  * TODO: implement true ARM memory barriers for macros below.
    41  */
     39#ifdef KERNEL
     40#include <arch/cp15.h>
     41#else
     42#include <libarch/cp15.h>
     43#endif
     44
    4245#define CS_ENTER_BARRIER()  asm volatile ("" ::: "memory")
    4346#define CS_LEAVE_BARRIER()  asm volatile ("" ::: "memory")
    4447
     48#if defined PROCESSOR_ARCH_armv7_a
     49/* ARMv7 uses instructions for memory barriers see ARM Architecture reference
     50 * manual for details:
     51 * DMB: ch. A8.8.43 page A8-376
     52 * DSB: ch. A8.8.44 page A8-378
     53 * See ch. A3.8.3 page A3-148 for details about memory barrier implementation
     54 * and functionality on armv7 architecture.
     55 */
     56#define memory_barrier()  asm volatile ("dmb" ::: "memory")
     57#define read_barrier()    asm volatile ("dsb" ::: "memory")
     58#define write_barrier()   asm volatile ("dsb st" ::: "memory")
     59#define inst_barrier()    asm volatile ("isb" ::: "memory")
     60#elif defined PROCESSOR_ARCH_armv6 | defined KERNEL
     61/*
     62 * ARMv6 introduced user access of the following commands:
     63 * - Prefetch flush
     64 * - Data synchronization barrier
     65 * - Data memory barrier
     66 * - Clean and prefetch range operations.
     67 * ARM Architecture Reference Manual version I ch. B.3.2.1 p. B3-4
     68 */
     69/* ARMv6- use system control coprocessor (CP15) for memory barrier instructions.
     70 * Although at least mcr p15, 0, r0, c7, c10, 4 is mentioned in earlier archs,
     71 * CP15 implementation is mandatory only for armv6+.
     72 */
     73#define memory_barrier()  CP15DMB_write(0)
     74#define read_barrier()    CP15DSB_write(0)
     75#define write_barrier()   read_barrier()
     76#define inst_barrier()    CP15ISB_write(0)
     77#else
     78/* Older manuals mention syscalls as a way to implement cache coherency and
     79 * barriers. See for example ARM Architecture Reference Manual Version D
     80 * chapter 2.7.4 Prefetching and self-modifying code (p. A2-28)
     81 */
     82// TODO implement on per PROCESSOR basis or via syscalls
    4583#define memory_barrier()  asm volatile ("" ::: "memory")
    4684#define read_barrier()    asm volatile ("" ::: "memory")
    4785#define write_barrier()   asm volatile ("" ::: "memory")
     86#define inst_barrier()    asm volatile ("" ::: "memory")
     87#endif
    4888
    4989/*
     
    62102 */
    63103
    64 /* Available on both all supported arms,
     104#if defined PROCESSOR_ARCH_armv7_a | defined PROCESSOR_ARCH_armv6 | defined KERNEL
     105/* Available on all supported arms,
    65106 * invalidates entire ICache so the written value does not matter. */
    66 #define smc_coherence(a) asm volatile ( "mcr p15, 0, r0, c7, c5, 0")
    67 #define smc_coherence_block(a, l) smc_coherence(a)
     107//TODO might be PL1 only on armv5-
     108#define smc_coherence(a) \
     109do { \
     110        DCCMVAU_write((uint32_t)(a));  /* Flush changed memory */\
     111        write_barrier();               /* Wait for completion */\
     112        ICIALLU_write(0);              /* Flush ICache */\
     113        inst_barrier();                /* Wait for Inst refetch */\
     114} while (0)
     115/* @note: Cache type register is not available in uspace. We would need
     116 * to export the cache line value, or use syscall for uspace smc_coherence */
     117#define smc_coherence_block(a, l) \
     118do { \
     119        for (uintptr_t addr = (uintptr_t)a; addr < (uintptr_t)a + l; addr += 4)\
     120                smc_coherence(addr); \
     121} while (0)
     122#else
     123#define smc_coherence(a)
     124#define smc_coherence_block(a, l)
     125#endif
    68126
    69127
  • kernel/arch/arm32/include/cpu.h

    r5e761f3 rb1011dae  
    4040#include <arch/asm.h>
    4141
     42enum {
     43        ARM_MAX_CACHE_LEVELS = 7,
     44};
    4245
    4346/** Struct representing ARM CPU identification. */
     
    5760        /** Revision number. */
    5861        uint32_t rev_num;
     62
     63        struct {
     64                unsigned ways;
     65                unsigned sets;
     66                unsigned line_size;
     67                unsigned way_shift;
     68                unsigned set_shift;
     69        } dcache[ARM_MAX_CACHE_LEVELS];
     70        unsigned dcache_levels;
    5971} cpu_arch_t;
    6072
  • kernel/arch/arm32/include/cycle.h

    r5e761f3 rb1011dae  
    3838
    3939#include <trace.h>
     40#include <arch/cp15.h>
    4041
    4142/** Return count of CPU cycles.
     
    4849NO_TRACE static inline uint64_t get_cycle(void)
    4950{
     51#ifdef PROCESSOR_ARCH_armv7_a
     52        if ((ID_PFR1_read() & ID_PFR1_GEN_TIMER_EXT_MASK) ==
     53            ID_PFR1_GEN_TIMER_EXT) {
     54            uint32_t low = 0, high = 0;
     55            asm volatile( "MRRC p15, 0, %[low], %[high], c14": [low]"=r"(low), [high]"=r"(high));
     56           return ((uint64_t)high << 32) | low;
     57        } else {
     58                return (uint64_t)PMCCNTR_read() * 64;
     59        }
     60#endif
    5061        return 0;
    5162}
  • kernel/arch/arm32/include/mm/frame.h

    r5e761f3 rb1011dae  
    4747
    4848#ifdef MACHINE_gta02
     49
     50#define PHYSMEM_START_ADDR       0x30008000
    4951#define BOOT_PAGE_TABLE_ADDRESS  0x30010000
     52
    5053#elif defined MACHINE_beagleboardxm
     54
     55#define PHYSMEM_START_ADDR       0x80000000
    5156#define BOOT_PAGE_TABLE_ADDRESS  0x80008000
     57
    5258#elif defined MACHINE_beaglebone
     59
     60#define PHYSMEM_START_ADDR       0x80000000
    5361#define BOOT_PAGE_TABLE_ADDRESS  0x80008000
     62
    5463#else
     64
     65#define PHYSMEM_START_ADDR       0x00000000
    5566#define BOOT_PAGE_TABLE_ADDRESS  0x00008000
     67
    5668#endif
    5769
    5870#define BOOT_PAGE_TABLE_START_FRAME     (BOOT_PAGE_TABLE_ADDRESS >> FRAME_WIDTH)
    5971#define BOOT_PAGE_TABLE_SIZE_IN_FRAMES  (BOOT_PAGE_TABLE_SIZE >> FRAME_WIDTH)
    60 
    61 #ifdef MACHINE_gta02
    62 #define PHYSMEM_START_ADDR      0x30008000
    63 #elif defined MACHINE_beagleboardxm
    64 #define PHYSMEM_START_ADDR      0x80000000
    65 #elif defined MACHINE_beaglebone
    66 #define PHYSMEM_START_ADDR      0x80000000
    67 #else
    68 #define PHYSMEM_START_ADDR      0x00000000
    69 #endif
    7072
    7173extern void frame_low_arch_init(void);
  • kernel/arch/arm32/include/mm/page.h

    r5e761f3 rb1011dae  
    129129        set_pt_level1_present((pte_t *) (ptl3), (size_t) (i))
    130130
    131 #if defined(PROCESSOR_armv6) | defined(PROCESSOR_armv7_a)
     131#if defined(PROCESSOR_ARCH_armv6) | defined(PROCESSOR_ARCH_armv7_a)
    132132#include "page_armv6.h"
    133 #elif defined(PROCESSOR_armv4) | defined(PROCESSOR_armv5)
     133#elif defined(PROCESSOR_ARCH_armv4) | defined(PROCESSOR_ARCH_armv5)
    134134#include "page_armv4.h"
    135135#else
  • kernel/arch/arm32/include/mm/page_fault.h

    r5e761f3 rb1011dae  
    4242/** Decribes CP15 "fault status register" (FSR).
    4343 *
    44  * See ARM Architecture Reference Manual ch. B4.9.6 (pdf p.743).
     44 * "VMSAv6 added a fifth fault status bit (bit[10]) to both the IFSR and DFSR.
     45 * It is IMPLEMENTATION DEFINED how this bit is encoded in earlier versions of
     46 * the architecture. A write flag (bit[11] of the DFSR) has also been
     47 * introduced."
     48 * ARM Architecture Reference Manual version i ch. B4.6 (PDF p. 719)
     49 *
     50 * See ARM Architecture Reference Manual ch. B4.9.6 (pdf p.743). for FSR info
    4551 */
    4652typedef union {
  • kernel/arch/arm32/include/regutils.h

    r5e761f3 rb1011dae  
    4141#define STATUS_REG_MODE_MASK         0x1f
    4242
    43 /* COntrol register bit values see ch. B4.1.130 of ARM Architecture Reference
    44  * Manual ARMv7-A and ARMv7-R edition, page 1687 */
    45 #define CP15_R1_MMU_EN            (1 << 0)
    46 #define CP15_R1_ALIGN_CHECK_EN    (1 << 1)  /* Allow alignemnt check */
    47 #define CP15_R1_CACHE_EN          (1 << 2)
    48 #define CP15_R1_CP15_BARRIER_EN   (1 << 5)
    49 #define CP15_R1_B_EN              (1 << 7)  /* ARMv6- only big endian switch */
    50 #define CP15_R1_SWAP_EN           (1 << 10)
    51 #define CP15_R1_BRANCH_PREDICT_EN (1 << 11)
    52 #define CP15_R1_INST_CACHE_EN     (1 << 12)
    53 #define CP15_R1_HIGH_VECTORS_EN   (1 << 13)
    54 #define CP15_R1_ROUND_ROBIN_EN    (1 << 14)
    55 #define CP15_R1_HW_ACCESS_FLAG_EN (1 << 17)
    56 #define CP15_R1_WRITE_XN_EN       (1 << 19) /* Only if virt. supported */
    57 #define CP15_R1_USPCE_WRITE_XN_EN (1 << 20) /* Only if virt. supported */
    58 #define CP15_R1_FAST_IRQ_EN       (1 << 21) /* Disbale impl.specific features */
    59 #define CP15_R1_UNALIGNED_EN      (1 << 22) /* Must be 1 on armv7 */
    60 #define CP15_R1_IRQ_VECTORS_EN    (1 << 24)
    61 #define CP15_R1_BIG_ENDIAN_EXC    (1 << 25)
    62 #define CP15_R1_NMFI_EN           (1 << 27)
    63 #define CP15_R1_TEX_REMAP_EN      (1 << 28)
    64 #define CP15_R1_ACCESS_FLAG_EN    (1 << 29)
    65 #define CP15_R1_THUMB_EXC_EN      (1 << 30)
    66 
    6743/* 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 
     44enum {
     45        USER_MODE = 0x10,
     46        FIQ_MODE = 0x11,
     47        IRQ_MODE = 0x12,
     48        SUPERVISOR_MODE = 0x13,
     49        MONITOR_MODE = 0x16,
     50        ABORT_MODE = 0x17,
     51        HYPERVISOR_MODE = 0x1a,
     52        UNDEFINED_MODE = 0x1b,
     53        SYSTEM_MODE = 0x1f,
     54        MODE_MASK = 0x1f,
     55};
    7656/* [CS]PRS manipulation macros */
    7757#define GEN_STATUS_READ(nm, reg) \
  • kernel/arch/arm32/src/cpu/cpu.c

    r5e761f3 rb1011dae  
    3434 */
    3535
     36#include <arch/cache.h>
    3637#include <arch/cpu.h>
     38#include <arch/cp15.h>
    3739#include <cpu.h>
    3840#include <arch.h>
    3941#include <print.h>
     42
     43static inline unsigned log2(unsigned val)
     44{
     45        unsigned log = 0;
     46        --val;
     47        while (val) {
     48                ++log;
     49                val >>= 1;
     50        }
     51        return log;
     52}
     53
     54static unsigned dcache_ways(unsigned level);
     55static unsigned dcache_sets(unsigned level);
     56static unsigned dcache_linesize_log(unsigned level);
     57
    4058
    4159/** Implementers (vendor) names */
     
    8199static void arch_cpu_identify(cpu_arch_t *cpu)
    82100{
    83         uint32_t ident;
    84         asm volatile (
    85                 "mrc p15, 0, %[ident], c0, c0, 0\n"
    86                 : [ident] "=r" (ident)
    87         );
    88        
    89         cpu->imp_num = ident >> 24;
    90         cpu->variant_num = (ident << 8) >> 28;
    91         cpu->arch_num = (ident << 12) >> 28;
    92         cpu->prim_part_num = (ident << 16) >> 20;
    93         cpu->rev_num = (ident << 28) >> 28;
     101        const uint32_t ident = MIDR_read();
     102
     103        cpu->imp_num = (ident >> MIDR_IMPLEMENTER_SHIFT) & MIDR_IMPLEMENTER_MASK;
     104        cpu->variant_num = (ident >> MIDR_VARIANT_SHIFT) & MIDR_VARIANT_MASK;
     105        cpu->arch_num = (ident >> MIDR_ARCHITECTURE_SHIFT) & MIDR_ARCHITECTURE_MASK;
     106        cpu->prim_part_num = (ident >> MIDR_PART_NUMBER_SHIFT) & MIDR_PART_NUMBER_MASK;
     107        cpu->rev_num = (ident >> MIDR_REVISION_SHIFT) & MIDR_REVISION_MASK;
     108
    94109        // TODO CPUs with arch_num == 0xf use CPUID scheme for identification
     110        cpu->dcache_levels = dcache_levels();
     111
     112        for (unsigned i = 0; i < cpu->dcache_levels; ++i) {
     113                cpu->dcache[i].ways = dcache_ways(i);
     114                cpu->dcache[i].sets = dcache_sets(i);
     115                cpu->dcache[i].way_shift = 31 - log2(cpu->dcache[i].ways);
     116                cpu->dcache[i].set_shift = dcache_linesize_log(i);
     117                cpu->dcache[i].line_size = 1 << dcache_linesize_log(i);
     118                printf("Found DCache L%u: %u-way, %u sets, %u byte lines "
     119                    "(shifts: w%u, s%u)\n", i + 1, cpu->dcache[i].ways,
     120                    cpu->dcache[i].sets, cpu->dcache[i].line_size,
     121                    cpu->dcache[i].way_shift, cpu->dcache[i].set_shift);
     122        }
    95123}
    96124
     
    98126void cpu_arch_init(void)
    99127{
    100 #if defined(PROCESSOR_armv7_a) | defined(PROCESSOR_armv6)
    101         uint32_t control_reg = 0;
    102         asm volatile (
    103                 "mrc p15, 0, %[control_reg], c1, c0"
    104                 : [control_reg] "=r" (control_reg)
    105         );
     128        uint32_t control_reg = SCTLR_read();
    106129       
    107         /* Turn off tex remap, RAZ ignores writes prior to armv7 */
    108         control_reg &= ~CP15_R1_TEX_REMAP_EN;
    109         /* Turn off accessed flag, RAZ ignores writes prior to armv7 */
    110         control_reg &= ~(CP15_R1_ACCESS_FLAG_EN | CP15_R1_HW_ACCESS_FLAG_EN);
    111         /* Enable unaligned access, RAZ ignores writes prior to armv6
    112          * switchable on armv6, RAO ignores writes on armv7,
     130        /* Turn off tex remap, RAZ/WI prior to armv7 */
     131        control_reg &= ~SCTLR_TEX_REMAP_EN_FLAG;
     132        /* Turn off accessed flag, RAZ/WI prior to armv7 */
     133        control_reg &= ~(SCTLR_ACCESS_FLAG_EN_FLAG | SCTLR_HW_ACCESS_FLAG_EN_FLAG);
     134
     135        /* Unaligned access is supported on armv6+ */
     136#if defined(PROCESSOR_ARCH_armv7_a) | defined(PROCESSOR_ARCH_armv6)
     137        /* Enable unaligned access, RAZ/WI prior to armv6
     138         * switchable on armv6, RAO/WI writes on armv7,
    113139         * see ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition
    114140         * L.3.1 (p. 2456) */
    115         control_reg |= CP15_R1_UNALIGNED_EN;
     141        control_reg |= SCTLR_UNALIGNED_EN_FLAG;
    116142        /* Disable alignment checks, this turns unaligned access to undefined,
    117143         * unless U bit is set. */
    118         control_reg &= ~CP15_R1_ALIGN_CHECK_EN;
     144        control_reg &= ~SCTLR_ALIGN_CHECK_EN_FLAG;
    119145        /* Enable caching, On arm prior to armv7 there is only one level
    120146         * of caches. Data cache is coherent.
     
    124150         *    ARM Architecture Reference Manual ARMv7-A and ARMv7-R Edition
    125151         *    B3.11.1 (p. 1383)
    126          * ICache coherency is elaborate on in barrier.h.
    127          * We are safe to turn these on.
     152         * We are safe to turn this on. For arm v6 see ch L.6.2 (p. 2469)
     153         * L2 Cache for armv7 is enabled by default (i.e. controlled by
     154         * this flag).
    128155         */
    129         control_reg |= CP15_R1_CACHE_EN | CP15_R1_INST_CACHE_EN;
    130        
    131         asm volatile (
    132                 "mcr p15, 0, %[control_reg], c1, c0"
    133                 :: [control_reg] "r" (control_reg)
    134         );
    135 #endif
     156        control_reg |= SCTLR_CACHE_EN_FLAG;
     157#endif
     158#ifdef PROCESSOR_ARCH_armv7_a
     159         /* ICache coherency is elaborate on in barrier.h.
     160          * VIPT and PIPT caches need maintenance only on code modify,
     161          * so it should be safe for general use.
     162          * Enable branch predictors too as they follow the same rules
     163          * as ICache and they can be flushed together
     164          */
     165        if ((CTR_read() & CTR_L1I_POLICY_MASK) != CTR_L1I_POLICY_AIVIVT) {
     166                control_reg |=
     167                    SCTLR_INST_CACHE_EN_FLAG | SCTLR_BRANCH_PREDICT_EN_FLAG;
     168        }
     169#endif
     170        SCTLR_write(control_reg);
     171
    136172#ifdef CONFIG_FPU
    137173        fpu_setup();
     174#endif
     175
     176#ifdef PROCESSOR_ARCH_armv7_a
     177        if ((ID_PFR1_read() & ID_PFR1_GEN_TIMER_EXT_MASK) !=
     178            ID_PFR1_GEN_TIMER_EXT) {
     179                PMCR_write(PMCR_read() | PMCR_E_FLAG | PMCR_D_FLAG);
     180                PMCNTENSET_write(PMCNTENSET_CYCLE_COUNTER_EN_FLAG);
     181        }
    138182#endif
    139183}
     
    155199}
    156200
     201/** See chapter B4.1.19 of ARM Architecture Reference Manual */
     202static unsigned dcache_linesize_log(unsigned level)
     203{
     204#ifdef PROCESSOR_ARCH_armv7_a
     205        CSSELR_write((level & CCSELR_LEVEL_MASK) << CCSELR_LEVEL_SHIFT);
     206        const unsigned ls_log = 2 +
     207            ((CCSIDR_read() >> CCSIDR_LINESIZE_SHIFT) & CCSIDR_LINESIZE_MASK);
     208        return ls_log + 2; //return log2(bytes)
     209#endif
     210        return 0;
     211
     212}
     213
     214/** See chapter B4.1.19 of ARM Architecture Reference Manual */
     215static unsigned dcache_ways(unsigned level)
     216{
     217#ifdef PROCESSOR_ARCH_armv7_a
     218        CSSELR_write((level & CCSELR_LEVEL_MASK) << CCSELR_LEVEL_SHIFT);
     219        const unsigned ways = 1 +
     220            ((CCSIDR_read() >> CCSIDR_ASSOC_SHIFT) & CCSIDR_ASSOC_MASK);
     221        return ways;
     222#endif
     223        return 0;
     224}
     225
     226/** See chapter B4.1.19 of ARM Architecture Reference Manual */
     227static unsigned dcache_sets(unsigned level)
     228{
     229#ifdef PROCESSOR_ARCH_armv7_a
     230        CSSELR_write((level & CCSELR_LEVEL_MASK) << CCSELR_LEVEL_SHIFT);
     231        const unsigned sets = 1 +
     232            ((CCSIDR_read() >> CCSIDR_NUMSETS_SHIFT) & CCSIDR_NUMSETS_MASK);
     233        return sets;
     234#endif
     235        return 0;
     236}
     237
     238unsigned dcache_levels(void)
     239{
     240        unsigned levels = 0;
     241#ifdef PROCESSOR_ARCH_armv7_a
     242        const uint32_t val = CLIDR_read();
     243        for (unsigned i = 1; i <= 7; ++i) {
     244                const unsigned ctype = CLIDR_CACHE(i, val);
     245                switch (ctype) {
     246                case CLIDR_DCACHE_ONLY:
     247                case CLIDR_SEP_CACHE:
     248                case CLIDR_UNI_CACHE:
     249                        ++levels;
     250                default:
     251                        (void)0;
     252                }
     253        }
     254#endif
     255        return levels;
     256}
     257
     258static void dcache_clean_manual(unsigned level, bool invalidate,
     259    unsigned ways, unsigned sets, unsigned way_shift, unsigned set_shift)
     260{
     261
     262        for (unsigned i = 0; i < ways; ++i) {
     263                for (unsigned j = 0; j < sets; ++j) {
     264                        const uint32_t val =
     265                            ((level & 0x7) << 1) |
     266                            (j << set_shift) | (i << way_shift);
     267                        if (invalidate)
     268                                DCCISW_write(val);
     269                        else
     270                                DCCSW_write(val);
     271                }
     272        }
     273}
     274
     275void dcache_flush(void)
     276{
     277        /* See ARM Architecture Reference Manual ch. B4.2.1 p. B4-1724 */
     278        const unsigned levels = dcache_levels();
     279        for (unsigned i = 0; i < levels; ++i) {
     280                const unsigned ways = dcache_ways(i);
     281                const unsigned sets = dcache_sets(i);
     282                const unsigned way_shift =  31 - log2(ways);
     283                const unsigned set_shift = dcache_linesize_log(i);
     284                dcache_clean_manual(i, false, ways, sets, way_shift, set_shift);
     285        }
     286}
     287
     288void dcache_flush_invalidate(void)
     289{
     290        /* See ARM Architecture Reference Manual ch. B4.2.1 p. B4-1724 */
     291        const unsigned levels = dcache_levels();
     292        for (unsigned i = 0; i < levels; ++i) {
     293                const unsigned ways = dcache_ways(i);
     294                const unsigned sets = dcache_sets(i);
     295                const unsigned way_shift =  31 - log2(ways);
     296                const unsigned set_shift = dcache_linesize_log(i);
     297                dcache_clean_manual(i, true, ways, sets, way_shift, set_shift);
     298        }
     299}
     300
     301
     302void cpu_dcache_flush(void)
     303{
     304        for (unsigned i = 0; i < CPU->arch.dcache_levels; ++i)
     305                dcache_clean_manual(i, false,
     306                    CPU->arch.dcache[i].ways, CPU->arch.dcache[i].sets,
     307                    CPU->arch.dcache[i].way_shift, CPU->arch.dcache[i].set_shift);
     308}
     309
     310void cpu_dcache_flush_invalidate(void)
     311{
     312        const unsigned levels =  dcache_levels();
     313        for (unsigned i = 0; i < levels; ++i)
     314                dcache_clean_manual(i, true,
     315                    CPU->arch.dcache[i].ways, CPU->arch.dcache[i].sets,
     316                    CPU->arch.dcache[i].way_shift, CPU->arch.dcache[i].set_shift);
     317}
     318
     319void icache_invalidate(void)
     320{
     321        ICIALLU_write(0);
     322}
     323
    157324/** @}
    158325 */
  • kernel/arch/arm32/src/exception.c

    r5e761f3 rb1011dae  
    3939#include <interrupt.h>
    4040#include <arch/mm/page_fault.h>
     41#include <arch/cp15.h>
    4142#include <arch/barrier.h>
    4243#include <print.h>
     
    7374        /* make it LDR instruction and store at exception vector */
    7475        *vector = handler_address_ptr | LDR_OPCODE;
    75         smc_coherence(*vector);
     76        smc_coherence(vector);
    7677       
    7778        /* store handler's address */
     
    136137static void high_vectors(void)
    137138{
    138         uint32_t control_reg = 0;
    139         asm volatile (
    140                 "mrc p15, 0, %[control_reg], c1, c0"
    141                 : [control_reg] "=r" (control_reg)
    142         );
     139        uint32_t control_reg = SCTLR_read();
    143140       
    144141        /* switch on the high vectors bit */
    145         control_reg |= CP15_R1_HIGH_VECTORS_EN;
    146        
    147         asm volatile (
    148                 "mcr p15, 0, %[control_reg], c1, c0"
    149                 :: [control_reg] "r" (control_reg)
    150         );
     142        control_reg |= SCTLR_HIGH_VECTORS_EN_FLAG;
     143       
     144        SCTLR_write(control_reg);
    151145}
    152146#endif
  • kernel/arch/arm32/src/fpu_context.c

    r5e761f3 rb1011dae  
    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#ifdef PROCESSOR_ARCH_armv7_a
     151        /* Allow coprocessor access */
     152        uint32_t cpacr = CPACR_read();
     153        /* FPU needs access to coprocessor 10 and 11.
     154         * Moreover, they need to have same access enabled */
     155        cpacr &= ~(CPACR_CP_MASK(10) | CPACR_CP_MASK(11));
     156        cpacr |= (CPACR_CP_FULL_ACCESS(10) | CPACR_CP_FULL_ACCESS(11));
     157        CPACR_write(cpacr);
     158#endif
     159}
     160
    229161
    230162void fpu_init(void)
    231163{
     164        /* Check if we have access */
     165        if (!fpu_have_coprocessor_access())
     166                return;
     167
    232168        /* Clear all fpu flags */
    233169        fpexc_write(0);
     
    241177void fpu_setup(void)
    242178{
    243         uint32_t fpsid = 0;
    244         asm volatile (
    245                 "vmrs %0, fpsid\n"
    246                 :"=r"(fpsid)::
    247         );
     179        /* Enable coprocessor access*/
     180        fpu_enable_coprocessor_access();
     181
     182        /* Check if we succeeded */
     183        if (!fpu_have_coprocessor_access())
     184                return;
     185
     186        const uint32_t fpsid = fpsid_read();
    248187        if (fpsid & FPSID_SW_ONLY_FLAG) {
    249188                printf("No FPU avaiable\n");
     
    265204        case FPU_VFPv3_NO_COMMON:
    266205        case FPU_VFPv3_COMMONv3: {
    267                 uint32_t mvfr0 = 0;
    268                 asm volatile (
    269                         "vmrs %0,mvfr0\n"
    270                         :"=r"(mvfr0)::
    271                 );
     206                const uint32_t mvfr0 = mvfr0_read();
    272207                /* See page B4-1637 */
    273208                if ((mvfr0 & 0xf) == 0x1) {
     
    288223bool handle_if_fpu_exception(void)
    289224{
     225        /* Check if we have access */
     226        if (!fpu_have_coprocessor_access())
     227                return false;
     228
    290229        const uint32_t fpexc = fpexc_read();
    291230        if (fpexc & FPEXC_ENABLED_FLAG) {
     
    305244void fpu_enable(void)
    306245{
     246        /* Check if we have access */
     247        if (!fpu_have_coprocessor_access())
     248                return;
    307249        /* Enable FPU instructions */
    308250        fpexc_write(fpexc_read() | FPEXC_ENABLED_FLAG);
     
    311253void fpu_disable(void)
    312254{
     255        /* Check if we have access */
     256        if (!fpu_have_coprocessor_access())
     257                return;
    313258        /* Disable FPU instructions */
    314259        fpexc_write(fpexc_read() & ~FPEXC_ENABLED_FLAG);
     
    317262void fpu_context_save(fpu_context_t *ctx)
    318263{
     264        /* This is only necessary if we enable fpu exceptions. */
     265#if 0
    319266        const uint32_t fpexc = fpexc_read();
    320267
     
    323270                //TODO implement common subarch context saving
    324271        }
     272#endif
    325273        if (save_context)
    326274                save_context(ctx);
  • kernel/arch/arm32/src/mach/beagleboardxm/beagleboardxm.c

    r5e761f3 rb1011dae  
    3838#include <genarch/drivers/amdm37x/irc.h>
    3939#include <genarch/drivers/amdm37x/gpt.h>
    40 #include <genarch/drivers/amdm37x/dispc.h>
    4140#include <genarch/fb/fb.h>
    4241#include <genarch/srln/srln.h>
     
    6160
    6261static struct beagleboard {
    63         amdm37x_dispc_regs_t *dispc;
    6462        amdm37x_irc_regs_t *irc_addr;
    6563        amdm37x_uart_t uart;
     
    8583}
    8684
    87 static void bbxm_setup_fb(unsigned width, unsigned height, unsigned bpp)
    88 {
    89         const unsigned pixel_bytes = (bpp / 8);
    90         const size_t size = ALIGN_UP(width * height * pixel_bytes, FRAME_SIZE);
    91         const unsigned frames = size / FRAME_SIZE;
    92         unsigned order = 0;
    93         unsigned frame = 1;
    94         while (frame < frames) {
    95                 frame *= 2;
    96                 ++order;
    97         }
    98         /* prefer highmem as we don't care about virtual mapping. */
    99         void *buffer = frame_alloc(order, FRAME_LOWMEM);
    100         if (!buffer) {
    101                 printf("Failed to allocate framebuffer.\n");
    102                 return;
    103         }
    104 
    105         amdm37x_dispc_setup_fb(beagleboard.dispc, width, height, bpp,
    106             (uintptr_t) buffer);
    107 
    108         fb_properties_t prop = {
    109                 .addr = (uintptr_t)buffer,
    110                 .offset = 0,
    111                 .x = width,
    112                 .y = height,
    113                 .scan = width * pixel_bytes,
    114                 .visual = VISUAL_RGB_5_6_5_LE
    115         };
    116         switch (bpp)
    117         {
    118         case 8:
    119                 prop.visual = VISUAL_INDIRECT_8; break;
    120         case 16:
    121                 prop.visual = VISUAL_RGB_5_6_5_LE; break;
    122         case 24:
    123                 prop.visual = VISUAL_BGR_8_8_8; break;
    124         case 32:
    125                 prop.visual = VISUAL_RGB_8_8_8_0; break;
    126         default:
    127                 printf("Invalid framebuffer bit depth: bailing out.\n");
    128                 return;
    129         }
    130         outdev_t *fb_dev = fb_init(&prop);
    131         if (fb_dev)
    132                 stdout_wire(fb_dev);
    133 
    134 }
    135 
    13685static void bb_timer_irq_handler(irq_t *irq)
    13786{
     
    154103        ASSERT(beagleboard.irc_addr);
    155104        amdm37x_irc_init(beagleboard.irc_addr);
    156 
    157         /* Map display controller */
    158         beagleboard.dispc = (void*) km_map(AMDM37x_DISPC_BASE_ADDRESS,
    159             AMDM37x_DISPC_SIZE, PAGE_NOT_CACHEABLE);
    160         ASSERT(beagleboard.dispc);
    161105
    162106        /* Initialize timer. Use timer1, because it is in WKUP power domain
     
    223167static void bbxm_output_init(void)
    224168{
    225 #ifdef CONFIG_FB
    226         bbxm_setup_fb(CONFIG_BFB_WIDTH, CONFIG_BFB_HEIGHT, CONFIG_BFB_BPP);
    227 #else
    228         (void)bbxm_setup_fb;
    229 #endif
    230169        /* UART3 is wired to external RS232 connector */
    231170        const bool ok = amdm37x_uart_init(&beagleboard.uart,
  • kernel/arch/arm32/src/mm/page_fault.c

    r5e761f3 rb1011dae  
    3434 */
    3535#include <panic.h>
     36#include <arch/cp15.h>
    3637#include <arch/exception.h>
    3738#include <arch/mm/page_fault.h>
     
    127128}
    128129
    129 
    130 /** Returns value stored in comnbined/data fault status register.
    131  *
    132  *  @return Value stored in CP15 fault status register (FSR).
    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  */
    143 static inline fault_status_t read_data_fault_status_register(void)
    144 {
    145         fault_status_t fsu;
    146        
    147         /* Combined/Data fault status is stored in CP15 register 5, c0. */
    148         asm volatile (
    149                 "mrc p15, 0, %[dummy], c5, c0, 0"
    150                 : [dummy] "=r" (fsu.raw)
    151         );
    152        
    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
    161  *         fault)
    162  */
    163 static inline uintptr_t read_data_fault_address_register(void)
    164 {
    165         uintptr_t ret;
    166        
    167         /* fault adress is stored in CP15 register 6 */
    168         asm volatile (
    169                 "mrc p15, 0, %[ret], c6, c0, 0"
    170                 : [ret] "=r" (ret)
    171         );
    172        
    173         return ret;
    174 }
    175 
    176 #if defined(PROCESSOR_armv4) | defined(PROCESSOR_armv5)
     130#if defined(PROCESSOR_ARCH_armv4) | defined(PROCESSOR_ARCH_armv5)
    177131/** Decides whether read or write into memory is requested.
    178132 *
     
    244198void data_abort(unsigned int exc_no, istate_t *istate)
    245199{
    246         const uintptr_t badvaddr = read_data_fault_address_register();
    247         const fault_status_t fsr = read_data_fault_status_register();
     200        const uintptr_t badvaddr = DFAR_read();
     201        const fault_status_t fsr = { .raw = DFSR_read() };
    248202        const dfsr_source_t source = fsr.raw & DFSR_SOURCE_MASK;
    249203
     
    281235        }
    282236
    283 #if defined(PROCESSOR_armv6) | defined(PROCESSOR_armv7_a)
     237#if defined(PROCESSOR_ARCH_armv6) | defined(PROCESSOR_ARCH_armv7_a)
    284238        const pf_access_t access =
    285239            fsr.data.wr ? PF_ACCESS_WRITE : PF_ACCESS_READ;
    286 #elif defined(PROCESSOR_armv4) | defined(PROCESSOR_armv5)
     240#elif defined(PROCESSOR_ARCH_armv4) | defined(PROCESSOR_ARCH_armv5)
    287241        const pf_access_t access = get_memory_access_type(istate->pc, badvaddr);
    288242#else
  • uspace/Makefile

    r5e761f3 rb1011dae  
    194194ifeq ($(UARCH),arm32)
    195195        DIRS += \
    196                 drv/infrastructure/rootamdm37x
     196                drv/infrastructure/rootamdm37x \
     197                drv/fb/amdm37x_dispc
    197198endif
    198199
  • uspace/drv/fb/amdm37x_dispc/amdm37x_dispc_regs.h

    r5e761f3 rb1011dae  
    11/*
    2  * Copyright (c) 2012 Jan Vesely
     2 * Copyright (c) 2013 Jan Vesely
    33 * All rights reserved.
    44 *
     
    3434 */
    3535
    36 #ifndef KERN_AMDM37x_DISPC_H_
    37 #define KERN_AMDM37x_DISPC_H_
     36#ifndef AMDM37x_DISPC_REGS_H_
     37#define AMDM37x_DISPC_REGS_H_
    3838
    3939/* AMDM37x TRM p. 1813 */
     
    4141#define AMDM37x_DISPC_SIZE 1024
    4242
    43 #define __paddname(line) PADD32_ ## line
    44 #define _paddname(line) __paddname(line)
    45 #define PADD32(count) uint32_t _paddname(__LINE__)[count]
    46 
    47 #include <typedefs.h>
     43#include <macros.h>
    4844
    4945typedef struct {
     
    5147#define AMDM37X_DISPC_REVISION_MASK  0xff
    5248
    53         PADD32(3);
     49        PADD32[3];
    5450        ioport32_t sysconfig;
    5551#define AMDM37X_DISPC_SYSCONFIG_AUTOIDLE_FLAG  (1 << 0)
     
    8682#define AMDM37X_DISPC_IRQ_WAKEUP_FLAG  (1 << 16)
    8783
    88         PADD32(8);
     84        PADD32[8];
    8985        ioport32_t control;
    9086#define AMDM37X_DISPC_CONTROL_LCD_ENABLE_FLAG  (1 << 0)
     
    149145#define AMDM37X_DISPC_CONFIG_TVALPHABLENDERENABLE_FLAG  (1 << 19)
    150146
    151         PADD32(1);
     147        PADD32[1];
    152148        ioport32_t default_color[2];
    153149        ioport32_t trans_color[2];
     
    215211#define AMDM37X_DISPC_SIZE_HEIGHT_SHIFT  16
    216212
    217                 PADD32(4);
     213                PADD32[4];
    218214                ioport32_t attributes;
    219215#define AMDM37X_DISPC_GFX_ATTRIBUTES_ENABLE_FLAG  (1 << 0)
     
    266262                } fir_coef[8];
    267263                ioport32_t conv_coef[5];
    268                 PADD32(2);
     264                PADD32[2];
    269265        } vid[2];
    270266        /* 0x1d4 */
     
    273269        ioport32_t vid_fir_coef_v[8];
    274270        /* 0x200 */
    275         PADD32(8);
     271        PADD32[8];
    276272        /* 0x220 */
    277273        ioport32_t cpr_coef_r;
     
    283279        ioport32_t vid_preload[2];
    284280
    285 } __attribute__((packed)) amdm37x_dispc_regs_t;
    286 
    287 
    288 static inline void amdm37x_dispc_setup_fb(amdm37x_dispc_regs_t *regs,
    289     unsigned x, unsigned y, unsigned bpp, uintptr_t pa)
    290 {
    291         ASSERT(regs);
    292         /* Init sequence for dispc is in chapter 7.6.5.1.4 p. 1810,
    293          * no idea what parts of that work. */
    294 
    295         /* Disable all interrupts */
    296         regs->irqenable = 0;
    297 
    298         /* Pixel format specifics*/
    299         uint32_t attrib_pixel_format = 0;
    300         uint32_t control_data_lanes = 0;
    301         switch (bpp)
    302         {
    303         case 32:
    304                 attrib_pixel_format = AMDM37X_DISPC_GFX_ATTRIBUTES_FORMAT_RGBX;
    305                 control_data_lanes = AMDM37X_DISPC_CONTROL_TFTDATALINES_24B;
    306                 break;
    307         case 24:
    308                 attrib_pixel_format = AMDM37X_DISPC_GFX_ATTRIBUTES_FORMAT_RGB24;
    309                 control_data_lanes = AMDM37X_DISPC_CONTROL_TFTDATALINES_24B;
    310                 break;
    311         case 16:
    312                 attrib_pixel_format = AMDM37X_DISPC_GFX_ATTRIBUTES_FORMAT_RGB16;
    313                 control_data_lanes = AMDM37X_DISPC_CONTROL_TFTDATALINES_16B;
    314                 break;
    315         default:
    316                 ASSERT(false);
    317         }
    318 
    319         /* Prepare sizes */
    320         const uint32_t size_reg =
    321             (((x - 1) & AMDM37X_DISPC_SIZE_WIDTH_MASK)
    322                 << AMDM37X_DISPC_SIZE_WIDTH_SHIFT) |
    323             (((y - 1) & AMDM37X_DISPC_SIZE_HEIGHT_MASK)
    324                 << AMDM37X_DISPC_SIZE_HEIGHT_SHIFT);
    325 
    326         /* modes taken from u-boot, for 1024x768 */
    327         // TODO replace magic values with actual correct values
    328 //      regs->timing_h = 0x1a4024c9;
    329 //      regs->timing_v = 0x02c00509;
    330 //      regs->pol_freq = 0x00007028;
    331 //      regs->divisor  = 0x00010001;
    332 
    333         /* setup output */
    334         regs->size_lcd = size_reg;
    335         regs->size_dig = size_reg;
    336 
    337         /* Nice blue default color */
    338         regs->default_color[0] = 0x0000ff;
    339         regs->default_color[1] = 0x0000ff;
    340 
    341         /* Setup control register */
    342         uint32_t control = 0 |
    343                 AMDM37X_DISPC_CONTROL_PCKFREEENABLE_FLAG |
    344                 (control_data_lanes << AMDM37X_DISPC_CONTROL_TFTDATALINES_SHIFT) |
    345                 AMDM37X_DISPC_CONTROL_GPOUT0_FLAG |
    346                 AMDM37X_DISPC_CONTROL_GPOUT1_FLAG;
    347         regs->control = control;
    348 
    349         /* No gamma stuff only data */
    350         uint32_t config = (AMDM37X_DISPC_CONFIG_LOADMODE_DATAEVERYFRAME
    351                     << AMDM37X_DISPC_CONFIG_LOADMODE_SHIFT);
    352         regs->config = config;
    353 
    354 
    355         /* Set framebuffer base address */
    356         regs->gfx.ba[0] = pa;
    357         regs->gfx.ba[1] = pa;
    358         regs->gfx.position = 0;
    359 
    360         /* Setup fb size */
    361         regs->gfx.size = size_reg;
    362 
    363         /* Set pixel format */
    364         uint32_t attribs = 0 |
    365             (attrib_pixel_format << AMDM37X_DISPC_GFX_ATTRIBUTES_FORMAT_SHIFT);
    366         regs->gfx.attributes = attribs;
    367 
    368         /* 0x03ff03c0 is the default */
    369         regs->gfx.fifo_threshold = 0x03ff03c0;
    370         /* This value should be stride - width, 1 means next pixel i.e.
    371          * stride == width */
    372         regs->gfx.row_inc = 1;
    373         /* number of bytes to next pixel in BPP multiples */
    374         regs->gfx.pixel_inc = 1;
    375         /* only used if video is played over fb */
    376         regs->gfx.window_skip = 0;
    377         /* Gamma and palette table */
    378         regs->gfx.table_ba = 0;
    379 
    380         /* enable frame buffer graphics */
    381         regs->gfx.attributes |= AMDM37X_DISPC_GFX_ATTRIBUTES_ENABLE_FLAG;
    382         /* Update register values */
    383         regs->control |= AMDM37X_DISPC_CONTROL_GOLCD_FLAG;
    384         regs->control |= AMDM37X_DISPC_CONTROL_GODIGITAL_FLAG;
    385         /* Enable output */
    386         regs->control |= AMDM37X_DISPC_CONTROL_LCD_ENABLE_FLAG;
    387         regs->control |= AMDM37X_DISPC_CONTROL_DIGITAL_ENABLE_FLAG;
    388 }
     281} amdm37x_dispc_regs_t;
    389282
    390283
  • uspace/drv/infrastructure/rootamdm37x/rootamdm37x.c

    r5e761f3 rb1011dae  
    195195                ddf_msg(LVL_ERROR, "Failed to add EHCI function for "
    196196                    "BeagleBoard-xM platform.");
     197        if (rootamdm37x_add_fun(dev, "dispc", "amdm37x&dispc", &ehci) != EOK)
     198                ddf_msg(LVL_ERROR, "Failed to add dispc function for "
     199                    "BeagleBoard-xM platform.");
    197200
    198201        return EOK;
  • uspace/lib/c/arch/arm32/Makefile.common

    r5e761f3 rb1011dae  
    2828#
    2929
    30 GCC_CFLAGS += -ffixed-r9 -mtp=soft -fno-omit-frame-pointer -mapcs-frame -march=$(subst _,-,$(PROCESSOR))
     30GCC_CFLAGS += -ffixed-r9 -mtp=soft -fno-omit-frame-pointer -mapcs-frame -march=$(subst _,-,$(PROCESSOR_ARCH))
    3131
    3232ifeq ($(CONFIG_FPU),y)
  • uspace/lib/drv/include/ddf/log.h

    r5e761f3 rb1011dae  
    4444    size_t);
    4545
     46#define ddf_log_fatal(msg...) ddf_msg(LVL_FATAL, msg)
     47#define ddf_log_error(msg...) ddf_msg(LVL_ERROR, msg)
     48#define ddf_log_warning(msg...) ddf_msg(LVL_WARN, msg)
     49#define ddf_log_note(msg...) ddf_msg(LVL_NOTE, msg)
     50#define ddf_log_debug(msg...) ddf_msg(LVL_DEBUG, msg)
     51#define ddf_log_verbose(msg...) ddf_msg(LVL_DEBUG2, msg)
     52
    4653#endif
    4754
Note: See TracChangeset for help on using the changeset viewer.