Changeset 005b765 in mainline


Ignore:
Timestamp:
2013-01-24T22:07:06Z (11 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
03362fbd, 3acd1bb, d59c046
Parents:
6218d4b (diff), 24bead17 (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 arm improvements.

Speed up boot by enabling caches early (but disable before jumping to kernel).
Add cycle counters on armv7.
Move bbxm dispc driver to uspace.
Add arm PROCESSOR and PROCESSOR_ARCH defines.

Files:
7 added
27 edited
1 moved

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    r6218d4b r005b765  
    8787
    8888% CPU type
     89@ "cortex_a8" ARM Cortex A-8
     90! [PLATFORM=arm32&MACHINE=beagleboardxm] PROCESSOR (choice)
     91
     92% CPU type
     93@ "arm920t" ARM920T
     94! [PLATFORM=arm32&MACHINE=gta02] PROCESSOR (choice)
     95
     96% CPU type
     97@ "arm926ej_s" ARM926EJ-S
     98! [PLATFORM=arm32&MACHINE=integratorcp] PROCESSOR (choice)
     99
     100
     101# Add more ARMv4 CPUs
     102% CPU arch
    89103@ "armv4" ARMv4
    90 ! [PLATFORM=arm32&(MACHINE=gta02)] PROCESSOR (choice)
    91 
    92 % CPU type
     104! [PLATFORM=arm32&(PROCESSOR=arm920t)] PROCESSOR_ARCH (choice)
     105
     106# Add more ARMv5 CPUs
     107% CPU arch
    93108@ "armv5" ARMv5
    94 ! [PLATFORM=arm32&MACHINE=integratorcp] PROCESSOR (choice)
    95 
    96 % CPU type
     109! [PLATFORM=arm32&(PROCESSOR=arm926ej_s)] PROCESSOR_ARCH (choice)
     110
     111# Add more ARMv7-A CPUs
     112% CPU arch
    97113@ "armv7_a" ARMv7-A
    98 ! [PLATFORM=arm32&MACHINE=beagleboardxm] PROCESSOR (choice)
     114! [PLATFORM=arm32&(PROCESSOR=cortex_a8)] PROCESSOR_ARCH (choice)
    99115
    100116% RAM disk format
     
    348364## armv7 made fpu hardware compulsory
    349365% FPU support
    350 ! [PLATFORM=arm32&PROCESSOR=armv7_a] CONFIG_FPU (y)
     366! [PLATFORM=arm32&PROCESSOR_ARCH=armv7_a] CONFIG_FPU (y)
    351367
    352368% FPU support
  • boot/arch/arm32/Makefile.inc

    r6218d4b r005b765  
    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

    r6218d4b r005b765  
    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

    r6218d4b r005b765  
    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

    r6218d4b r005b765  
    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
    7676
    77         # Now clean D-cache to guarantee coherency between I-cache and D-cache.
     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
    7889
    79         # D-cache clean and invalidate procedure.
    80         # See ARM920T TRM pages 2-17, 4-17.
    81 
    82         # Initialize segment
    83         mov     r4, #0
    84         # Initialize index
    85 1:      mov     r5, #0
    86 2:      orr     r6, r4, r5
    87         # Clean and invalidate a single line
    88         mcr     p15, 0, r6, c7, c10, 2
    89         # Increment index
    90         add     r5, r5, #(1 << CP15_C7_IDX_SHIFT)
    91         cmp     r5, #0
    92         bne     2b
    93         # Increment segment
    94         add     r4, #(1 << CP15_C7_SEG_SHIFT)
    95         tst     r4, #(1 << (CP15_C7_SEG_SHIFT + CP15_C7_SEG_SIZE))
    96         beq     1b
     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
    9798#endif
    98 
    9999        mov pc, r0
  • boot/arch/arm32/src/main.c

    r6218d4b r005b765  
    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        printf("Booting the kernel...\n");
    118156        jump_to_kernel((void *) PA2KA(BOOT_OFFSET), &bootinfo);
    119157}
  • boot/arch/arm32/src/mm.c

    r6218d4b r005b765  
    5656        else
    5757                return 1;
    58 #else
     58#elif defined MACHINE_beagleboardxm
     59        const unsigned long address = section << PTE_SECTION_SHIFT;
     60        if (address >= BBXM_RAM_START && address < BBXM_RAM_END)
     61                return 1;
     62#endif
    5963        return 0;
    60 #endif
    6164}
    6265
     
    130133                "mcr p15, 0, r0, c3, c0, 0\n"
    131134               
    132 #ifdef PROCESSOR_armv7_a
    133                 /* Read Auxiliary control register */
    134                 "mrc p15, 0, r0, c1, c0, 1\n"
    135                 /* Mask to enable L2 cache */
    136                 "ldr r1, =0x00000002\n"
    137                 "orr r0, r0, r1\n"
    138                 /* Store Auxiliary control register */
    139                 "mrc p15, 0, r0, c1, c0, 1\n"
    140 #endif
    141135                /* Current settings */
    142136                "mrc p15, 0, r0, c1, c0, 0\n"
    143137               
    144 #ifdef PROCESSOR_armv7_a
    145                 /* Mask to enable paging, caching */
    146                 "ldr r1, =0x00000005\n"
    147 #else
    148 #ifdef MACHINE_gta02
    149                 /* Mask to enable paging (bit 0),
    150                    D-cache (bit 2), I-cache (bit 12) */
    151                 "ldr r1, =0x00001005\n"
    152 #else
    153                 /* Mask to enable paging */
    154                 "ldr r1, =0x00000001\n"
    155 #endif
    156 #endif
     138                /* Enable ICache, DCache, BPredictors and MMU,
     139                 * we disable caches before jumping to kernel
     140                 * so this is safe for all archs.
     141                 */
     142                "ldr r1, =0x00001805\n"
     143               
    157144                "orr r0, r0, r1\n"
    158145               
  • kernel/arch/arm32/Makefile.inc

    r6218d4b r005b765  
    3333ATSIGN = %
    3434
    35 GCC_CFLAGS += -fno-omit-frame-pointer -mapcs-frame -march=$(subst _,-,$(PROCESSOR)) -mno-unaligned-access
    36 
    37 ifeq ($(MACHINE),beagleboardxm)
    38 GCC_CFLAGS += -mcpu=cortex-a8
    39 endif
     35GCC_CFLAGS += -fno-omit-frame-pointer -mapcs-frame -march=$(subst _,-,$(PROCESSOR_ARCH)) -mno-unaligned-access
    4036
    4137ifeq ($(CONFIG_FPU),y)
  • kernel/arch/arm32/include/asm.h

    r6218d4b r005b765  
    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

    r6218d4b r005b765  
    3737#define KERN_arm32_BARRIER_H_
    3838
    39 /*
    40  * 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
    47  */
     39#ifdef KERNEL
     40#include <arch/cp15.h>
     41#else
     42#include <libarch/cp15.h>
     43#endif
     44
    4845#define CS_ENTER_BARRIER()  asm volatile ("" ::: "memory")
    4946#define CS_LEAVE_BARRIER()  asm volatile ("" ::: "memory")
     
    6057#define read_barrier()    asm volatile ("dsb" ::: "memory")
    6158#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)
    6277#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
    6383#define memory_barrier()  asm volatile ("" ::: "memory")
    6484#define read_barrier()    asm volatile ("" ::: "memory")
    6585#define write_barrier()   asm volatile ("" ::: "memory")
     86#define inst_barrier()    asm volatile ("" ::: "memory")
    6687#endif
     88
    6789/*
    6890 * There are multiple ways ICache can be implemented on ARM machines. Namely
     
    80102 */
    81103
    82 #ifdef PROCESSOR_ARCH_armv7_a
    83 #define smc_coherence(a) asm volatile ( "isb" ::: "memory")
    84 #define smc_coherence_block(a, l) smc_coherence(a)
    85 #else
     104#if defined PROCESSOR_ARCH_armv7_a | defined PROCESSOR_ARCH_armv6 | defined KERNEL
    86105/* Available on all supported arms,
    87106 * invalidates entire ICache so the written value does not matter. */
    88 //TODO might be PL1 only on armv5 -
    89 #define smc_coherence(a) asm volatile ( "mcr p15, 0, r0, c7, c5, 0")
    90 #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)
    91125#endif
    92126
  • kernel/arch/arm32/include/cp15.h

    r6218d4b r005b765  
    5555
    5656/* Identification registers */
     57enum {
     58        MIDR_IMPLEMENTER_MASK = 0xff,
     59        MIDR_IMPLEMENTER_SHIFT = 24,
     60        MIDR_VARIANT_MASK = 0xf,
     61        MIDR_VARIANT_SHIFT = 20,
     62        MIDR_ARCHITECTURE_MASK = 0xf,
     63        MIDR_ARCHITECTURE_SHIFT = 16,
     64        MIDR_PART_NUMBER_MASK = 0xfff,
     65        MIDR_PART_NUMBER_SHIFT = 4,
     66        MIDR_REVISION_MASK = 0xf,
     67        MIDR_REVISION_SHIFT = 0,
     68};
    5769CONTROL_REG_GEN_READ(MIDR, c0, 0, c0, 0);
     70
     71enum {
     72        CTR_FORMAT_MASK = 0xe0000000,
     73        CTR_FORMAT_ARMv7 = 0x80000000,
     74        CTR_FORMAT_ARMv6 = 0x00000000,
     75        /* ARMv7 format */
     76        CTR_CWG_MASK = 0xf,
     77        CTR_CWG_SHIFT = 24,
     78        CTR_ERG_MASK = 0xf,
     79        CTR_ERG_SHIFT = 20,
     80        CTR_D_MIN_LINE_MASK = 0xf,
     81        CTR_D_MIN_LINE_SHIFT = 16,
     82        CTR_I_MIN_LINE_MASK = 0xf,
     83        CTR_I_MIN_LINE_SHIFT = 0,
     84        CTR_L1I_POLICY_MASK = 0x0000c000,
     85        CTR_L1I_POLICY_AIVIVT = 0x00004000,
     86        CTR_L1I_POLICY_VIPT = 0x00008000,
     87        CTR_L1I_POLICY_PIPT = 0x0000c000,
     88        /* ARMv6 format */
     89        CTR_CTYPE_MASK = 0x1e000000,
     90        CTR_CTYPE_WT = 0x00000000,
     91        CTR_CTYPE_WB_NL = 0x04000000,
     92        CTR_CTYPE_WB_D = 0x0a000000,
     93        CTR_CTYPE_WB_A = 0x0c000000, /**< ARMv5- only */
     94        CTR_CTYPE_WB_B = 0x0e000000, /**< ARMv5- only */
     95        CTR_CTYPE_WB_C = 0x1c000000,
     96        CTR_SEP_FLAG = 1 << 24,
     97        CTR_DCACHE_P_FLAG = 1 << 23,
     98        CTR_DCACHE_SIZE_MASK = 0xf,
     99        CTR_DCACHE_SIZE_SHIFT = 18,
     100        CTR_DCACHE_ASSOC_MASK = 0x7,
     101        CTR_DCACHE_ASSOC_SHIFT = 15,
     102        CTR_DCACHE_M_FLAG = 1 << 14,
     103        CTR_DCACHE_LEN_MASK = 0x3,
     104        CTR_DCACHE_LEN_SHIFT = 0,
     105        CTR_ICACHE_P_FLAG = 1 << 11,
     106        CTR_ICACHE_SIZE_MASK = 0xf,
     107        CTR_ICACHE_SIZE_SHIFT = 6,
     108        CTR_ICACHE_ASSOC_MASK = 0x7,
     109        CTR_ICACHE_ASSOC_SHIFT = 3,
     110        CTR_ICACHE_M_FLAG = 1 << 2,
     111        CTR_ICACHE_LEN_MASK = 0x3,
     112        CTR_ICACHE_LEN_SHIFT = 0,
     113};
    58114CONTROL_REG_GEN_READ(CTR, c0, 0, c0, 1);
    59115CONTROL_REG_GEN_READ(TCMR, c0, 0, c0, 2);
     
    104160CONTROL_REG_GEN_READ(ID_ISAR5, c0, 0, c2, 5);
    105161
     162enum {
     163        CCSIDR_WT_FLAG = 1 << 31,
     164        CCSIDR_WB_FLAG = 1 << 30,
     165        CCSIDR_RA_FLAG = 1 << 29,
     166        CCSIDR_WA_FLAG = 1 << 28,
     167        CCSIDR_NUMSETS_MASK = 0x7fff,
     168        CCSIDR_NUMSETS_SHIFT = 13,
     169        CCSIDR_ASSOC_MASK = 0x3ff,
     170        CCSIDR_ASSOC_SHIFT = 3,
     171        CCSIDR_LINESIZE_MASK = 0x7,
     172        CCSIDR_LINESIZE_SHIFT = 0,
     173};
    106174CONTROL_REG_GEN_READ(CCSIDR, c0, 1, c0, 0);
     175
     176enum {
     177        CLIDR_LOUU_MASK = 0x7,
     178        CLIDR_LOUU_SHIFT = 27,
     179        CLIDR_LOC_MASK = 0x7,
     180        CLIDR_LOC_SHIFT = 24,
     181        CLIDR_LOUIS_MASK = 0x7,
     182        CLIDR_LOUIS_SHIFT = 21,
     183        CLIDR_NOCACHE = 0x0,
     184        CLIDR_ICACHE_ONLY = 0x1,
     185        CLIDR_DCACHE_ONLY = 0x2,
     186        CLIDR_SEP_CACHE = 0x3,
     187        CLIDR_UNI_CACHE = 0x4,
     188        CLIDR_CACHE_MASK = 0x7,
     189#define CLIDR_CACHE(level, val)   ((val >> (level - 1) * 3) & CLIDR_CACHE_MASK)
     190};
    107191CONTROL_REG_GEN_READ(CLIDR, c0, 1, c0, 1);
    108192CONTROL_REG_GEN_READ(AIDR, c0, 1, c0, 7); /* Implementation defined or MIDR */
    109193
     194enum {
     195        CCSELR_LEVEL_MASK = 0x7,
     196        CCSELR_LEVEL_SHIFT = 1,
     197        CCSELR_INSTRUCTION_FLAG = 1 << 0,
     198};
    110199CONTROL_REG_GEN_READ(CSSELR, c0, 2, c0, 0);
    111200CONTROL_REG_GEN_WRITE(CSSELR, c0, 2, c0, 0);
     
    116205
    117206/* System control registers */
     207/* COntrol register bit values see ch. B4.1.130 of ARM Architecture Reference
     208 * Manual ARMv7-A and ARMv7-R edition, page 1687 */
     209enum {
     210        SCTLR_MMU_EN_FLAG            = 1 << 0,
     211        SCTLR_ALIGN_CHECK_EN_FLAG    = 1 << 1,  /* Allow alignemnt check */
     212        SCTLR_CACHE_EN_FLAG          = 1 << 2,
     213        SCTLR_CP15_BARRIER_EN_FLAG   = 1 << 5,
     214        SCTLR_B_EN_FLAG              = 1 << 7,  /* ARMv6-, big endian switch */
     215        SCTLR_SWAP_EN_FLAG           = 1 << 10,
     216        SCTLR_BRANCH_PREDICT_EN_FLAG = 1 << 11,
     217        SCTLR_INST_CACHE_EN_FLAG     = 1 << 12,
     218        SCTLR_HIGH_VECTORS_EN_FLAG   = 1 << 13,
     219        SCTLR_ROUND_ROBIN_EN_FLAG    = 1 << 14,
     220        SCTLR_HW_ACCESS_FLAG_EN_FLAG = 1 << 17,
     221        SCTLR_WRITE_XN_EN_FLAG       = 1 << 19, /* Only if virt. supported */
     222        SCTLR_USPCE_WRITE_XN_EN_FLAG = 1 << 20, /* Only if virt. supported */
     223        SCTLR_FAST_IRQ_EN_FLAG       = 1 << 21, /* Disable impl. specific feat*/
     224        SCTLR_UNALIGNED_EN_FLAG      = 1 << 22, /* Must be 1 on armv7 */
     225        SCTLR_IRQ_VECTORS_EN_FLAG    = 1 << 24,
     226        SCTLR_BIG_ENDIAN_EXC_FLAG    = 1 << 25,
     227        SCTLR_NMFI_EN_FLAG           = 1 << 27,
     228        SCTLR_TEX_REMAP_EN_FLAG      = 1 << 28,
     229        SCTLR_ACCESS_FLAG_EN_FLAG    = 1 << 29,
     230        SCTLR_THUMB_EXC_EN_FLAG      = 1 << 30,
     231};
    118232CONTROL_REG_GEN_READ(SCTLR, c1, 0, c0, 0);
    119233CONTROL_REG_GEN_WRITE(SCTLR, c1, 0, c0, 0);
     
    302416CONTROL_REG_GEN_WRITE(TLBIALLNSNHS, c8, 4, c7, 4);
    303417
    304 /* c9 are reserved */
     418/* c9 are performance monitoring resgisters */
     419enum {
     420        PMCR_IMP_MASK = 0xff,
     421        PMCR_IMP_SHIFT = 24,
     422        PMCR_IDCODE_MASK = 0xff,
     423        PMCR_IDCODE_SHIFT = 16,
     424        PMCR_EVENT_NUM_MASK = 0x1f,
     425        PMCR_EVENT_NUM_SHIFT = 11,
     426        PMCR_DP_FLAG = 1 << 5,
     427        PMCR_X_FLAG = 1 << 4,
     428        PMCR_D_FLAG = 1 << 3,
     429        PMCR_C_FLAG = 1 << 2,
     430        PMCR_P_FLAG = 1 << 1,
     431        PMCR_E_FLAG = 1 << 0,
     432};
     433CONTROL_REG_GEN_READ(PMCR, c9, 0, c12, 0);
     434CONTROL_REG_GEN_WRITE(PMCR, c9, 0, c12, 0);
     435enum {
     436        PMCNTENSET_CYCLE_COUNTER_EN_FLAG = 1 << 31,
     437#define PMCNTENSET_COUNTER_EN_FLAG(c)   (1 << c)
     438};
     439CONTROL_REG_GEN_READ(PMCNTENSET, c9, 0, c12, 1);
     440CONTROL_REG_GEN_WRITE(PMCNTENSET, c9, 0, c12, 1);
     441CONTROL_REG_GEN_READ(PMCCNTR, c9, 0, c13, 0);
     442CONTROL_REG_GEN_WRITE(PMCCNTR, c9, 0, c13, 0);
     443
    305444
    306445/*c10 has tons of reserved too */
  • kernel/arch/arm32/include/cpu.h

    r6218d4b r005b765  
    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

    r6218d4b r005b765  
    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

    r6218d4b r005b765  
    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#else
     59
     60#define PHYSMEM_START_ADDR       0x00000000
    5361#define BOOT_PAGE_TABLE_ADDRESS  0x00008000
     62
    5463#endif
    5564
     
    5766#define BOOT_PAGE_TABLE_SIZE_IN_FRAMES  (BOOT_PAGE_TABLE_SIZE >> FRAME_WIDTH)
    5867
    59 #ifdef MACHINE_gta02
    60 #define PHYSMEM_START_ADDR      0x30008000
    61 #elif defined MACHINE_beagleboardxm
    62 #define PHYSMEM_START_ADDR      0x80000000
    63 #else
    64 #define PHYSMEM_START_ADDR      0x00000000
    65 #endif
    6668
    6769extern void frame_low_arch_init(void);
  • kernel/arch/arm32/include/mm/page.h

    r6218d4b r005b765  
    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

    r6218d4b r005b765  
    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

    r6218d4b r005b765  
    4040#define STATUS_REG_IRQ_DISABLED_BIT  (1 << 7)
    4141#define STATUS_REG_MODE_MASK         0x1f
    42 
    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)
    6642
    6743/* ARM Processor Operation Modes */
  • kernel/arch/arm32/include/security_ext.h

    r6218d4b r005b765  
    4848static inline bool sec_ext_is_implemented()
    4949{
    50 #ifdef PROCESSOR_armv7_a
     50#ifdef PROCESSOR_ARCH_armv7_a
    5151        const uint32_t idpfr = ID_PFR1_read() & ID_PFR1_SEC_EXT_MASK;
    5252        return idpfr == ID_PFR1_SEC_EXT || idpfr == ID_PFR1_SEC_EXT_RFR;
  • kernel/arch/arm32/src/cpu/cpu.c

    r6218d4b r005b765  
    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

    r6218d4b r005b765  
    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

    r6218d4b r005b765  
    119119 * rely on user decision to use CONFIG_FPU.
    120120 */
    121 #ifdef PROCESSOR_armv7_a
     121#ifdef PROCESSOR_ARC_armv7_a
    122122        const uint32_t cpacr = CPACR_read();
    123123        /* FPU needs access to coprocessor 10 and 11.
     
    148148 * rely on user decision to use CONFIG_FPU.
    149149 */
    150 #ifndef PROCESSOR_armv7_a
    151         return;
    152 #endif
    153 
     150#ifdef PROCESSOR_ARCH_armv7_a
    154151        /* Allow coprocessor access */
    155152        uint32_t cpacr = CPACR_read();
     
    159156        cpacr |= (CPACR_CP_FULL_ACCESS(10) | CPACR_CP_FULL_ACCESS(11));
    160157        CPACR_write(cpacr);
    161 
    162         smc_coherence(0);
     158#endif
    163159}
    164160
  • kernel/arch/arm32/src/mach/beagleboardxm/beagleboardxm.c

    r6218d4b r005b765  
    3838#include <genarch/drivers/amdm37x_uart/amdm37x_uart.h>
    3939#include <genarch/drivers/amdm37x_gpt/amdm37x_gpt.h>
    40 #include <genarch/drivers/amdm37x_dispc/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

    r6218d4b r005b765  
    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

    r6218d4b r005b765  
    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

    r6218d4b r005b765  
    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

    r6218d4b r005b765  
    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

    r6218d4b r005b765  
    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

    r6218d4b r005b765  
    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.