1 /* 2 * Copyright 2004-2009 Analog Devices Inc. 3 * 4 * Licensed under the GPL-2 or later. 5 */ 6 7 #ifndef __ASM_BFIN_PROCESSOR_H 8 #define __ASM_BFIN_PROCESSOR_H 9 10 /* 11 * Default implementation of macro that returns current 12 * instruction pointer ("program counter"). 13 */ 14 #define current_text_addr() ({ __label__ _l; _l: &&_l;}) 15 16 #include <asm/ptrace.h> 17 #include <mach/blackfin.h> 18 rdusp(void)19static inline unsigned long rdusp(void) 20 { 21 unsigned long usp; 22 23 __asm__ __volatile__("%0 = usp;\n\t":"=da"(usp)); 24 return usp; 25 } 26 wrusp(unsigned long usp)27static inline void wrusp(unsigned long usp) 28 { 29 __asm__ __volatile__("usp = %0;\n\t"::"da"(usp)); 30 } 31 __get_SP(void)32static inline unsigned long __get_SP(void) 33 { 34 unsigned long sp; 35 36 __asm__ __volatile__("%0 = sp;\n\t" : "=da"(sp)); 37 return sp; 38 } 39 40 /* 41 * User space process size: 1st byte beyond user address space. 42 * Fairly meaningless on nommu. Parts of user programs can be scattered 43 * in a lot of places, so just disable this by setting it to 0xFFFFFFFF. 44 */ 45 #define TASK_SIZE 0xFFFFFFFF 46 47 #ifdef __KERNEL__ 48 #define STACK_TOP TASK_SIZE 49 #endif 50 51 #define TASK_UNMAPPED_BASE 0 52 53 struct thread_struct { 54 unsigned long ksp; /* kernel stack pointer */ 55 unsigned long usp; /* user stack pointer */ 56 unsigned short seqstat; /* saved status register */ 57 unsigned long esp0; /* points to SR of stack frame pt_regs */ 58 unsigned long pc; /* instruction pointer */ 59 void * debuggerinfo; 60 }; 61 62 #define INIT_THREAD { \ 63 sizeof(init_stack) + (unsigned long) init_stack, 0, \ 64 PS_S, 0, 0 \ 65 } 66 67 extern void start_thread(struct pt_regs *regs, unsigned long new_ip, 68 unsigned long new_sp); 69 70 /* Forward declaration, a strange C thing */ 71 struct task_struct; 72 73 /* Free all resources held by a thread. */ release_thread(struct task_struct * dead_task)74static inline void release_thread(struct task_struct *dead_task) 75 { 76 } 77 78 /* 79 * Return saved PC of a blocked thread. 80 */ 81 #define thread_saved_pc(tsk) (tsk->thread.pc) 82 83 unsigned long get_wchan(struct task_struct *p); 84 85 #define KSTK_EIP(tsk) \ 86 ({ \ 87 unsigned long eip = 0; \ 88 if ((tsk)->thread.esp0 > PAGE_SIZE && \ 89 MAP_NR((tsk)->thread.esp0) < max_mapnr) \ 90 eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ 91 eip; }) 92 #define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) 93 94 #define cpu_relax() smp_mb() 95 #define cpu_relax_lowlatency() cpu_relax() 96 97 /* Get the Silicon Revision of the chip */ bfin_revid(void)98static inline uint32_t __pure bfin_revid(void) 99 { 100 /* Always use CHIPID, to work around ANOMALY_05000234 */ 101 uint32_t revid = (bfin_read_CHIPID() & CHIPID_VERSION) >> 28; 102 103 #ifdef _BOOTROM_GET_DXE_ADDRESS_TWI 104 /* 105 * ANOMALY_05000364 106 * Incorrect Revision Number in DSPID Register 107 */ 108 if (ANOMALY_05000364 && 109 bfin_read16(_BOOTROM_GET_DXE_ADDRESS_TWI) == 0x2796) 110 revid = 1; 111 #endif 112 113 return revid; 114 } 115 bfin_cpuid(void)116static inline uint16_t __pure bfin_cpuid(void) 117 { 118 return (bfin_read_CHIPID() & CHIPID_FAMILY) >> 12; 119 } 120 bfin_dspid(void)121static inline uint32_t __pure bfin_dspid(void) 122 { 123 return bfin_read_DSPID(); 124 } 125 126 #define blackfin_core_id() (bfin_dspid() & 0xff) 127 bfin_compiled_revid(void)128static inline uint32_t __pure bfin_compiled_revid(void) 129 { 130 #if defined(CONFIG_BF_REV_0_0) 131 return 0; 132 #elif defined(CONFIG_BF_REV_0_1) 133 return 1; 134 #elif defined(CONFIG_BF_REV_0_2) 135 return 2; 136 #elif defined(CONFIG_BF_REV_0_3) 137 return 3; 138 #elif defined(CONFIG_BF_REV_0_4) 139 return 4; 140 #elif defined(CONFIG_BF_REV_0_5) 141 return 5; 142 #elif defined(CONFIG_BF_REV_0_6) 143 return 6; 144 #elif defined(CONFIG_BF_REV_ANY) 145 return 0xffff; 146 #else 147 return -1; 148 #endif 149 } 150 151 #endif 152