1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#ifndef __ASM_AVR32_PROCESSOR_H
9#define __ASM_AVR32_PROCESSOR_H
10
11#include <asm/page.h>
12#include <asm/cache.h>
13
14#define TASK_SIZE	0x80000000
15
16#ifndef __ASSEMBLY__
17
18static inline void *current_text_addr(void)
19{
20	register void *pc asm("pc");
21	return pc;
22}
23
24enum arch_type {
25	ARCH_AVR32A,
26	ARCH_AVR32B,
27	ARCH_MAX
28};
29
30enum cpu_type {
31	CPU_MORGAN,
32	CPU_AT32AP,
33	CPU_MAX
34};
35
36enum tlb_config {
37	TLB_NONE,
38	TLB_SPLIT,
39	TLB_UNIFIED,
40	TLB_INVALID
41};
42
43#define AVR32_FEATURE_RMW	(1 << 0)
44#define AVR32_FEATURE_DSP	(1 << 1)
45#define AVR32_FEATURE_SIMD	(1 << 2)
46#define AVR32_FEATURE_OCD	(1 << 3)
47#define AVR32_FEATURE_PCTR	(1 << 4)
48#define AVR32_FEATURE_JAVA	(1 << 5)
49#define AVR32_FEATURE_FPU	(1 << 6)
50
51struct avr32_cpuinfo {
52	struct clk *clk;
53	unsigned long loops_per_jiffy;
54	enum arch_type arch_type;
55	enum cpu_type cpu_type;
56	unsigned short arch_revision;
57	unsigned short cpu_revision;
58	enum tlb_config tlb_config;
59	unsigned long features;
60
61	struct cache_info icache;
62	struct cache_info dcache;
63};
64
65extern struct avr32_cpuinfo boot_cpu_data;
66
67#ifdef CONFIG_SMP
68extern struct avr32_cpuinfo cpu_data[];
69#define current_cpu_data cpu_data[smp_processor_id()]
70#else
71#define cpu_data (&boot_cpu_data)
72#define current_cpu_data boot_cpu_data
73#endif
74
75/* This decides where the kernel will search for a free chunk of vm
76 * space during mmap's
77 */
78#define TASK_UNMAPPED_BASE	(PAGE_ALIGN(TASK_SIZE / 3))
79
80#define cpu_relax()		barrier()
81#define cpu_sync_pipeline()	asm volatile("sub pc, -2" : : : "memory")
82
83struct cpu_context {
84	unsigned long sr;
85	unsigned long pc;
86	unsigned long ksp;	/* Kernel stack pointer */
87	unsigned long r7;
88	unsigned long r6;
89	unsigned long r5;
90	unsigned long r4;
91	unsigned long r3;
92	unsigned long r2;
93	unsigned long r1;
94	unsigned long r0;
95};
96
97/* This struct contains the CPU context as stored by switch_to() */
98struct thread_struct {
99	struct cpu_context cpu_context;
100	unsigned long single_step_addr;
101	u16 single_step_insn;
102};
103
104#define INIT_THREAD {						\
105	.cpu_context = {					\
106		.ksp = sizeof(init_stack) + (long)&init_stack,	\
107	},							\
108}
109
110/*
111 * Do necessary setup to start up a newly executed thread.
112 */
113#define start_thread(regs, new_pc, new_sp)	 \
114	do {					 \
115		set_fs(USER_DS);		 \
116		memset(regs, 0, sizeof(*regs));	 \
117		regs->sr = MODE_USER;		 \
118		regs->pc = new_pc & ~1;		 \
119		regs->sp = new_sp;		 \
120	} while(0)
121
122struct task_struct;
123
124/* Free all resources held by a thread */
125extern void release_thread(struct task_struct *);
126
127/* Create a kernel thread without removing it from tasklists */
128extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
129
130/* Prepare to copy thread state - unlazy all lazy status */
131#define prepare_to_copy(tsk) do { } while(0)
132
133/* Return saved PC of a blocked thread */
134#define thread_saved_pc(tsk)    ((tsk)->thread.cpu_context.pc)
135
136struct pt_regs;
137extern unsigned long get_wchan(struct task_struct *p);
138extern void show_regs_log_lvl(struct pt_regs *regs, const char *log_lvl);
139extern void show_stack_log_lvl(struct task_struct *tsk, unsigned long sp,
140			       struct pt_regs *regs, const char *log_lvl);
141
142#define KSTK_EIP(tsk)	((tsk)->thread.cpu_context.pc)
143#define KSTK_ESP(tsk)	((tsk)->thread.cpu_context.ksp)
144
145#define ARCH_HAS_PREFETCH
146
147static inline void prefetch(const void *x)
148{
149	const char *c = x;
150	asm volatile("pref %0" : : "r"(c));
151}
152#define PREFETCH_STRIDE	L1_CACHE_BYTES
153
154#endif /* __ASSEMBLY__ */
155
156#endif /* __ASM_AVR32_PROCESSOR_H */
157