Changes in / [2921602:ed29fe4] in mainline


Ignore:
Files:
1 deleted
16 edited

Legend:

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

    r2921602 red29fe4  
    5656jump_to_kernel:
    5757        #
     58        # TODO
    5859        # Make sure that the I-cache, D-cache and memory are mutually coherent
    5960        # before passing control to the copied code.
     
    6768#define CP15_C1_BP              11
    6869#define CP15_C1_DC              2
    69 
    70 
    71 #ifndef PROCESSOR_ARCH_armv7_a
     70        # Disable I-cache and D-cache before the kernel is started.
    7271        mrc     p15, 0, r4, c1, c0, 0
    73        
    74         # D-cache before the kernel is started.
    7572        bic     r4, r4, #(1 << CP15_C1_DC)
    76 
    77         # Disable I-cache and Branche predictors.
    7873        bic     r4, r4, #(1 << CP15_C1_IC)
    7974        bic     r4, r4, #(1 << CP15_C1_BP)
    80        
    8175        mcr     p15, 0, r4, c1, c0, 0
    82 #endif
    83 
    8476
    8577       
     
    8981#else
    9082        #cp15 dsb, r4 is ignored (should be zero)
    91         mov r4, #0
    9283        mcr p15, 0, r4, c7, c10, 4
    9384#endif
    9485       
    9586        # Clean ICache and BPredictors, r4 ignored (SBZ)
    96         mov r4, #0
    9787        mcr p15, 0, r4, c7, c5, 0
    9888        nop
  • boot/arch/arm32/src/main.c

    r2921602 red29fe4  
    5353extern void *bdata_end;
    5454
     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
    5571static inline void clean_dcache_poc(void *address, size_t size)
    5672{
    5773        const uintptr_t addr = (uintptr_t)address;
     74        /* DCCMVAC - clean by address to the point of coherence */
    5875        for (uintptr_t a = addr; a < addr + size; a += 4) {
    59                 /* DCCMVAC - clean by address to the point of coherence */
    6076                asm volatile ("mcr p15, 0, %[a], c7, c10, 1\n" :: [a]"r"(a) : );
    6177        }
     
    6682void bootstrap(void)
    6783{
     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
    6891        /* Enable MMU and caches */
    6992        mmu_start();
     
    82105                    components[i].start, components[i].name, components[i].inflated,
    83106                    components[i].size);
     107                invalidate_dcache(components[i].start, components[i].size);
    84108        }
    85109       
     
    124148                        halt();
    125149                }
    126                 /* Make sure data are in the memory, ICache will need them */
    127150                clean_dcache_poc(dest[i - 1], components[i - 1].inflated);
    128151        }
  • boot/arch/arm32/src/mm.c

    r2921602 red29fe4  
    3737#include <arch/asm.h>
    3838#include <arch/mm.h>
    39 #include <arch/cp15.h>
    40 
    41 #ifdef PROCESSOR_ARCH_armv7_a
    42 static unsigned log2(unsigned val)
    43 {
    44         unsigned log = 0;
    45         while (val >> log++);
    46         return log - 2;
    47 }
    48 
    49 static 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 */
    68 static 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
    8539
    8640/** Disable the MMU */
     
    10660static inline int section_cacheable(pfn_t section)
    10761{
    108         const unsigned long address = section << PTE_SECTION_SHIFT;
    10962#ifdef MACHINE_gta02
    110         if (address < GTA02_IOMEM_START || address >= GTA02_IOMEM_END)
     63        unsigned long address = section << PTE_SECTION_SHIFT;
     64
     65        if (address >= GTA02_IOMEM_START && address < GTA02_IOMEM_END)
     66                return 0;
     67        else
    11168                return 1;
    11269#elif defined MACHINE_beagleboardxm
     70        const unsigned long address = section << PTE_SECTION_SHIFT;
    11371        if (address >= BBXM_RAM_START && address < BBXM_RAM_END)
    11472                return 1;
    11573#elif defined MACHINE_beaglebone
     74        const unsigned long address = section << PTE_SECTION_SHIFT;
    11675        if (address >= AM335x_RAM_START && address < AM335x_RAM_END)
    11776                return 1;
    11877#endif
    119         return address * 0;
     78        return 0;
    12079}
    12180
     
    13695{
    13796        pte->descriptor_type = PTE_DESCRIPTOR_SECTION;
     97        pte->bufferable = 1;
     98        pte->cacheable = section_cacheable(frame);
    13899        pte->xn = 0;
    139100        pte->domain = 0;
    140101        pte->should_be_zero_1 = 0;
    141102        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);
    155103        pte->tex = 0;
    156 #endif
    157104        pte->access_permission_1 = 0;
    158105        pte->shareable = 0;
     
    166113static void init_boot_pt(void)
    167114{
    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)
     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++)
    178119                init_ptl0_section(&boot_pt[page], page);
    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);
     120       
     121        asm volatile (
     122                "mcr p15, 0, %[pt], c2, c0, 0\n"
     123                :: [pt] "r" (boot_pt)
     124        );
    190125}
    191126
     
    206141                 * we disable caches before jumping to kernel
    207142                 * so this is safe for all archs.
    208                  * Enable VMSAv6 the bit (23) is only writable on ARMv6.
    209143                 */
    210                 "ldr r1, =0x00801805\n"
     144                "ldr r1, =0x00001805\n"
    211145               
    212146                "orr r0, r0, r1\n"
     
    226160void mmu_start() {
    227161        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
    235162        init_boot_pt();
    236163        enable_paging();
  • kernel/arch/arm32/include/arch/asm.h

    r2921602 red29fe4  
    3838
    3939#include <typedefs.h>
    40 #include <arch/cp15.h>
    4140#include <arch/stack.h>
    4241#include <config.h>
     
    5251 * chapter 2.3.8 p.2-22 (52 in the PDF)
    5352 *
    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+.
     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+.
    5756 */
    5857NO_TRACE static inline void cpu_sleep(void)
     
    6160        asm volatile ( "wfe" );
    6261#elif defined(PROCESSOR_ARCH_armv6) | defined(PROCESSOR_arm926ej_s) | defined(PROCESSOR_arm920t)
    63         WFI_write(0);
     62        asm volatile ( "mcr p15, 0, R0, c7, c0, 4" );
    6463#endif
    6564}
  • kernel/arch/arm32/include/arch/cp15.h

    r2921602 red29fe4  
    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)
    180173};
    181174CONTROL_REG_GEN_READ(CCSIDR, c0, 1, c0, 0);
     
    194187        CLIDR_UNI_CACHE = 0x4,
    195188        CLIDR_CACHE_MASK = 0x7,
    196 /** levels counted from 0 */
    197 #define CLIDR_CACHE(level, val)   ((val >> (level * 3)) & CLIDR_CACHE_MASK)
     189#define CLIDR_CACHE(level, val)   ((val >> (level - 1) * 3) & CLIDR_CACHE_MASK)
    198190};
    199191CONTROL_REG_GEN_READ(CLIDR, c0, 1, c0, 1);
     
    301293
    302294/* Memory protection and control registers */
    303 enum {
    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 };
    314295CONTROL_REG_GEN_READ(TTBR0, c2, 0, c0, 0);
    315296CONTROL_REG_GEN_WRITE(TTBR0, c2, 0, c0, 0);
     
    382363
    383364CONTROL_REG_GEN_WRITE(DCIMVAC, c7, 0, c6, 1);
    384 CONTROL_REG_GEN_WRITE(DCISW, c7, 0, c6, 2);
     365CONTROL_REG_GEN_WRITE(DCIMSW, c7, 0, c6, 2);
    385366
    386367CONTROL_REG_GEN_WRITE(ATS1CPR, c7, 0, c8, 0);
     
    388369CONTROL_REG_GEN_WRITE(ATS1CUR, c7, 0, c8, 2);
    389370CONTROL_REG_GEN_WRITE(ATS1CUW, c7, 0, c8, 3);
    390 CONTROL_REG_GEN_WRITE(ATS12NSOPR, c7, 0, c8, 4);
    391 CONTROL_REG_GEN_WRITE(ATS12NSOPW, c7, 0, c8, 5);
    392 CONTROL_REG_GEN_WRITE(ATS12NSOUR, c7, 0, c8, 6);
    393 CONTROL_REG_GEN_WRITE(ATS12NSOUW, c7, 0, c8, 7);
     371CONTROL_REG_GEN_WRITE(ATS1NSOPR, c7, 0, c8, 4);
     372CONTROL_REG_GEN_WRITE(ATS1NSOPW, c7, 0, c8, 5);
     373CONTROL_REG_GEN_WRITE(ATS1NSOUR, c7, 0, c8, 6);
     374CONTROL_REG_GEN_WRITE(ATS1NSOUW, c7, 0, c8, 7);
    394375
    395376
  • kernel/arch/arm32/include/arch/mm/page.h

    r2921602 red29fe4  
    4141#include <arch/exception.h>
    4242#include <arch/barrier.h>
    43 #include <arch/cp15.h>
    4443#include <trace.h>
    4544
     
    9695/* Set PTE address accessors for each level. */
    9796#define SET_PTL0_ADDRESS_ARCH(ptl0) \
    98         set_ptl0_addr((pte_t *) (ptl0))
     97        (set_ptl0_addr((pte_t *) (ptl0)))
    9998#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
    100         set_ptl1_addr((pte_t*) (ptl0), i, a)
     99        (((pte_t *) (ptl0))[(i)].l0.coarse_table_addr = (a) >> 10)
    101100#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
    102101#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
    103102#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \
    104         set_ptl3_addr((pte_t*) (ptl3), i, a)
     103        (((pte_t *) (ptl3))[(i)].l1.frame_base_addr = (a) >> 12)
    105104
    106105/* Get PTE flags accessors for each level. */
     
    130129        set_pt_level1_present((pte_t *) (ptl3), (size_t) (i))
    131130
    132 
    133 #define pt_coherence(page) pt_coherence_m(page, 1)
    134 
    135131#if defined(PROCESSOR_ARCH_armv6) | defined(PROCESSOR_ARCH_armv7_a)
    136132#include "page_armv6.h"
     
    141137#endif
    142138
    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  */
    153 NO_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 
    160 NO_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 
    166 NO_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 
    172139#endif
    173140
  • kernel/arch/arm32/include/arch/mm/page_armv4.h

    r2921602 red29fe4  
    120120#define PTE_DESCRIPTOR_SMALL_PAGE       2
    121121
    122 #define pt_coherence_m(pt, count) \
    123 do { \
    124         for (unsigned i = 0; i < count; ++i) \
    125                 DCCMVAU_write((uintptr_t)(pt + i)); \
    126         read_barrier(); \
    127 } while (0)
     122
     123/** Sets the address of level 0 page table.
     124 *
     125 * @param pt Pointer to the page table to set.
     126 *
     127 */
     128NO_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
    128136
    129137/** Returns level 0 page table entry flags.
     
    215223       
    216224        /* default access permission */
    217         p->access_permission_0 = p->access_permission_1 =
     225        p->access_permission_0 = p->access_permission_1 = 
    218226            p->access_permission_2 = p->access_permission_3 =
    219227            PTE_AP_USER_NO_KERNEL_RW;
     
    221229        if (flags & PAGE_USER)  {
    222230                if (flags & PAGE_READ) {
    223                         p->access_permission_0 = p->access_permission_1 =
    224                             p->access_permission_2 = p->access_permission_3 =
     231                        p->access_permission_0 = p->access_permission_1 = 
     232                            p->access_permission_2 = p->access_permission_3 = 
    225233                            PTE_AP_USER_RO_KERNEL_RW;
    226234                }
    227235                if (flags & PAGE_WRITE) {
    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;
     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; 
    231239                }
    232240        }
  • kernel/arch/arm32/include/arch/mm/page_armv6.h

    r2921602 red29fe4  
    4040#error "Do not include arch specific page.h directly use generic page.h instead"
    4141#endif
    42 
    4342
    4443/* Macros for querying the last-level PTE entries. */
     
    126125#define PTE_DESCRIPTOR_SMALL_PAGE_NX    3
    127126
    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) \
    156 do { \
    157         for (unsigned i = 0; i < count; ++i) \
    158                 DCCMVAU_write((uintptr_t)(pt + i)); \
    159         read_barrier(); \
    160 } while (0)
     127/** Sets the address of level 0 page table.
     128 *
     129 * @param pt Pointer to the page table to set.
     130 *
     131 */
     132NO_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}
    161139
    162140
     
    228206                p->ns = 0;
    229207        }
    230         pt_coherence(p);
    231208}
    232209
     
    255232                        p->descriptor_type = PTE_DESCRIPTOR_SMALL_PAGE_NX;
    256233        }
    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         }
     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;
    279241       
    280242        /* Shareable is ignored for devices (non-cacheable),
    281          * turn it off for normal memory. */
    282         p->shareable = 0;
     243         * turn it on for normal memory. */
     244        p->shareable = 1;
    283245       
    284246        p->non_global = !(flags & PAGE_GLOBAL);
     
    294256                        p->access_permission_1 = PTE_AP1_RO;
    295257        }
    296         pt_coherence(p);
    297258}
    298259
     
    303264        p->should_be_zero_0 = 0;
    304265        p->should_be_zero_1 = 0;
     266        write_barrier();
    305267        p->descriptor_type = PTE_DESCRIPTOR_COARSE_TABLE;
    306         pt_coherence(p);
    307268}
    308269
     
    312273
    313274        p->descriptor_type = PTE_DESCRIPTOR_SMALL_PAGE;
    314         pt_coherence(p);
    315275}
    316276
  • kernel/arch/arm32/src/cpu/cpu.c

    r2921602 red29fe4  
    157157#endif
    158158#ifdef PROCESSOR_ARCH_armv7_a
    159          /* ICache coherency is elaborated on in barrier.h.
     159         /* ICache coherency is elaborate 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);
    171168        }
    172169#endif
     
    207204#ifdef PROCESSOR_ARCH_armv7_a
    208205        CSSELR_write((level & CCSELR_LEVEL_MASK) << CCSELR_LEVEL_SHIFT);
    209         const uint32_t ccsidr = CCSIDR_read();
    210         return CCSIDR_LINESIZE_LOG(ccsidr);
     206        const unsigned ls_log = 2 +
     207            ((CCSIDR_read() >> CCSIDR_LINESIZE_SHIFT) & CCSIDR_LINESIZE_MASK);
     208        return ls_log + 2; //return log2(bytes)
    211209#endif
    212210        return 0;
     
    219217#ifdef PROCESSOR_ARCH_armv7_a
    220218        CSSELR_write((level & CCSELR_LEVEL_MASK) << CCSELR_LEVEL_SHIFT);
    221         const uint32_t ccsidr = CCSIDR_read();
    222         return CCSIDR_WAYS(ccsidr);
     219        const unsigned ways = 1 +
     220            ((CCSIDR_read() >> CCSIDR_ASSOC_SHIFT) & CCSIDR_ASSOC_MASK);
     221        return ways;
    223222#endif
    224223        return 0;
     
    230229#ifdef PROCESSOR_ARCH_armv7_a
    231230        CSSELR_write((level & CCSELR_LEVEL_MASK) << CCSELR_LEVEL_SHIFT);
    232         const uint32_t ccsidr = CCSIDR_read();
    233         return CCSIDR_SETS(ccsidr);
     231        const unsigned sets = 1 +
     232            ((CCSIDR_read() >> CCSIDR_NUMSETS_SHIFT) & CCSIDR_NUMSETS_MASK);
     233        return sets;
    234234#endif
    235235        return 0;
     
    241241#ifdef PROCESSOR_ARCH_armv7_a
    242242        const uint32_t val = CLIDR_read();
    243         for (unsigned i = 0; i < 8; ++i) {
     243        for (unsigned i = 1; i <= 7; ++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 = 32 - log2(ways);
     282                const unsigned way_shift =  31 - 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 = 32 - log2(ways);
     295                const unsigned way_shift =  31 - 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

    r2921602 red29fe4  
    8585static void bb_timer_irq_handler(irq_t *irq)
    8686{
    87         amdm37x_gpt_irq_ack(&beagleboard.timer);
    88 
    8987        /*
    9088         * We are holding a lock which prevents preemption.
    9189         * Release the lock, call clock() and reacquire the lock again.
    9290         */
     91        amdm37x_gpt_irq_ack(&beagleboard.timer);
    9392        spinlock_unlock(&irq->lock);
    9493        clock();
     
    148147{
    149148        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);
    164161}
    165162
  • kernel/arch/arm32/src/mm/tlb.c

    r2921602 red29fe4  
    3737#include <arch/mm/asid.h>
    3838#include <arch/asm.h>
    39 #include <arch/cp15.h>
    4039#include <typedefs.h>
    4140#include <arch/mm/page.h>
    42 #include <arch/cache.h>
    4341
    4442/** Invalidate all entries in TLB.
     
    4846void tlb_invalidate_all(void)
    4947{
    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();
     48        asm volatile (
     49                "eor r1, r1\n"
     50                "mcr p15, 0, r1, c8, c7, 0\n"
     51                ::: "r1"
     52        );
    6353}
    6454
     
    7060{
    7161        tlb_invalidate_all();
    72         // TODO: why not TLBIASID_write(asid) ?
    7362}
    7463
     
    7665 *
    7766 * @param page Virtual adress of the page
    78  */
     67 */ 
    7968static inline void invalidate_page(uintptr_t page)
    8069{
    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();
     70        asm volatile (
     71                "mcr p15, 0, %[page], c8, c7, 1\n"
     72                :: [page] "r" (page)
     73        );
    9574}
    9675
     
    10483void tlb_invalidate_pages(asid_t asid __attribute__((unused)), uintptr_t page, size_t cnt)
    10584{
    106         for (unsigned i = 0; i < cnt; i++)
     85        unsigned int i;
     86
     87        for (i = 0; i < cnt; i++)
    10788                invalidate_page(page + i * PAGE_SIZE);
    10889}
  • kernel/genarch/include/genarch/drivers/amdm37x/gpt.h

    r2921602 red29fe4  
    3939#include <typedefs.h>
    4040#include <mm/km.h>
    41 #include <time/clock.h>
    4241
    4342/* AMDM37x TRM p. 2740 */
     
    129128#define AMDM37x_GPT_TCLR_CE_FLAG  (1 << 6)
    130129#define AMDM37x_GPT_TCLR_SCPWM  (1 << 7)
    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)
     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)
    140134#define AMDM37x_GPT_TCLR_PT_FLAG  (1 << 12)
    141135#define AMDM37x_GPT_TCLR_CAPT_MODE_FLAG  (1 << 13)
     
    215209        timer->regs = (void*) km_map(ioregs, iosize, PAGE_NOT_CACHEABLE);
    216210
    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 
    222211        /* Set autoreload */
    223         timer->regs->tclr |= AMDM37x_GPT_TCLR_AR_FLAG;
     212        timer->regs->tclr = AMDM37x_GPT_TCLR_AR_FLAG;
    224213
    225214        timer->special_available = (
     
    227216            (ioregs == AMDM37x_GPT2_BASE_ADDRESS) ||
    228217            (ioregs == AMDM37x_GPT10_BASE_ADDRESS));
    229         /* Select reload value */
    230218        timer->regs->tldr = 0xffffffff - (32768 / hz) + 1;
    231         /* Set current counter value */
    232219        timer->regs->tccr = 0xffffffff - (32768 / hz) + 1;
    233 
    234220        if (timer->special_available) {
    235                 /* Set values according to formula (manual p. 2733) */
     221                /* Set values for according to formula (manual p. 2733) */
    236222                /* Use temporary variables for easier debugging */
    237223                const uint32_t tpir =
    238224                    ((32768 / hz + 1) * 1000000) - (32768000L * (1000 / hz));
    239225                const uint32_t tnir =
    240                     ((32768 / hz) * 1000000) - (32768000L * (1000 / hz));
     226                    ((32768 / hz) * 1000000) - (32768000 * (1000 / hz));
    241227                timer->regs->tpir = tpir;
    242228                timer->regs->tnir = tnir;
     
    255241}
    256242
    257 static inline bool amdm37x_gpt_irq_ack(amdm37x_gpt_t* timer)
     243static inline void amdm37x_gpt_irq_ack(amdm37x_gpt_t* timer)
    258244{
    259245        ASSERT(timer);
    260246        ASSERT(timer->regs);
    261247        /* Clear all pending interrupts */
    262         const uint32_t tisr = timer->regs->tisr;
    263         timer->regs->tisr = tisr;
    264         return tisr != 0;
     248        timer->regs->tisr = timer->regs->tisr;
    265249}
    266250
  • kernel/genarch/src/mm/page_pt.c

    r2921602 red29fe4  
    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          * 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);
     182         */
    187183        memsetb(&ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0);
    188184       
  • uspace/drv/infrastructure/rootamdm37x/rootamdm37x.c

    r2921602 red29fe4  
    4848
    4949typedef struct {
    50         const char *name;
    51         match_id_t match_id;
    5250        hw_resource_list_t hw_resources;
    5351} rootamdm37x_fun_t;
    5452
    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 
     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
    6958
    7059static hw_resource_t ohci_res[] = {
     
    9988};
    10089
    101 static 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 
    132 static 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 
     90static const rootamdm37x_fun_t ohci = {
     91        .hw_resources = {
     92            .resources = ohci_res,
     93            .count = sizeof(ohci_res)/sizeof(ohci_res[0]),
     94        }
     95};
     96
     97static const rootamdm37x_fun_t ehci = {
     98        .hw_resources = {
     99            .resources = ehci_res,
     100            .count = sizeof(ehci_res) / sizeof(ehci_res[0]),
     101        }
     102};
    150103
    151104static hw_resource_list_t *rootamdm37x_get_resources(ddf_fun_t *fnode);
     
    161114};
    162115
    163 static 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 
     116static 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       
    170121        /* Create new device function. */
    171         ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, fun->name);
     122        ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, name);
    172123        if (fnode == NULL)
    173124                return ENOMEM;
    174125       
    175126        /* Add match id */
    176         int ret = ddf_fun_add_match_id(fnode,
    177             fun->match_id.id, fun->match_id.score);
     127        int ret = ddf_fun_add_match_id(fnode, str_match_id, 100);
    178128        if (ret != EOK) {
    179129                ddf_fun_destroy(fnode);
     
    196146        ret = ddf_fun_bind(fnode);
    197147        if (ret != EOK) {
    198                 ddf_msg(LVL_ERROR, "Failed binding function %s.", fun->name);
     148                ddf_msg(LVL_ERROR, "Failed binding function %s.", name);
    199149                ddf_fun_destroy(fnode);
    200150                return ret;
     
    239189
    240190        /* Register functions */
    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         }
     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
    246201        return EOK;
    247202}
  • uspace/drv/infrastructure/rootamdm37x/uhh.h

    r2921602 red29fe4  
    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

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