processor.h 3.9 KB
Newer Older
B
Bryan Wu 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
#ifndef __ASM_BFIN_PROCESSOR_H
#define __ASM_BFIN_PROCESSOR_H

/*
 * Default implementation of macro that returns current
 * instruction pointer ("program counter").
 */
#define current_text_addr() ({ __label__ _l; _l: &&_l;})

#include <asm/blackfin.h>
#include <asm/segment.h>
#include <linux/compiler.h>

static inline unsigned long rdusp(void)
{
	unsigned long usp;

	__asm__ __volatile__("%0 = usp;\n\t":"=da"(usp));
	return usp;
}

static inline void wrusp(unsigned long usp)
{
	__asm__ __volatile__("usp = %0;\n\t"::"da"(usp));
}

/*
 * User space process size: 1st byte beyond user address space.
29 30
 * Fairly meaningless on nommu.  Parts of user programs can be scattered
 * in a lot of places, so just disable this by setting it to 0xFFFFFFFF.
B
Bryan Wu 已提交
31
 */
32
#define TASK_SIZE	0xFFFFFFFF
B
Bryan Wu 已提交
33

34 35 36 37
#ifdef __KERNEL__
#define STACK_TOP	TASK_SIZE
#endif

B
Bryan Wu 已提交
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
#define TASK_UNMAPPED_BASE	0

struct thread_struct {
	unsigned long ksp;	/* kernel stack pointer */
	unsigned long usp;	/* user stack pointer */
	unsigned short seqstat;	/* saved status register */
	unsigned long esp0;	/* points to SR of stack frame pt_regs */
	unsigned long pc;	/* instruction pointer */
	void *        debuggerinfo;
};

#define INIT_THREAD  {						\
	sizeof(init_stack) + (unsigned long) init_stack, 0,	\
	PS_S, 0, 0						\
}

/*
 * Do necessary setup to start up a newly executed thread.
 *
 * pass the data segment into user programs if it exists,
 * it can't hurt anything as far as I can tell
 */
#define start_thread(_regs, _pc, _usp)					\
do {									\
	set_fs(USER_DS);						\
	(_regs)->pc = (_pc);						\
	if (current->mm)						\
		(_regs)->p5 = current->mm->start_data;			\
R
Roman Zippel 已提交
66
	task_thread_info(current)->l1_task_info.stack_start		\
B
Bryan Wu 已提交
67
		= (void *)current->mm->context.stack_start;		\
R
Roman Zippel 已提交
68 69
	task_thread_info(current)->l1_task_info.lowest_sp = (void *)(_usp); \
	memcpy(L1_SCRATCH_TASK_INFO, &task_thread_info(current)->l1_task_info, \
B
Bryan Wu 已提交
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
		sizeof(*L1_SCRATCH_TASK_INFO));				\
	wrusp(_usp);							\
} while(0)

/* Forward declaration, a strange C thing */
struct task_struct;

/* Free all resources held by a thread. */
static inline void release_thread(struct task_struct *dead_task)
{
}

#define prepare_to_copy(tsk)	do { } while (0)

extern int kernel_thread(int (*fn) (void *), void *arg, unsigned long flags);

/*
 * Free current thread data structures etc..
 */
static inline void exit_thread(void)
{
}

/*
 * Return saved PC of a blocked thread.
 */
#define thread_saved_pc(tsk)	(tsk->thread.pc)

unsigned long get_wchan(struct task_struct *p);

#define	KSTK_EIP(tsk)							\
    ({									\
	unsigned long eip = 0;						\
	if ((tsk)->thread.esp0 > PAGE_SIZE &&				\
	    MAP_NR((tsk)->thread.esp0) < max_mapnr)			\
	      eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc;	\
	eip; })
#define	KSTK_ESP(tsk)	((tsk) == current ? rdusp() : (tsk)->thread.usp)

109 110
#define cpu_relax()    	smp_mb()

B
Bryan Wu 已提交
111 112

/* Get the Silicon Revision of the chip */
113
static inline uint32_t __pure bfin_revid(void)
B
Bryan Wu 已提交
114 115
{
	/* stored in the upper 4 bits */
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
	uint32_t revid = bfin_read_CHIPID() >> 28;

#ifdef CONFIG_BF52x
	/* ANOMALY_05000357
	 * Incorrect Revision Number in DSPID Register
	 */
	if (revid == 0)
		switch (bfin_read16(_BOOTROM_GET_DXE_ADDRESS_TWI)) {
		case 0x0010:
			revid = 0;
			break;
		case 0x2796:
			revid = 1;
			break;
		default:
			revid = 0xFFFF;
			break;
		}
#endif
	return revid;
B
Bryan Wu 已提交
136 137
}

138 139 140
static inline uint16_t __pure bfin_cpuid(void)
{
	return (bfin_read_CHIPID() & CHIPID_FAMILY) >> 12;
141
}
142

143 144 145
static inline uint32_t __pure bfin_dspid(void)
{
	return bfin_read_DSPID();
146 147
}

148
static inline uint32_t __pure bfin_compiled_revid(void)
B
Bryan Wu 已提交
149 150 151 152 153 154 155 156 157 158 159 160 161
{
#if defined(CONFIG_BF_REV_0_0)
	return 0;
#elif defined(CONFIG_BF_REV_0_1)
	return 1;
#elif defined(CONFIG_BF_REV_0_2)
	return 2;
#elif defined(CONFIG_BF_REV_0_3)
	return 3;
#elif defined(CONFIG_BF_REV_0_4)
	return 4;
#elif defined(CONFIG_BF_REV_0_5)
	return 5;
162 163
#elif defined(CONFIG_BF_REV_0_6)
	return 6;
164 165 166 167
#elif defined(CONFIG_BF_REV_ANY)
	return 0xffff;
#else
	return -1;
B
Bryan Wu 已提交
168 169 170 171
#endif
}

#endif