summaryrefslogtreecommitdiffstats
path: root/include/asm-arm/cpu-multi32.h
blob: 7f07bc8e55cd0d7369b9d30d387c0ffcd0f3b790 (plain)
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
29
30
31
32
33
34
35
36
37
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
66
67
68
69
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
 *  linux/include/asm-arm/cpu-multi32.h
 *
 *  Copyright (C) 2000 Russell King
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#ifndef __ASSEMBLY__

#include <asm/page.h>

/* forward-declare task_struct */
struct task_struct;

/*
 * Don't change this structure - ASM code
 * relies on it.
 */
extern struct processor {
	/* MISC
	 * get data abort address/flags
	 */
	void (*_data_abort)(unsigned long pc);
	/*
	 * check for any bugs
	 */
	void (*_check_bugs)(void);
	/*
	 * Set up any processor specifics
	 */
	void (*_proc_init)(void);
	/*
	 * Disable any processor specifics
	 */
	void (*_proc_fin)(void);
	/*
	 * Special stuff for a reset
	 */
	volatile void (*reset)(unsigned long addr);
	/*
	 * Idle the processor
	 */
	int (*_do_idle)(int mode);
	/*
	 * Processor architecture specific
	 */
	struct {	/* CACHE */
		/*
		 * flush all caches
		 */
		void (*clean_invalidate_all)(void);
		/*
		 * flush a specific page or pages
		 */
		void (*clean_invalidate_range)(unsigned long address, unsigned long end, int flags);
		/*
		 * flush a page to RAM
		 */
		void (*_flush_ram_page)(void *virt_page);
	} cache;

	struct {	/* D-cache */
		/*
		 * invalidate the specified data range
		 */
		void (*invalidate_range)(unsigned long start, unsigned long end);
		/*
		 * clean specified data range
		 */
		void (*clean_range)(unsigned long start, unsigned long end);
		/*
		 * obsolete flush cache entry
		 */
		void (*clean_page)(void *virt_page);
		/*
		 * clean a virtual address range from the
		 * D-cache without flushing the cache.
		 */
		void (*clean_entry)(unsigned long start);
	} dcache;

	struct {	/* I-cache */
		/*
		 * invalidate the I-cache for the specified range
		 */
		void (*invalidate_range)(unsigned long start, unsigned long end);
		/*
		 * invalidate the I-cache for the specified virtual page
		 */
		void (*invalidate_page)(void *virt_page);
	} icache;

	struct {	/* TLB */
		/*
		 * flush all TLBs
		 */
		void (*invalidate_all)(void);
		/*
		 * flush a specific TLB
		 */
		void (*invalidate_range)(unsigned long address, unsigned long end);
		/*
		 * flush a specific TLB
		 */
		void (*invalidate_page)(unsigned long address, int flags);
	} tlb;

	struct {	/* PageTable */
		/*
		 * Set the page table
		 */
		void (*set_pgd)(unsigned long pgd_phys);
		/*
		 * Set a PMD (handling IMP bit 4)
		 */
		void (*set_pmd)(pmd_t *pmdp, pmd_t pmd);
		/*
		 * Set a PTE
		 */
		void (*set_pte)(pte_t *ptep, pte_t pte);
	} pgtable;
} processor;

extern const struct processor arm6_processor_functions;
extern const struct processor arm7_processor_functions;
extern const struct processor sa110_processor_functions;

#define cpu_data_abort(pc)			processor._data_abort(pc)
#define cpu_check_bugs()			processor._check_bugs()
#define cpu_proc_init()				processor._proc_init()
#define cpu_proc_fin()				processor._proc_fin()
#define cpu_reset(addr)				processor.reset(addr)
#define cpu_do_idle(mode)			processor._do_idle(mode)

#define cpu_cache_clean_invalidate_all()	processor.cache.clean_invalidate_all()
#define cpu_cache_clean_invalidate_range(s,e,f)	processor.cache.clean_invalidate_range(s,e,f)
#define cpu_flush_ram_page(vp)			processor.cache._flush_ram_page(vp)

#define cpu_dcache_clean_page(vp)		processor.dcache.clean_page(vp)
#define cpu_dcache_clean_entry(addr)		processor.dcache.clean_entry(addr)
#define cpu_dcache_clean_range(s,e)		processor.dcache.clean_range(s,e)
#define cpu_dcache_invalidate_range(s,e)	processor.dcache.invalidate_range(s,e)

#define cpu_icache_invalidate_range(s,e)	processor.icache.invalidate_range(s,e)
#define cpu_icache_invalidate_page(vp)		processor.icache.invalidate_page(vp)

#define cpu_tlb_invalidate_all()		processor.tlb.invalidate_all()
#define cpu_tlb_invalidate_range(s,e)		processor.tlb.invalidate_range(s,e)
#define cpu_tlb_invalidate_page(vp,f)		processor.tlb.invalidate_page(vp,f)

#define cpu_set_pgd(pgd)			processor.pgtable.set_pgd(pgd)
#define cpu_set_pmd(pmdp, pmd)			processor.pgtable.set_pmd(pmdp, pmd)
#define cpu_set_pte(ptep, pte)			processor.pgtable.set_pte(ptep, pte)

#define cpu_switch_mm(pgd,tsk)			cpu_set_pgd(__virt_to_phys((unsigned long)(pgd)))

#endif