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 */
16 struct task_struct;
17 
18 /*
19  * Don't change this structure - ASM code
20  * relies on it.
21  */
22 extern 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)(void);
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 
127 extern const struct processor arm6_processor_functions;
128 extern const struct processor arm7_processor_functions;
129 extern 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()				processor._do_idle()
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