274 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			274 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #ifndef _ARM_CPUFUNC_H
 | |
| #define _ARM_CPUFUNC_H
 | |
| 
 | |
| /* Data memory barrier */
 | |
| static inline void dmb(void)
 | |
| {
 | |
| 	asm volatile("dmb" : : : "memory");
 | |
| }
 | |
| 
 | |
| /* Data synchronization barrier */
 | |
| static inline void dsb(void)
 | |
| {
 | |
| 	asm volatile("dsb" : : : "memory");
 | |
| }
 | |
| 
 | |
| /* Instruction synchronization barrier */
 | |
| static inline void isb(void)
 | |
| {
 | |
| 	asm volatile("isb" : : : "memory");
 | |
| }
 | |
| 
 | |
| static inline void barrier(void)
 | |
| {
 | |
| 	dsb();
 | |
| 	isb();
 | |
| }
 | |
| 
 | |
| static inline void refresh_tlb(void)
 | |
| {
 | |
| 	dsb();
 | |
| 	/* Invalidate entire unified TLB */
 | |
| 	asm volatile("mcr p15, 0, r0, c8, c7, 0 @ TLBIALL\n\t");
 | |
| 	dsb();
 | |
| 	isb();
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Read System Control Register */
 | |
| static inline u32_t read_sctlr()
 | |
| {
 | |
|     u32_t ctl;
 | |
| 
 | |
|     asm volatile("mrc p15, 0, %[ctl], c1, c0, 0 @ Read SCTLR\n\t"
 | |
| 		 : [ctl] "=r" (ctl));
 | |
|     return ctl;
 | |
| }
 | |
| 
 | |
| /* Write System Control Register */
 | |
| static inline void write_sctlr(u32_t ctl)
 | |
| {
 | |
|     asm volatile("mcr p15, 0, %[ctl], c1, c0, 0 @ Write SCTLR\n\t"
 | |
| 		 : : [ctl] "r" (ctl));
 | |
| }
 | |
| 
 | |
| /* Read Translation Table Base Register 0 */
 | |
| static inline u32_t read_ttbr0()
 | |
| {
 | |
|     u32_t bar;
 | |
| 
 | |
|     asm volatile("mrc p15, 0, %[bar], c2, c0, 0 @ Read TTBR0\n\t"
 | |
| 		 : [bar] "=r" (bar));
 | |
|     return bar;
 | |
| }
 | |
| 
 | |
| /* Write Translation Table Base Register 0 */
 | |
| static inline void write_ttbr0(u32_t bar)
 | |
| {
 | |
|     barrier();
 | |
|     asm volatile("mcr p15, 0, %[bar], c2, c0, 0 @ Write TTBR0\n\t"
 | |
| 		 : : [bar] "r" (bar));
 | |
|     refresh_tlb();
 | |
| }
 | |
| 
 | |
| /* Reload Translation Table Base Register 0 */
 | |
| static inline void reload_ttbr0(void)
 | |
| {
 | |
|     reg_t ttbr = read_ttbr0();
 | |
|     write_ttbr0(ttbr);
 | |
|     refresh_tlb();
 | |
| }
 | |
| 
 | |
| /* Read Translation Table Base Register 1 */
 | |
| static inline u32_t read_ttbr1()
 | |
| {
 | |
|     u32_t bar;
 | |
| 
 | |
|     asm volatile("mrc p15, 0, %[bar], c2, c0, 1 @ Read TTBR1\n\t"
 | |
| 		 : [bar] "=r" (bar));
 | |
|     return bar;
 | |
| }
 | |
| 
 | |
| /* Write Translation Table Base Register 1 */
 | |
| static inline void write_ttbr1(u32_t bar)
 | |
| {
 | |
|     barrier();
 | |
|     asm volatile("mcr p15, 0, %[bar], c2, c0, 1 @ Write TTBR1\n\t"
 | |
| 		 : : [bar] "r" (bar));
 | |
|     refresh_tlb();
 | |
| }
 | |
| 
 | |
| /* Reload Translation Table Base Register 1 */
 | |
| static inline void reload_ttbr1(void)
 | |
| {
 | |
|     reg_t ttbr = read_ttbr1();
 | |
|     write_ttbr1(ttbr);
 | |
|     refresh_tlb();
 | |
| }
 | |
| 
 | |
| /* Read Translation Table Base Control Register */
 | |
| static inline u32_t read_ttbcr()
 | |
| {
 | |
|     u32_t bcr;
 | |
| 
 | |
|     asm volatile("mrc p15, 0, %[bcr], c2, c0, 2 @ Read TTBCR\n\t"
 | |
| 		 : [bcr] "=r" (bcr));
 | |
|     return bcr;
 | |
| }
 | |
| 
 | |
| /* Write Translation Table Base Control Register */
 | |
| static inline void write_ttbcr(u32_t bcr)
 | |
| {
 | |
|     asm volatile("mcr p15, 0, %[bcr], c2, c0, 2 @ Write TTBCR\n\t"
 | |
| 		 : : [bcr] "r" (bcr));
 | |
| }
 | |
| 
 | |
| /* Read Domain Access Control Register */
 | |
| static inline u32_t read_dacr()
 | |
| {
 | |
|     u32_t dacr;
 | |
| 
 | |
|     asm volatile("mrc p15, 0, %[dacr], c3, c0, 0 @ Read DACR\n\t"
 | |
| 		 : [dacr] "=r" (dacr));
 | |
|     return dacr;
 | |
| }
 | |
| 
 | |
| /* Write Domain Access Control Register */
 | |
| static inline void write_dacr(u32_t dacr)
 | |
| {
 | |
|     asm volatile("mcr p15, 0, %[dacr], c3, c0, 0 @ Write DACR\n\t"
 | |
| 		 : : [dacr] "r" (dacr));
 | |
| }
 | |
| 
 | |
| /* Read Data Fault Status Register */
 | |
| static inline u32_t read_dfsr()
 | |
| {
 | |
|     u32_t fsr;
 | |
| 
 | |
|     asm volatile("mrc p15, 0, %[fsr], c5, c0, 0 @ Read DFSR\n\t"
 | |
| 		 : [fsr] "=r" (fsr));
 | |
|     return fsr;
 | |
| }
 | |
| 
 | |
| /* Write Data Fault Status Register */
 | |
| static inline void write_dfsr(u32_t fsr)
 | |
| {
 | |
|     asm volatile("mcr p15, 0, %[fsr], c5, c0, 0 @ Write DFSR\n\t"
 | |
| 		 : : [fsr] "r" (fsr));
 | |
| }
 | |
| 
 | |
| /* Read Instruction Fault Status Register */
 | |
| static inline u32_t read_ifsr()
 | |
| {
 | |
|     u32_t fsr;
 | |
| 
 | |
|     asm volatile("mrc p15, 0, %[fsr], c5, c0, 1 @ Read IFSR\n\t"
 | |
| 		 : [fsr] "=r" (fsr));
 | |
|     return fsr;
 | |
| }
 | |
| 
 | |
| /* Write Instruction Fault Status Register */
 | |
| static inline void write_ifsr(u32_t fsr)
 | |
| {
 | |
|     asm volatile("mcr p15, 0, %[fsr], c5, c0, 1 @ Write IFSR\n\t"
 | |
| 		 : : [fsr] "r" (fsr));
 | |
| }
 | |
| 
 | |
| /* Read Data Fault Address Register */
 | |
| static inline u32_t read_dfar()
 | |
| {
 | |
|     u32_t far;
 | |
| 
 | |
|     asm volatile("mrc p15, 0, %[far], c6, c0, 0 @ Read DFAR\n\t"
 | |
| 		 : [far] "=r" (far));
 | |
|     return far;
 | |
| }
 | |
| 
 | |
| /* Write Data Fault Address Register */
 | |
| static inline void write_dfar(u32_t far)
 | |
| {
 | |
|     asm volatile("mcr p15, 0, %[far], c6, c0, 0 @ Write DFAR\n\t"
 | |
| 		 : : [far] "r" (far));
 | |
| }
 | |
| 
 | |
| /* Read Instruction Fault Address Register */
 | |
| static inline u32_t read_ifar()
 | |
| {
 | |
|     u32_t far;
 | |
| 
 | |
|     asm volatile("mrc p15, 0, %[far], c6, c0, 2 @ Read IFAR\n\t"
 | |
| 		 : [far] "=r" (far));
 | |
|     return far;
 | |
| }
 | |
| 
 | |
| /* Write Instruction Fault Address Register */
 | |
| static inline void write_ifar(u32_t far)
 | |
| {
 | |
|     asm volatile("mcr p15, 0, %[far], c6, c0, 2 @ Write IFAR\n\t"
 | |
| 		 : : [far] "r" (far));
 | |
| }
 | |
| 
 | |
| /* Read Vector Base Address Register */
 | |
| static inline u32_t read_vbar()
 | |
| {
 | |
|     u32_t vbar;
 | |
| 
 | |
|     asm volatile("mrc p15, 0, %[vbar], c12, c0, 0 @ Read VBAR\n\t"
 | |
| 		 : [vbar] "=r" (vbar));
 | |
|     return vbar;
 | |
| }
 | |
| 
 | |
| /* Write Vector Base Address Register */
 | |
| static inline void write_vbar(u32_t vbar)
 | |
| {
 | |
|     asm volatile("mcr p15, 0, %[vbar], c12, c0, 0 @ Write VBAR\n\t"
 | |
| 		 : : [vbar] "r" (vbar));
 | |
|     asm volatile("dsb");
 | |
| }
 | |
| 
 | |
| /* Read the Main ID Register  */
 | |
| static inline u32_t read_midr()
 | |
| {
 | |
|     u32_t id;
 | |
| 
 | |
|     asm volatile("mrc p15, 0, %[id], c0, c0, 0 @ read MIDR\n\t"
 | |
| 		 : [id] "=r" (id));
 | |
|     return id;
 | |
| }
 | |
| 
 | |
| /* Read Auxiliary Control Register */
 | |
| static inline u32_t read_actlr()
 | |
| {
 | |
|     u32_t ctl;
 | |
| 
 | |
|     asm volatile("mrc p15, 0, %[ctl], c1, c0, 1 @ Read ACTLR\n\t"
 | |
| 		 : [ctl] "=r" (ctl));
 | |
|     return ctl;
 | |
| }
 | |
| 
 | |
| /* Write Auxiliary Control Register */
 | |
| static inline void write_actlr(u32_t ctl)
 | |
| {
 | |
|     asm volatile("mcr p15, 0, %[ctl], c1, c0, 1 @ Write ACTLR\n\t"
 | |
| 		 : : [ctl] "r" (ctl));
 | |
| }
 | |
| 
 | |
| /* Read Current Program Status Register */
 | |
| static inline u32_t read_cpsr()
 | |
| {
 | |
|     u32_t status;
 | |
| 
 | |
|     asm volatile("mrs %[status], cpsr @ read CPSR"
 | |
| 		 : [status] "=r" (status));
 | |
|     return status;
 | |
| }
 | |
| 
 | |
| /* Write Current Program Status Register */
 | |
| static inline void write_cpsr(u32_t status)
 | |
| {
 | |
|     asm volatile("msr cpsr_c, %[status] @ write CPSR"
 | |
| 		 : : [status] "r" (status));
 | |
| }
 | |
| 
 | |
| #endif /* _ARM_CPUFUNC_H */
 | 
