1/*
2 *  linux/include/asm-arm/cpu-multi32.h
3 *
4 *  Copyright (C) 2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef __ASSEMBLY__
11
12#include <asm/memory.h>
13#include <asm/page.h>
14
15/* forward-declare task_struct */
16struct task_struct;
17
18/*
19 * Don't change this structure - ASM code
20 * relies on it.
21 */
22extern struct processor {
23	/* MISC
24	 * get data abort address/flags
25	 */
26	void (*_data_abort)(unsigned long pc);
27	/*
28	 * check for any bugs
29	 */
30	void (*_check_bugs)(void);
31	/*
32	 * Set up any processor specifics
33	 */
34	void (*_proc_init)(void);
35	/*
36	 * Disable any processor specifics
37	 */
38	void (*_proc_fin)(void);
39	/*
40	 * Special stuff for a reset
41	 */
42	volatile void (*reset)(unsigned long addr);
43	/*
44	 * Idle the processor
45	 */
46	int (*_do_idle)(int mode);
47	/*
48	 * Processor architecture specific
49	 */
50	struct {	/* CACHE */
51		/*
52		 * flush all caches
53		 */
54		void (*clean_invalidate_all)(void);
55		/*
56		 * flush a specific page or pages
57		 */
58		void (*clean_invalidate_range)(unsigned long address, unsigned long end, int flags);
59		/*
60		 * flush a page to RAM
61		 */
62		void (*_flush_ram_page)(void *virt_page);
63	} cache;
64
65	struct {	/* D-cache */
66		/*
67		 * invalidate the specified data range
68		 */
69		void (*invalidate_range)(unsigned long start, unsigned long end);
70		/*
71		 * clean specified data range
72		 */
73		void (*clean_range)(unsigned long start, unsigned long end);
74		/*
75		 * obsolete flush cache entry
76		 */
77		void (*clean_page)(void *virt_page);
78		/*
79		 * clean a virtual address range from the
80		 * D-cache without flushing the cache.
81		 */
82		void (*clean_entry)(unsigned long start);
83	} dcache;
84
85	struct {	/* I-cache */
86		/*
87		 * invalidate the I-cache for the specified range
88		 */
89		void (*invalidate_range)(unsigned long start, unsigned long end);
90		/*
91		 * invalidate the I-cache for the specified virtual page
92		 */
93		void (*invalidate_page)(void *virt_page);
94	} icache;
95
96	struct {	/* TLB */
97		/*
98		 * flush all TLBs
99		 */
100		void (*invalidate_all)(void);
101		/*
102		 * flush a specific TLB
103		 */
104		void (*invalidate_range)(unsigned long address, unsigned long end);
105		/*
106		 * flush a specific TLB
107		 */
108		void (*invalidate_page)(unsigned long address, int flags);
109	} tlb;
110
111	struct {	/* PageTable */
112		/*
113		 * Set the page table
114		 */
115		void (*set_pgd)(unsigned long pgd_phys);
116		/*
117		 * Set a PMD (handling IMP bit 4)
118		 */
119		void (*set_pmd)(pmd_t *pmdp, pmd_t pmd);
120		/*
121		 * Set a PTE
122		 */
123		void (*set_pte)(pte_t *ptep, pte_t pte);
124	} pgtable;
125} processor;
126
127extern const struct processor arm6_processor_functions;
128extern const struct processor arm7_processor_functions;
129extern const struct processor sa110_processor_functions;
130
131#define cpu_data_abort(pc)			processor._data_abort(pc)
132#define cpu_check_bugs()			processor._check_bugs()
133#define cpu_proc_init()				processor._proc_init()
134#define cpu_proc_fin()				processor._proc_fin()
135#define cpu_reset(addr)				processor.reset(addr)
136#define cpu_do_idle(mode)			processor._do_idle(mode)
137
138#define cpu_cache_clean_invalidate_all()	processor.cache.clean_invalidate_all()
139#define cpu_cache_clean_invalidate_range(s,e,f)	processor.cache.clean_invalidate_range(s,e,f)
140#define cpu_flush_ram_page(vp)			processor.cache._flush_ram_page(vp)
141
142#define cpu_dcache_clean_page(vp)		processor.dcache.clean_page(vp)
143#define cpu_dcache_clean_entry(addr)		processor.dcache.clean_entry(addr)
144#define cpu_dcache_clean_range(s,e)		processor.dcache.clean_range(s,e)
145#define cpu_dcache_invalidate_range(s,e)	processor.dcache.invalidate_range(s,e)
146
147#define cpu_icache_invalidate_range(s,e)	processor.icache.invalidate_range(s,e)
148#define cpu_icache_invalidate_page(vp)		processor.icache.invalidate_page(vp)
149
150#define cpu_tlb_invalidate_all()		processor.tlb.invalidate_all()
151#define cpu_tlb_invalidate_range(s,e)		processor.tlb.invalidate_range(s,e)
152#define cpu_tlb_invalidate_page(vp,f)		processor.tlb.invalidate_page(vp,f)
153
154#define cpu_set_pgd(pgd)			processor.pgtable.set_pgd(pgd)
155#define cpu_set_pmd(pmdp, pmd)			processor.pgtable.set_pmd(pmdp, pmd)
156#define cpu_set_pte(ptep, pte)			processor.pgtable.set_pte(ptep, pte)
157
158#define cpu_switch_mm(pgd,tsk)			cpu_set_pgd(__virt_to_phys((unsigned long)(pgd)))
159
160#define cpu_get_pgd()	\
161	({						\
162		unsigned long pg;			\
163		__asm__("mrc p15, 0, %0, c2, c0, 0"	\
164			 : "=r" (pg));			\
165		pg &= ~0x3fff;				\
166		(pgd_t *)phys_to_virt(pg);		\
167	})
168
169#endif
170