Changeset b1011dae in mainline
- Timestamp:
- 2013-01-24T21:18:18Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 077b9172
- Parents:
- 5e761f3 (diff), c124dce3 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 10 added
- 25 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
HelenOS.config
r5e761f3 rb1011dae 88 88 89 89 % CPU type 90 @ "cortex_a8" ARM Cortex A-8 91 ! [PLATFORM=arm32&(MACHINE=beagleboardxm|MACHINE=beaglebone)] PROCESSOR (choice) 92 93 % CPU type 94 @ "arm920t" ARM920T 95 ! [PLATFORM=arm32&MACHINE=gta02] PROCESSOR (choice) 96 97 % CPU type 98 @ "arm926ej_s" ARM926EJ-S 99 ! [PLATFORM=arm32&MACHINE=integratorcp] PROCESSOR (choice) 100 101 102 # Add more ARMv4 CPUs 103 % CPU arch 90 104 @ "armv4" ARMv4 91 ! [PLATFORM=arm32&(MACHINE=gta02)] PROCESSOR (choice) 92 93 % CPU type 105 ! [PLATFORM=arm32&(PROCESSOR=arm920t)] PROCESSOR_ARCH (choice) 106 107 # Add more ARMv5 CPUs 108 % CPU arch 94 109 @ "armv5" ARMv5 95 ! [PLATFORM=arm32&MACHINE=integratorcp] PROCESSOR (choice) 96 97 % CPU type 110 ! [PLATFORM=arm32&(PROCESSOR=arm926ej_s)] PROCESSOR_ARCH (choice) 111 112 # Add more ARMv7-A CPUs 113 % CPU arch 98 114 @ "armv7_a" ARMv7-A 99 ! [PLATFORM=arm32&( MACHINE=beagleboardxm|MACHINE=beaglebone)] PROCESSOR(choice)115 ! [PLATFORM=arm32&(PROCESSOR=cortex_a8)] PROCESSOR_ARCH (choice) 100 116 101 117 % RAM disk format … … 349 365 ## armv7 made fpu hardware compulsory 350 366 % FPU support 351 ! [PLATFORM=arm32&PROCESSOR =armv7_a] CONFIG_FPU (y)367 ! [PLATFORM=arm32&PROCESSOR_ARCH=armv7_a] CONFIG_FPU (y) 352 368 353 369 % FPU support -
boot/arch/arm32/Makefile.inc
r5e761f3 rb1011dae 49 49 BITS = 32 50 50 ENDIANESS = LE 51 EXTRA_CFLAGS = -march=$(subst _,-,$(PROCESSOR )) -mno-unaligned-access51 EXTRA_CFLAGS = -march=$(subst _,-,$(PROCESSOR_ARCH)) -mno-unaligned-access 52 52 53 53 ifeq ($(MACHINE), gta02) … … 59 59 RD_DRVS += \ 60 60 infrastructure/rootamdm37x \ 61 fb/amdm37x_dispc \ 61 62 bus/usb/ehci \ 62 63 bus/usb/ohci \ -
boot/arch/arm32/_link.ld.in
r5e761f3 rb1011dae 11 11 . = BOOT_BASE + 0x8000; 12 12 .data : { 13 bdata_start = .; 13 14 *(BOOTPT); /* bootstrap page table */ 14 15 *(BOOTSTACK); /* bootstrap stack */ … … 24 25 [[COMPONENTS]] 25 26 } 26 27 bdata_end = .; 28 27 29 /DISCARD/ : { 28 30 *(.gnu.*); -
boot/arch/arm32/include/mm.h
r5e761f3 rb1011dae 58 58 #define GTA02_IOMEM_END 0x60000000 59 59 60 /** Start of ram memory on BBxM */ 61 #define BBXM_RAM_START 0x80000000 62 /** Start of ram memory on BBxM */ 63 #define BBXM_RAM_END 0xc0000000 64 65 60 66 /* Page table level 0 entry - "section" format is used 61 67 * (one-level paging, 1 MB sized pages). Used only while booting the kernel. -
boot/arch/arm32/src/asm.S
r5e761f3 rb1011dae 61 61 # 62 62 63 #if defined(MACHINE_gta02) 63 # 64 # r0 is kernel entry point 65 # r1 is pointer to the bootinfo structure 64 66 65 67 #define CP15_C1_IC 12 68 #define CP15_C1_BP 11 66 69 #define CP15_C1_DC 2 67 #define CP15_C7_SEG_SHIFT 568 #define CP15_C7_SEG_SIZE 369 #define CP15_C7_IDX_SHIFT 2670 71 70 # Disable I-cache and D-cache before the kernel is started. 72 71 mrc p15, 0, r4, c1, c0, 0 73 72 bic r4, r4, #(1 << CP15_C1_DC) 74 73 bic r4, r4, #(1 << CP15_C1_IC) 74 bic r4, r4, #(1 << CP15_C1_BP) 75 75 mcr p15, 0, r4, c1, c0, 0 76 77 78 #Wait for the operations to complete 79 #ifdef PROCESSOR_ARCH_armv7_a 80 dsb 81 #else 82 #cp15 dsb, r4 is ignored (should be zero) 83 mcr p15, 0, r4, c7, c10, 4 84 #endif 85 86 # Clean ICache and BPredictors, r4 ignored (SBZ) 87 mcr p15, 0, r4, c7, c5, 0 88 nop 89 90 #Wait for the operations to complete 91 #ifdef PROCESSOR_ARCH_armv7_a 92 isb 93 nop 94 #else 95 # cp15 isb 96 mcr p15, 0, r4, c7, c5, 4 97 nop 98 #endif 99 100 #TODO:This should not be necessary 101 102 #if defined(MACHINE_gta02) 103 104 #define CP15_C7_SEG_SHIFT 5 105 #define CP15_C7_SEG_SIZE 3 106 #define CP15_C7_IDX_SHIFT 26 76 107 77 108 # Now clean D-cache to guarantee coherency between I-cache and D-cache. -
boot/arch/arm32/src/main.c
r5e761f3 rb1011dae 50 50 #define TOP2ADDR(top) (((void *) PA2KA(BOOT_OFFSET)) + (top)) 51 51 52 extern void *bdata_start; 53 extern void *bdata_end; 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 71 static inline void clean_dcache_poc(void *address, size_t size) 72 { 73 const uintptr_t addr = (uintptr_t)address; 74 /* DCCMVAC - clean by address to the point of coherence */ 75 for (uintptr_t a = addr; a < addr + size; a += 4) { 76 asm volatile ("mcr p15, 0, %[a], c7, c10, 1\n" :: [a]"r"(a) : ); 77 } 78 } 79 52 80 static bootinfo_t bootinfo; 53 81 54 82 void bootstrap(void) 55 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 91 /* Enable MMU and caches */ 56 92 mmu_start(); 57 93 version_print(); 58 94 95 printf("Boot data: %p -> %p\n", &bdata_start, &bdata_end); 59 96 printf("\nMemory statistics\n"); 60 97 printf(" %p|%p: bootstrap stack\n", &boot_stack, &boot_stack); … … 64 101 (void *) PA2KA(BOOT_OFFSET), (void *) BOOT_OFFSET); 65 102 66 size_t i; 67 for (i = 0; i < COMPONENTS; i++) 103 for (size_t i = 0; i < COMPONENTS; i++) { 68 104 printf(" %p|%p: %s image (%u/%u bytes)\n", components[i].start, 69 105 components[i].start, components[i].name, components[i].inflated, 70 106 components[i].size); 107 invalidate_dcache(components[i].start, components[i].size); 108 } 71 109 72 110 void *dest[COMPONENTS]; … … 74 112 size_t cnt = 0; 75 113 bootinfo.cnt = 0; 76 for ( i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) {114 for (size_t i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) { 77 115 top = ALIGN_UP(top, PAGE_SIZE); 78 116 … … 94 132 printf("\nInflating components ... "); 95 133 96 for ( i = cnt; i > 0; i--) {134 for (size_t i = cnt; i > 0; i--) { 97 135 void *tail = components[i - 1].start + components[i - 1].size; 98 136 if (tail >= dest[i - 1]) { … … 106 144 int err = inflate(components[i - 1].start, components[i - 1].size, 107 145 dest[i - 1], components[i - 1].inflated); 108 109 146 if (err != EOK) { 110 147 printf("\n%s: Inflating error %d\n", components[i - 1].name, err); 111 148 halt(); 112 149 } 150 clean_dcache_poc(dest[i - 1], components[i - 1].inflated); 113 151 } 114 152 115 153 printf(".\n"); 116 154 117 printf("Booting the kernel... \n"); 155 void *kernel_end = (void *) PA2KA(BOOT_OFFSET + components[0].inflated); 156 printf("Booting the kernel...\n"); 118 157 jump_to_kernel((void *) PA2KA(BOOT_OFFSET), &bootinfo); 119 158 } -
boot/arch/arm32/src/mm.c
r5e761f3 rb1011dae 66 66 else 67 67 return 1; 68 #else 68 #elif defined MACHINE_beagleboardxm 69 const unsigned long address = section << PTE_SECTION_SHIFT; 70 if (address >= BBXM_RAM_START && address < BBXM_RAM_END) 71 return 1; 72 #endif 69 73 return 0; 70 #endif71 74 } 72 75 … … 129 132 "mrc p15, 0, r0, c1, c0, 0\n" 130 133 131 #ifdef PROCESSOR_armv7_a 132 /* Mask to enable paging, caching */ 133 "ldr r1, =0x00000005\n" 134 #else 135 #ifdef MACHINE_gta02 136 /* Mask to enable paging (bit 0), 137 D-cache (bit 2), I-cache (bit 12) */ 138 "ldr r1, =0x00001005\n" 139 #else 140 /* Mask to enable paging */ 141 "ldr r1, =0x00000001\n" 142 #endif 143 #endif 134 /* Enable ICache, DCache, BPredictors and MMU, 135 * we disable caches before jumping to kernel 136 * so this is safe for all archs. 137 */ 138 "ldr r1, =0x00001805\n" 139 144 140 "orr r0, r0, r1\n" 145 141 -
kernel/arch/arm32/Makefile.inc
r5e761f3 rb1011dae 33 33 ATSIGN = % 34 34 35 GCC_CFLAGS += -fno-omit-frame-pointer -mapcs-frame -march=$(subst _,-,$(PROCESSOR )) -mno-unaligned-access35 GCC_CFLAGS += -fno-omit-frame-pointer -mapcs-frame -march=$(subst _,-,$(PROCESSOR_ARCH)) -mno-unaligned-access 36 36 37 37 ifeq ($(CONFIG_FPU),y) 38 38 # This is necessary to allow vmsr insn and fpexc manipulation 39 39 # Use vfp32 to allow context save/restore of d16-d31 regs. 40 GCC_CFLAGS += -mfloat-abi=hard -mfpu=vfp340 AFLAGS += -mfloat-abi=hard -mfpu=vfp3 41 41 endif 42 42 … … 70 70 ifeq ($(CONFIG_FPU),y) 71 71 ARCH_SOURCES += arch/$(KARCH)/src/fpu_context.c 72 ARCH_SOURCES += arch/$(KARCH)/src/fpu.s 72 73 endif 73 74 -
kernel/arch/arm32/include/asm.h
r5e761f3 rb1011dae 43 43 #include <trace.h> 44 44 45 /** No such instruction on old ARM to sleep CPU.45 /** CPU specific way to sleep cpu. 46 46 * 47 47 * ARMv7 introduced wait for event and wait for interrupt (wfe/wfi). 48 48 * ARM920T has custom coprocessor action to do the same. See ARM920T Technical 49 49 * Reference Manual ch 4.9 p. 4-23 (103 in the PDF) 50 * ARM926EJ-S uses the same coprocessor instruction as ARM920T. See ARM926EJ-S 51 * chapter 2.3.8 p.2-22 (52 in the PDF) 52 * 53 * @note Although mcr p15, 0, R0, c7, c0, 4 is defined in ARM Architecture 54 * reference manual for armv4/5 CP15 implementation is mandatory only for 55 * armv6+. 50 56 */ 51 57 NO_TRACE static inline void cpu_sleep(void) 52 58 { 53 #ifdef PROCESSOR_ armv7_a54 asm volatile ( "wfe" ::);55 #elif defined( MACHINE_gta02)56 asm volatile ( "mcr p15, 0,R0,c7,c0,4" ::);59 #ifdef PROCESSOR_ARCH_armv7_a 60 asm volatile ( "wfe" ); 61 #elif defined(PROCESSOR_ARCH_armv6) | defined(PROCESSOR_arm926ej_s) | defined(PROCESSOR_arm920t) 62 asm volatile ( "mcr p15, 0, R0, c7, c0, 4" ); 57 63 #endif 58 64 } -
kernel/arch/arm32/include/barrier.h
r5e761f3 rb1011dae 37 37 #define KERN_arm32_BARRIER_H_ 38 38 39 /* 40 * TODO: implement true ARM memory barriers for macros below. 41 */ 39 #ifdef KERNEL 40 #include <arch/cp15.h> 41 #else 42 #include <libarch/cp15.h> 43 #endif 44 42 45 #define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") 43 46 #define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") 44 47 48 #if defined PROCESSOR_ARCH_armv7_a 49 /* ARMv7 uses instructions for memory barriers see ARM Architecture reference 50 * manual for details: 51 * DMB: ch. A8.8.43 page A8-376 52 * DSB: ch. A8.8.44 page A8-378 53 * See ch. A3.8.3 page A3-148 for details about memory barrier implementation 54 * and functionality on armv7 architecture. 55 */ 56 #define memory_barrier() asm volatile ("dmb" ::: "memory") 57 #define read_barrier() asm volatile ("dsb" ::: "memory") 58 #define write_barrier() asm volatile ("dsb st" ::: "memory") 59 #define inst_barrier() asm volatile ("isb" ::: "memory") 60 #elif defined PROCESSOR_ARCH_armv6 | defined KERNEL 61 /* 62 * ARMv6 introduced user access of the following commands: 63 * - Prefetch flush 64 * - Data synchronization barrier 65 * - Data memory barrier 66 * - Clean and prefetch range operations. 67 * ARM Architecture Reference Manual version I ch. B.3.2.1 p. B3-4 68 */ 69 /* ARMv6- use system control coprocessor (CP15) for memory barrier instructions. 70 * Although at least mcr p15, 0, r0, c7, c10, 4 is mentioned in earlier archs, 71 * CP15 implementation is mandatory only for armv6+. 72 */ 73 #define memory_barrier() CP15DMB_write(0) 74 #define read_barrier() CP15DSB_write(0) 75 #define write_barrier() read_barrier() 76 #define inst_barrier() CP15ISB_write(0) 77 #else 78 /* Older manuals mention syscalls as a way to implement cache coherency and 79 * barriers. See for example ARM Architecture Reference Manual Version D 80 * chapter 2.7.4 Prefetching and self-modifying code (p. A2-28) 81 */ 82 // TODO implement on per PROCESSOR basis or via syscalls 45 83 #define memory_barrier() asm volatile ("" ::: "memory") 46 84 #define read_barrier() asm volatile ("" ::: "memory") 47 85 #define write_barrier() asm volatile ("" ::: "memory") 86 #define inst_barrier() asm volatile ("" ::: "memory") 87 #endif 48 88 49 89 /* … … 62 102 */ 63 103 64 /* Available on both all supported arms, 104 #if defined PROCESSOR_ARCH_armv7_a | defined PROCESSOR_ARCH_armv6 | defined KERNEL 105 /* Available on all supported arms, 65 106 * invalidates entire ICache so the written value does not matter. */ 66 #define smc_coherence(a) asm volatile ( "mcr p15, 0, r0, c7, c5, 0") 67 #define smc_coherence_block(a, l) smc_coherence(a) 107 //TODO might be PL1 only on armv5- 108 #define smc_coherence(a) \ 109 do { \ 110 DCCMVAU_write((uint32_t)(a)); /* Flush changed memory */\ 111 write_barrier(); /* Wait for completion */\ 112 ICIALLU_write(0); /* Flush ICache */\ 113 inst_barrier(); /* Wait for Inst refetch */\ 114 } while (0) 115 /* @note: Cache type register is not available in uspace. We would need 116 * to export the cache line value, or use syscall for uspace smc_coherence */ 117 #define smc_coherence_block(a, l) \ 118 do { \ 119 for (uintptr_t addr = (uintptr_t)a; addr < (uintptr_t)a + l; addr += 4)\ 120 smc_coherence(addr); \ 121 } while (0) 122 #else 123 #define smc_coherence(a) 124 #define smc_coherence_block(a, l) 125 #endif 68 126 69 127 -
kernel/arch/arm32/include/cpu.h
r5e761f3 rb1011dae 40 40 #include <arch/asm.h> 41 41 42 enum { 43 ARM_MAX_CACHE_LEVELS = 7, 44 }; 42 45 43 46 /** Struct representing ARM CPU identification. */ … … 57 60 /** Revision number. */ 58 61 uint32_t rev_num; 62 63 struct { 64 unsigned ways; 65 unsigned sets; 66 unsigned line_size; 67 unsigned way_shift; 68 unsigned set_shift; 69 } dcache[ARM_MAX_CACHE_LEVELS]; 70 unsigned dcache_levels; 59 71 } cpu_arch_t; 60 72 -
kernel/arch/arm32/include/cycle.h
r5e761f3 rb1011dae 38 38 39 39 #include <trace.h> 40 #include <arch/cp15.h> 40 41 41 42 /** Return count of CPU cycles. … … 48 49 NO_TRACE static inline uint64_t get_cycle(void) 49 50 { 51 #ifdef PROCESSOR_ARCH_armv7_a 52 if ((ID_PFR1_read() & ID_PFR1_GEN_TIMER_EXT_MASK) == 53 ID_PFR1_GEN_TIMER_EXT) { 54 uint32_t low = 0, high = 0; 55 asm volatile( "MRRC p15, 0, %[low], %[high], c14": [low]"=r"(low), [high]"=r"(high)); 56 return ((uint64_t)high << 32) | low; 57 } else { 58 return (uint64_t)PMCCNTR_read() * 64; 59 } 60 #endif 50 61 return 0; 51 62 } -
kernel/arch/arm32/include/mm/frame.h
r5e761f3 rb1011dae 47 47 48 48 #ifdef MACHINE_gta02 49 50 #define PHYSMEM_START_ADDR 0x30008000 49 51 #define BOOT_PAGE_TABLE_ADDRESS 0x30010000 52 50 53 #elif defined MACHINE_beagleboardxm 54 55 #define PHYSMEM_START_ADDR 0x80000000 51 56 #define BOOT_PAGE_TABLE_ADDRESS 0x80008000 57 52 58 #elif defined MACHINE_beaglebone 59 60 #define PHYSMEM_START_ADDR 0x80000000 53 61 #define BOOT_PAGE_TABLE_ADDRESS 0x80008000 62 54 63 #else 64 65 #define PHYSMEM_START_ADDR 0x00000000 55 66 #define BOOT_PAGE_TABLE_ADDRESS 0x00008000 67 56 68 #endif 57 69 58 70 #define BOOT_PAGE_TABLE_START_FRAME (BOOT_PAGE_TABLE_ADDRESS >> FRAME_WIDTH) 59 71 #define BOOT_PAGE_TABLE_SIZE_IN_FRAMES (BOOT_PAGE_TABLE_SIZE >> FRAME_WIDTH) 60 61 #ifdef MACHINE_gta0262 #define PHYSMEM_START_ADDR 0x3000800063 #elif defined MACHINE_beagleboardxm64 #define PHYSMEM_START_ADDR 0x8000000065 #elif defined MACHINE_beaglebone66 #define PHYSMEM_START_ADDR 0x8000000067 #else68 #define PHYSMEM_START_ADDR 0x0000000069 #endif70 72 71 73 extern void frame_low_arch_init(void); -
kernel/arch/arm32/include/mm/page.h
r5e761f3 rb1011dae 129 129 set_pt_level1_present((pte_t *) (ptl3), (size_t) (i)) 130 130 131 #if defined(PROCESSOR_ armv6) | defined(PROCESSOR_armv7_a)131 #if defined(PROCESSOR_ARCH_armv6) | defined(PROCESSOR_ARCH_armv7_a) 132 132 #include "page_armv6.h" 133 #elif defined(PROCESSOR_ armv4) | defined(PROCESSOR_armv5)133 #elif defined(PROCESSOR_ARCH_armv4) | defined(PROCESSOR_ARCH_armv5) 134 134 #include "page_armv4.h" 135 135 #else -
kernel/arch/arm32/include/mm/page_fault.h
r5e761f3 rb1011dae 42 42 /** Decribes CP15 "fault status register" (FSR). 43 43 * 44 * See ARM Architecture Reference Manual ch. B4.9.6 (pdf p.743). 44 * "VMSAv6 added a fifth fault status bit (bit[10]) to both the IFSR and DFSR. 45 * It is IMPLEMENTATION DEFINED how this bit is encoded in earlier versions of 46 * the architecture. A write flag (bit[11] of the DFSR) has also been 47 * introduced." 48 * ARM Architecture Reference Manual version i ch. B4.6 (PDF p. 719) 49 * 50 * See ARM Architecture Reference Manual ch. B4.9.6 (pdf p.743). for FSR info 45 51 */ 46 52 typedef union { -
kernel/arch/arm32/include/regutils.h
r5e761f3 rb1011dae 41 41 #define STATUS_REG_MODE_MASK 0x1f 42 42 43 /* COntrol register bit values see ch. B4.1.130 of ARM Architecture Reference44 * Manual ARMv7-A and ARMv7-R edition, page 1687 */45 #define CP15_R1_MMU_EN (1 << 0)46 #define CP15_R1_ALIGN_CHECK_EN (1 << 1) /* Allow alignemnt check */47 #define CP15_R1_CACHE_EN (1 << 2)48 #define CP15_R1_CP15_BARRIER_EN (1 << 5)49 #define CP15_R1_B_EN (1 << 7) /* ARMv6- only big endian switch */50 #define CP15_R1_SWAP_EN (1 << 10)51 #define CP15_R1_BRANCH_PREDICT_EN (1 << 11)52 #define CP15_R1_INST_CACHE_EN (1 << 12)53 #define CP15_R1_HIGH_VECTORS_EN (1 << 13)54 #define CP15_R1_ROUND_ROBIN_EN (1 << 14)55 #define CP15_R1_HW_ACCESS_FLAG_EN (1 << 17)56 #define CP15_R1_WRITE_XN_EN (1 << 19) /* Only if virt. supported */57 #define CP15_R1_USPCE_WRITE_XN_EN (1 << 20) /* Only if virt. supported */58 #define CP15_R1_FAST_IRQ_EN (1 << 21) /* Disbale impl.specific features */59 #define CP15_R1_UNALIGNED_EN (1 << 22) /* Must be 1 on armv7 */60 #define CP15_R1_IRQ_VECTORS_EN (1 << 24)61 #define CP15_R1_BIG_ENDIAN_EXC (1 << 25)62 #define CP15_R1_NMFI_EN (1 << 27)63 #define CP15_R1_TEX_REMAP_EN (1 << 28)64 #define CP15_R1_ACCESS_FLAG_EN (1 << 29)65 #define CP15_R1_THUMB_EXC_EN (1 << 30)66 67 43 /* ARM Processor Operation Modes */ 68 #define USER_MODE 0x10 69 #define FIQ_MODE 0x11 70 #define IRQ_MODE 0x12 71 #define SUPERVISOR_MODE 0x13 72 #define ABORT_MODE 0x17 73 #define UNDEFINED_MODE 0x1b 74 #define SYSTEM_MODE 0x1f 75 44 enum { 45 USER_MODE = 0x10, 46 FIQ_MODE = 0x11, 47 IRQ_MODE = 0x12, 48 SUPERVISOR_MODE = 0x13, 49 MONITOR_MODE = 0x16, 50 ABORT_MODE = 0x17, 51 HYPERVISOR_MODE = 0x1a, 52 UNDEFINED_MODE = 0x1b, 53 SYSTEM_MODE = 0x1f, 54 MODE_MASK = 0x1f, 55 }; 76 56 /* [CS]PRS manipulation macros */ 77 57 #define GEN_STATUS_READ(nm, reg) \ -
kernel/arch/arm32/src/cpu/cpu.c
r5e761f3 rb1011dae 34 34 */ 35 35 36 #include <arch/cache.h> 36 37 #include <arch/cpu.h> 38 #include <arch/cp15.h> 37 39 #include <cpu.h> 38 40 #include <arch.h> 39 41 #include <print.h> 42 43 static inline unsigned log2(unsigned val) 44 { 45 unsigned log = 0; 46 --val; 47 while (val) { 48 ++log; 49 val >>= 1; 50 } 51 return log; 52 } 53 54 static unsigned dcache_ways(unsigned level); 55 static unsigned dcache_sets(unsigned level); 56 static unsigned dcache_linesize_log(unsigned level); 57 40 58 41 59 /** Implementers (vendor) names */ … … 81 99 static void arch_cpu_identify(cpu_arch_t *cpu) 82 100 { 83 uint32_t ident; 84 asm volatile ( 85 "mrc p15, 0, %[ident], c0, c0, 0\n" 86 : [ident] "=r" (ident) 87 ); 88 89 cpu->imp_num = ident >> 24; 90 cpu->variant_num = (ident << 8) >> 28; 91 cpu->arch_num = (ident << 12) >> 28; 92 cpu->prim_part_num = (ident << 16) >> 20; 93 cpu->rev_num = (ident << 28) >> 28; 101 const uint32_t ident = MIDR_read(); 102 103 cpu->imp_num = (ident >> MIDR_IMPLEMENTER_SHIFT) & MIDR_IMPLEMENTER_MASK; 104 cpu->variant_num = (ident >> MIDR_VARIANT_SHIFT) & MIDR_VARIANT_MASK; 105 cpu->arch_num = (ident >> MIDR_ARCHITECTURE_SHIFT) & MIDR_ARCHITECTURE_MASK; 106 cpu->prim_part_num = (ident >> MIDR_PART_NUMBER_SHIFT) & MIDR_PART_NUMBER_MASK; 107 cpu->rev_num = (ident >> MIDR_REVISION_SHIFT) & MIDR_REVISION_MASK; 108 94 109 // TODO CPUs with arch_num == 0xf use CPUID scheme for identification 110 cpu->dcache_levels = dcache_levels(); 111 112 for (unsigned i = 0; i < cpu->dcache_levels; ++i) { 113 cpu->dcache[i].ways = dcache_ways(i); 114 cpu->dcache[i].sets = dcache_sets(i); 115 cpu->dcache[i].way_shift = 31 - log2(cpu->dcache[i].ways); 116 cpu->dcache[i].set_shift = dcache_linesize_log(i); 117 cpu->dcache[i].line_size = 1 << dcache_linesize_log(i); 118 printf("Found DCache L%u: %u-way, %u sets, %u byte lines " 119 "(shifts: w%u, s%u)\n", i + 1, cpu->dcache[i].ways, 120 cpu->dcache[i].sets, cpu->dcache[i].line_size, 121 cpu->dcache[i].way_shift, cpu->dcache[i].set_shift); 122 } 95 123 } 96 124 … … 98 126 void cpu_arch_init(void) 99 127 { 100 #if defined(PROCESSOR_armv7_a) | defined(PROCESSOR_armv6) 101 uint32_t control_reg = 0; 102 asm volatile ( 103 "mrc p15, 0, %[control_reg], c1, c0" 104 : [control_reg] "=r" (control_reg) 105 ); 128 uint32_t control_reg = SCTLR_read(); 106 129 107 /* Turn off tex remap, RAZ ignores writes prior to armv7 */ 108 control_reg &= ~CP15_R1_TEX_REMAP_EN; 109 /* Turn off accessed flag, RAZ ignores writes prior to armv7 */ 110 control_reg &= ~(CP15_R1_ACCESS_FLAG_EN | CP15_R1_HW_ACCESS_FLAG_EN); 111 /* Enable unaligned access, RAZ ignores writes prior to armv6 112 * switchable on armv6, RAO ignores writes on armv7, 130 /* Turn off tex remap, RAZ/WI prior to armv7 */ 131 control_reg &= ~SCTLR_TEX_REMAP_EN_FLAG; 132 /* Turn off accessed flag, RAZ/WI prior to armv7 */ 133 control_reg &= ~(SCTLR_ACCESS_FLAG_EN_FLAG | SCTLR_HW_ACCESS_FLAG_EN_FLAG); 134 135 /* Unaligned access is supported on armv6+ */ 136 #if defined(PROCESSOR_ARCH_armv7_a) | defined(PROCESSOR_ARCH_armv6) 137 /* Enable unaligned access, RAZ/WI prior to armv6 138 * switchable on armv6, RAO/WI writes on armv7, 113 139 * see ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition 114 140 * L.3.1 (p. 2456) */ 115 control_reg |= CP15_R1_UNALIGNED_EN;141 control_reg |= SCTLR_UNALIGNED_EN_FLAG; 116 142 /* Disable alignment checks, this turns unaligned access to undefined, 117 143 * unless U bit is set. */ 118 control_reg &= ~ CP15_R1_ALIGN_CHECK_EN;144 control_reg &= ~SCTLR_ALIGN_CHECK_EN_FLAG; 119 145 /* Enable caching, On arm prior to armv7 there is only one level 120 146 * of caches. Data cache is coherent. … … 124 150 * ARM Architecture Reference Manual ARMv7-A and ARMv7-R Edition 125 151 * B3.11.1 (p. 1383) 126 * ICache coherency is elaborate on in barrier.h. 127 * We are safe to turn these on. 152 * We are safe to turn this on. For arm v6 see ch L.6.2 (p. 2469) 153 * L2 Cache for armv7 is enabled by default (i.e. controlled by 154 * this flag). 128 155 */ 129 control_reg |= CP15_R1_CACHE_EN | CP15_R1_INST_CACHE_EN; 130 131 asm volatile ( 132 "mcr p15, 0, %[control_reg], c1, c0" 133 :: [control_reg] "r" (control_reg) 134 ); 135 #endif 156 control_reg |= SCTLR_CACHE_EN_FLAG; 157 #endif 158 #ifdef PROCESSOR_ARCH_armv7_a 159 /* ICache coherency is elaborate on in barrier.h. 160 * VIPT and PIPT caches need maintenance only on code modify, 161 * so it should be safe for general use. 162 * Enable branch predictors too as they follow the same rules 163 * as ICache and they can be flushed together 164 */ 165 if ((CTR_read() & CTR_L1I_POLICY_MASK) != CTR_L1I_POLICY_AIVIVT) { 166 control_reg |= 167 SCTLR_INST_CACHE_EN_FLAG | SCTLR_BRANCH_PREDICT_EN_FLAG; 168 } 169 #endif 170 SCTLR_write(control_reg); 171 136 172 #ifdef CONFIG_FPU 137 173 fpu_setup(); 174 #endif 175 176 #ifdef PROCESSOR_ARCH_armv7_a 177 if ((ID_PFR1_read() & ID_PFR1_GEN_TIMER_EXT_MASK) != 178 ID_PFR1_GEN_TIMER_EXT) { 179 PMCR_write(PMCR_read() | PMCR_E_FLAG | PMCR_D_FLAG); 180 PMCNTENSET_write(PMCNTENSET_CYCLE_COUNTER_EN_FLAG); 181 } 138 182 #endif 139 183 } … … 155 199 } 156 200 201 /** See chapter B4.1.19 of ARM Architecture Reference Manual */ 202 static unsigned dcache_linesize_log(unsigned level) 203 { 204 #ifdef PROCESSOR_ARCH_armv7_a 205 CSSELR_write((level & CCSELR_LEVEL_MASK) << CCSELR_LEVEL_SHIFT); 206 const unsigned ls_log = 2 + 207 ((CCSIDR_read() >> CCSIDR_LINESIZE_SHIFT) & CCSIDR_LINESIZE_MASK); 208 return ls_log + 2; //return log2(bytes) 209 #endif 210 return 0; 211 212 } 213 214 /** See chapter B4.1.19 of ARM Architecture Reference Manual */ 215 static unsigned dcache_ways(unsigned level) 216 { 217 #ifdef PROCESSOR_ARCH_armv7_a 218 CSSELR_write((level & CCSELR_LEVEL_MASK) << CCSELR_LEVEL_SHIFT); 219 const unsigned ways = 1 + 220 ((CCSIDR_read() >> CCSIDR_ASSOC_SHIFT) & CCSIDR_ASSOC_MASK); 221 return ways; 222 #endif 223 return 0; 224 } 225 226 /** See chapter B4.1.19 of ARM Architecture Reference Manual */ 227 static unsigned dcache_sets(unsigned level) 228 { 229 #ifdef PROCESSOR_ARCH_armv7_a 230 CSSELR_write((level & CCSELR_LEVEL_MASK) << CCSELR_LEVEL_SHIFT); 231 const unsigned sets = 1 + 232 ((CCSIDR_read() >> CCSIDR_NUMSETS_SHIFT) & CCSIDR_NUMSETS_MASK); 233 return sets; 234 #endif 235 return 0; 236 } 237 238 unsigned dcache_levels(void) 239 { 240 unsigned levels = 0; 241 #ifdef PROCESSOR_ARCH_armv7_a 242 const uint32_t val = CLIDR_read(); 243 for (unsigned i = 1; i <= 7; ++i) { 244 const unsigned ctype = CLIDR_CACHE(i, val); 245 switch (ctype) { 246 case CLIDR_DCACHE_ONLY: 247 case CLIDR_SEP_CACHE: 248 case CLIDR_UNI_CACHE: 249 ++levels; 250 default: 251 (void)0; 252 } 253 } 254 #endif 255 return levels; 256 } 257 258 static void dcache_clean_manual(unsigned level, bool invalidate, 259 unsigned ways, unsigned sets, unsigned way_shift, unsigned set_shift) 260 { 261 262 for (unsigned i = 0; i < ways; ++i) { 263 for (unsigned j = 0; j < sets; ++j) { 264 const uint32_t val = 265 ((level & 0x7) << 1) | 266 (j << set_shift) | (i << way_shift); 267 if (invalidate) 268 DCCISW_write(val); 269 else 270 DCCSW_write(val); 271 } 272 } 273 } 274 275 void dcache_flush(void) 276 { 277 /* See ARM Architecture Reference Manual ch. B4.2.1 p. B4-1724 */ 278 const unsigned levels = dcache_levels(); 279 for (unsigned i = 0; i < levels; ++i) { 280 const unsigned ways = dcache_ways(i); 281 const unsigned sets = dcache_sets(i); 282 const unsigned way_shift = 31 - log2(ways); 283 const unsigned set_shift = dcache_linesize_log(i); 284 dcache_clean_manual(i, false, ways, sets, way_shift, set_shift); 285 } 286 } 287 288 void dcache_flush_invalidate(void) 289 { 290 /* See ARM Architecture Reference Manual ch. B4.2.1 p. B4-1724 */ 291 const unsigned levels = dcache_levels(); 292 for (unsigned i = 0; i < levels; ++i) { 293 const unsigned ways = dcache_ways(i); 294 const unsigned sets = dcache_sets(i); 295 const unsigned way_shift = 31 - log2(ways); 296 const unsigned set_shift = dcache_linesize_log(i); 297 dcache_clean_manual(i, true, ways, sets, way_shift, set_shift); 298 } 299 } 300 301 302 void cpu_dcache_flush(void) 303 { 304 for (unsigned i = 0; i < CPU->arch.dcache_levels; ++i) 305 dcache_clean_manual(i, false, 306 CPU->arch.dcache[i].ways, CPU->arch.dcache[i].sets, 307 CPU->arch.dcache[i].way_shift, CPU->arch.dcache[i].set_shift); 308 } 309 310 void cpu_dcache_flush_invalidate(void) 311 { 312 const unsigned levels = dcache_levels(); 313 for (unsigned i = 0; i < levels; ++i) 314 dcache_clean_manual(i, true, 315 CPU->arch.dcache[i].ways, CPU->arch.dcache[i].sets, 316 CPU->arch.dcache[i].way_shift, CPU->arch.dcache[i].set_shift); 317 } 318 319 void icache_invalidate(void) 320 { 321 ICIALLU_write(0); 322 } 323 157 324 /** @} 158 325 */ -
kernel/arch/arm32/src/exception.c
r5e761f3 rb1011dae 39 39 #include <interrupt.h> 40 40 #include <arch/mm/page_fault.h> 41 #include <arch/cp15.h> 41 42 #include <arch/barrier.h> 42 43 #include <print.h> … … 73 74 /* make it LDR instruction and store at exception vector */ 74 75 *vector = handler_address_ptr | LDR_OPCODE; 75 smc_coherence( *vector);76 smc_coherence(vector); 76 77 77 78 /* store handler's address */ … … 136 137 static void high_vectors(void) 137 138 { 138 uint32_t control_reg = 0; 139 asm volatile ( 140 "mrc p15, 0, %[control_reg], c1, c0" 141 : [control_reg] "=r" (control_reg) 142 ); 139 uint32_t control_reg = SCTLR_read(); 143 140 144 141 /* switch on the high vectors bit */ 145 control_reg |= CP15_R1_HIGH_VECTORS_EN; 146 147 asm volatile ( 148 "mcr p15, 0, %[control_reg], c1, c0" 149 :: [control_reg] "r" (control_reg) 150 ); 142 control_reg |= SCTLR_HIGH_VECTORS_EN_FLAG; 143 144 SCTLR_write(control_reg); 151 145 } 152 146 #endif -
kernel/arch/arm32/src/fpu_context.c
r5e761f3 rb1011dae 37 37 #include <arch.h> 38 38 #include <arch/types.h> 39 #include <arch/security_ext.h> 40 #include <arch/cp15.h> 39 41 #include <cpu.h> 40 42 … … 55 57 }; 56 58 59 extern uint32_t fpsid_read(void); 60 extern uint32_t mvfr0_read(void); 61 57 62 enum { 58 63 FPEXC_EX_FLAG = (1 << 31), 59 64 FPEXC_ENABLED_FLAG = (1 << 30), 60 65 }; 66 extern uint32_t fpexc_read(void); 67 extern void fpexc_write(uint32_t); 61 68 62 69 /** ARM Architecture Reference Manual ch. B4.1.58, p. B$-1551 */ … … 94 101 FPSCR_EN_ALL = FPSCR_DENORMAL_EN_FLAG | FPSCR_INEXACT_EN_FLAG | FPSCR_UNDERFLOW_EN_FLAG | FPSCR_OVERFLOW_EN_FLAG | FPSCR_ZERO_DIV_EN_FLAG | FPSCR_INVALID_OP_EN_FLAG, 95 102 }; 96 97 static inline uint32_t fpscr_read() 98 { 99 uint32_t reg; 100 asm volatile ( 101 "vmrs %0, fpscr\n" 102 :"=r" (reg):: 103 ); 104 return reg; 105 } 106 107 static inline void fpscr_write(uint32_t val) 108 { 109 asm volatile ( 110 "vmsr fpscr, %0\n" 111 ::"r" (val): 112 ); 113 } 114 115 static inline uint32_t fpexc_read() 116 { 117 uint32_t reg; 118 asm volatile ( 119 "vmrs %0, fpexc\n" 120 :"=r" (reg):: 121 ); 122 return reg; 123 } 124 125 static inline void fpexc_write(uint32_t val) 126 { 127 asm volatile ( 128 "vmsr fpexc, %0\n" 129 ::"r" (val): 130 ); 131 } 103 extern uint32_t fpscr_read(void); 104 extern void fpscr_write(uint32_t); 105 106 extern void fpu_context_save_s32(fpu_context_t *); 107 extern void fpu_context_restore_s32(fpu_context_t *); 108 extern void fpu_context_save_d16(fpu_context_t *); 109 extern void fpu_context_restore_d16(fpu_context_t *); 110 extern void fpu_context_save_d32(fpu_context_t *); 111 extern void fpu_context_restore_d32(fpu_context_t *); 132 112 133 113 static void (*save_context)(fpu_context_t *ctx); 134 114 static void (*restore_context)(fpu_context_t *ctx); 135 115 136 /** Saves 32 single precision fpu registers. 137 * @param ctx FPU context area. 138 * Used by VFPv1 139 */ 140 static void fpu_context_save_s32(fpu_context_t *ctx) 141 { 142 asm volatile ( 143 "vmrs r1, fpexc\n" 144 "vmrs r2, fpscr\n" 145 "stmia %0!, {r1, r2}\n" 146 "vstmia %0!, {s0-s31}\n" 147 ::"r" (ctx): "r1","r2","memory" 148 ); 149 } 150 151 /** Restores 32 single precision fpu registers. 152 * @param ctx FPU context area. 153 * Used by VFPv1 154 */ 155 static void fpu_context_restore_s32(fpu_context_t *ctx) 156 { 157 asm volatile ( 158 "ldmia %0!, {r1, r2}\n" 159 "vmsr fpexc, r1\n" 160 "vmsr fpscr, r2\n" 161 "vldmia %0!, {s0-s31}\n" 162 ::"r" (ctx): "r1","r2" 163 ); 164 } 165 166 /** Saves 16 double precision fpu registers. 167 * @param ctx FPU context area. 168 * Used by VFPv2, VFPv3-d16, and VFPv4-d16. 169 */ 170 static void fpu_context_save_d16(fpu_context_t *ctx) 171 { 172 asm volatile ( 173 "vmrs r1, fpexc\n" 174 "vmrs r2, fpscr\n" 175 "stmia %0!, {r1, r2}\n" 176 "vstmia %0!, {d0-d15}\n" 177 ::"r" (ctx): "r1","r2","memory" 178 ); 179 } 180 181 /** Restores 16 double precision fpu registers. 182 * @param ctx FPU context area. 183 * Used by VFPv2, VFPv3-d16, and VFPv4-d16. 184 */ 185 static void fpu_context_restore_d16(fpu_context_t *ctx) 186 { 187 asm volatile ( 188 "ldmia %0!, {r1, r2}\n" 189 "vmsr fpexc, r1\n" 190 "vmsr fpscr, r2\n" 191 "vldmia %0!, {d0-d15}\n" 192 ::"r" (ctx): "r1","r2" 193 ); 194 } 195 196 /** Saves 32 double precision fpu registers. 197 * @param ctx FPU context area. 198 * Used by VFPv3-d32, VFPv4-d32, and advanced SIMD. 199 */ 200 static void fpu_context_save_d32(fpu_context_t *ctx) 201 { 202 asm volatile ( 203 "vmrs r1, fpexc\n" 204 "stmia %0!, {r1}\n" 205 "vmrs r1, fpscr\n" 206 "stmia %0!, {r1}\n" 207 "vstmia %0!, {d0-d15}\n" 208 "vstmia %0!, {d16-d31}\n" 209 ::"r" (ctx): "r1","memory" 210 ); 211 } 212 213 /** Restores 32 double precision fpu registers. 214 * @param ctx FPU context area. 215 * Used by VFPv3-d32, VFPv4-d32, and advanced SIMD. 216 */ 217 static void fpu_context_restore_d32(fpu_context_t *ctx) 218 { 219 asm volatile ( 220 "ldmia %0!, {r1}\n" 221 "vmsr fpexc, r1\n" 222 "ldmia %0!, {r1}\n" 223 "vmsr fpscr, r1\n" 224 "vldmia %0!, {d0-d15}\n" 225 "vldmia %0!, {d16-d31}\n" 226 ::"r" (ctx): "r1" 227 ); 228 } 116 static int fpu_have_coprocessor_access() 117 { 118 /* The register containing the information (CPACR) is not available on armv6- 119 * rely on user decision to use CONFIG_FPU. 120 */ 121 #ifdef PROCESSOR_ARC_armv7_a 122 const uint32_t cpacr = CPACR_read(); 123 /* FPU needs access to coprocessor 10 and 11. 124 * Moreover they need to have same access enabledd */ 125 if (((cpacr & CPACR_CP_MASK(10)) != CPACR_CP_FULL_ACCESS(10)) && 126 ((cpacr & CPACR_CP_MASK(11)) != CPACR_CP_FULL_ACCESS(11))) { 127 printf("No access to CP10 and CP11: %" PRIx32 "\n", cpacr); 128 return 0; 129 } 130 #endif 131 return 1; 132 } 133 134 /** Enable coprocessor access. Turn both non-secure mode bit and generic access. 135 * Cortex A8 Manual says: 136 * "You must execute an Instruction Memory Barrier (IMB) sequence immediately 137 * after an update of the Coprocessor Access Control Register, see Memory 138 * Barriers in the ARM Architecture Reference Manual. You must not attempt to 139 * execute any instructions that are affected by the change of access rights 140 * between the IMB sequence and the register update." 141 * Cortex a8 TRM ch. 3.2.27. c1, Coprocessor Access Control Register 142 * 143 * @note do we need to call secure monitor here? 144 */ 145 static void fpu_enable_coprocessor_access() 146 { 147 /* The register containing the information (CPACR) is not available on armv6- 148 * rely on user decision to use CONFIG_FPU. 149 */ 150 #ifdef PROCESSOR_ARCH_armv7_a 151 /* Allow coprocessor access */ 152 uint32_t cpacr = CPACR_read(); 153 /* FPU needs access to coprocessor 10 and 11. 154 * Moreover, they need to have same access enabled */ 155 cpacr &= ~(CPACR_CP_MASK(10) | CPACR_CP_MASK(11)); 156 cpacr |= (CPACR_CP_FULL_ACCESS(10) | CPACR_CP_FULL_ACCESS(11)); 157 CPACR_write(cpacr); 158 #endif 159 } 160 229 161 230 162 void fpu_init(void) 231 163 { 164 /* Check if we have access */ 165 if (!fpu_have_coprocessor_access()) 166 return; 167 232 168 /* Clear all fpu flags */ 233 169 fpexc_write(0); … … 241 177 void fpu_setup(void) 242 178 { 243 uint32_t fpsid = 0; 244 asm volatile ( 245 "vmrs %0, fpsid\n" 246 :"=r"(fpsid):: 247 ); 179 /* Enable coprocessor access*/ 180 fpu_enable_coprocessor_access(); 181 182 /* Check if we succeeded */ 183 if (!fpu_have_coprocessor_access()) 184 return; 185 186 const uint32_t fpsid = fpsid_read(); 248 187 if (fpsid & FPSID_SW_ONLY_FLAG) { 249 188 printf("No FPU avaiable\n"); … … 265 204 case FPU_VFPv3_NO_COMMON: 266 205 case FPU_VFPv3_COMMONv3: { 267 uint32_t mvfr0 = 0; 268 asm volatile ( 269 "vmrs %0,mvfr0\n" 270 :"=r"(mvfr0):: 271 ); 206 const uint32_t mvfr0 = mvfr0_read(); 272 207 /* See page B4-1637 */ 273 208 if ((mvfr0 & 0xf) == 0x1) { … … 288 223 bool handle_if_fpu_exception(void) 289 224 { 225 /* Check if we have access */ 226 if (!fpu_have_coprocessor_access()) 227 return false; 228 290 229 const uint32_t fpexc = fpexc_read(); 291 230 if (fpexc & FPEXC_ENABLED_FLAG) { … … 305 244 void fpu_enable(void) 306 245 { 246 /* Check if we have access */ 247 if (!fpu_have_coprocessor_access()) 248 return; 307 249 /* Enable FPU instructions */ 308 250 fpexc_write(fpexc_read() | FPEXC_ENABLED_FLAG); … … 311 253 void fpu_disable(void) 312 254 { 255 /* Check if we have access */ 256 if (!fpu_have_coprocessor_access()) 257 return; 313 258 /* Disable FPU instructions */ 314 259 fpexc_write(fpexc_read() & ~FPEXC_ENABLED_FLAG); … … 317 262 void fpu_context_save(fpu_context_t *ctx) 318 263 { 264 /* This is only necessary if we enable fpu exceptions. */ 265 #if 0 319 266 const uint32_t fpexc = fpexc_read(); 320 267 … … 323 270 //TODO implement common subarch context saving 324 271 } 272 #endif 325 273 if (save_context) 326 274 save_context(ctx); -
kernel/arch/arm32/src/mach/beagleboardxm/beagleboardxm.c
r5e761f3 rb1011dae 38 38 #include <genarch/drivers/amdm37x/irc.h> 39 39 #include <genarch/drivers/amdm37x/gpt.h> 40 #include <genarch/drivers/amdm37x/dispc.h>41 40 #include <genarch/fb/fb.h> 42 41 #include <genarch/srln/srln.h> … … 61 60 62 61 static struct beagleboard { 63 amdm37x_dispc_regs_t *dispc;64 62 amdm37x_irc_regs_t *irc_addr; 65 63 amdm37x_uart_t uart; … … 85 83 } 86 84 87 static void bbxm_setup_fb(unsigned width, unsigned height, unsigned bpp)88 {89 const unsigned pixel_bytes = (bpp / 8);90 const size_t size = ALIGN_UP(width * height * pixel_bytes, FRAME_SIZE);91 const unsigned frames = size / FRAME_SIZE;92 unsigned order = 0;93 unsigned frame = 1;94 while (frame < frames) {95 frame *= 2;96 ++order;97 }98 /* prefer highmem as we don't care about virtual mapping. */99 void *buffer = frame_alloc(order, FRAME_LOWMEM);100 if (!buffer) {101 printf("Failed to allocate framebuffer.\n");102 return;103 }104 105 amdm37x_dispc_setup_fb(beagleboard.dispc, width, height, bpp,106 (uintptr_t) buffer);107 108 fb_properties_t prop = {109 .addr = (uintptr_t)buffer,110 .offset = 0,111 .x = width,112 .y = height,113 .scan = width * pixel_bytes,114 .visual = VISUAL_RGB_5_6_5_LE115 };116 switch (bpp)117 {118 case 8:119 prop.visual = VISUAL_INDIRECT_8; break;120 case 16:121 prop.visual = VISUAL_RGB_5_6_5_LE; break;122 case 24:123 prop.visual = VISUAL_BGR_8_8_8; break;124 case 32:125 prop.visual = VISUAL_RGB_8_8_8_0; break;126 default:127 printf("Invalid framebuffer bit depth: bailing out.\n");128 return;129 }130 outdev_t *fb_dev = fb_init(&prop);131 if (fb_dev)132 stdout_wire(fb_dev);133 134 }135 136 85 static void bb_timer_irq_handler(irq_t *irq) 137 86 { … … 154 103 ASSERT(beagleboard.irc_addr); 155 104 amdm37x_irc_init(beagleboard.irc_addr); 156 157 /* Map display controller */158 beagleboard.dispc = (void*) km_map(AMDM37x_DISPC_BASE_ADDRESS,159 AMDM37x_DISPC_SIZE, PAGE_NOT_CACHEABLE);160 ASSERT(beagleboard.dispc);161 105 162 106 /* Initialize timer. Use timer1, because it is in WKUP power domain … … 223 167 static void bbxm_output_init(void) 224 168 { 225 #ifdef CONFIG_FB226 bbxm_setup_fb(CONFIG_BFB_WIDTH, CONFIG_BFB_HEIGHT, CONFIG_BFB_BPP);227 #else228 (void)bbxm_setup_fb;229 #endif230 169 /* UART3 is wired to external RS232 connector */ 231 170 const bool ok = amdm37x_uart_init(&beagleboard.uart, -
kernel/arch/arm32/src/mm/page_fault.c
r5e761f3 rb1011dae 34 34 */ 35 35 #include <panic.h> 36 #include <arch/cp15.h> 36 37 #include <arch/exception.h> 37 38 #include <arch/mm/page_fault.h> … … 127 128 } 128 129 129 130 /** Returns value stored in comnbined/data fault status register. 131 * 132 * @return Value stored in CP15 fault status register (FSR). 133 * 134 * "VMSAv6 added a fifth fault status bit (bit[10]) to both the IFSR and DFSR. 135 * It is IMPLEMENTATION DEFINED how this bit is encoded in earlier versions of 136 * the architecture. A write flag (bit[11] of the DFSR) has also been 137 * introduced." 138 * ARM Architecture Reference Manual version i ch. B4.6 (PDF p. 719) 139 * 140 * See ch. B4.9.6 for location of data/instruction FSR. 141 * 142 */ 143 static inline fault_status_t read_data_fault_status_register(void) 144 { 145 fault_status_t fsu; 146 147 /* Combined/Data fault status is stored in CP15 register 5, c0. */ 148 asm volatile ( 149 "mrc p15, 0, %[dummy], c5, c0, 0" 150 : [dummy] "=r" (fsu.raw) 151 ); 152 153 return fsu; 154 } 155 156 /** Returns DFAR (fault address register) content. 157 * 158 * This register is equivalent to FAR on pre armv6 machines. 159 * 160 * @return DFAR (fault address register) content (address that caused a page 161 * fault) 162 */ 163 static inline uintptr_t read_data_fault_address_register(void) 164 { 165 uintptr_t ret; 166 167 /* fault adress is stored in CP15 register 6 */ 168 asm volatile ( 169 "mrc p15, 0, %[ret], c6, c0, 0" 170 : [ret] "=r" (ret) 171 ); 172 173 return ret; 174 } 175 176 #if defined(PROCESSOR_armv4) | defined(PROCESSOR_armv5) 130 #if defined(PROCESSOR_ARCH_armv4) | defined(PROCESSOR_ARCH_armv5) 177 131 /** Decides whether read or write into memory is requested. 178 132 * … … 244 198 void data_abort(unsigned int exc_no, istate_t *istate) 245 199 { 246 const uintptr_t badvaddr = read_data_fault_address_register();247 const fault_status_t fsr = read_data_fault_status_register();200 const uintptr_t badvaddr = DFAR_read(); 201 const fault_status_t fsr = { .raw = DFSR_read() }; 248 202 const dfsr_source_t source = fsr.raw & DFSR_SOURCE_MASK; 249 203 … … 281 235 } 282 236 283 #if defined(PROCESSOR_ armv6) | defined(PROCESSOR_armv7_a)237 #if defined(PROCESSOR_ARCH_armv6) | defined(PROCESSOR_ARCH_armv7_a) 284 238 const pf_access_t access = 285 239 fsr.data.wr ? PF_ACCESS_WRITE : PF_ACCESS_READ; 286 #elif defined(PROCESSOR_ armv4) | defined(PROCESSOR_armv5)240 #elif defined(PROCESSOR_ARCH_armv4) | defined(PROCESSOR_ARCH_armv5) 287 241 const pf_access_t access = get_memory_access_type(istate->pc, badvaddr); 288 242 #else -
uspace/Makefile
r5e761f3 rb1011dae 194 194 ifeq ($(UARCH),arm32) 195 195 DIRS += \ 196 drv/infrastructure/rootamdm37x 196 drv/infrastructure/rootamdm37x \ 197 drv/fb/amdm37x_dispc 197 198 endif 198 199 -
uspace/drv/fb/amdm37x_dispc/amdm37x_dispc_regs.h
r5e761f3 rb1011dae 1 1 /* 2 * Copyright (c) 201 2Jan Vesely2 * Copyright (c) 2013 Jan Vesely 3 3 * All rights reserved. 4 4 * … … 34 34 */ 35 35 36 #ifndef KERN_AMDM37x_DISPC_H_37 #define KERN_AMDM37x_DISPC_H_36 #ifndef AMDM37x_DISPC_REGS_H_ 37 #define AMDM37x_DISPC_REGS_H_ 38 38 39 39 /* AMDM37x TRM p. 1813 */ … … 41 41 #define AMDM37x_DISPC_SIZE 1024 42 42 43 #define __paddname(line) PADD32_ ## line 44 #define _paddname(line) __paddname(line) 45 #define PADD32(count) uint32_t _paddname(__LINE__)[count] 46 47 #include <typedefs.h> 43 #include <macros.h> 48 44 49 45 typedef struct { … … 51 47 #define AMDM37X_DISPC_REVISION_MASK 0xff 52 48 53 PADD32 (3);49 PADD32[3]; 54 50 ioport32_t sysconfig; 55 51 #define AMDM37X_DISPC_SYSCONFIG_AUTOIDLE_FLAG (1 << 0) … … 86 82 #define AMDM37X_DISPC_IRQ_WAKEUP_FLAG (1 << 16) 87 83 88 PADD32 (8);84 PADD32[8]; 89 85 ioport32_t control; 90 86 #define AMDM37X_DISPC_CONTROL_LCD_ENABLE_FLAG (1 << 0) … … 149 145 #define AMDM37X_DISPC_CONFIG_TVALPHABLENDERENABLE_FLAG (1 << 19) 150 146 151 PADD32 (1);147 PADD32[1]; 152 148 ioport32_t default_color[2]; 153 149 ioport32_t trans_color[2]; … … 215 211 #define AMDM37X_DISPC_SIZE_HEIGHT_SHIFT 16 216 212 217 PADD32 (4);213 PADD32[4]; 218 214 ioport32_t attributes; 219 215 #define AMDM37X_DISPC_GFX_ATTRIBUTES_ENABLE_FLAG (1 << 0) … … 266 262 } fir_coef[8]; 267 263 ioport32_t conv_coef[5]; 268 PADD32 (2);264 PADD32[2]; 269 265 } vid[2]; 270 266 /* 0x1d4 */ … … 273 269 ioport32_t vid_fir_coef_v[8]; 274 270 /* 0x200 */ 275 PADD32 (8);271 PADD32[8]; 276 272 /* 0x220 */ 277 273 ioport32_t cpr_coef_r; … … 283 279 ioport32_t vid_preload[2]; 284 280 285 } __attribute__((packed)) amdm37x_dispc_regs_t; 286 287 288 static inline void amdm37x_dispc_setup_fb(amdm37x_dispc_regs_t *regs, 289 unsigned x, unsigned y, unsigned bpp, uintptr_t pa) 290 { 291 ASSERT(regs); 292 /* Init sequence for dispc is in chapter 7.6.5.1.4 p. 1810, 293 * no idea what parts of that work. */ 294 295 /* Disable all interrupts */ 296 regs->irqenable = 0; 297 298 /* Pixel format specifics*/ 299 uint32_t attrib_pixel_format = 0; 300 uint32_t control_data_lanes = 0; 301 switch (bpp) 302 { 303 case 32: 304 attrib_pixel_format = AMDM37X_DISPC_GFX_ATTRIBUTES_FORMAT_RGBX; 305 control_data_lanes = AMDM37X_DISPC_CONTROL_TFTDATALINES_24B; 306 break; 307 case 24: 308 attrib_pixel_format = AMDM37X_DISPC_GFX_ATTRIBUTES_FORMAT_RGB24; 309 control_data_lanes = AMDM37X_DISPC_CONTROL_TFTDATALINES_24B; 310 break; 311 case 16: 312 attrib_pixel_format = AMDM37X_DISPC_GFX_ATTRIBUTES_FORMAT_RGB16; 313 control_data_lanes = AMDM37X_DISPC_CONTROL_TFTDATALINES_16B; 314 break; 315 default: 316 ASSERT(false); 317 } 318 319 /* Prepare sizes */ 320 const uint32_t size_reg = 321 (((x - 1) & AMDM37X_DISPC_SIZE_WIDTH_MASK) 322 << AMDM37X_DISPC_SIZE_WIDTH_SHIFT) | 323 (((y - 1) & AMDM37X_DISPC_SIZE_HEIGHT_MASK) 324 << AMDM37X_DISPC_SIZE_HEIGHT_SHIFT); 325 326 /* modes taken from u-boot, for 1024x768 */ 327 // TODO replace magic values with actual correct values 328 // regs->timing_h = 0x1a4024c9; 329 // regs->timing_v = 0x02c00509; 330 // regs->pol_freq = 0x00007028; 331 // regs->divisor = 0x00010001; 332 333 /* setup output */ 334 regs->size_lcd = size_reg; 335 regs->size_dig = size_reg; 336 337 /* Nice blue default color */ 338 regs->default_color[0] = 0x0000ff; 339 regs->default_color[1] = 0x0000ff; 340 341 /* Setup control register */ 342 uint32_t control = 0 | 343 AMDM37X_DISPC_CONTROL_PCKFREEENABLE_FLAG | 344 (control_data_lanes << AMDM37X_DISPC_CONTROL_TFTDATALINES_SHIFT) | 345 AMDM37X_DISPC_CONTROL_GPOUT0_FLAG | 346 AMDM37X_DISPC_CONTROL_GPOUT1_FLAG; 347 regs->control = control; 348 349 /* No gamma stuff only data */ 350 uint32_t config = (AMDM37X_DISPC_CONFIG_LOADMODE_DATAEVERYFRAME 351 << AMDM37X_DISPC_CONFIG_LOADMODE_SHIFT); 352 regs->config = config; 353 354 355 /* Set framebuffer base address */ 356 regs->gfx.ba[0] = pa; 357 regs->gfx.ba[1] = pa; 358 regs->gfx.position = 0; 359 360 /* Setup fb size */ 361 regs->gfx.size = size_reg; 362 363 /* Set pixel format */ 364 uint32_t attribs = 0 | 365 (attrib_pixel_format << AMDM37X_DISPC_GFX_ATTRIBUTES_FORMAT_SHIFT); 366 regs->gfx.attributes = attribs; 367 368 /* 0x03ff03c0 is the default */ 369 regs->gfx.fifo_threshold = 0x03ff03c0; 370 /* This value should be stride - width, 1 means next pixel i.e. 371 * stride == width */ 372 regs->gfx.row_inc = 1; 373 /* number of bytes to next pixel in BPP multiples */ 374 regs->gfx.pixel_inc = 1; 375 /* only used if video is played over fb */ 376 regs->gfx.window_skip = 0; 377 /* Gamma and palette table */ 378 regs->gfx.table_ba = 0; 379 380 /* enable frame buffer graphics */ 381 regs->gfx.attributes |= AMDM37X_DISPC_GFX_ATTRIBUTES_ENABLE_FLAG; 382 /* Update register values */ 383 regs->control |= AMDM37X_DISPC_CONTROL_GOLCD_FLAG; 384 regs->control |= AMDM37X_DISPC_CONTROL_GODIGITAL_FLAG; 385 /* Enable output */ 386 regs->control |= AMDM37X_DISPC_CONTROL_LCD_ENABLE_FLAG; 387 regs->control |= AMDM37X_DISPC_CONTROL_DIGITAL_ENABLE_FLAG; 388 } 281 } amdm37x_dispc_regs_t; 389 282 390 283 -
uspace/drv/infrastructure/rootamdm37x/rootamdm37x.c
r5e761f3 rb1011dae 195 195 ddf_msg(LVL_ERROR, "Failed to add EHCI function for " 196 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."); 197 200 198 201 return EOK; -
uspace/lib/c/arch/arm32/Makefile.common
r5e761f3 rb1011dae 28 28 # 29 29 30 GCC_CFLAGS += -ffixed-r9 -mtp=soft -fno-omit-frame-pointer -mapcs-frame -march=$(subst _,-,$(PROCESSOR ))30 GCC_CFLAGS += -ffixed-r9 -mtp=soft -fno-omit-frame-pointer -mapcs-frame -march=$(subst _,-,$(PROCESSOR_ARCH)) 31 31 32 32 ifeq ($(CONFIG_FPU),y) -
uspace/lib/drv/include/ddf/log.h
r5e761f3 rb1011dae 44 44 size_t); 45 45 46 #define ddf_log_fatal(msg...) ddf_msg(LVL_FATAL, msg) 47 #define ddf_log_error(msg...) ddf_msg(LVL_ERROR, msg) 48 #define ddf_log_warning(msg...) ddf_msg(LVL_WARN, msg) 49 #define ddf_log_note(msg...) ddf_msg(LVL_NOTE, msg) 50 #define ddf_log_debug(msg...) ddf_msg(LVL_DEBUG, msg) 51 #define ddf_log_verbose(msg...) ddf_msg(LVL_DEBUG2, msg) 52 46 53 #endif 47 54
Note:
See TracChangeset
for help on using the changeset viewer.