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 <asm/blackfin.h> 18 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 27static inline void wrusp(unsigned long usp) 28{ 29 __asm__ __volatile__("usp = %0;\n\t"::"da"(usp)); 30} 31 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 53struct 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 67extern void start_thread(struct pt_regs *regs, unsigned long new_ip, 68 unsigned long new_sp); 69 70/* Forward declaration, a strange C thing */ 71struct task_struct; 72 73/* Free all resources held by a thread. */ 74static inline void release_thread(struct task_struct *dead_task) 75{ 76} 77 78#define prepare_to_copy(tsk) do { } while (0) 79 80extern int kernel_thread(int (*fn) (void *), void *arg, unsigned long flags); 81 82/* 83 * Free current thread data structures etc.. 84 */ 85static inline void exit_thread(void) 86{ 87} 88 89/* 90 * Return saved PC of a blocked thread. 91 */ 92#define thread_saved_pc(tsk) (tsk->thread.pc) 93 94unsigned long get_wchan(struct task_struct *p); 95 96#define KSTK_EIP(tsk) \ 97 ({ \ 98 unsigned long eip = 0; \ 99 if ((tsk)->thread.esp0 > PAGE_SIZE && \ 100 MAP_NR((tsk)->thread.esp0) < max_mapnr) \ 101 eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ 102 eip; }) 103#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) 104 105#define cpu_relax() smp_mb() 106 107 108/* Get the Silicon Revision of the chip */ 109static inline uint32_t __pure bfin_revid(void) 110{ 111 /* Always use CHIPID, to work around ANOMALY_05000234 */ 112 uint32_t revid = (bfin_read_CHIPID() & CHIPID_VERSION) >> 28; 113 114#ifdef _BOOTROM_GET_DXE_ADDRESS_TWI 115 /* 116 * ANOMALY_05000364 117 * Incorrect Revision Number in DSPID Register 118 */ 119 if (ANOMALY_05000364 && 120 bfin_read16(_BOOTROM_GET_DXE_ADDRESS_TWI) == 0x2796) 121 revid = 1; 122#endif 123 124 return revid; 125} 126 127static inline uint16_t __pure bfin_cpuid(void) 128{ 129 return (bfin_read_CHIPID() & CHIPID_FAMILY) >> 12; 130} 131 132static inline uint32_t __pure bfin_dspid(void) 133{ 134 return bfin_read_DSPID(); 135} 136 137static inline uint32_t __pure bfin_compiled_revid(void) 138{ 139#if defined(CONFIG_BF_REV_0_0) 140 return 0; 141#elif defined(CONFIG_BF_REV_0_1) 142 return 1; 143#elif defined(CONFIG_BF_REV_0_2) 144 return 2; 145#elif defined(CONFIG_BF_REV_0_3) 146 return 3; 147#elif defined(CONFIG_BF_REV_0_4) 148 return 4; 149#elif defined(CONFIG_BF_REV_0_5) 150 return 5; 151#elif defined(CONFIG_BF_REV_0_6) 152 return 6; 153#elif defined(CONFIG_BF_REV_ANY) 154 return 0xffff; 155#else 156 return -1; 157#endif 158} 159 160#endif 161