Changes in / [2921602:ed29fe4] in mainline
- Files:
-
- 1 deleted
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/arch/arm32/src/asm.S
r2921602 red29fe4 56 56 jump_to_kernel: 57 57 # 58 # TODO 58 59 # Make sure that the I-cache, D-cache and memory are mutually coherent 59 60 # before passing control to the copied code. … … 67 68 #define CP15_C1_BP 11 68 69 #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. 72 71 mrc p15, 0, r4, c1, c0, 0 73 74 # D-cache before the kernel is started.75 72 bic r4, r4, #(1 << CP15_C1_DC) 76 77 # Disable I-cache and Branche predictors.78 73 bic r4, r4, #(1 << CP15_C1_IC) 79 74 bic r4, r4, #(1 << CP15_C1_BP) 80 81 75 mcr p15, 0, r4, c1, c0, 0 82 #endif83 84 76 85 77 … … 89 81 #else 90 82 #cp15 dsb, r4 is ignored (should be zero) 91 mov r4, #092 83 mcr p15, 0, r4, c7, c10, 4 93 84 #endif 94 85 95 86 # Clean ICache and BPredictors, r4 ignored (SBZ) 96 mov r4, #097 87 mcr p15, 0, r4, c7, c5, 0 98 88 nop -
boot/arch/arm32/src/main.c
r2921602 red29fe4 53 53 extern void *bdata_end; 54 54 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 55 71 static inline void clean_dcache_poc(void *address, size_t size) 56 72 { 57 73 const uintptr_t addr = (uintptr_t)address; 74 /* DCCMVAC - clean by address to the point of coherence */ 58 75 for (uintptr_t a = addr; a < addr + size; a += 4) { 59 /* DCCMVAC - clean by address to the point of coherence */60 76 asm volatile ("mcr p15, 0, %[a], c7, c10, 1\n" :: [a]"r"(a) : ); 61 77 } … … 66 82 void bootstrap(void) 67 83 { 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 68 91 /* Enable MMU and caches */ 69 92 mmu_start(); … … 82 105 components[i].start, components[i].name, components[i].inflated, 83 106 components[i].size); 107 invalidate_dcache(components[i].start, components[i].size); 84 108 } 85 109 … … 124 148 halt(); 125 149 } 126 /* Make sure data are in the memory, ICache will need them */127 150 clean_dcache_poc(dest[i - 1], components[i - 1].inflated); 128 151 } -
boot/arch/arm32/src/mm.c
r2921602 red29fe4 37 37 #include <arch/asm.h> 38 38 #include <arch/mm.h> 39 #include <arch/cp15.h>40 41 #ifdef PROCESSOR_ARCH_armv7_a42 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 #endif85 39 86 40 /** Disable the MMU */ … … 106 60 static inline int section_cacheable(pfn_t section) 107 61 { 108 const unsigned long address = section << PTE_SECTION_SHIFT;109 62 #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 111 68 return 1; 112 69 #elif defined MACHINE_beagleboardxm 70 const unsigned long address = section << PTE_SECTION_SHIFT; 113 71 if (address >= BBXM_RAM_START && address < BBXM_RAM_END) 114 72 return 1; 115 73 #elif defined MACHINE_beaglebone 74 const unsigned long address = section << PTE_SECTION_SHIFT; 116 75 if (address >= AM335x_RAM_START && address < AM335x_RAM_END) 117 76 return 1; 118 77 #endif 119 return address *0;78 return 0; 120 79 } 121 80 … … 136 95 { 137 96 pte->descriptor_type = PTE_DESCRIPTOR_SECTION; 97 pte->bufferable = 1; 98 pte->cacheable = section_cacheable(frame); 138 99 pte->xn = 0; 139 100 pte->domain = 0; 140 101 pte->should_be_zero_1 = 0; 141 102 pte->access_permission_0 = PTE_AP_USER_NO_KERNEL_RW; 142 #ifdef PROCESSOR_ARCH_armv7_a143 /*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 #else153 pte->bufferable = 1;154 pte->cacheable = section_cacheable(frame);155 103 pte->tex = 0; 156 #endif157 104 pte->access_permission_1 = 0; 158 105 pte->shareable = 0; … … 166 113 static void init_boot_pt(void) 167 114 { 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++) 178 119 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 ); 190 125 } 191 126 … … 206 141 * we disable caches before jumping to kernel 207 142 * so this is safe for all archs. 208 * Enable VMSAv6 the bit (23) is only writable on ARMv6.209 143 */ 210 "ldr r1, =0x00 801805\n"144 "ldr r1, =0x00001805\n" 211 145 212 146 "orr r0, r0, r1\n" … … 226 160 void mmu_start() { 227 161 disable_paging(); 228 #ifdef PROCESSOR_ARCH_armv7_a229 /* Make sure we run in memory code when caches are enabled,230 * make sure we read memory data too. This part is ARMv7 specific as231 * 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 #endif235 162 init_boot_pt(); 236 163 enable_paging(); -
kernel/arch/arm32/include/arch/asm.h
r2921602 red29fe4 38 38 39 39 #include <typedefs.h> 40 #include <arch/cp15.h>41 40 #include <arch/stack.h> 42 41 #include <config.h> … … 52 51 * chapter 2.3.8 p.2-22 (52 in the PDF) 53 52 * 54 * @note Although CP15WFI (mcr p15, 0, R0, c7, c0, 4) is defined in ARM55 * Architecture reference manual for armv4/5, CP15 implementation is mandatory56 * only forarmv6+.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+. 57 56 */ 58 57 NO_TRACE static inline void cpu_sleep(void) … … 61 60 asm volatile ( "wfe" ); 62 61 #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" ); 64 63 #endif 65 64 } -
kernel/arch/arm32/include/arch/cp15.h
r2921602 red29fe4 171 171 CCSIDR_LINESIZE_MASK = 0x7, 172 172 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)180 173 }; 181 174 CONTROL_REG_GEN_READ(CCSIDR, c0, 1, c0, 0); … … 194 187 CLIDR_UNI_CACHE = 0x4, 195 188 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) 198 190 }; 199 191 CONTROL_REG_GEN_READ(CLIDR, c0, 1, c0, 1); … … 301 293 302 294 /* 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 };314 295 CONTROL_REG_GEN_READ(TTBR0, c2, 0, c0, 0); 315 296 CONTROL_REG_GEN_WRITE(TTBR0, c2, 0, c0, 0); … … 382 363 383 364 CONTROL_REG_GEN_WRITE(DCIMVAC, c7, 0, c6, 1); 384 CONTROL_REG_GEN_WRITE(DCI SW, c7, 0, c6, 2);365 CONTROL_REG_GEN_WRITE(DCIMSW, c7, 0, c6, 2); 385 366 386 367 CONTROL_REG_GEN_WRITE(ATS1CPR, c7, 0, c8, 0); … … 388 369 CONTROL_REG_GEN_WRITE(ATS1CUR, c7, 0, c8, 2); 389 370 CONTROL_REG_GEN_WRITE(ATS1CUW, c7, 0, c8, 3); 390 CONTROL_REG_GEN_WRITE(ATS1 2NSOPR, c7, 0, c8, 4);391 CONTROL_REG_GEN_WRITE(ATS1 2NSOPW, c7, 0, c8, 5);392 CONTROL_REG_GEN_WRITE(ATS1 2NSOUR, c7, 0, c8, 6);393 CONTROL_REG_GEN_WRITE(ATS1 2NSOUW, c7, 0, c8, 7);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); 394 375 395 376 -
kernel/arch/arm32/include/arch/mm/page.h
r2921602 red29fe4 41 41 #include <arch/exception.h> 42 42 #include <arch/barrier.h> 43 #include <arch/cp15.h>44 43 #include <trace.h> 45 44 … … 96 95 /* Set PTE address accessors for each level. */ 97 96 #define SET_PTL0_ADDRESS_ARCH(ptl0) \ 98 set_ptl0_addr((pte_t *) (ptl0))97 (set_ptl0_addr((pte_t *) (ptl0))) 99 98 #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) 101 100 #define SET_PTL2_ADDRESS_ARCH(ptl1, i, a) 102 101 #define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) 103 102 #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) 105 104 106 105 /* Get PTE flags accessors for each level. */ … … 130 129 set_pt_level1_present((pte_t *) (ptl3), (size_t) (i)) 131 130 132 133 #define pt_coherence(page) pt_coherence_m(page, 1)134 135 131 #if defined(PROCESSOR_ARCH_armv6) | defined(PROCESSOR_ARCH_armv7_a) 136 132 #include "page_armv6.h" … … 141 137 #endif 142 138 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 172 139 #endif 173 140 -
kernel/arch/arm32/include/arch/mm/page_armv4.h
r2921602 red29fe4 120 120 #define PTE_DESCRIPTOR_SMALL_PAGE 2 121 121 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 */ 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 128 136 129 137 /** Returns level 0 page table entry flags. … … 215 223 216 224 /* default access permission */ 217 p->access_permission_0 = p->access_permission_1 = 225 p->access_permission_0 = p->access_permission_1 = 218 226 p->access_permission_2 = p->access_permission_3 = 219 227 PTE_AP_USER_NO_KERNEL_RW; … … 221 229 if (flags & PAGE_USER) { 222 230 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 = 225 233 PTE_AP_USER_RO_KERNEL_RW; 226 234 } 227 235 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; 231 239 } 232 240 } -
kernel/arch/arm32/include/arch/mm/page_armv6.h
r2921602 red29fe4 40 40 #error "Do not include arch specific page.h directly use generic page.h instead" 41 41 #endif 42 43 42 44 43 /* Macros for querying the last-level PTE entries. */ … … 126 125 #define PTE_DESCRIPTOR_SMALL_PAGE_NX 3 127 126 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 */ 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 } 161 139 162 140 … … 228 206 p->ns = 0; 229 207 } 230 pt_coherence(p);231 208 } 232 209 … … 255 232 p->descriptor_type = PTE_DESCRIPTOR_SMALL_PAGE_NX; 256 233 } 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; 279 241 280 242 /* Shareable is ignored for devices (non-cacheable), 281 * turn it o fffor normal memory. */282 p->shareable = 0;243 * turn it on for normal memory. */ 244 p->shareable = 1; 283 245 284 246 p->non_global = !(flags & PAGE_GLOBAL); … … 294 256 p->access_permission_1 = PTE_AP1_RO; 295 257 } 296 pt_coherence(p);297 258 } 298 259 … … 303 264 p->should_be_zero_0 = 0; 304 265 p->should_be_zero_1 = 0; 266 write_barrier(); 305 267 p->descriptor_type = PTE_DESCRIPTOR_COARSE_TABLE; 306 pt_coherence(p);307 268 } 308 269 … … 312 273 313 274 p->descriptor_type = PTE_DESCRIPTOR_SMALL_PAGE; 314 pt_coherence(p);315 275 } 316 276 -
kernel/arch/arm32/src/cpu/cpu.c
r2921602 red29fe4 157 157 #endif 158 158 #ifdef PROCESSOR_ARCH_armv7_a 159 /* ICache coherency is elaborate don in barrier.h.159 /* ICache coherency is elaborate on in barrier.h. 160 160 * VIPT and PIPT caches need maintenance only on code modify, 161 161 * so it should be safe for general use. … … 166 166 control_reg |= 167 167 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);171 168 } 172 169 #endif … … 207 204 #ifdef PROCESSOR_ARCH_armv7_a 208 205 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) 211 209 #endif 212 210 return 0; … … 219 217 #ifdef PROCESSOR_ARCH_armv7_a 220 218 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; 223 222 #endif 224 223 return 0; … … 230 229 #ifdef PROCESSOR_ARCH_armv7_a 231 230 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; 234 234 #endif 235 235 return 0; … … 241 241 #ifdef PROCESSOR_ARCH_armv7_a 242 242 const uint32_t val = CLIDR_read(); 243 for (unsigned i = 0; i < 8; ++i) {243 for (unsigned i = 1; i <= 7; ++i) { 244 244 const unsigned ctype = CLIDR_CACHE(i, val); 245 245 switch (ctype) { … … 280 280 const unsigned ways = dcache_ways(i); 281 281 const unsigned sets = dcache_sets(i); 282 const unsigned way_shift = 32- log2(ways);282 const unsigned way_shift = 31 - log2(ways); 283 283 const unsigned set_shift = dcache_linesize_log(i); 284 284 dcache_clean_manual(i, false, ways, sets, way_shift, set_shift); … … 293 293 const unsigned ways = dcache_ways(i); 294 294 const unsigned sets = dcache_sets(i); 295 const unsigned way_shift = 32- log2(ways);295 const unsigned way_shift = 31 - log2(ways); 296 296 const unsigned set_shift = dcache_linesize_log(i); 297 297 dcache_clean_manual(i, true, ways, sets, way_shift, set_shift); -
kernel/arch/arm32/src/mach/beagleboardxm/beagleboardxm.c
r2921602 red29fe4 85 85 static void bb_timer_irq_handler(irq_t *irq) 86 86 { 87 amdm37x_gpt_irq_ack(&beagleboard.timer);88 89 87 /* 90 88 * We are holding a lock which prevents preemption. 91 89 * Release the lock, call clock() and reacquire the lock again. 92 90 */ 91 amdm37x_gpt_irq_ack(&beagleboard.timer); 93 92 spinlock_unlock(&irq->lock); 94 93 clock(); … … 148 147 { 149 148 const unsigned inum = amdm37x_irc_inum_get(beagleboard.irc_addr); 149 amdm37x_irc_irq_ack(beagleboard.irc_addr); 150 150 151 151 irq_t *irq = irq_dispatch_and_lock(inum); … … 159 159 CPU->id, inum); 160 160 } 161 /** amdm37x manual ch. 12.5.2 (p. 2428) places irc ack at the end162 * of ISR. DO this to avoid strange behavior. */163 amdm37x_irc_irq_ack(beagleboard.irc_addr);164 161 } 165 162 -
kernel/arch/arm32/src/mm/tlb.c
r2921602 red29fe4 37 37 #include <arch/mm/asid.h> 38 38 #include <arch/asm.h> 39 #include <arch/cp15.h>40 39 #include <typedefs.h> 41 40 #include <arch/mm/page.h> 42 #include <arch/cache.h>43 41 44 42 /** Invalidate all entries in TLB. … … 48 46 void tlb_invalidate_all(void) 49 47 { 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 ); 63 53 } 64 54 … … 70 60 { 71 61 tlb_invalidate_all(); 72 // TODO: why not TLBIASID_write(asid) ?73 62 } 74 63 … … 76 65 * 77 66 * @param page Virtual adress of the page 78 */ 67 */ 79 68 static inline void invalidate_page(uintptr_t page) 80 69 { 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 ); 95 74 } 96 75 … … 104 83 void tlb_invalidate_pages(asid_t asid __attribute__((unused)), uintptr_t page, size_t cnt) 105 84 { 106 for (unsigned i = 0; i < cnt; i++) 85 unsigned int i; 86 87 for (i = 0; i < cnt; i++) 107 88 invalidate_page(page + i * PAGE_SIZE); 108 89 } -
kernel/genarch/include/genarch/drivers/amdm37x/gpt.h
r2921602 red29fe4 39 39 #include <typedefs.h> 40 40 #include <mm/km.h> 41 #include <time/clock.h>42 41 43 42 /* AMDM37x TRM p. 2740 */ … … 129 128 #define AMDM37x_GPT_TCLR_CE_FLAG (1 << 6) 130 129 #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) 140 134 #define AMDM37x_GPT_TCLR_PT_FLAG (1 << 12) 141 135 #define AMDM37x_GPT_TCLR_CAPT_MODE_FLAG (1 << 13) … … 215 209 timer->regs = (void*) km_map(ioregs, iosize, PAGE_NOT_CACHEABLE); 216 210 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 222 211 /* Set autoreload */ 223 timer->regs->tclr |= AMDM37x_GPT_TCLR_AR_FLAG;212 timer->regs->tclr = AMDM37x_GPT_TCLR_AR_FLAG; 224 213 225 214 timer->special_available = ( … … 227 216 (ioregs == AMDM37x_GPT2_BASE_ADDRESS) || 228 217 (ioregs == AMDM37x_GPT10_BASE_ADDRESS)); 229 /* Select reload value */230 218 timer->regs->tldr = 0xffffffff - (32768 / hz) + 1; 231 /* Set current counter value */232 219 timer->regs->tccr = 0xffffffff - (32768 / hz) + 1; 233 234 220 if (timer->special_available) { 235 /* Set values according to formula (manual p. 2733) */221 /* Set values for according to formula (manual p. 2733) */ 236 222 /* Use temporary variables for easier debugging */ 237 223 const uint32_t tpir = 238 224 ((32768 / hz + 1) * 1000000) - (32768000L * (1000 / hz)); 239 225 const uint32_t tnir = 240 ((32768 / hz) * 1000000) - (32768000 L* (1000 / hz));226 ((32768 / hz) * 1000000) - (32768000 * (1000 / hz)); 241 227 timer->regs->tpir = tpir; 242 228 timer->regs->tnir = tnir; … … 255 241 } 256 242 257 static inline boolamdm37x_gpt_irq_ack(amdm37x_gpt_t* timer)243 static inline void amdm37x_gpt_irq_ack(amdm37x_gpt_t* timer) 258 244 { 259 245 ASSERT(timer); 260 246 ASSERT(timer->regs); 261 247 /* 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; 265 249 } 266 250 -
kernel/genarch/src/mm/page_pt.c
r2921602 red29fe4 112 112 */ 113 113 write_barrier(); 114 SET_PTL2_PRESENT(ptl1, PTL1_INDEX(page)); 114 SET_PTL2_PRESENT(ptl1, PTL1_INDEX(page)); 115 115 } 116 116 … … 180 180 * Destroy the mapping. 181 181 * 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 */ 187 183 memsetb(&ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0); 188 184 -
uspace/drv/infrastructure/rootamdm37x/rootamdm37x.c
r2921602 red29fe4 48 48 49 49 typedef struct { 50 const char *name;51 match_id_t match_id;52 50 hw_resource_list_t hw_resources; 53 51 } rootamdm37x_fun_t; 54 52 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 69 58 70 59 static hw_resource_t ohci_res[] = { … … 99 88 }; 100 89 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 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 }; 150 103 151 104 static hw_resource_list_t *rootamdm37x_get_resources(ddf_fun_t *fnode); … … 161 114 }; 162 115 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 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 170 121 /* 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); 172 123 if (fnode == NULL) 173 124 return ENOMEM; 174 125 175 126 /* 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); 178 128 if (ret != EOK) { 179 129 ddf_fun_destroy(fnode); … … 196 146 ret = ddf_fun_bind(fnode); 197 147 if (ret != EOK) { 198 ddf_msg(LVL_ERROR, "Failed binding function %s.", fun->name);148 ddf_msg(LVL_ERROR, "Failed binding function %s.", name); 199 149 ddf_fun_destroy(fnode); 200 150 return ret; … … 239 189 240 190 /* 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 246 201 return EOK; 247 202 } -
uspace/drv/infrastructure/rootamdm37x/uhh.h
r2921602 red29fe4 85 85 #define UHH_DEBUG_CSR_EHCI_SIMULATION_MODE_FLAG (1 << 6) 86 86 #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) 88 88 #define UHH_DEBUG_CSR_OHCI_CCS1_FLAG (1 << 17) 89 89 #define UHH_DEBUG_CSR_OHCI_CCS2_FLAG (1 << 18) -
uspace/lib/c/include/macros.h
r2921602 red29fe4 40 40 #define abs(a) ((a) >= 0 ? (a) : -(a)) 41 41 42 #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))43 42 44 43 #define KiB2SIZE(kb) ((kb) << 10)
Note:
See TracChangeset
for help on using the changeset viewer.