Changeset 2921602 in mainline


Ignore:
Timestamp:
2013-08-15T09:48:01Z (11 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
03c971f, ab92305
Parents:
ed29fe4 (diff), 34847e2 (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 arm32 improvements and fixes

  • caches are now enabled (and used) on all armv7-a machines
  • fixed ghost interrupt issue on bbxm (thx mlombardi)
  • other minor fixes
Files:
1 added
16 edited

Legend:

Unmodified
Added
Removed
  • boot/arch/arm32/src/asm.S

    red29fe4 r2921602  
    5656jump_to_kernel:
    5757        #
    58         # TODO
    5958        # Make sure that the I-cache, D-cache and memory are mutually coherent
    6059        # before passing control to the copied code.
     
    6867#define CP15_C1_BP              11
    6968#define CP15_C1_DC              2
    70         # Disable I-cache and D-cache before the kernel is started.
     69
     70
     71#ifndef PROCESSOR_ARCH_armv7_a
    7172        mrc     p15, 0, r4, c1, c0, 0
     73       
     74        # D-cache before the kernel is started.
    7275        bic     r4, r4, #(1 << CP15_C1_DC)
     76
     77        # Disable I-cache and Branche predictors.
    7378        bic     r4, r4, #(1 << CP15_C1_IC)
    7479        bic     r4, r4, #(1 << CP15_C1_BP)
     80       
    7581        mcr     p15, 0, r4, c1, c0, 0
     82#endif
     83
    7684
    7785       
     
    8189#else
    8290        #cp15 dsb, r4 is ignored (should be zero)
     91        mov r4, #0
    8392        mcr p15, 0, r4, c7, c10, 4
    8493#endif
    8594       
    8695        # Clean ICache and BPredictors, r4 ignored (SBZ)
     96        mov r4, #0
    8797        mcr p15, 0, r4, c7, c5, 0
    8898        nop
  • boot/arch/arm32/src/main.c

    red29fe4 r2921602  
    5353extern void *bdata_end;
    5454
    55 
    56 static 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 
    62 static 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 
    7155static inline void clean_dcache_poc(void *address, size_t size)
    7256{
    7357        const uintptr_t addr = (uintptr_t)address;
    74         /* DCCMVAC - clean by address to the point of coherence */
    7558        for (uintptr_t a = addr; a < addr + size; a += 4) {
     59                /* DCCMVAC - clean by address to the point of coherence */
    7660                asm volatile ("mcr p15, 0, %[a], c7, c10, 1\n" :: [a]"r"(a) : );
    7761        }
     
    8266void bootstrap(void)
    8367{
    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 
    9168        /* Enable MMU and caches */
    9269        mmu_start();
     
    10582                    components[i].start, components[i].name, components[i].inflated,
    10683                    components[i].size);
    107                 invalidate_dcache(components[i].start, components[i].size);
    10884        }
    10985       
     
    148124                        halt();
    149125                }
     126                /* Make sure data are in the memory, ICache will need them */
    150127                clean_dcache_poc(dest[i - 1], components[i - 1].inflated);
    151128        }
  • boot/arch/arm32/src/mm.c

    red29fe4 r2921602  
    3737#include <arch/asm.h>
    3838#include <arch/mm.h>
     39#include <arch/cp15.h>
     40
     41#ifdef PROCESSOR_ARCH_armv7_a
     42static unsigned log2(unsigned val)
     43{
     44        unsigned log = 0;
     45        while (val >> log++);
     46        return log - 2;
     47}
     48
     49static void dcache_invalidate_level(unsigned level)
     50{
     51        CSSELR_write(level << 1);
     52        const uint32_t ccsidr = CCSIDR_read();
     53        const unsigned sets = CCSIDR_SETS(ccsidr);
     54        const unsigned ways = CCSIDR_WAYS(ccsidr);
     55        const unsigned line_log = CCSIDR_LINESIZE_LOG(ccsidr);
     56        const unsigned set_shift = line_log;
     57        const unsigned way_shift = 32 - log2(ways);
     58
     59        for (unsigned k = 0; k < ways; ++k)
     60                for (unsigned j = 0; j < sets; ++j) {
     61                        const uint32_t val = (level << 1) |
     62                            (j << set_shift) | (k << way_shift);
     63                        DCISW_write(val);
     64                }
     65}
     66
     67/** invalidate all dcaches -- armv7 */
     68static void cache_invalidate(void)
     69{
     70        const uint32_t cinfo = CLIDR_read();
     71        for (unsigned i = 0; i < 7; ++i) {
     72                switch (CLIDR_CACHE(i, cinfo))
     73                {
     74                case CLIDR_DCACHE_ONLY:
     75                case CLIDR_SEP_CACHE:
     76                case CLIDR_UNI_CACHE:
     77                        dcache_invalidate_level(i);
     78                }
     79        }
     80        asm volatile ( "dsb\n" );
     81        ICIALLU_write(0);
     82        asm volatile ( "isb\n" );
     83}
     84#endif
    3985
    4086/** Disable the MMU */
     
    60106static inline int section_cacheable(pfn_t section)
    61107{
     108        const unsigned long address = section << PTE_SECTION_SHIFT;
    62109#ifdef MACHINE_gta02
    63         unsigned long address = section << PTE_SECTION_SHIFT;
    64 
    65         if (address >= GTA02_IOMEM_START && address < GTA02_IOMEM_END)
    66                 return 0;
    67         else
     110        if (address < GTA02_IOMEM_START || address >= GTA02_IOMEM_END)
    68111                return 1;
    69112#elif defined MACHINE_beagleboardxm
    70         const unsigned long address = section << PTE_SECTION_SHIFT;
    71113        if (address >= BBXM_RAM_START && address < BBXM_RAM_END)
    72114                return 1;
    73115#elif defined MACHINE_beaglebone
    74         const unsigned long address = section << PTE_SECTION_SHIFT;
    75116        if (address >= AM335x_RAM_START && address < AM335x_RAM_END)
    76117                return 1;
    77118#endif
    78         return 0;
     119        return address * 0;
    79120}
    80121
     
    95136{
    96137        pte->descriptor_type = PTE_DESCRIPTOR_SECTION;
    97         pte->bufferable = 1;
    98         pte->cacheable = section_cacheable(frame);
    99138        pte->xn = 0;
    100139        pte->domain = 0;
    101140        pte->should_be_zero_1 = 0;
    102141        pte->access_permission_0 = PTE_AP_USER_NO_KERNEL_RW;
     142#ifdef PROCESSOR_ARCH_armv7_a
     143        /*
     144         * Keeps this setting in sync with memory type attributes in:
     145         * init_boot_pt (boot/arch/arm32/src/mm.c)
     146         * set_pt_level1_flags (kernel/arch/arm32/include/arch/mm/page_armv6.h)
     147         * set_ptl0_addr (kernel/arch/arm32/include/arch/mm/page.h)
     148         */
     149        pte->tex = section_cacheable(frame) ? 5 : 0;
     150        pte->cacheable = section_cacheable(frame) ? 0 : 0;
     151        pte->bufferable = section_cacheable(frame) ? 1 : 0;
     152#else
     153        pte->bufferable = 1;
     154        pte->cacheable = section_cacheable(frame);
    103155        pte->tex = 0;
     156#endif
    104157        pte->access_permission_1 = 0;
    105158        pte->shareable = 0;
     
    113166static void init_boot_pt(void)
    114167{
    115         const pfn_t split_page = PTL0_ENTRIES;
    116         /* Create 1:1 virtual-physical mapping (in lower 2 GB). */
    117         pfn_t page;
    118         for (page = 0; page < split_page; page++)
     168        /*
     169         * Create 1:1 virtual-physical mapping.
     170         * Physical memory on BBxM a BBone starts at 2GB
     171         * boundary, icp has a memory mirror at 2GB.
     172         * (ARM Integrator Core Module User guide ch. 6.3,  p. 6-7)
     173         * gta02 somehow works (probably due to limited address size),
     174         * s3c2442b manual ch. 5, p.5-1:
     175         * "Address space: 128Mbytes per bank (total 1GB/8 banks)"
     176         */
     177        for (pfn_t page = 0; page < PTL0_ENTRIES; ++page)
    119178                init_ptl0_section(&boot_pt[page], page);
    120        
    121         asm volatile (
    122                 "mcr p15, 0, %[pt], c2, c0, 0\n"
    123                 :: [pt] "r" (boot_pt)
    124         );
     179
     180        /*
     181         * Tell MMU page might be cached. Keeps this setting in sync
     182         * with memory type attributes in:
     183         * init_ptl0_section (boot/arch/arm32/src/mm.c)
     184         * set_pt_level1_flags (kernel/arch/arm32/include/arch/mm/page_armv6.h)
     185         * set_ptl0_addr (kernel/arch/arm32/include/arch/mm/page.h)
     186         */
     187        uint32_t val = (uint32_t)boot_pt & TTBR_ADDR_MASK;
     188        val |= TTBR_RGN_WBWA_CACHE | TTBR_C_FLAG;
     189        TTBR0_write(val);
    125190}
    126191
     
    141206                 * we disable caches before jumping to kernel
    142207                 * so this is safe for all archs.
     208                 * Enable VMSAv6 the bit (23) is only writable on ARMv6.
    143209                 */
    144                 "ldr r1, =0x00001805\n"
     210                "ldr r1, =0x00801805\n"
    145211               
    146212                "orr r0, r0, r1\n"
     
    160226void mmu_start() {
    161227        disable_paging();
     228#ifdef PROCESSOR_ARCH_armv7_a
     229        /* Make sure we run in memory code when caches are enabled,
     230         * make sure we read memory data too. This part is ARMv7 specific as
     231         * ARMv7 no longer invalidates caches on restart.
     232         * See chapter B2.2.2 of ARM Architecture Reference Manual p. B2-1263*/
     233        cache_invalidate();
     234#endif
    162235        init_boot_pt();
    163236        enable_paging();
  • kernel/arch/arm32/include/arch/asm.h

    red29fe4 r2921602  
    3838
    3939#include <typedefs.h>
     40#include <arch/cp15.h>
    4041#include <arch/stack.h>
    4142#include <config.h>
     
    5152 * chapter 2.3.8 p.2-22 (52 in the PDF)
    5253 *
    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+.
     54 * @note Although CP15WFI (mcr p15, 0, R0, c7, c0, 4) is defined in ARM
     55 * Architecture reference manual for armv4/5, CP15 implementation is mandatory
     56 * only for armv6+.
    5657 */
    5758NO_TRACE static inline void cpu_sleep(void)
     
    6061        asm volatile ( "wfe" );
    6162#elif defined(PROCESSOR_ARCH_armv6) | defined(PROCESSOR_arm926ej_s) | defined(PROCESSOR_arm920t)
    62         asm volatile ( "mcr p15, 0, R0, c7, c0, 4" );
     63        WFI_write(0);
    6364#endif
    6465}
  • kernel/arch/arm32/include/arch/cp15.h

    red29fe4 r2921602  
    171171        CCSIDR_LINESIZE_MASK = 0x7,
    172172        CCSIDR_LINESIZE_SHIFT = 0,
     173#define CCSIDR_SETS(val) \
     174        (((val >> CCSIDR_NUMSETS_SHIFT) & CCSIDR_NUMSETS_MASK) + 1)
     175#define CCSIDR_WAYS(val) \
     176        (((val >> CCSIDR_ASSOC_SHIFT) & CCSIDR_ASSOC_MASK) + 1)
     177/* The register value is log(linesize_in_words) - 2 */
     178#define CCSIDR_LINESIZE_LOG(val) \
     179        (((val >> CCSIDR_LINESIZE_SHIFT) & CCSIDR_LINESIZE_MASK) + 2 + 2)
    173180};
    174181CONTROL_REG_GEN_READ(CCSIDR, c0, 1, c0, 0);
     
    187194        CLIDR_UNI_CACHE = 0x4,
    188195        CLIDR_CACHE_MASK = 0x7,
    189 #define CLIDR_CACHE(level, val)   ((val >> (level - 1) * 3) & CLIDR_CACHE_MASK)
     196/** levels counted from 0 */
     197#define CLIDR_CACHE(level, val)   ((val >> (level * 3)) & CLIDR_CACHE_MASK)
    190198};
    191199CONTROL_REG_GEN_READ(CLIDR, c0, 1, c0, 1);
     
    293301
    294302/* Memory protection and control registers */
     303enum {
     304        TTBR_ADDR_MASK = 0xffffff80,
     305        TTBR_NOS_FLAG = 1 << 5,
     306        TTBR_RGN_MASK = 0x3 << 3,
     307        TTBR_RGN_NO_CACHE = 0x0 << 3,
     308        TTBR_RGN_WBWA_CACHE = 0x1 << 3,
     309        TTBR_RGN_WT_CACHE = 0x2 << 3,
     310        TTBR_RGN_WB_CACHE = 0x3 << 3,
     311        TTBR_S_FLAG = 1 << 1,
     312        TTBR_C_FLAG = 1 << 0,
     313};
    295314CONTROL_REG_GEN_READ(TTBR0, c2, 0, c0, 0);
    296315CONTROL_REG_GEN_WRITE(TTBR0, c2, 0, c0, 0);
     
    363382
    364383CONTROL_REG_GEN_WRITE(DCIMVAC, c7, 0, c6, 1);
    365 CONTROL_REG_GEN_WRITE(DCIMSW, c7, 0, c6, 2);
     384CONTROL_REG_GEN_WRITE(DCISW, c7, 0, c6, 2);
    366385
    367386CONTROL_REG_GEN_WRITE(ATS1CPR, c7, 0, c8, 0);
     
    369388CONTROL_REG_GEN_WRITE(ATS1CUR, c7, 0, c8, 2);
    370389CONTROL_REG_GEN_WRITE(ATS1CUW, c7, 0, c8, 3);
    371 CONTROL_REG_GEN_WRITE(ATS1NSOPR, c7, 0, c8, 4);
    372 CONTROL_REG_GEN_WRITE(ATS1NSOPW, c7, 0, c8, 5);
    373 CONTROL_REG_GEN_WRITE(ATS1NSOUR, c7, 0, c8, 6);
    374 CONTROL_REG_GEN_WRITE(ATS1NSOUW, c7, 0, c8, 7);
     390CONTROL_REG_GEN_WRITE(ATS12NSOPR, c7, 0, c8, 4);
     391CONTROL_REG_GEN_WRITE(ATS12NSOPW, c7, 0, c8, 5);
     392CONTROL_REG_GEN_WRITE(ATS12NSOUR, c7, 0, c8, 6);
     393CONTROL_REG_GEN_WRITE(ATS12NSOUW, c7, 0, c8, 7);
    375394
    376395
  • kernel/arch/arm32/include/arch/mm/page.h

    red29fe4 r2921602  
    4141#include <arch/exception.h>
    4242#include <arch/barrier.h>
     43#include <arch/cp15.h>
    4344#include <trace.h>
    4445
     
    9596/* Set PTE address accessors for each level. */
    9697#define SET_PTL0_ADDRESS_ARCH(ptl0) \
    97         (set_ptl0_addr((pte_t *) (ptl0)))
     98        set_ptl0_addr((pte_t *) (ptl0))
    9899#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
    99         (((pte_t *) (ptl0))[(i)].l0.coarse_table_addr = (a) >> 10)
     100        set_ptl1_addr((pte_t*) (ptl0), i, a)
    100101#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
    101102#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
    102103#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \
    103         (((pte_t *) (ptl3))[(i)].l1.frame_base_addr = (a) >> 12)
     104        set_ptl3_addr((pte_t*) (ptl3), i, a)
    104105
    105106/* Get PTE flags accessors for each level. */
     
    129130        set_pt_level1_present((pte_t *) (ptl3), (size_t) (i))
    130131
     132
     133#define pt_coherence(page) pt_coherence_m(page, 1)
     134
    131135#if defined(PROCESSOR_ARCH_armv6) | defined(PROCESSOR_ARCH_armv7_a)
    132136#include "page_armv6.h"
     
    137141#endif
    138142
     143/** Sets the address of level 0 page table.
     144 *
     145 * @param pt Pointer to the page table to set.
     146 *
     147 * Page tables are always in cacheable memory.
     148 * Make sure the memory type is correct, and in sync with:
     149 * init_boot_pt (boot/arch/arm32/src/mm.c)
     150 * init_ptl0_section (boot/arch/arm32/src/mm.c)
     151 * set_pt_level1_flags (kernel/arch/arm32/include/arch/mm/page_armv6.h)
     152 */
     153NO_TRACE static inline void set_ptl0_addr(pte_t *pt)
     154{
     155        uint32_t val = (uint32_t)pt & TTBR_ADDR_MASK;
     156        val |= TTBR_RGN_WBWA_CACHE | TTBR_C_FLAG;
     157        TTBR0_write(val);
     158}
     159
     160NO_TRACE static inline void set_ptl1_addr(pte_t *pt, size_t i, uintptr_t address)
     161{
     162        pt[i].l0.coarse_table_addr = address >> 10;
     163        pt_coherence(&pt[i].l0);
     164}
     165
     166NO_TRACE static inline void set_ptl3_addr(pte_t *pt, size_t i, uintptr_t address)
     167{
     168        pt[i].l1.frame_base_addr = address >> 12;
     169        pt_coherence(&pt[i].l1);
     170}
     171
    139172#endif
    140173
  • kernel/arch/arm32/include/arch/mm/page_armv4.h

    red29fe4 r2921602  
    120120#define PTE_DESCRIPTOR_SMALL_PAGE       2
    121121
    122 
    123 /** Sets the address of level 0 page table.
    124  *
    125  * @param pt Pointer to the page table to set.
    126  *
    127  */
    128 NO_TRACE static inline void set_ptl0_addr(pte_t *pt)
    129 {
    130         asm volatile (
    131                 "mcr p15, 0, %[pt], c2, c0, 0\n"
    132                 :: [pt] "r" (pt)
    133         );
    134 }
    135 
     122#define pt_coherence_m(pt, count) \
     123do { \
     124        for (unsigned i = 0; i < count; ++i) \
     125                DCCMVAU_write((uintptr_t)(pt + i)); \
     126        read_barrier(); \
     127} while (0)
    136128
    137129/** Returns level 0 page table entry flags.
     
    223215       
    224216        /* default access permission */
    225         p->access_permission_0 = p->access_permission_1 = 
     217        p->access_permission_0 = p->access_permission_1 =
    226218            p->access_permission_2 = p->access_permission_3 =
    227219            PTE_AP_USER_NO_KERNEL_RW;
     
    229221        if (flags & PAGE_USER)  {
    230222                if (flags & PAGE_READ) {
    231                         p->access_permission_0 = p->access_permission_1 = 
    232                             p->access_permission_2 = p->access_permission_3 = 
     223                        p->access_permission_0 = p->access_permission_1 =
     224                            p->access_permission_2 = p->access_permission_3 =
    233225                            PTE_AP_USER_RO_KERNEL_RW;
    234226                }
    235227                if (flags & PAGE_WRITE) {
    236                         p->access_permission_0 = p->access_permission_1 = 
    237                             p->access_permission_2 = p->access_permission_3 = 
    238                             PTE_AP_USER_RW_KERNEL_RW; 
     228                        p->access_permission_0 = p->access_permission_1 =
     229                            p->access_permission_2 = p->access_permission_3 =
     230                            PTE_AP_USER_RW_KERNEL_RW;
    239231                }
    240232        }
  • kernel/arch/arm32/include/arch/mm/page_armv6.h

    red29fe4 r2921602  
    4040#error "Do not include arch specific page.h directly use generic page.h instead"
    4141#endif
     42
    4243
    4344/* Macros for querying the last-level PTE entries. */
     
    125126#define PTE_DESCRIPTOR_SMALL_PAGE_NX    3
    126127
    127 /** Sets the address of level 0 page table.
    128  *
    129  * @param pt Pointer to the page table to set.
    130  *
    131  */
    132 NO_TRACE static inline void set_ptl0_addr(pte_t *pt)
    133 {
    134         asm volatile (
    135                 "mcr p15, 0, %[pt], c2, c0, 0\n"
    136                 :: [pt] "r" (pt)
    137         );
    138 }
     128
     129/**
     130 * For an ARMv7 implementation that does not include the Large Physical Address Extension,
     131 * and in implementations of architecture versions before ARMv7, if the translation tables
     132 * are held in Write-Back Cacheable memory, the caches must be cleaned to the point of
     133 * unification after writing to the translation tables and before the DSB instruction. This
     134 * ensures that the updated translation table are visible to a hardware translation table walk.
     135 *
     136 * Therefore, an example instruction sequence for writing a translation table entry,
     137 * covering changes to the instruction
     138 * or data mappings in a uniprocessor system is:
     139 * STR rx, [Translation table entry]
     140 * ; write new entry to the translation table
     141 * Clean cache line [Translation table entry] : This operation is not required with the
     142 * ; Multiprocessing Extensions.
     143 * DSB
     144 * ; ensures visibility of the data cleaned from the D Cache
     145 * Invalidate TLB entry by MVA (and ASID if non-global) [page address]
     146 * Invalidate BTC
     147 * DSB
     148 * ; ensure completion of the Invalidate TLB operation
     149 * ISB
     150 * ; ensure table changes visible to instruction fetch
     151 *
     152 * ARM Architecture reference chp. B3.10.1 p. B3-1375
     153 * @note: see TTRB0/1 for pt memory type
     154 */
     155#define pt_coherence_m(pt, count) \
     156do { \
     157        for (unsigned i = 0; i < count; ++i) \
     158                DCCMVAU_write((uintptr_t)(pt + i)); \
     159        read_barrier(); \
     160} while (0)
    139161
    140162
     
    206228                p->ns = 0;
    207229        }
     230        pt_coherence(p);
    208231}
    209232
     
    232255                        p->descriptor_type = PTE_DESCRIPTOR_SMALL_PAGE_NX;
    233256        }
    234        
    235         /* tex=0 buf=1 and cache=1 => normal memory
    236          * tex=0 buf=1 and cache=0 => shareable device mmio
    237          */
    238         p->cacheable = (flags & PAGE_CACHEABLE);
    239         p->bufferable = 1;
    240         p->tex = 0;
     257
     258        if (flags & PAGE_CACHEABLE) {
     259                /*
     260                 * Write-through, no write-allocate memory, see ch. B3.8.2
     261                 * (p. B3-1358) of ARM Architecture reference manual.
     262                 * Make sure the memory type is correct, and in sync with:
     263                 * init_boot_pt (boot/arch/arm32/src/mm.c)
     264                 * init_ptl0_section (boot/arch/arm32/src/mm.c)
     265                 * set_ptl0_addr (kernel/arch/arm32/include/arch/mm/page.h)
     266                 */
     267                p->tex = 5;
     268                p->cacheable = 0;
     269                p->bufferable = 1;
     270        } else {
     271                /*
     272                 * Shareable device memory, see ch. B3.8.2 (p. B3-1358) of
     273                 * ARM Architecture reference manual.
     274                 */
     275                p->tex = 0;
     276                p->cacheable = 0;
     277                p->bufferable = 1;
     278        }
    241279       
    242280        /* Shareable is ignored for devices (non-cacheable),
    243          * turn it on for normal memory. */
    244         p->shareable = 1;
     281         * turn it off for normal memory. */
     282        p->shareable = 0;
    245283       
    246284        p->non_global = !(flags & PAGE_GLOBAL);
     
    256294                        p->access_permission_1 = PTE_AP1_RO;
    257295        }
     296        pt_coherence(p);
    258297}
    259298
     
    264303        p->should_be_zero_0 = 0;
    265304        p->should_be_zero_1 = 0;
    266         write_barrier();
    267305        p->descriptor_type = PTE_DESCRIPTOR_COARSE_TABLE;
     306        pt_coherence(p);
    268307}
    269308
     
    273312
    274313        p->descriptor_type = PTE_DESCRIPTOR_SMALL_PAGE;
     314        pt_coherence(p);
    275315}
    276316
  • kernel/arch/arm32/src/cpu/cpu.c

    red29fe4 r2921602  
    157157#endif
    158158#ifdef PROCESSOR_ARCH_armv7_a
    159          /* ICache coherency is elaborate on in barrier.h.
     159         /* ICache coherency is elaborated on in barrier.h.
    160160          * VIPT and PIPT caches need maintenance only on code modify,
    161161          * so it should be safe for general use.
     
    166166                control_reg |=
    167167                    SCTLR_INST_CACHE_EN_FLAG | SCTLR_BRANCH_PREDICT_EN_FLAG;
     168        } else {
     169                control_reg &=
     170                    ~(SCTLR_INST_CACHE_EN_FLAG | SCTLR_BRANCH_PREDICT_EN_FLAG);
    168171        }
    169172#endif
     
    204207#ifdef PROCESSOR_ARCH_armv7_a
    205208        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        const uint32_t ccsidr = CCSIDR_read();
     210        return CCSIDR_LINESIZE_LOG(ccsidr);
    209211#endif
    210212        return 0;
     
    217219#ifdef PROCESSOR_ARCH_armv7_a
    218220        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;
     221        const uint32_t ccsidr = CCSIDR_read();
     222        return CCSIDR_WAYS(ccsidr);
    222223#endif
    223224        return 0;
     
    229230#ifdef PROCESSOR_ARCH_armv7_a
    230231        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;
     232        const uint32_t ccsidr = CCSIDR_read();
     233        return CCSIDR_SETS(ccsidr);
    234234#endif
    235235        return 0;
     
    241241#ifdef PROCESSOR_ARCH_armv7_a
    242242        const uint32_t val = CLIDR_read();
    243         for (unsigned i = 1; i <= 7; ++i) {
     243        for (unsigned i = 0; i < 8; ++i) {
    244244                const unsigned ctype = CLIDR_CACHE(i, val);
    245245                switch (ctype) {
     
    280280                const unsigned ways = dcache_ways(i);
    281281                const unsigned sets = dcache_sets(i);
    282                 const unsigned way_shift =  31 - log2(ways);
     282                const unsigned way_shift = 32 - log2(ways);
    283283                const unsigned set_shift = dcache_linesize_log(i);
    284284                dcache_clean_manual(i, false, ways, sets, way_shift, set_shift);
     
    293293                const unsigned ways = dcache_ways(i);
    294294                const unsigned sets = dcache_sets(i);
    295                 const unsigned way_shift =  31 - log2(ways);
     295                const unsigned way_shift = 32 - log2(ways);
    296296                const unsigned set_shift = dcache_linesize_log(i);
    297297                dcache_clean_manual(i, true, ways, sets, way_shift, set_shift);
  • kernel/arch/arm32/src/mach/beagleboardxm/beagleboardxm.c

    red29fe4 r2921602  
    8585static void bb_timer_irq_handler(irq_t *irq)
    8686{
     87        amdm37x_gpt_irq_ack(&beagleboard.timer);
     88
    8789        /*
    8890         * We are holding a lock which prevents preemption.
    8991         * Release the lock, call clock() and reacquire the lock again.
    9092         */
    91         amdm37x_gpt_irq_ack(&beagleboard.timer);
    9293        spinlock_unlock(&irq->lock);
    9394        clock();
     
    147148{
    148149        const unsigned inum = amdm37x_irc_inum_get(beagleboard.irc_addr);
    149         amdm37x_irc_irq_ack(beagleboard.irc_addr);
    150150
    151151        irq_t *irq = irq_dispatch_and_lock(inum);
     
    159159                    CPU->id, inum);
    160160        }
     161        /** amdm37x manual ch. 12.5.2 (p. 2428) places irc ack at the end
     162         * of ISR. DO this to avoid strange behavior. */
     163        amdm37x_irc_irq_ack(beagleboard.irc_addr);
    161164}
    162165
  • kernel/arch/arm32/src/mm/tlb.c

    red29fe4 r2921602  
    3737#include <arch/mm/asid.h>
    3838#include <arch/asm.h>
     39#include <arch/cp15.h>
    3940#include <typedefs.h>
    4041#include <arch/mm/page.h>
     42#include <arch/cache.h>
    4143
    4244/** Invalidate all entries in TLB.
     
    4648void tlb_invalidate_all(void)
    4749{
    48         asm volatile (
    49                 "eor r1, r1\n"
    50                 "mcr p15, 0, r1, c8, c7, 0\n"
    51                 ::: "r1"
    52         );
     50        TLBIALL_write(0);
     51        /*
     52         * "A TLB maintenance operation is only guaranteed to be complete after
     53         * the execution of a DSB instruction."
     54         * "An ISB instruction, or a return from an exception, causes the
     55         * effect of all completed TLB maintenance operations that appear in
     56         * program order before the ISB or return from exception to be visible
     57         * to all subsequent instructions, including the instruction fetches
     58         * for those instructions."
     59         * ARM Architecture reference Manual ch. B3.10.1 p. B3-1374 B3-1375
     60         */
     61        read_barrier();
     62        inst_barrier();
    5363}
    5464
     
    6070{
    6171        tlb_invalidate_all();
     72        // TODO: why not TLBIASID_write(asid) ?
    6273}
    6374
     
    6576 *
    6677 * @param page Virtual adress of the page
    67  */ 
     78 */
    6879static inline void invalidate_page(uintptr_t page)
    6980{
    70         asm volatile (
    71                 "mcr p15, 0, %[page], c8, c7, 1\n"
    72                 :: [page] "r" (page)
    73         );
     81        //TODO: What about TLBIMVAA?
     82        TLBIMVA_write(page);
     83        /*
     84         * "A TLB maintenance operation is only guaranteed to be complete after
     85         * the execution of a DSB instruction."
     86         * "An ISB instruction, or a return from an exception, causes the
     87         * effect of all completed TLB maintenance operations that appear in
     88         * program order before the ISB or return from exception to be visible
     89         * to all subsequent instructions, including the instruction fetches
     90         * for those instructions."
     91         * ARM Architecture reference Manual ch. B3.10.1 p. B3-1374 B3-1375
     92         */
     93        read_barrier();
     94        inst_barrier();
    7495}
    7596
     
    83104void tlb_invalidate_pages(asid_t asid __attribute__((unused)), uintptr_t page, size_t cnt)
    84105{
    85         unsigned int i;
    86 
    87         for (i = 0; i < cnt; i++)
     106        for (unsigned i = 0; i < cnt; i++)
    88107                invalidate_page(page + i * PAGE_SIZE);
    89108}
  • kernel/genarch/include/genarch/drivers/amdm37x/gpt.h

    red29fe4 r2921602  
    3939#include <typedefs.h>
    4040#include <mm/km.h>
     41#include <time/clock.h>
    4142
    4243/* AMDM37x TRM p. 2740 */
     
    128129#define AMDM37x_GPT_TCLR_CE_FLAG  (1 << 6)
    129130#define AMDM37x_GPT_TCLR_SCPWM  (1 << 7)
    130 #define AMDM37x_GPT_TCLR_TCM_MASK  (0x3)
    131 #define AMDM37x_GPT_TCLR_TCM_SHIFT  (8)
    132 #define AMDM37x_GPT_TCLR_TRG_MASK  (0x3)
    133 #define AMDM37x_GPT_TCLR_TRG_SHIFT (10)
     131#define AMDM37x_GPT_TCLR_TCM_MASK  (0x3 << 8)
     132#define AMDM37x_GPT_TCLR_TCM_NO_CAPTURE   (0x0 << 8)
     133#define AMDM37x_GPT_TCLR_TCM_RAISE_CAPTURE   (0x1 << 8)
     134#define AMDM37x_GPT_TCLR_TCM_FALL_CAPTURE   (0x2 << 8)
     135#define AMDM37x_GPT_TCLR_TCM_BOTH_CAPTURE   (0x3 << 8)
     136#define AMDM37x_GPT_TCLR_TRG_MASK  (0x3 << 10)
     137#define AMDM37x_GPT_TCLR_TRG_NO  (0x0 << 10)
     138#define AMDM37x_GPT_TCLR_TRG_OVERFLOW  (0x1 << 10)
     139#define AMDM37x_GPT_TCLR_TRG_OVERMATCH  (0x2 << 10)
    134140#define AMDM37x_GPT_TCLR_PT_FLAG  (1 << 12)
    135141#define AMDM37x_GPT_TCLR_CAPT_MODE_FLAG  (1 << 13)
     
    209215        timer->regs = (void*) km_map(ioregs, iosize, PAGE_NOT_CACHEABLE);
    210216
     217        /* Reset the timer */
     218        timer->regs->tiocp_cfg |= AMDM37x_GPT_TIOCP_CFG_SOFTRESET_FLAG;
     219
     220        while (!(timer->regs->tistat & AMDM37x_GPT_TISTAT_RESET_DONE_FLAG));
     221
    211222        /* Set autoreload */
    212         timer->regs->tclr = AMDM37x_GPT_TCLR_AR_FLAG;
     223        timer->regs->tclr |= AMDM37x_GPT_TCLR_AR_FLAG;
    213224
    214225        timer->special_available = (
     
    216227            (ioregs == AMDM37x_GPT2_BASE_ADDRESS) ||
    217228            (ioregs == AMDM37x_GPT10_BASE_ADDRESS));
     229        /* Select reload value */
    218230        timer->regs->tldr = 0xffffffff - (32768 / hz) + 1;
     231        /* Set current counter value */
    219232        timer->regs->tccr = 0xffffffff - (32768 / hz) + 1;
     233
    220234        if (timer->special_available) {
    221                 /* Set values for according to formula (manual p. 2733) */
     235                /* Set values according to formula (manual p. 2733) */
    222236                /* Use temporary variables for easier debugging */
    223237                const uint32_t tpir =
    224238                    ((32768 / hz + 1) * 1000000) - (32768000L * (1000 / hz));
    225239                const uint32_t tnir =
    226                     ((32768 / hz) * 1000000) - (32768000 * (1000 / hz));
     240                    ((32768 / hz) * 1000000) - (32768000L * (1000 / hz));
    227241                timer->regs->tpir = tpir;
    228242                timer->regs->tnir = tnir;
     
    241255}
    242256
    243 static inline void amdm37x_gpt_irq_ack(amdm37x_gpt_t* timer)
     257static inline bool amdm37x_gpt_irq_ack(amdm37x_gpt_t* timer)
    244258{
    245259        ASSERT(timer);
    246260        ASSERT(timer->regs);
    247261        /* Clear all pending interrupts */
    248         timer->regs->tisr = timer->regs->tisr;
     262        const uint32_t tisr = timer->regs->tisr;
     263        timer->regs->tisr = tisr;
     264        return tisr != 0;
    249265}
    250266
  • kernel/genarch/src/mm/page_pt.c

    red29fe4 r2921602  
    112112                 */
    113113                write_barrier();
    114                 SET_PTL2_PRESENT(ptl1, PTL1_INDEX(page));       
     114                SET_PTL2_PRESENT(ptl1, PTL1_INDEX(page));
    115115        }
    116116       
     
    180180         * Destroy the mapping.
    181181         * Setting to PAGE_NOT_PRESENT is not sufficient.
    182          */
     182         * But we need SET_FRAME for possible PT coherence maintenance.
     183         * At least on ARM.
     184         */
     185        //TODO: Fix this inconsistency
     186        SET_FRAME_FLAGS(ptl3, PTL3_INDEX(page), PAGE_NOT_PRESENT);
    183187        memsetb(&ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0);
    184188       
  • uspace/drv/infrastructure/rootamdm37x/rootamdm37x.c

    red29fe4 r2921602  
    4848
    4949typedef struct {
     50        const char *name;
     51        match_id_t match_id;
    5052        hw_resource_list_t hw_resources;
    5153} rootamdm37x_fun_t;
    5254
    53 /* See amdm37x TRM page. 3316 for these values */
    54 #define OHCI_BASE_ADDRESS  0x48064400
    55 #define OHCI_SIZE  1024
    56 #define EHCI_BASE_ADDRESS  0x48064800
    57 #define EHCI_SIZE  1024
     55/* See amdm37x TRM page 3316 for these values */
     56#define OHCI_BASE_ADDRESS   0x48064400
     57#define OHCI_SIZE   1024
     58#define EHCI_BASE_ADDRESS   0x48064800
     59#define EHCI_SIZE   1024
     60
     61/* See amdm37x TRM page 1813 for these values */
     62#define DSS_BASE_ADDRESS   0x48050000
     63#define DSS_SIZE   512
     64#define DISPC_BASE_ADDRESS   0x48050400
     65#define DISPC_SIZE   1024
     66#define VIDEO_ENC_BASE_ADDRESS   0x48050C00
     67#define VIDEO_ENC_SIZE   256
     68
    5869
    5970static hw_resource_t ohci_res[] = {
     
    8899};
    89100
    90 static const rootamdm37x_fun_t ohci = {
    91         .hw_resources = {
    92             .resources = ohci_res,
    93             .count = sizeof(ohci_res)/sizeof(ohci_res[0]),
    94         }
    95 };
    96 
    97 static const rootamdm37x_fun_t ehci = {
    98         .hw_resources = {
    99             .resources = ehci_res,
    100             .count = sizeof(ehci_res) / sizeof(ehci_res[0]),
    101         }
    102 };
     101static hw_resource_t disp_res[] = {
     102        {
     103                .type = MEM_RANGE,
     104                .res.io_range = {
     105                        .address = DSS_BASE_ADDRESS,
     106                        .size = DSS_SIZE,
     107                        .endianness = LITTLE_ENDIAN
     108                },
     109        },
     110        {
     111                .type = MEM_RANGE,
     112                .res.io_range = {
     113                        .address = DISPC_BASE_ADDRESS,
     114                        .size = DISPC_SIZE,
     115                        .endianness = LITTLE_ENDIAN
     116                },
     117        },
     118        {
     119                .type = MEM_RANGE,
     120                .res.io_range = {
     121                        .address = VIDEO_ENC_BASE_ADDRESS,
     122                        .size = VIDEO_ENC_SIZE,
     123                        .endianness = LITTLE_ENDIAN
     124                },
     125        },
     126        {
     127                .type = INTERRUPT,
     128                .res.interrupt = { .irq = 25 },
     129        },
     130};
     131
     132static const rootamdm37x_fun_t amdm37x_funcs[] = {
     133{
     134        .name = "ohci",
     135        .match_id = { .id = "usb/host=ohci", .score = 90 },
     136        .hw_resources = { .resources = ohci_res, .count = ARRAY_SIZE(ohci_res) }
     137},
     138{
     139        .name = "ehci",
     140        .match_id = { .id = "usb/host=ehci", .score = 90 },
     141        .hw_resources = { .resources = ehci_res, .count = ARRAY_SIZE(ehci_res) }
     142},
     143{
     144        .name = "fb",
     145        .match_id = { .id = "amdm37x&dispc", .score = 90 },
     146        .hw_resources = { .resources = disp_res, .count = ARRAY_SIZE(disp_res) }
     147},
     148};
     149
    103150
    104151static hw_resource_list_t *rootamdm37x_get_resources(ddf_fun_t *fnode);
     
    114161};
    115162
    116 static int rootamdm37x_add_fun(ddf_dev_t *dev, const char *name,
    117     const char *str_match_id, const rootamdm37x_fun_t *fun)
    118 {
    119         ddf_msg(LVL_DEBUG, "Adding new function '%s'.", name);
    120        
     163static int rootamdm37x_add_fun(ddf_dev_t *dev, const rootamdm37x_fun_t *fun)
     164{
     165        assert(dev);
     166        assert(fun);
     167
     168        ddf_msg(LVL_DEBUG, "Adding new function '%s'.", fun->name);
     169
    121170        /* Create new device function. */
    122         ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, name);
     171        ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, fun->name);
    123172        if (fnode == NULL)
    124173                return ENOMEM;
    125174       
    126175        /* Add match id */
    127         int ret = ddf_fun_add_match_id(fnode, str_match_id, 100);
     176        int ret = ddf_fun_add_match_id(fnode,
     177            fun->match_id.id, fun->match_id.score);
    128178        if (ret != EOK) {
    129179                ddf_fun_destroy(fnode);
     
    146196        ret = ddf_fun_bind(fnode);
    147197        if (ret != EOK) {
    148                 ddf_msg(LVL_ERROR, "Failed binding function %s.", name);
     198                ddf_msg(LVL_ERROR, "Failed binding function %s.", fun->name);
    149199                ddf_fun_destroy(fnode);
    150200                return ret;
     
    189239
    190240        /* Register functions */
    191         if (rootamdm37x_add_fun(dev, "ohci", "usb/host=ohci", &ohci) != EOK)
    192                 ddf_msg(LVL_ERROR, "Failed to add OHCI function for "
    193                     "BeagleBoard-xM platform.");
    194         if (rootamdm37x_add_fun(dev, "ehci", "usb/host=ehci", &ehci) != EOK)
    195                 ddf_msg(LVL_ERROR, "Failed to add EHCI function for "
    196                     "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.");
    200 
     241        for (unsigned i = 0; i < ARRAY_SIZE(amdm37x_funcs); ++i) {
     242                if (rootamdm37x_add_fun(dev, &amdm37x_funcs[i]) != EOK)
     243                        ddf_msg(LVL_ERROR, "Failed to add %s function for "
     244                            "BeagleBoard-xM platform.", amdm37x_funcs[i].name);
     245        }
    201246        return EOK;
    202247}
  • uspace/drv/infrastructure/rootamdm37x/uhh.h

    red29fe4 r2921602  
    8585#define UHH_DEBUG_CSR_EHCI_SIMULATION_MODE_FLAG  (1 << 6)
    8686#define UHH_DEBUG_CSR_OHCI_CNTSEL_FLAG  (1 << 7)
    87 #define UHH_DEBUG_CSR_OHCI_GLOBAL_sUSPEND_FLAG  (1 << 16)
     87#define UHH_DEBUG_CSR_OHCI_GLOBAL_SUSPEND_FLAG  (1 << 16)
    8888#define UHH_DEBUG_CSR_OHCI_CCS1_FLAG  (1 << 17)
    8989#define UHH_DEBUG_CSR_OHCI_CCS2_FLAG  (1 << 18)
  • uspace/lib/c/include/macros.h

    red29fe4 r2921602  
    4040#define abs(a)     ((a) >= 0 ? (a) : -(a))
    4141
     42#define ARRAY_SIZE(array)   (sizeof(array) / sizeof(array[0]))
    4243
    4344#define KiB2SIZE(kb)  ((kb) << 10)
Note: See TracChangeset for help on using the changeset viewer.