diff options
38 files changed, 1410 insertions, 90 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 9b6d19f74078..73b6e764034c 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
@@ -99,7 +99,16 @@ source "init/Kconfig" | |||
99 | 99 | ||
100 | source "kernel/Kconfig.freezer" | 100 | source "kernel/Kconfig.freezer" |
101 | 101 | ||
102 | menu "System Type" | 102 | menu "Platform selection" |
103 | |||
104 | config ARCH_VEXPRESS | ||
105 | bool "ARMv8 software model (Versatile Express)" | ||
106 | select ARCH_REQUIRE_GPIOLIB | ||
107 | select COMMON_CLK_VERSATILE | ||
108 | select VEXPRESS_CONFIG | ||
109 | help | ||
110 | This enables support for the ARMv8 software model (Versatile | ||
111 | Express). | ||
103 | 112 | ||
104 | endmenu | 113 | endmenu |
105 | 114 | ||
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile index 32ac0aef0068..68457e9e0975 100644 --- a/arch/arm64/boot/dts/Makefile +++ b/arch/arm64/boot/dts/Makefile | |||
@@ -1,3 +1,5 @@ | |||
1 | dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb foundation-v8.dtb | ||
2 | |||
1 | targets += dtbs | 3 | targets += dtbs |
2 | targets += $(dtb-y) | 4 | targets += $(dtb-y) |
3 | 5 | ||
diff --git a/arch/arm64/boot/dts/foundation-v8.dts b/arch/arm64/boot/dts/foundation-v8.dts new file mode 100644 index 000000000000..198682b6de31 --- /dev/null +++ b/arch/arm64/boot/dts/foundation-v8.dts | |||
@@ -0,0 +1,230 @@ | |||
1 | /* | ||
2 | * ARM Ltd. | ||
3 | * | ||
4 | * ARMv8 Foundation model DTS | ||
5 | */ | ||
6 | |||
7 | /dts-v1/; | ||
8 | |||
9 | / { | ||
10 | model = "Foundation-v8A"; | ||
11 | compatible = "arm,foundation-aarch64", "arm,vexpress"; | ||
12 | interrupt-parent = <&gic>; | ||
13 | #address-cells = <2>; | ||
14 | #size-cells = <2>; | ||
15 | |||
16 | chosen { }; | ||
17 | |||
18 | aliases { | ||
19 | serial0 = &v2m_serial0; | ||
20 | serial1 = &v2m_serial1; | ||
21 | serial2 = &v2m_serial2; | ||
22 | serial3 = &v2m_serial3; | ||
23 | }; | ||
24 | |||
25 | cpus { | ||
26 | #address-cells = <1>; | ||
27 | #size-cells = <0>; | ||
28 | |||
29 | cpu@0 { | ||
30 | device_type = "cpu"; | ||
31 | compatible = "arm,armv8"; | ||
32 | reg = <0x0 0x0>; | ||
33 | enable-method = "spin-table"; | ||
34 | cpu-release-addr = <0x0 0x8000fff8>; | ||
35 | }; | ||
36 | cpu@1 { | ||
37 | device_type = "cpu"; | ||
38 | compatible = "arm,armv8"; | ||
39 | reg = <0x0 0x1>; | ||
40 | enable-method = "spin-table"; | ||
41 | cpu-release-addr = <0x0 0x8000fff8>; | ||
42 | }; | ||
43 | cpu@2 { | ||
44 | device_type = "cpu"; | ||
45 | compatible = "arm,armv8"; | ||
46 | reg = <0x0 0x2>; | ||
47 | enable-method = "spin-table"; | ||
48 | cpu-release-addr = <0x0 0x8000fff8>; | ||
49 | }; | ||
50 | cpu@3 { | ||
51 | device_type = "cpu"; | ||
52 | compatible = "arm,armv8"; | ||
53 | reg = <0x0 0x3>; | ||
54 | enable-method = "spin-table"; | ||
55 | cpu-release-addr = <0x0 0x8000fff8>; | ||
56 | }; | ||
57 | }; | ||
58 | |||
59 | memory@80000000 { | ||
60 | device_type = "memory"; | ||
61 | reg = <0x00000000 0x80000000 0 0x80000000>, | ||
62 | <0x00000008 0x80000000 0 0x80000000>; | ||
63 | }; | ||
64 | |||
65 | gic: interrupt-controller@2c001000 { | ||
66 | compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; | ||
67 | #interrupt-cells = <3>; | ||
68 | #address-cells = <0>; | ||
69 | interrupt-controller; | ||
70 | reg = <0x0 0x2c001000 0 0x1000>, | ||
71 | <0x0 0x2c002000 0 0x1000>, | ||
72 | <0x0 0x2c004000 0 0x2000>, | ||
73 | <0x0 0x2c006000 0 0x2000>; | ||
74 | interrupts = <1 9 0xf04>; | ||
75 | }; | ||
76 | |||
77 | timer { | ||
78 | compatible = "arm,armv8-timer"; | ||
79 | interrupts = <1 13 0xff01>, | ||
80 | <1 14 0xff01>, | ||
81 | <1 11 0xff01>, | ||
82 | <1 10 0xff01>; | ||
83 | clock-frequency = <100000000>; | ||
84 | }; | ||
85 | |||
86 | pmu { | ||
87 | compatible = "arm,armv8-pmuv3"; | ||
88 | interrupts = <0 60 4>, | ||
89 | <0 61 4>, | ||
90 | <0 62 4>, | ||
91 | <0 63 4>; | ||
92 | }; | ||
93 | |||
94 | smb { | ||
95 | compatible = "arm,vexpress,v2m-p1", "simple-bus"; | ||
96 | arm,v2m-memory-map = "rs1"; | ||
97 | #address-cells = <2>; /* SMB chipselect number and offset */ | ||
98 | #size-cells = <1>; | ||
99 | |||
100 | ranges = <0 0 0 0x08000000 0x04000000>, | ||
101 | <1 0 0 0x14000000 0x04000000>, | ||
102 | <2 0 0 0x18000000 0x04000000>, | ||
103 | <3 0 0 0x1c000000 0x04000000>, | ||
104 | <4 0 0 0x0c000000 0x04000000>, | ||
105 | <5 0 0 0x10000000 0x04000000>; | ||
106 | |||
107 | #interrupt-cells = <1>; | ||
108 | interrupt-map-mask = <0 0 63>; | ||
109 | interrupt-map = <0 0 0 &gic 0 0 4>, | ||
110 | <0 0 1 &gic 0 1 4>, | ||
111 | <0 0 2 &gic 0 2 4>, | ||
112 | <0 0 3 &gic 0 3 4>, | ||
113 | <0 0 4 &gic 0 4 4>, | ||
114 | <0 0 5 &gic 0 5 4>, | ||
115 | <0 0 6 &gic 0 6 4>, | ||
116 | <0 0 7 &gic 0 7 4>, | ||
117 | <0 0 8 &gic 0 8 4>, | ||
118 | <0 0 9 &gic 0 9 4>, | ||
119 | <0 0 10 &gic 0 10 4>, | ||
120 | <0 0 11 &gic 0 11 4>, | ||
121 | <0 0 12 &gic 0 12 4>, | ||
122 | <0 0 13 &gic 0 13 4>, | ||
123 | <0 0 14 &gic 0 14 4>, | ||
124 | <0 0 15 &gic 0 15 4>, | ||
125 | <0 0 16 &gic 0 16 4>, | ||
126 | <0 0 17 &gic 0 17 4>, | ||
127 | <0 0 18 &gic 0 18 4>, | ||
128 | <0 0 19 &gic 0 19 4>, | ||
129 | <0 0 20 &gic 0 20 4>, | ||
130 | <0 0 21 &gic 0 21 4>, | ||
131 | <0 0 22 &gic 0 22 4>, | ||
132 | <0 0 23 &gic 0 23 4>, | ||
133 | <0 0 24 &gic 0 24 4>, | ||
134 | <0 0 25 &gic 0 25 4>, | ||
135 | <0 0 26 &gic 0 26 4>, | ||
136 | <0 0 27 &gic 0 27 4>, | ||
137 | <0 0 28 &gic 0 28 4>, | ||
138 | <0 0 29 &gic 0 29 4>, | ||
139 | <0 0 30 &gic 0 30 4>, | ||
140 | <0 0 31 &gic 0 31 4>, | ||
141 | <0 0 32 &gic 0 32 4>, | ||
142 | <0 0 33 &gic 0 33 4>, | ||
143 | <0 0 34 &gic 0 34 4>, | ||
144 | <0 0 35 &gic 0 35 4>, | ||
145 | <0 0 36 &gic 0 36 4>, | ||
146 | <0 0 37 &gic 0 37 4>, | ||
147 | <0 0 38 &gic 0 38 4>, | ||
148 | <0 0 39 &gic 0 39 4>, | ||
149 | <0 0 40 &gic 0 40 4>, | ||
150 | <0 0 41 &gic 0 41 4>, | ||
151 | <0 0 42 &gic 0 42 4>; | ||
152 | |||
153 | ethernet@2,02000000 { | ||
154 | compatible = "smsc,lan91c111"; | ||
155 | reg = <2 0x02000000 0x10000>; | ||
156 | interrupts = <15>; | ||
157 | }; | ||
158 | |||
159 | v2m_clk24mhz: clk24mhz { | ||
160 | compatible = "fixed-clock"; | ||
161 | #clock-cells = <0>; | ||
162 | clock-frequency = <24000000>; | ||
163 | clock-output-names = "v2m:clk24mhz"; | ||
164 | }; | ||
165 | |||
166 | v2m_refclk1mhz: refclk1mhz { | ||
167 | compatible = "fixed-clock"; | ||
168 | #clock-cells = <0>; | ||
169 | clock-frequency = <1000000>; | ||
170 | clock-output-names = "v2m:refclk1mhz"; | ||
171 | }; | ||
172 | |||
173 | v2m_refclk32khz: refclk32khz { | ||
174 | compatible = "fixed-clock"; | ||
175 | #clock-cells = <0>; | ||
176 | clock-frequency = <32768>; | ||
177 | clock-output-names = "v2m:refclk32khz"; | ||
178 | }; | ||
179 | |||
180 | iofpga@3,00000000 { | ||
181 | compatible = "arm,amba-bus", "simple-bus"; | ||
182 | #address-cells = <1>; | ||
183 | #size-cells = <1>; | ||
184 | ranges = <0 3 0 0x200000>; | ||
185 | |||
186 | v2m_sysreg: sysreg@010000 { | ||
187 | compatible = "arm,vexpress-sysreg"; | ||
188 | reg = <0x010000 0x1000>; | ||
189 | }; | ||
190 | |||
191 | v2m_serial0: uart@090000 { | ||
192 | compatible = "arm,pl011", "arm,primecell"; | ||
193 | reg = <0x090000 0x1000>; | ||
194 | interrupts = <5>; | ||
195 | clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; | ||
196 | clock-names = "uartclk", "apb_pclk"; | ||
197 | }; | ||
198 | |||
199 | v2m_serial1: uart@0a0000 { | ||
200 | compatible = "arm,pl011", "arm,primecell"; | ||
201 | reg = <0x0a0000 0x1000>; | ||
202 | interrupts = <6>; | ||
203 | clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; | ||
204 | clock-names = "uartclk", "apb_pclk"; | ||
205 | }; | ||
206 | |||
207 | v2m_serial2: uart@0b0000 { | ||
208 | compatible = "arm,pl011", "arm,primecell"; | ||
209 | reg = <0x0b0000 0x1000>; | ||
210 | interrupts = <7>; | ||
211 | clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; | ||
212 | clock-names = "uartclk", "apb_pclk"; | ||
213 | }; | ||
214 | |||
215 | v2m_serial3: uart@0c0000 { | ||
216 | compatible = "arm,pl011", "arm,primecell"; | ||
217 | reg = <0x0c0000 0x1000>; | ||
218 | interrupts = <8>; | ||
219 | clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; | ||
220 | clock-names = "uartclk", "apb_pclk"; | ||
221 | }; | ||
222 | |||
223 | virtio_block@0130000 { | ||
224 | compatible = "virtio,mmio"; | ||
225 | reg = <0x130000 0x1000>; | ||
226 | interrupts = <42>; | ||
227 | }; | ||
228 | }; | ||
229 | }; | ||
230 | }; | ||
diff --git a/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts b/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts new file mode 100644 index 000000000000..572005ea2217 --- /dev/null +++ b/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts | |||
@@ -0,0 +1,159 @@ | |||
1 | /* | ||
2 | * ARM Ltd. Fast Models | ||
3 | * | ||
4 | * Architecture Envelope Model (AEM) ARMv8-A | ||
5 | * ARMAEMv8AMPCT | ||
6 | * | ||
7 | * RTSM_VE_AEMv8A.lisa | ||
8 | */ | ||
9 | |||
10 | /dts-v1/; | ||
11 | |||
12 | /memreserve/ 0x80000000 0x00010000; | ||
13 | |||
14 | / { | ||
15 | model = "RTSM_VE_AEMv8A"; | ||
16 | compatible = "arm,rtsm_ve,aemv8a", "arm,vexpress"; | ||
17 | interrupt-parent = <&gic>; | ||
18 | #address-cells = <2>; | ||
19 | #size-cells = <2>; | ||
20 | |||
21 | chosen { }; | ||
22 | |||
23 | aliases { | ||
24 | serial0 = &v2m_serial0; | ||
25 | serial1 = &v2m_serial1; | ||
26 | serial2 = &v2m_serial2; | ||
27 | serial3 = &v2m_serial3; | ||
28 | }; | ||
29 | |||
30 | cpus { | ||
31 | #address-cells = <2>; | ||
32 | #size-cells = <0>; | ||
33 | |||
34 | cpu@0 { | ||
35 | device_type = "cpu"; | ||
36 | compatible = "arm,armv8"; | ||
37 | reg = <0x0 0x0>; | ||
38 | enable-method = "spin-table"; | ||
39 | cpu-release-addr = <0x0 0x8000fff8>; | ||
40 | }; | ||
41 | cpu@1 { | ||
42 | device_type = "cpu"; | ||
43 | compatible = "arm,armv8"; | ||
44 | reg = <0x0 0x1>; | ||
45 | enable-method = "spin-table"; | ||
46 | cpu-release-addr = <0x0 0x8000fff8>; | ||
47 | }; | ||
48 | cpu@2 { | ||
49 | device_type = "cpu"; | ||
50 | compatible = "arm,armv8"; | ||
51 | reg = <0x0 0x2>; | ||
52 | enable-method = "spin-table"; | ||
53 | cpu-release-addr = <0x0 0x8000fff8>; | ||
54 | }; | ||
55 | cpu@3 { | ||
56 | device_type = "cpu"; | ||
57 | compatible = "arm,armv8"; | ||
58 | reg = <0x0 0x3>; | ||
59 | enable-method = "spin-table"; | ||
60 | cpu-release-addr = <0x0 0x8000fff8>; | ||
61 | }; | ||
62 | }; | ||
63 | |||
64 | memory@80000000 { | ||
65 | device_type = "memory"; | ||
66 | reg = <0x00000000 0x80000000 0 0x80000000>, | ||
67 | <0x00000008 0x80000000 0 0x80000000>; | ||
68 | }; | ||
69 | |||
70 | gic: interrupt-controller@2c001000 { | ||
71 | compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; | ||
72 | #interrupt-cells = <3>; | ||
73 | #address-cells = <0>; | ||
74 | interrupt-controller; | ||
75 | reg = <0x0 0x2c001000 0 0x1000>, | ||
76 | <0x0 0x2c002000 0 0x1000>, | ||
77 | <0x0 0x2c004000 0 0x2000>, | ||
78 | <0x0 0x2c006000 0 0x2000>; | ||
79 | interrupts = <1 9 0xf04>; | ||
80 | }; | ||
81 | |||
82 | timer { | ||
83 | compatible = "arm,armv8-timer"; | ||
84 | interrupts = <1 13 0xff01>, | ||
85 | <1 14 0xff01>, | ||
86 | <1 11 0xff01>, | ||
87 | <1 10 0xff01>; | ||
88 | clock-frequency = <100000000>; | ||
89 | }; | ||
90 | |||
91 | pmu { | ||
92 | compatible = "arm,armv8-pmuv3"; | ||
93 | interrupts = <0 60 4>, | ||
94 | <0 61 4>, | ||
95 | <0 62 4>, | ||
96 | <0 63 4>; | ||
97 | }; | ||
98 | |||
99 | smb { | ||
100 | compatible = "simple-bus"; | ||
101 | |||
102 | #address-cells = <2>; | ||
103 | #size-cells = <1>; | ||
104 | ranges = <0 0 0 0x08000000 0x04000000>, | ||
105 | <1 0 0 0x14000000 0x04000000>, | ||
106 | <2 0 0 0x18000000 0x04000000>, | ||
107 | <3 0 0 0x1c000000 0x04000000>, | ||
108 | <4 0 0 0x0c000000 0x04000000>, | ||
109 | <5 0 0 0x10000000 0x04000000>; | ||
110 | |||
111 | #interrupt-cells = <1>; | ||
112 | interrupt-map-mask = <0 0 63>; | ||
113 | interrupt-map = <0 0 0 &gic 0 0 4>, | ||
114 | <0 0 1 &gic 0 1 4>, | ||
115 | <0 0 2 &gic 0 2 4>, | ||
116 | <0 0 3 &gic 0 3 4>, | ||
117 | <0 0 4 &gic 0 4 4>, | ||
118 | <0 0 5 &gic 0 5 4>, | ||
119 | <0 0 6 &gic 0 6 4>, | ||
120 | <0 0 7 &gic 0 7 4>, | ||
121 | <0 0 8 &gic 0 8 4>, | ||
122 | <0 0 9 &gic 0 9 4>, | ||
123 | <0 0 10 &gic 0 10 4>, | ||
124 | <0 0 11 &gic 0 11 4>, | ||
125 | <0 0 12 &gic 0 12 4>, | ||
126 | <0 0 13 &gic 0 13 4>, | ||
127 | <0 0 14 &gic 0 14 4>, | ||
128 | <0 0 15 &gic 0 15 4>, | ||
129 | <0 0 16 &gic 0 16 4>, | ||
130 | <0 0 17 &gic 0 17 4>, | ||
131 | <0 0 18 &gic 0 18 4>, | ||
132 | <0 0 19 &gic 0 19 4>, | ||
133 | <0 0 20 &gic 0 20 4>, | ||
134 | <0 0 21 &gic 0 21 4>, | ||
135 | <0 0 22 &gic 0 22 4>, | ||
136 | <0 0 23 &gic 0 23 4>, | ||
137 | <0 0 24 &gic 0 24 4>, | ||
138 | <0 0 25 &gic 0 25 4>, | ||
139 | <0 0 26 &gic 0 26 4>, | ||
140 | <0 0 27 &gic 0 27 4>, | ||
141 | <0 0 28 &gic 0 28 4>, | ||
142 | <0 0 29 &gic 0 29 4>, | ||
143 | <0 0 30 &gic 0 30 4>, | ||
144 | <0 0 31 &gic 0 31 4>, | ||
145 | <0 0 32 &gic 0 32 4>, | ||
146 | <0 0 33 &gic 0 33 4>, | ||
147 | <0 0 34 &gic 0 34 4>, | ||
148 | <0 0 35 &gic 0 35 4>, | ||
149 | <0 0 36 &gic 0 36 4>, | ||
150 | <0 0 37 &gic 0 37 4>, | ||
151 | <0 0 38 &gic 0 38 4>, | ||
152 | <0 0 39 &gic 0 39 4>, | ||
153 | <0 0 40 &gic 0 40 4>, | ||
154 | <0 0 41 &gic 0 41 4>, | ||
155 | <0 0 42 &gic 0 42 4>; | ||
156 | |||
157 | /include/ "rtsm_ve-motherboard.dtsi" | ||
158 | }; | ||
159 | }; | ||
diff --git a/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi b/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi new file mode 100644 index 000000000000..b45e5f39f577 --- /dev/null +++ b/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi | |||
@@ -0,0 +1,234 @@ | |||
1 | /* | ||
2 | * ARM Ltd. Fast Models | ||
3 | * | ||
4 | * Versatile Express (VE) system model | ||
5 | * Motherboard component | ||
6 | * | ||
7 | * VEMotherBoard.lisa | ||
8 | */ | ||
9 | |||
10 | motherboard { | ||
11 | arm,v2m-memory-map = "rs1"; | ||
12 | compatible = "arm,vexpress,v2m-p1", "simple-bus"; | ||
13 | #address-cells = <2>; /* SMB chipselect number and offset */ | ||
14 | #size-cells = <1>; | ||
15 | #interrupt-cells = <1>; | ||
16 | ranges; | ||
17 | |||
18 | flash@0,00000000 { | ||
19 | compatible = "arm,vexpress-flash", "cfi-flash"; | ||
20 | reg = <0 0x00000000 0x04000000>, | ||
21 | <4 0x00000000 0x04000000>; | ||
22 | bank-width = <4>; | ||
23 | }; | ||
24 | |||
25 | vram@2,00000000 { | ||
26 | compatible = "arm,vexpress-vram"; | ||
27 | reg = <2 0x00000000 0x00800000>; | ||
28 | }; | ||
29 | |||
30 | ethernet@2,02000000 { | ||
31 | compatible = "smsc,lan91c111"; | ||
32 | reg = <2 0x02000000 0x10000>; | ||
33 | interrupts = <15>; | ||
34 | }; | ||
35 | |||
36 | v2m_clk24mhz: clk24mhz { | ||
37 | compatible = "fixed-clock"; | ||
38 | #clock-cells = <0>; | ||
39 | clock-frequency = <24000000>; | ||
40 | clock-output-names = "v2m:clk24mhz"; | ||
41 | }; | ||
42 | |||
43 | v2m_refclk1mhz: refclk1mhz { | ||
44 | compatible = "fixed-clock"; | ||
45 | #clock-cells = <0>; | ||
46 | clock-frequency = <1000000>; | ||
47 | clock-output-names = "v2m:refclk1mhz"; | ||
48 | }; | ||
49 | |||
50 | v2m_refclk32khz: refclk32khz { | ||
51 | compatible = "fixed-clock"; | ||
52 | #clock-cells = <0>; | ||
53 | clock-frequency = <32768>; | ||
54 | clock-output-names = "v2m:refclk32khz"; | ||
55 | }; | ||
56 | |||
57 | iofpga@3,00000000 { | ||
58 | compatible = "arm,amba-bus", "simple-bus"; | ||
59 | #address-cells = <1>; | ||
60 | #size-cells = <1>; | ||
61 | ranges = <0 3 0 0x200000>; | ||
62 | |||
63 | v2m_sysreg: sysreg@010000 { | ||
64 | compatible = "arm,vexpress-sysreg"; | ||
65 | reg = <0x010000 0x1000>; | ||
66 | gpio-controller; | ||
67 | #gpio-cells = <2>; | ||
68 | }; | ||
69 | |||
70 | v2m_sysctl: sysctl@020000 { | ||
71 | compatible = "arm,sp810", "arm,primecell"; | ||
72 | reg = <0x020000 0x1000>; | ||
73 | clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&v2m_clk24mhz>; | ||
74 | clock-names = "refclk", "timclk", "apb_pclk"; | ||
75 | #clock-cells = <1>; | ||
76 | clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3"; | ||
77 | }; | ||
78 | |||
79 | aaci@040000 { | ||
80 | compatible = "arm,pl041", "arm,primecell"; | ||
81 | reg = <0x040000 0x1000>; | ||
82 | interrupts = <11>; | ||
83 | clocks = <&v2m_clk24mhz>; | ||
84 | clock-names = "apb_pclk"; | ||
85 | }; | ||
86 | |||
87 | mmci@050000 { | ||
88 | compatible = "arm,pl180", "arm,primecell"; | ||
89 | reg = <0x050000 0x1000>; | ||
90 | interrupts = <9 10>; | ||
91 | cd-gpios = <&v2m_sysreg 0 0>; | ||
92 | wp-gpios = <&v2m_sysreg 1 0>; | ||
93 | max-frequency = <12000000>; | ||
94 | vmmc-supply = <&v2m_fixed_3v3>; | ||
95 | clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; | ||
96 | clock-names = "mclk", "apb_pclk"; | ||
97 | }; | ||
98 | |||
99 | kmi@060000 { | ||
100 | compatible = "arm,pl050", "arm,primecell"; | ||
101 | reg = <0x060000 0x1000>; | ||
102 | interrupts = <12>; | ||
103 | clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; | ||
104 | clock-names = "KMIREFCLK", "apb_pclk"; | ||
105 | }; | ||
106 | |||
107 | kmi@070000 { | ||
108 | compatible = "arm,pl050", "arm,primecell"; | ||
109 | reg = <0x070000 0x1000>; | ||
110 | interrupts = <13>; | ||
111 | clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; | ||
112 | clock-names = "KMIREFCLK", "apb_pclk"; | ||
113 | }; | ||
114 | |||
115 | v2m_serial0: uart@090000 { | ||
116 | compatible = "arm,pl011", "arm,primecell"; | ||
117 | reg = <0x090000 0x1000>; | ||
118 | interrupts = <5>; | ||
119 | clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; | ||
120 | clock-names = "uartclk", "apb_pclk"; | ||
121 | }; | ||
122 | |||
123 | v2m_serial1: uart@0a0000 { | ||
124 | compatible = "arm,pl011", "arm,primecell"; | ||
125 | reg = <0x0a0000 0x1000>; | ||
126 | interrupts = <6>; | ||
127 | clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; | ||
128 | clock-names = "uartclk", "apb_pclk"; | ||
129 | }; | ||
130 | |||
131 | v2m_serial2: uart@0b0000 { | ||
132 | compatible = "arm,pl011", "arm,primecell"; | ||
133 | reg = <0x0b0000 0x1000>; | ||
134 | interrupts = <7>; | ||
135 | clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; | ||
136 | clock-names = "uartclk", "apb_pclk"; | ||
137 | }; | ||
138 | |||
139 | v2m_serial3: uart@0c0000 { | ||
140 | compatible = "arm,pl011", "arm,primecell"; | ||
141 | reg = <0x0c0000 0x1000>; | ||
142 | interrupts = <8>; | ||
143 | clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; | ||
144 | clock-names = "uartclk", "apb_pclk"; | ||
145 | }; | ||
146 | |||
147 | wdt@0f0000 { | ||
148 | compatible = "arm,sp805", "arm,primecell"; | ||
149 | reg = <0x0f0000 0x1000>; | ||
150 | interrupts = <0>; | ||
151 | clocks = <&v2m_refclk32khz>, <&v2m_clk24mhz>; | ||
152 | clock-names = "wdogclk", "apb_pclk"; | ||
153 | }; | ||
154 | |||
155 | v2m_timer01: timer@110000 { | ||
156 | compatible = "arm,sp804", "arm,primecell"; | ||
157 | reg = <0x110000 0x1000>; | ||
158 | interrupts = <2>; | ||
159 | clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_clk24mhz>; | ||
160 | clock-names = "timclken1", "timclken2", "apb_pclk"; | ||
161 | }; | ||
162 | |||
163 | v2m_timer23: timer@120000 { | ||
164 | compatible = "arm,sp804", "arm,primecell"; | ||
165 | reg = <0x120000 0x1000>; | ||
166 | interrupts = <3>; | ||
167 | clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&v2m_clk24mhz>; | ||
168 | clock-names = "timclken1", "timclken2", "apb_pclk"; | ||
169 | }; | ||
170 | |||
171 | rtc@170000 { | ||
172 | compatible = "arm,pl031", "arm,primecell"; | ||
173 | reg = <0x170000 0x1000>; | ||
174 | interrupts = <4>; | ||
175 | clocks = <&v2m_clk24mhz>; | ||
176 | clock-names = "apb_pclk"; | ||
177 | }; | ||
178 | |||
179 | clcd@1f0000 { | ||
180 | compatible = "arm,pl111", "arm,primecell"; | ||
181 | reg = <0x1f0000 0x1000>; | ||
182 | interrupts = <14>; | ||
183 | clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>; | ||
184 | clock-names = "clcdclk", "apb_pclk"; | ||
185 | }; | ||
186 | }; | ||
187 | |||
188 | v2m_fixed_3v3: fixedregulator@0 { | ||
189 | compatible = "regulator-fixed"; | ||
190 | regulator-name = "3V3"; | ||
191 | regulator-min-microvolt = <3300000>; | ||
192 | regulator-max-microvolt = <3300000>; | ||
193 | regulator-always-on; | ||
194 | }; | ||
195 | |||
196 | mcc { | ||
197 | compatible = "arm,vexpress,config-bus", "simple-bus"; | ||
198 | arm,vexpress,config-bridge = <&v2m_sysreg>; | ||
199 | |||
200 | v2m_oscclk1: osc@1 { | ||
201 | /* CLCD clock */ | ||
202 | compatible = "arm,vexpress-osc"; | ||
203 | arm,vexpress-sysreg,func = <1 1>; | ||
204 | freq-range = <23750000 63500000>; | ||
205 | #clock-cells = <0>; | ||
206 | clock-output-names = "v2m:oscclk1"; | ||
207 | }; | ||
208 | |||
209 | reset@0 { | ||
210 | compatible = "arm,vexpress-reset"; | ||
211 | arm,vexpress-sysreg,func = <5 0>; | ||
212 | }; | ||
213 | |||
214 | muxfpga@0 { | ||
215 | compatible = "arm,vexpress-muxfpga"; | ||
216 | arm,vexpress-sysreg,func = <7 0>; | ||
217 | }; | ||
218 | |||
219 | shutdown@0 { | ||
220 | compatible = "arm,vexpress-shutdown"; | ||
221 | arm,vexpress-sysreg,func = <8 0>; | ||
222 | }; | ||
223 | |||
224 | reboot@0 { | ||
225 | compatible = "arm,vexpress-reboot"; | ||
226 | arm,vexpress-sysreg,func = <9 0>; | ||
227 | }; | ||
228 | |||
229 | dvimode@0 { | ||
230 | compatible = "arm,vexpress-dvimode"; | ||
231 | arm,vexpress-sysreg,func = <11 0>; | ||
232 | }; | ||
233 | }; | ||
234 | }; | ||
diff --git a/arch/arm64/boot/dts/skeleton.dtsi b/arch/arm64/boot/dts/skeleton.dtsi new file mode 100644 index 000000000000..38ead821bb42 --- /dev/null +++ b/arch/arm64/boot/dts/skeleton.dtsi | |||
@@ -0,0 +1,13 @@ | |||
1 | /* | ||
2 | * Skeleton device tree; the bare minimum needed to boot; just include and | ||
3 | * add a compatible value. The bootloader will typically populate the memory | ||
4 | * node. | ||
5 | */ | ||
6 | |||
7 | / { | ||
8 | #address-cells = <2>; | ||
9 | #size-cells = <1>; | ||
10 | chosen { }; | ||
11 | aliases { }; | ||
12 | memory { device_type = "memory"; reg = <0 0 0>; }; | ||
13 | }; | ||
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 09bef29f3a09..8d9696adb440 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig | |||
@@ -23,6 +23,7 @@ CONFIG_MODULES=y | |||
23 | CONFIG_MODULE_UNLOAD=y | 23 | CONFIG_MODULE_UNLOAD=y |
24 | # CONFIG_BLK_DEV_BSG is not set | 24 | # CONFIG_BLK_DEV_BSG is not set |
25 | # CONFIG_IOSCHED_DEADLINE is not set | 25 | # CONFIG_IOSCHED_DEADLINE is not set |
26 | CONFIG_ARCH_VEXPRESS=y | ||
26 | CONFIG_SMP=y | 27 | CONFIG_SMP=y |
27 | CONFIG_PREEMPT_VOLUNTARY=y | 28 | CONFIG_PREEMPT_VOLUNTARY=y |
28 | CONFIG_CMDLINE="console=ttyAMA0" | 29 | CONFIG_CMDLINE="console=ttyAMA0" |
@@ -47,11 +48,14 @@ CONFIG_BLK_DEV_SD=y | |||
47 | # CONFIG_SCSI_LOWLEVEL is not set | 48 | # CONFIG_SCSI_LOWLEVEL is not set |
48 | CONFIG_NETDEVICES=y | 49 | CONFIG_NETDEVICES=y |
49 | CONFIG_MII=y | 50 | CONFIG_MII=y |
51 | CONFIG_SMC91X=y | ||
50 | # CONFIG_WLAN is not set | 52 | # CONFIG_WLAN is not set |
51 | CONFIG_INPUT_EVDEV=y | 53 | CONFIG_INPUT_EVDEV=y |
52 | # CONFIG_SERIO_I8042 is not set | 54 | # CONFIG_SERIO_I8042 is not set |
53 | # CONFIG_SERIO_SERPORT is not set | 55 | # CONFIG_SERIO_SERPORT is not set |
54 | CONFIG_LEGACY_PTY_COUNT=16 | 56 | CONFIG_LEGACY_PTY_COUNT=16 |
57 | CONFIG_SERIAL_AMBA_PL011=y | ||
58 | CONFIG_SERIAL_AMBA_PL011_CONSOLE=y | ||
55 | # CONFIG_HW_RANDOM is not set | 59 | # CONFIG_HW_RANDOM is not set |
56 | # CONFIG_HWMON is not set | 60 | # CONFIG_HWMON is not set |
57 | CONFIG_FB=y | 61 | CONFIG_FB=y |
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild index e5fe4f99fe10..79a642d199f2 100644 --- a/arch/arm64/include/asm/Kbuild +++ b/arch/arm64/include/asm/Kbuild | |||
@@ -39,7 +39,6 @@ generic-y += shmbuf.h | |||
39 | generic-y += sizes.h | 39 | generic-y += sizes.h |
40 | generic-y += socket.h | 40 | generic-y += socket.h |
41 | generic-y += sockios.h | 41 | generic-y += sockios.h |
42 | generic-y += string.h | ||
43 | generic-y += switch_to.h | 42 | generic-y += switch_to.h |
44 | generic-y += swab.h | 43 | generic-y += swab.h |
45 | generic-y += termbits.h | 44 | generic-y += termbits.h |
@@ -49,4 +48,5 @@ generic-y += trace_clock.h | |||
49 | generic-y += types.h | 48 | generic-y += types.h |
50 | generic-y += unaligned.h | 49 | generic-y += unaligned.h |
51 | generic-y += user.h | 50 | generic-y += user.h |
51 | generic-y += vga.h | ||
52 | generic-y += xor.h | 52 | generic-y += xor.h |
diff --git a/arch/arm64/include/asm/bitops.h b/arch/arm64/include/asm/bitops.h index 5e693073b030..aa5b59d6ba43 100644 --- a/arch/arm64/include/asm/bitops.h +++ b/arch/arm64/include/asm/bitops.h | |||
@@ -32,6 +32,16 @@ | |||
32 | #error only <linux/bitops.h> can be included directly | 32 | #error only <linux/bitops.h> can be included directly |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | /* | ||
36 | * Little endian assembly atomic bitops. | ||
37 | */ | ||
38 | extern void set_bit(int nr, volatile unsigned long *p); | ||
39 | extern void clear_bit(int nr, volatile unsigned long *p); | ||
40 | extern void change_bit(int nr, volatile unsigned long *p); | ||
41 | extern int test_and_set_bit(int nr, volatile unsigned long *p); | ||
42 | extern int test_and_clear_bit(int nr, volatile unsigned long *p); | ||
43 | extern int test_and_change_bit(int nr, volatile unsigned long *p); | ||
44 | |||
35 | #include <asm-generic/bitops/builtin-__ffs.h> | 45 | #include <asm-generic/bitops/builtin-__ffs.h> |
36 | #include <asm-generic/bitops/builtin-ffs.h> | 46 | #include <asm-generic/bitops/builtin-ffs.h> |
37 | #include <asm-generic/bitops/builtin-__fls.h> | 47 | #include <asm-generic/bitops/builtin-__fls.h> |
@@ -45,9 +55,13 @@ | |||
45 | #include <asm-generic/bitops/hweight.h> | 55 | #include <asm-generic/bitops/hweight.h> |
46 | #include <asm-generic/bitops/lock.h> | 56 | #include <asm-generic/bitops/lock.h> |
47 | 57 | ||
48 | #include <asm-generic/bitops/atomic.h> | ||
49 | #include <asm-generic/bitops/non-atomic.h> | 58 | #include <asm-generic/bitops/non-atomic.h> |
50 | #include <asm-generic/bitops/le.h> | 59 | #include <asm-generic/bitops/le.h> |
51 | #include <asm-generic/bitops/ext2-atomic.h> | 60 | |
61 | /* | ||
62 | * Ext2 is defined to use little-endian byte ordering. | ||
63 | */ | ||
64 | #define ext2_set_bit_atomic(lock, nr, p) test_and_set_bit_le(nr, p) | ||
65 | #define ext2_clear_bit_atomic(lock, nr, p) test_and_clear_bit_le(nr, p) | ||
52 | 66 | ||
53 | #endif /* __ASM_BITOPS_H */ | 67 | #endif /* __ASM_BITOPS_H */ |
diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h index 968b5cbfc260..8a8ce0e73a38 100644 --- a/arch/arm64/include/asm/cmpxchg.h +++ b/arch/arm64/include/asm/cmpxchg.h | |||
@@ -170,4 +170,7 @@ static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old, | |||
170 | (unsigned long)(n), \ | 170 | (unsigned long)(n), \ |
171 | sizeof(*(ptr)))) | 171 | sizeof(*(ptr)))) |
172 | 172 | ||
173 | #define cmpxchg64(ptr,o,n) cmpxchg((ptr),(o),(n)) | ||
174 | #define cmpxchg64_local(ptr,o,n) cmpxchg_local((ptr),(o),(n)) | ||
175 | |||
173 | #endif /* __ASM_CMPXCHG_H */ | 176 | #endif /* __ASM_CMPXCHG_H */ |
diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h index 618b450e5a1d..899af807ef0f 100644 --- a/arch/arm64/include/asm/compat.h +++ b/arch/arm64/include/asm/compat.h | |||
@@ -35,14 +35,16 @@ typedef s32 compat_clock_t; | |||
35 | typedef s32 compat_pid_t; | 35 | typedef s32 compat_pid_t; |
36 | typedef u32 __compat_uid_t; | 36 | typedef u32 __compat_uid_t; |
37 | typedef u32 __compat_gid_t; | 37 | typedef u32 __compat_gid_t; |
38 | typedef u16 __compat_uid16_t; | ||
39 | typedef u16 __compat_gid16_t; | ||
38 | typedef u32 __compat_uid32_t; | 40 | typedef u32 __compat_uid32_t; |
39 | typedef u32 __compat_gid32_t; | 41 | typedef u32 __compat_gid32_t; |
40 | typedef u32 compat_mode_t; | 42 | typedef u16 compat_mode_t; |
41 | typedef u32 compat_ino_t; | 43 | typedef u32 compat_ino_t; |
42 | typedef u32 compat_dev_t; | 44 | typedef u32 compat_dev_t; |
43 | typedef s32 compat_off_t; | 45 | typedef s32 compat_off_t; |
44 | typedef s64 compat_loff_t; | 46 | typedef s64 compat_loff_t; |
45 | typedef s16 compat_nlink_t; | 47 | typedef s32 compat_nlink_t; |
46 | typedef u16 compat_ipc_pid_t; | 48 | typedef u16 compat_ipc_pid_t; |
47 | typedef s32 compat_daddr_t; | 49 | typedef s32 compat_daddr_t; |
48 | typedef u32 compat_caddr_t; | 50 | typedef u32 compat_caddr_t; |
@@ -50,9 +52,11 @@ typedef __kernel_fsid_t compat_fsid_t; | |||
50 | typedef s32 compat_key_t; | 52 | typedef s32 compat_key_t; |
51 | typedef s32 compat_timer_t; | 53 | typedef s32 compat_timer_t; |
52 | 54 | ||
55 | typedef s16 compat_short_t; | ||
53 | typedef s32 compat_int_t; | 56 | typedef s32 compat_int_t; |
54 | typedef s32 compat_long_t; | 57 | typedef s32 compat_long_t; |
55 | typedef s64 compat_s64; | 58 | typedef s64 compat_s64; |
59 | typedef u16 compat_ushort_t; | ||
56 | typedef u32 compat_uint_t; | 60 | typedef u32 compat_uint_t; |
57 | typedef u32 compat_ulong_t; | 61 | typedef u32 compat_ulong_t; |
58 | typedef u64 compat_u64; | 62 | typedef u64 compat_u64; |
@@ -72,20 +76,20 @@ struct compat_stat { | |||
72 | compat_dev_t st_dev; | 76 | compat_dev_t st_dev; |
73 | compat_ino_t st_ino; | 77 | compat_ino_t st_ino; |
74 | compat_mode_t st_mode; | 78 | compat_mode_t st_mode; |
75 | compat_nlink_t st_nlink; | 79 | compat_ushort_t st_nlink; |
76 | __compat_uid32_t st_uid; | 80 | __compat_uid16_t st_uid; |
77 | __compat_gid32_t st_gid; | 81 | __compat_gid16_t st_gid; |
78 | compat_dev_t st_rdev; | 82 | compat_dev_t st_rdev; |
79 | compat_off_t st_size; | 83 | compat_off_t st_size; |
80 | compat_off_t st_blksize; | 84 | compat_off_t st_blksize; |
81 | compat_off_t st_blocks; | 85 | compat_off_t st_blocks; |
82 | compat_time_t st_atime; | 86 | compat_time_t st_atime; |
83 | u32 st_atime_nsec; | 87 | compat_ulong_t st_atime_nsec; |
84 | compat_time_t st_mtime; | 88 | compat_time_t st_mtime; |
85 | u32 st_mtime_nsec; | 89 | compat_ulong_t st_mtime_nsec; |
86 | compat_time_t st_ctime; | 90 | compat_time_t st_ctime; |
87 | u32 st_ctime_nsec; | 91 | compat_ulong_t st_ctime_nsec; |
88 | u32 __unused4[2]; | 92 | compat_ulong_t __unused4[2]; |
89 | }; | 93 | }; |
90 | 94 | ||
91 | struct compat_flock { | 95 | struct compat_flock { |
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index ef54125e6c1e..cf2749488cd4 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #define __ASM_CPUTYPE_H | 17 | #define __ASM_CPUTYPE_H |
18 | 18 | ||
19 | #define ID_MIDR_EL1 "midr_el1" | 19 | #define ID_MIDR_EL1 "midr_el1" |
20 | #define ID_MPIDR_EL1 "mpidr_el1" | ||
20 | #define ID_CTR_EL0 "ctr_el0" | 21 | #define ID_CTR_EL0 "ctr_el0" |
21 | 22 | ||
22 | #define ID_AA64PFR0_EL1 "id_aa64pfr0_el1" | 23 | #define ID_AA64PFR0_EL1 "id_aa64pfr0_el1" |
@@ -25,12 +26,24 @@ | |||
25 | #define ID_AA64ISAR0_EL1 "id_aa64isar0_el1" | 26 | #define ID_AA64ISAR0_EL1 "id_aa64isar0_el1" |
26 | #define ID_AA64MMFR0_EL1 "id_aa64mmfr0_el1" | 27 | #define ID_AA64MMFR0_EL1 "id_aa64mmfr0_el1" |
27 | 28 | ||
29 | #define INVALID_HWID ULONG_MAX | ||
30 | |||
31 | #define MPIDR_HWID_BITMASK 0xff00ffffff | ||
32 | |||
28 | #define read_cpuid(reg) ({ \ | 33 | #define read_cpuid(reg) ({ \ |
29 | u64 __val; \ | 34 | u64 __val; \ |
30 | asm("mrs %0, " reg : "=r" (__val)); \ | 35 | asm("mrs %0, " reg : "=r" (__val)); \ |
31 | __val; \ | 36 | __val; \ |
32 | }) | 37 | }) |
33 | 38 | ||
39 | #define ARM_CPU_IMP_ARM 0x41 | ||
40 | |||
41 | #define ARM_CPU_PART_AEM_V8 0xD0F0 | ||
42 | #define ARM_CPU_PART_FOUNDATION 0xD000 | ||
43 | #define ARM_CPU_PART_CORTEX_A57 0xD070 | ||
44 | |||
45 | #ifndef __ASSEMBLY__ | ||
46 | |||
34 | /* | 47 | /* |
35 | * The CPU ID never changes at run time, so we might as well tell the | 48 | * The CPU ID never changes at run time, so we might as well tell the |
36 | * compiler that it's constant. Use this function to read the CPU ID | 49 | * compiler that it's constant. Use this function to read the CPU ID |
@@ -41,9 +54,26 @@ static inline u32 __attribute_const__ read_cpuid_id(void) | |||
41 | return read_cpuid(ID_MIDR_EL1); | 54 | return read_cpuid(ID_MIDR_EL1); |
42 | } | 55 | } |
43 | 56 | ||
57 | static inline u64 __attribute_const__ read_cpuid_mpidr(void) | ||
58 | { | ||
59 | return read_cpuid(ID_MPIDR_EL1); | ||
60 | } | ||
61 | |||
62 | static inline unsigned int __attribute_const__ read_cpuid_implementor(void) | ||
63 | { | ||
64 | return (read_cpuid_id() & 0xFF000000) >> 24; | ||
65 | } | ||
66 | |||
67 | static inline unsigned int __attribute_const__ read_cpuid_part_number(void) | ||
68 | { | ||
69 | return (read_cpuid_id() & 0xFFF0); | ||
70 | } | ||
71 | |||
44 | static inline u32 __attribute_const__ read_cpuid_cachetype(void) | 72 | static inline u32 __attribute_const__ read_cpuid_cachetype(void) |
45 | { | 73 | { |
46 | return read_cpuid(ID_CTR_EL0); | 74 | return read_cpuid(ID_CTR_EL0); |
47 | } | 75 | } |
48 | 76 | ||
77 | #endif /* __ASSEMBLY__ */ | ||
78 | |||
49 | #endif | 79 | #endif |
diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h new file mode 100644 index 000000000000..78834123a32e --- /dev/null +++ b/arch/arm64/include/asm/esr.h | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 - ARM Ltd | ||
3 | * Author: Marc Zyngier <marc.zyngier@arm.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #ifndef __ASM_ESR_H | ||
19 | #define __ASM_ESR_H | ||
20 | |||
21 | #define ESR_EL1_EC_SHIFT (26) | ||
22 | #define ESR_EL1_IL (1U << 25) | ||
23 | |||
24 | #define ESR_EL1_EC_UNKNOWN (0x00) | ||
25 | #define ESR_EL1_EC_WFI (0x01) | ||
26 | #define ESR_EL1_EC_CP15_32 (0x03) | ||
27 | #define ESR_EL1_EC_CP15_64 (0x04) | ||
28 | #define ESR_EL1_EC_CP14_MR (0x05) | ||
29 | #define ESR_EL1_EC_CP14_LS (0x06) | ||
30 | #define ESR_EL1_EC_FP_ASIMD (0x07) | ||
31 | #define ESR_EL1_EC_CP10_ID (0x08) | ||
32 | #define ESR_EL1_EC_CP14_64 (0x0C) | ||
33 | #define ESR_EL1_EC_ILL_ISS (0x0E) | ||
34 | #define ESR_EL1_EC_SVC32 (0x11) | ||
35 | #define ESR_EL1_EC_SVC64 (0x15) | ||
36 | #define ESR_EL1_EC_SYS64 (0x18) | ||
37 | #define ESR_EL1_EC_IABT_EL0 (0x20) | ||
38 | #define ESR_EL1_EC_IABT_EL1 (0x21) | ||
39 | #define ESR_EL1_EC_PC_ALIGN (0x22) | ||
40 | #define ESR_EL1_EC_DABT_EL0 (0x24) | ||
41 | #define ESR_EL1_EC_DABT_EL1 (0x25) | ||
42 | #define ESR_EL1_EC_SP_ALIGN (0x26) | ||
43 | #define ESR_EL1_EC_FP_EXC32 (0x28) | ||
44 | #define ESR_EL1_EC_FP_EXC64 (0x2C) | ||
45 | #define ESR_EL1_EC_SERRROR (0x2F) | ||
46 | #define ESR_EL1_EC_BREAKPT_EL0 (0x30) | ||
47 | #define ESR_EL1_EC_BREAKPT_EL1 (0x31) | ||
48 | #define ESR_EL1_EC_SOFTSTP_EL0 (0x32) | ||
49 | #define ESR_EL1_EC_SOFTSTP_EL1 (0x33) | ||
50 | #define ESR_EL1_EC_WATCHPT_EL0 (0x34) | ||
51 | #define ESR_EL1_EC_WATCHPT_EL1 (0x35) | ||
52 | #define ESR_EL1_EC_BKPT32 (0x38) | ||
53 | #define ESR_EL1_EC_BRK64 (0x3C) | ||
54 | |||
55 | #endif /* __ASM_ESR_H */ | ||
diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h index ac63519b7b90..0303705fcad6 100644 --- a/arch/arm64/include/asm/exception.h +++ b/arch/arm64/include/asm/exception.h | |||
@@ -19,5 +19,6 @@ | |||
19 | #define __ASM_EXCEPTION_H | 19 | #define __ASM_EXCEPTION_H |
20 | 20 | ||
21 | #define __exception __attribute__((section(".exception.text"))) | 21 | #define __exception __attribute__((section(".exception.text"))) |
22 | #define __exception_irq_entry __exception | ||
22 | 23 | ||
23 | #endif /* __ASM_EXCEPTION_H */ | 24 | #endif /* __ASM_EXCEPTION_H */ |
diff --git a/arch/arm64/include/asm/hardirq.h b/arch/arm64/include/asm/hardirq.h index 507546353d62..990c051e7829 100644 --- a/arch/arm64/include/asm/hardirq.h +++ b/arch/arm64/include/asm/hardirq.h | |||
@@ -49,4 +49,9 @@ static inline void ack_bad_irq(unsigned int irq) | |||
49 | 49 | ||
50 | extern void handle_IRQ(unsigned int, struct pt_regs *); | 50 | extern void handle_IRQ(unsigned int, struct pt_regs *); |
51 | 51 | ||
52 | /* | ||
53 | * No arch-specific IRQ flags. | ||
54 | */ | ||
55 | #define set_irq_flags(irq, flags) | ||
56 | |||
52 | #endif /* __ASM_HARDIRQ_H */ | 57 | #endif /* __ASM_HARDIRQ_H */ |
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h index 57f12c991de2..2e12258aa7e4 100644 --- a/arch/arm64/include/asm/io.h +++ b/arch/arm64/include/asm/io.h | |||
@@ -92,10 +92,12 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) | |||
92 | #define readb_relaxed(c) ({ u8 __v = __raw_readb(c); __v; }) | 92 | #define readb_relaxed(c) ({ u8 __v = __raw_readb(c); __v; }) |
93 | #define readw_relaxed(c) ({ u16 __v = le16_to_cpu((__force __le16)__raw_readw(c)); __v; }) | 93 | #define readw_relaxed(c) ({ u16 __v = le16_to_cpu((__force __le16)__raw_readw(c)); __v; }) |
94 | #define readl_relaxed(c) ({ u32 __v = le32_to_cpu((__force __le32)__raw_readl(c)); __v; }) | 94 | #define readl_relaxed(c) ({ u32 __v = le32_to_cpu((__force __le32)__raw_readl(c)); __v; }) |
95 | #define readq_relaxed(c) ({ u64 __v = le64_to_cpu((__force __le64)__raw_readq(c)); __v; }) | ||
95 | 96 | ||
96 | #define writeb_relaxed(v,c) ((void)__raw_writeb((v),(c))) | 97 | #define writeb_relaxed(v,c) ((void)__raw_writeb((v),(c))) |
97 | #define writew_relaxed(v,c) ((void)__raw_writew((__force u16)cpu_to_le16(v),(c))) | 98 | #define writew_relaxed(v,c) ((void)__raw_writew((__force u16)cpu_to_le16(v),(c))) |
98 | #define writel_relaxed(v,c) ((void)__raw_writel((__force u32)cpu_to_le32(v),(c))) | 99 | #define writel_relaxed(v,c) ((void)__raw_writel((__force u32)cpu_to_le32(v),(c))) |
100 | #define writeq_relaxed(v,c) ((void)__raw_writeq((__force u64)cpu_to_le64(v),(c))) | ||
99 | 101 | ||
100 | /* | 102 | /* |
101 | * I/O memory access primitives. Reads are ordered relative to any | 103 | * I/O memory access primitives. Reads are ordered relative to any |
@@ -105,10 +107,12 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) | |||
105 | #define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) | 107 | #define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) |
106 | #define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) | 108 | #define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) |
107 | #define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; }) | 109 | #define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; }) |
110 | #define readq(c) ({ u64 __v = readq_relaxed(c); __iormb(); __v; }) | ||
108 | 111 | ||
109 | #define writeb(v,c) ({ __iowmb(); writeb_relaxed((v),(c)); }) | 112 | #define writeb(v,c) ({ __iowmb(); writeb_relaxed((v),(c)); }) |
110 | #define writew(v,c) ({ __iowmb(); writew_relaxed((v),(c)); }) | 113 | #define writew(v,c) ({ __iowmb(); writew_relaxed((v),(c)); }) |
111 | #define writel(v,c) ({ __iowmb(); writel_relaxed((v),(c)); }) | 114 | #define writel(v,c) ({ __iowmb(); writel_relaxed((v),(c)); }) |
115 | #define writeq(v,c) ({ __iowmb(); writeq_relaxed((v),(c)); }) | ||
112 | 116 | ||
113 | /* | 117 | /* |
114 | * I/O port access primitives. | 118 | * I/O port access primitives. |
diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h index a4e1cad3202a..0332fc077f6e 100644 --- a/arch/arm64/include/asm/irq.h +++ b/arch/arm64/include/asm/irq.h | |||
@@ -4,5 +4,6 @@ | |||
4 | #include <asm-generic/irq.h> | 4 | #include <asm-generic/irq.h> |
5 | 5 | ||
6 | extern void (*handle_arch_irq)(struct pt_regs *); | 6 | extern void (*handle_arch_irq)(struct pt_regs *); |
7 | extern void set_handle_irq(void (*handle_irq)(struct pt_regs *)); | ||
7 | 8 | ||
8 | #endif | 9 | #endif |
diff --git a/arch/arm64/lib/bitops.c b/arch/arm64/include/asm/smp_plat.h index aa4965e60acc..ed43a0d2b1b2 100644 --- a/arch/arm64/lib/bitops.c +++ b/arch/arm64/include/asm/smp_plat.h | |||
@@ -1,7 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2012 ARM Limited | 2 | * Definitions specific to SMP platforms. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify | 4 | * Copyright (C) 2013 ARM Ltd. |
5 | * | ||
6 | * 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 | 7 | * it under the terms of the GNU General Public License version 2 as |
6 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
7 | * | 9 | * |
@@ -14,12 +16,15 @@ | |||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
15 | */ | 17 | */ |
16 | 18 | ||
17 | #include <linux/kernel.h> | 19 | #ifndef __ASM_SMP_PLAT_H |
18 | #include <linux/spinlock.h> | 20 | #define __ASM_SMP_PLAT_H |
19 | #include <linux/atomic.h> | 21 | |
22 | #include <asm/types.h> | ||
23 | |||
24 | /* | ||
25 | * Logical CPU mapping. | ||
26 | */ | ||
27 | extern u64 __cpu_logical_map[NR_CPUS]; | ||
28 | #define cpu_logical_map(cpu) __cpu_logical_map[cpu] | ||
20 | 29 | ||
21 | #ifdef CONFIG_SMP | 30 | #endif /* __ASM_SMP_PLAT_H */ |
22 | arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = { | ||
23 | [0 ... (ATOMIC_HASH_SIZE-1)] = __ARCH_SPIN_LOCK_UNLOCKED | ||
24 | }; | ||
25 | #endif | ||
diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h new file mode 100644 index 000000000000..3ee8b303d9a9 --- /dev/null +++ b/arch/arm64/include/asm/string.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 ARM Ltd. | ||
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 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | #ifndef __ASM_STRING_H | ||
17 | #define __ASM_STRING_H | ||
18 | |||
19 | #define __HAVE_ARCH_STRRCHR | ||
20 | extern char *strrchr(const char *, int c); | ||
21 | |||
22 | #define __HAVE_ARCH_STRCHR | ||
23 | extern char *strchr(const char *, int c); | ||
24 | |||
25 | #define __HAVE_ARCH_MEMCPY | ||
26 | extern void *memcpy(void *, const void *, __kernel_size_t); | ||
27 | |||
28 | #define __HAVE_ARCH_MEMMOVE | ||
29 | extern void *memmove(void *, const void *, __kernel_size_t); | ||
30 | |||
31 | #define __HAVE_ARCH_MEMCHR | ||
32 | extern void *memchr(const void *, int, __kernel_size_t); | ||
33 | |||
34 | #define __HAVE_ARCH_MEMSET | ||
35 | extern void *memset(void *, int, __kernel_size_t); | ||
36 | |||
37 | #endif | ||
diff --git a/arch/arm64/kernel/arm64ksyms.c b/arch/arm64/kernel/arm64ksyms.c index aa3e948f7885..7df1aad29b67 100644 --- a/arch/arm64/kernel/arm64ksyms.c +++ b/arch/arm64/kernel/arm64ksyms.c | |||
@@ -39,10 +39,21 @@ EXPORT_SYMBOL(__copy_from_user); | |||
39 | EXPORT_SYMBOL(__copy_to_user); | 39 | EXPORT_SYMBOL(__copy_to_user); |
40 | EXPORT_SYMBOL(__clear_user); | 40 | EXPORT_SYMBOL(__clear_user); |
41 | 41 | ||
42 | /* bitops */ | ||
43 | #ifdef CONFIG_SMP | ||
44 | EXPORT_SYMBOL(__atomic_hash); | ||
45 | #endif | ||
46 | |||
47 | /* physical memory */ | 42 | /* physical memory */ |
48 | EXPORT_SYMBOL(memstart_addr); | 43 | EXPORT_SYMBOL(memstart_addr); |
44 | |||
45 | /* string / mem functions */ | ||
46 | EXPORT_SYMBOL(strchr); | ||
47 | EXPORT_SYMBOL(strrchr); | ||
48 | EXPORT_SYMBOL(memset); | ||
49 | EXPORT_SYMBOL(memcpy); | ||
50 | EXPORT_SYMBOL(memmove); | ||
51 | EXPORT_SYMBOL(memchr); | ||
52 | |||
53 | /* atomic bitops */ | ||
54 | EXPORT_SYMBOL(set_bit); | ||
55 | EXPORT_SYMBOL(test_and_set_bit); | ||
56 | EXPORT_SYMBOL(clear_bit); | ||
57 | EXPORT_SYMBOL(test_and_clear_bit); | ||
58 | EXPORT_SYMBOL(change_bit); | ||
59 | EXPORT_SYMBOL(test_and_change_bit); | ||
diff --git a/arch/arm64/kernel/early_printk.c b/arch/arm64/kernel/early_printk.c index 7e320a2edb9b..ac974f48a7a2 100644 --- a/arch/arm64/kernel/early_printk.c +++ b/arch/arm64/kernel/early_printk.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | 25 | ||
26 | #include <linux/amba/serial.h> | 26 | #include <linux/amba/serial.h> |
27 | #include <linux/serial_reg.h> | ||
27 | 28 | ||
28 | static void __iomem *early_base; | 29 | static void __iomem *early_base; |
29 | static void (*printch)(char ch); | 30 | static void (*printch)(char ch); |
@@ -40,6 +41,37 @@ static void pl011_printch(char ch) | |||
40 | ; | 41 | ; |
41 | } | 42 | } |
42 | 43 | ||
44 | /* | ||
45 | * Semihosting-based debug console | ||
46 | */ | ||
47 | static void smh_printch(char ch) | ||
48 | { | ||
49 | asm volatile("mov x1, %0\n" | ||
50 | "mov x0, #3\n" | ||
51 | "hlt 0xf000\n" | ||
52 | : : "r" (&ch) : "x0", "x1", "memory"); | ||
53 | } | ||
54 | |||
55 | /* | ||
56 | * 8250/16550 (8-bit aligned registers) single character TX. | ||
57 | */ | ||
58 | static void uart8250_8bit_printch(char ch) | ||
59 | { | ||
60 | while (!(readb_relaxed(early_base + UART_LSR) & UART_LSR_THRE)) | ||
61 | ; | ||
62 | writeb_relaxed(ch, early_base + UART_TX); | ||
63 | } | ||
64 | |||
65 | /* | ||
66 | * 8250/16550 (32-bit aligned registers) single character TX. | ||
67 | */ | ||
68 | static void uart8250_32bit_printch(char ch) | ||
69 | { | ||
70 | while (!(readl_relaxed(early_base + (UART_LSR << 2)) & UART_LSR_THRE)) | ||
71 | ; | ||
72 | writel_relaxed(ch, early_base + (UART_TX << 2)); | ||
73 | } | ||
74 | |||
43 | struct earlycon_match { | 75 | struct earlycon_match { |
44 | const char *name; | 76 | const char *name; |
45 | void (*printch)(char ch); | 77 | void (*printch)(char ch); |
@@ -47,6 +79,9 @@ struct earlycon_match { | |||
47 | 79 | ||
48 | static const struct earlycon_match earlycon_match[] __initconst = { | 80 | static const struct earlycon_match earlycon_match[] __initconst = { |
49 | { .name = "pl011", .printch = pl011_printch, }, | 81 | { .name = "pl011", .printch = pl011_printch, }, |
82 | { .name = "smh", .printch = smh_printch, }, | ||
83 | { .name = "uart8250-8bit", .printch = uart8250_8bit_printch, }, | ||
84 | { .name = "uart8250-32bit", .printch = uart8250_32bit_printch, }, | ||
50 | {} | 85 | {} |
51 | }; | 86 | }; |
52 | 87 | ||
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 514d6098dbee..c7e047049f2c 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <asm/assembler.h> | 24 | #include <asm/assembler.h> |
25 | #include <asm/asm-offsets.h> | 25 | #include <asm/asm-offsets.h> |
26 | #include <asm/errno.h> | 26 | #include <asm/errno.h> |
27 | #include <asm/esr.h> | ||
27 | #include <asm/thread_info.h> | 28 | #include <asm/thread_info.h> |
28 | #include <asm/unistd.h> | 29 | #include <asm/unistd.h> |
29 | #include <asm/unistd32.h> | 30 | #include <asm/unistd32.h> |
@@ -239,18 +240,18 @@ ENDPROC(el1_error_invalid) | |||
239 | el1_sync: | 240 | el1_sync: |
240 | kernel_entry 1 | 241 | kernel_entry 1 |
241 | mrs x1, esr_el1 // read the syndrome register | 242 | mrs x1, esr_el1 // read the syndrome register |
242 | lsr x24, x1, #26 // exception class | 243 | lsr x24, x1, #ESR_EL1_EC_SHIFT // exception class |
243 | cmp x24, #0x25 // data abort in EL1 | 244 | cmp x24, #ESR_EL1_EC_DABT_EL1 // data abort in EL1 |
244 | b.eq el1_da | 245 | b.eq el1_da |
245 | cmp x24, #0x18 // configurable trap | 246 | cmp x24, #ESR_EL1_EC_SYS64 // configurable trap |
246 | b.eq el1_undef | 247 | b.eq el1_undef |
247 | cmp x24, #0x26 // stack alignment exception | 248 | cmp x24, #ESR_EL1_EC_SP_ALIGN // stack alignment exception |
248 | b.eq el1_sp_pc | 249 | b.eq el1_sp_pc |
249 | cmp x24, #0x22 // pc alignment exception | 250 | cmp x24, #ESR_EL1_EC_PC_ALIGN // pc alignment exception |
250 | b.eq el1_sp_pc | 251 | b.eq el1_sp_pc |
251 | cmp x24, #0x00 // unknown exception in EL1 | 252 | cmp x24, #ESR_EL1_EC_UNKNOWN // unknown exception in EL1 |
252 | b.eq el1_undef | 253 | b.eq el1_undef |
253 | cmp x24, #0x30 // debug exception in EL1 | 254 | cmp x24, #ESR_EL1_EC_BREAKPT_EL1 // debug exception in EL1 |
254 | b.ge el1_dbg | 255 | b.ge el1_dbg |
255 | b el1_inv | 256 | b el1_inv |
256 | el1_da: | 257 | el1_da: |
@@ -346,27 +347,27 @@ el1_preempt: | |||
346 | el0_sync: | 347 | el0_sync: |
347 | kernel_entry 0 | 348 | kernel_entry 0 |
348 | mrs x25, esr_el1 // read the syndrome register | 349 | mrs x25, esr_el1 // read the syndrome register |
349 | lsr x24, x25, #26 // exception class | 350 | lsr x24, x25, #ESR_EL1_EC_SHIFT // exception class |
350 | cmp x24, #0x15 // SVC in 64-bit state | 351 | cmp x24, #ESR_EL1_EC_SVC64 // SVC in 64-bit state |
351 | b.eq el0_svc | 352 | b.eq el0_svc |
352 | adr lr, ret_from_exception | 353 | adr lr, ret_from_exception |
353 | cmp x24, #0x24 // data abort in EL0 | 354 | cmp x24, #ESR_EL1_EC_DABT_EL0 // data abort in EL0 |
354 | b.eq el0_da | 355 | b.eq el0_da |
355 | cmp x24, #0x20 // instruction abort in EL0 | 356 | cmp x24, #ESR_EL1_EC_IABT_EL0 // instruction abort in EL0 |
356 | b.eq el0_ia | 357 | b.eq el0_ia |
357 | cmp x24, #0x07 // FP/ASIMD access | 358 | cmp x24, #ESR_EL1_EC_FP_ASIMD // FP/ASIMD access |
358 | b.eq el0_fpsimd_acc | 359 | b.eq el0_fpsimd_acc |
359 | cmp x24, #0x2c // FP/ASIMD exception | 360 | cmp x24, #ESR_EL1_EC_FP_EXC64 // FP/ASIMD exception |
360 | b.eq el0_fpsimd_exc | 361 | b.eq el0_fpsimd_exc |
361 | cmp x24, #0x18 // configurable trap | 362 | cmp x24, #ESR_EL1_EC_SYS64 // configurable trap |
362 | b.eq el0_undef | 363 | b.eq el0_undef |
363 | cmp x24, #0x26 // stack alignment exception | 364 | cmp x24, #ESR_EL1_EC_SP_ALIGN // stack alignment exception |
364 | b.eq el0_sp_pc | 365 | b.eq el0_sp_pc |
365 | cmp x24, #0x22 // pc alignment exception | 366 | cmp x24, #ESR_EL1_EC_PC_ALIGN // pc alignment exception |
366 | b.eq el0_sp_pc | 367 | b.eq el0_sp_pc |
367 | cmp x24, #0x00 // unknown exception in EL0 | 368 | cmp x24, #ESR_EL1_EC_UNKNOWN // unknown exception in EL0 |
368 | b.eq el0_undef | 369 | b.eq el0_undef |
369 | cmp x24, #0x30 // debug exception in EL0 | 370 | cmp x24, #ESR_EL1_EC_BREAKPT_EL0 // debug exception in EL0 |
370 | b.ge el0_dbg | 371 | b.ge el0_dbg |
371 | b el0_inv | 372 | b el0_inv |
372 | 373 | ||
@@ -375,21 +376,21 @@ el0_sync: | |||
375 | el0_sync_compat: | 376 | el0_sync_compat: |
376 | kernel_entry 0, 32 | 377 | kernel_entry 0, 32 |
377 | mrs x25, esr_el1 // read the syndrome register | 378 | mrs x25, esr_el1 // read the syndrome register |
378 | lsr x24, x25, #26 // exception class | 379 | lsr x24, x25, #ESR_EL1_EC_SHIFT // exception class |
379 | cmp x24, #0x11 // SVC in 32-bit state | 380 | cmp x24, #ESR_EL1_EC_SVC32 // SVC in 32-bit state |
380 | b.eq el0_svc_compat | 381 | b.eq el0_svc_compat |
381 | adr lr, ret_from_exception | 382 | adr lr, ret_from_exception |
382 | cmp x24, #0x24 // data abort in EL0 | 383 | cmp x24, #ESR_EL1_EC_DABT_EL0 // data abort in EL0 |
383 | b.eq el0_da | 384 | b.eq el0_da |
384 | cmp x24, #0x20 // instruction abort in EL0 | 385 | cmp x24, #ESR_EL1_EC_IABT_EL0 // instruction abort in EL0 |
385 | b.eq el0_ia | 386 | b.eq el0_ia |
386 | cmp x24, #0x07 // FP/ASIMD access | 387 | cmp x24, #ESR_EL1_EC_FP_ASIMD // FP/ASIMD access |
387 | b.eq el0_fpsimd_acc | 388 | b.eq el0_fpsimd_acc |
388 | cmp x24, #0x28 // FP/ASIMD exception | 389 | cmp x24, #ESR_EL1_EC_FP_EXC32 // FP/ASIMD exception |
389 | b.eq el0_fpsimd_exc | 390 | b.eq el0_fpsimd_exc |
390 | cmp x24, #0x00 // unknown exception in EL0 | 391 | cmp x24, #ESR_EL1_EC_UNKNOWN // unknown exception in EL0 |
391 | b.eq el0_undef | 392 | b.eq el0_undef |
392 | cmp x24, #0x30 // debug exception in EL0 | 393 | cmp x24, #ESR_EL1_EC_BREAKPT_EL0 // debug exception in EL0 |
393 | b.ge el0_dbg | 394 | b.ge el0_dbg |
394 | b el0_inv | 395 | b el0_inv |
395 | el0_svc_compat: | 396 | el0_svc_compat: |
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 0a0a49756826..53dcae49e729 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <asm/assembler.h> | 26 | #include <asm/assembler.h> |
27 | #include <asm/ptrace.h> | 27 | #include <asm/ptrace.h> |
28 | #include <asm/asm-offsets.h> | 28 | #include <asm/asm-offsets.h> |
29 | #include <asm/cputype.h> | ||
29 | #include <asm/memory.h> | 30 | #include <asm/memory.h> |
30 | #include <asm/thread_info.h> | 31 | #include <asm/thread_info.h> |
31 | #include <asm/pgtable-hwdef.h> | 32 | #include <asm/pgtable-hwdef.h> |
@@ -229,7 +230,8 @@ ENTRY(secondary_holding_pen) | |||
229 | bl __calc_phys_offset // x24=phys offset | 230 | bl __calc_phys_offset // x24=phys offset |
230 | bl el2_setup // Drop to EL1 | 231 | bl el2_setup // Drop to EL1 |
231 | mrs x0, mpidr_el1 | 232 | mrs x0, mpidr_el1 |
232 | and x0, x0, #15 // CPU number | 233 | ldr x1, =MPIDR_HWID_BITMASK |
234 | and x0, x0, x1 | ||
233 | adr x1, 1b | 235 | adr x1, 1b |
234 | ldp x2, x3, [x1] | 236 | ldp x2, x3, [x1] |
235 | sub x1, x1, x2 | 237 | sub x1, x1, x2 |
diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c index 0373c6609eaf..ecb3354292ed 100644 --- a/arch/arm64/kernel/irq.c +++ b/arch/arm64/kernel/irq.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/irq.h> | 25 | #include <linux/irq.h> |
26 | #include <linux/smp.h> | 26 | #include <linux/smp.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/of_irq.h> | 28 | #include <linux/irqchip.h> |
29 | #include <linux/seq_file.h> | 29 | #include <linux/seq_file.h> |
30 | #include <linux/ratelimit.h> | 30 | #include <linux/ratelimit.h> |
31 | 31 | ||
@@ -67,18 +67,17 @@ void handle_IRQ(unsigned int irq, struct pt_regs *regs) | |||
67 | set_irq_regs(old_regs); | 67 | set_irq_regs(old_regs); |
68 | } | 68 | } |
69 | 69 | ||
70 | /* | 70 | void __init set_handle_irq(void (*handle_irq)(struct pt_regs *)) |
71 | * Interrupt controllers supported by the kernel. | 71 | { |
72 | */ | 72 | if (handle_arch_irq) |
73 | static const struct of_device_id intctrl_of_match[] __initconst = { | 73 | return; |
74 | /* IRQ controllers { .compatible, .data } info to go here */ | 74 | |
75 | {} | 75 | handle_arch_irq = handle_irq; |
76 | }; | 76 | } |
77 | 77 | ||
78 | void __init init_IRQ(void) | 78 | void __init init_IRQ(void) |
79 | { | 79 | { |
80 | of_irq_init(intctrl_of_match); | 80 | irqchip_init(); |
81 | |||
82 | if (!handle_arch_irq) | 81 | if (!handle_arch_irq) |
83 | panic("No interrupt controller found."); | 82 | panic("No interrupt controller found."); |
84 | } | 83 | } |
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 83a0ad5936a5..6f3822f98dcd 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c | |||
@@ -278,11 +278,17 @@ struct task_struct *__switch_to(struct task_struct *prev, | |||
278 | fpsimd_thread_switch(next); | 278 | fpsimd_thread_switch(next); |
279 | tls_thread_switch(next); | 279 | tls_thread_switch(next); |
280 | hw_breakpoint_thread_switch(next); | 280 | hw_breakpoint_thread_switch(next); |
281 | contextidr_thread_switch(next); | ||
282 | |||
283 | /* | ||
284 | * Complete any pending TLB or cache maintenance on this CPU in case | ||
285 | * the thread migrates to a different CPU. | ||
286 | */ | ||
287 | dsb(); | ||
281 | 288 | ||
282 | /* the actual thread switch */ | 289 | /* the actual thread switch */ |
283 | last = cpu_switch_to(prev, next); | 290 | last = cpu_switch_to(prev, next); |
284 | 291 | ||
285 | contextidr_thread_switch(next); | ||
286 | return last; | 292 | return last; |
287 | } | 293 | } |
288 | 294 | ||
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 113db863f832..6a9a53292590 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/kexec.h> | 32 | #include <linux/kexec.h> |
33 | #include <linux/crash_dump.h> | 33 | #include <linux/crash_dump.h> |
34 | #include <linux/root_dev.h> | 34 | #include <linux/root_dev.h> |
35 | #include <linux/clk-provider.h> | ||
35 | #include <linux/cpu.h> | 36 | #include <linux/cpu.h> |
36 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
37 | #include <linux/smp.h> | 38 | #include <linux/smp.h> |
@@ -46,6 +47,7 @@ | |||
46 | #include <asm/cputable.h> | 47 | #include <asm/cputable.h> |
47 | #include <asm/sections.h> | 48 | #include <asm/sections.h> |
48 | #include <asm/setup.h> | 49 | #include <asm/setup.h> |
50 | #include <asm/smp_plat.h> | ||
49 | #include <asm/cacheflush.h> | 51 | #include <asm/cacheflush.h> |
50 | #include <asm/tlbflush.h> | 52 | #include <asm/tlbflush.h> |
51 | #include <asm/traps.h> | 53 | #include <asm/traps.h> |
@@ -240,6 +242,8 @@ static void __init request_standard_resources(void) | |||
240 | } | 242 | } |
241 | } | 243 | } |
242 | 244 | ||
245 | u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID }; | ||
246 | |||
243 | void __init setup_arch(char **cmdline_p) | 247 | void __init setup_arch(char **cmdline_p) |
244 | { | 248 | { |
245 | setup_processor(); | 249 | setup_processor(); |
@@ -264,6 +268,7 @@ void __init setup_arch(char **cmdline_p) | |||
264 | 268 | ||
265 | psci_init(); | 269 | psci_init(); |
266 | 270 | ||
271 | cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK; | ||
267 | #ifdef CONFIG_SMP | 272 | #ifdef CONFIG_SMP |
268 | smp_init_cpus(); | 273 | smp_init_cpus(); |
269 | #endif | 274 | #endif |
@@ -277,6 +282,13 @@ void __init setup_arch(char **cmdline_p) | |||
277 | #endif | 282 | #endif |
278 | } | 283 | } |
279 | 284 | ||
285 | static int __init arm64_of_clk_init(void) | ||
286 | { | ||
287 | of_clk_init(NULL); | ||
288 | return 0; | ||
289 | } | ||
290 | arch_initcall(arm64_of_clk_init); | ||
291 | |||
280 | static DEFINE_PER_CPU(struct cpu, cpu_data); | 292 | static DEFINE_PER_CPU(struct cpu, cpu_data); |
281 | 293 | ||
282 | static int __init topology_init(void) | 294 | static int __init topology_init(void) |
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 261445c4666f..5d54e3717bf8 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <asm/pgtable.h> | 43 | #include <asm/pgtable.h> |
44 | #include <asm/pgalloc.h> | 44 | #include <asm/pgalloc.h> |
45 | #include <asm/processor.h> | 45 | #include <asm/processor.h> |
46 | #include <asm/smp_plat.h> | ||
46 | #include <asm/sections.h> | 47 | #include <asm/sections.h> |
47 | #include <asm/tlbflush.h> | 48 | #include <asm/tlbflush.h> |
48 | #include <asm/ptrace.h> | 49 | #include <asm/ptrace.h> |
@@ -53,7 +54,7 @@ | |||
53 | * where to place its SVC stack | 54 | * where to place its SVC stack |
54 | */ | 55 | */ |
55 | struct secondary_data secondary_data; | 56 | struct secondary_data secondary_data; |
56 | volatile unsigned long secondary_holding_pen_release = -1; | 57 | volatile unsigned long secondary_holding_pen_release = INVALID_HWID; |
57 | 58 | ||
58 | enum ipi_msg_type { | 59 | enum ipi_msg_type { |
59 | IPI_RESCHEDULE, | 60 | IPI_RESCHEDULE, |
@@ -70,7 +71,7 @@ static DEFINE_RAW_SPINLOCK(boot_lock); | |||
70 | * in coherency or not. This is necessary for the hotplug code to work | 71 | * in coherency or not. This is necessary for the hotplug code to work |
71 | * reliably. | 72 | * reliably. |
72 | */ | 73 | */ |
73 | static void __cpuinit write_pen_release(int val) | 74 | static void __cpuinit write_pen_release(u64 val) |
74 | { | 75 | { |
75 | void *start = (void *)&secondary_holding_pen_release; | 76 | void *start = (void *)&secondary_holding_pen_release; |
76 | unsigned long size = sizeof(secondary_holding_pen_release); | 77 | unsigned long size = sizeof(secondary_holding_pen_release); |
@@ -96,7 +97,7 @@ static int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
96 | /* | 97 | /* |
97 | * Update the pen release flag. | 98 | * Update the pen release flag. |
98 | */ | 99 | */ |
99 | write_pen_release(cpu); | 100 | write_pen_release(cpu_logical_map(cpu)); |
100 | 101 | ||
101 | /* | 102 | /* |
102 | * Send an event, causing the secondaries to read pen_release. | 103 | * Send an event, causing the secondaries to read pen_release. |
@@ -105,7 +106,7 @@ static int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
105 | 106 | ||
106 | timeout = jiffies + (1 * HZ); | 107 | timeout = jiffies + (1 * HZ); |
107 | while (time_before(jiffies, timeout)) { | 108 | while (time_before(jiffies, timeout)) { |
108 | if (secondary_holding_pen_release == -1UL) | 109 | if (secondary_holding_pen_release == INVALID_HWID) |
109 | break; | 110 | break; |
110 | udelay(10); | 111 | udelay(10); |
111 | } | 112 | } |
@@ -116,7 +117,7 @@ static int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
116 | */ | 117 | */ |
117 | raw_spin_unlock(&boot_lock); | 118 | raw_spin_unlock(&boot_lock); |
118 | 119 | ||
119 | return secondary_holding_pen_release != -1 ? -ENOSYS : 0; | 120 | return secondary_holding_pen_release != INVALID_HWID ? -ENOSYS : 0; |
120 | } | 121 | } |
121 | 122 | ||
122 | static DECLARE_COMPLETION(cpu_running); | 123 | static DECLARE_COMPLETION(cpu_running); |
@@ -190,7 +191,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void) | |||
190 | * Let the primary processor know we're out of the | 191 | * Let the primary processor know we're out of the |
191 | * pen, then head off into the C entry point | 192 | * pen, then head off into the C entry point |
192 | */ | 193 | */ |
193 | write_pen_release(-1); | 194 | write_pen_release(INVALID_HWID); |
194 | 195 | ||
195 | /* | 196 | /* |
196 | * Synchronise with the boot thread. | 197 | * Synchronise with the boot thread. |
@@ -244,11 +245,11 @@ static const struct smp_enable_ops *smp_enable_ops[NR_CPUS]; | |||
244 | 245 | ||
245 | static const struct smp_enable_ops * __init smp_get_enable_ops(const char *name) | 246 | static const struct smp_enable_ops * __init smp_get_enable_ops(const char *name) |
246 | { | 247 | { |
247 | const struct smp_enable_ops *ops = enable_ops[0]; | 248 | const struct smp_enable_ops **ops = enable_ops; |
248 | 249 | ||
249 | while (ops) { | 250 | while (*ops) { |
250 | if (!strcmp(name, ops->name)) | 251 | if (!strcmp(name, (*ops)->name)) |
251 | return ops; | 252 | return *ops; |
252 | 253 | ||
253 | ops++; | 254 | ops++; |
254 | } | 255 | } |
@@ -257,15 +258,80 @@ static const struct smp_enable_ops * __init smp_get_enable_ops(const char *name) | |||
257 | } | 258 | } |
258 | 259 | ||
259 | /* | 260 | /* |
260 | * Enumerate the possible CPU set from the device tree. | 261 | * Enumerate the possible CPU set from the device tree and build the |
262 | * cpu logical map array containing MPIDR values related to logical | ||
263 | * cpus. Assumes that cpu_logical_map(0) has already been initialized. | ||
261 | */ | 264 | */ |
262 | void __init smp_init_cpus(void) | 265 | void __init smp_init_cpus(void) |
263 | { | 266 | { |
264 | const char *enable_method; | 267 | const char *enable_method; |
265 | struct device_node *dn = NULL; | 268 | struct device_node *dn = NULL; |
266 | int cpu = 0; | 269 | int i, cpu = 1; |
270 | bool bootcpu_valid = false; | ||
267 | 271 | ||
268 | while ((dn = of_find_node_by_type(dn, "cpu"))) { | 272 | while ((dn = of_find_node_by_type(dn, "cpu"))) { |
273 | const u32 *cell; | ||
274 | u64 hwid; | ||
275 | |||
276 | /* | ||
277 | * A cpu node with missing "reg" property is | ||
278 | * considered invalid to build a cpu_logical_map | ||
279 | * entry. | ||
280 | */ | ||
281 | cell = of_get_property(dn, "reg", NULL); | ||
282 | if (!cell) { | ||
283 | pr_err("%s: missing reg property\n", dn->full_name); | ||
284 | goto next; | ||
285 | } | ||
286 | hwid = of_read_number(cell, of_n_addr_cells(dn)); | ||
287 | |||
288 | /* | ||
289 | * Non affinity bits must be set to 0 in the DT | ||
290 | */ | ||
291 | if (hwid & ~MPIDR_HWID_BITMASK) { | ||
292 | pr_err("%s: invalid reg property\n", dn->full_name); | ||
293 | goto next; | ||
294 | } | ||
295 | |||
296 | /* | ||
297 | * Duplicate MPIDRs are a recipe for disaster. Scan | ||
298 | * all initialized entries and check for | ||
299 | * duplicates. If any is found just ignore the cpu. | ||
300 | * cpu_logical_map was initialized to INVALID_HWID to | ||
301 | * avoid matching valid MPIDR values. | ||
302 | */ | ||
303 | for (i = 1; (i < cpu) && (i < NR_CPUS); i++) { | ||
304 | if (cpu_logical_map(i) == hwid) { | ||
305 | pr_err("%s: duplicate cpu reg properties in the DT\n", | ||
306 | dn->full_name); | ||
307 | goto next; | ||
308 | } | ||
309 | } | ||
310 | |||
311 | /* | ||
312 | * The numbering scheme requires that the boot CPU | ||
313 | * must be assigned logical id 0. Record it so that | ||
314 | * the logical map built from DT is validated and can | ||
315 | * be used. | ||
316 | */ | ||
317 | if (hwid == cpu_logical_map(0)) { | ||
318 | if (bootcpu_valid) { | ||
319 | pr_err("%s: duplicate boot cpu reg property in DT\n", | ||
320 | dn->full_name); | ||
321 | goto next; | ||
322 | } | ||
323 | |||
324 | bootcpu_valid = true; | ||
325 | |||
326 | /* | ||
327 | * cpu_logical_map has already been | ||
328 | * initialized and the boot cpu doesn't need | ||
329 | * the enable-method so continue without | ||
330 | * incrementing cpu. | ||
331 | */ | ||
332 | continue; | ||
333 | } | ||
334 | |||
269 | if (cpu >= NR_CPUS) | 335 | if (cpu >= NR_CPUS) |
270 | goto next; | 336 | goto next; |
271 | 337 | ||
@@ -274,22 +340,24 @@ void __init smp_init_cpus(void) | |||
274 | */ | 340 | */ |
275 | enable_method = of_get_property(dn, "enable-method", NULL); | 341 | enable_method = of_get_property(dn, "enable-method", NULL); |
276 | if (!enable_method) { | 342 | if (!enable_method) { |
277 | pr_err("CPU %d: missing enable-method property\n", cpu); | 343 | pr_err("%s: missing enable-method property\n", |
344 | dn->full_name); | ||
278 | goto next; | 345 | goto next; |
279 | } | 346 | } |
280 | 347 | ||
281 | smp_enable_ops[cpu] = smp_get_enable_ops(enable_method); | 348 | smp_enable_ops[cpu] = smp_get_enable_ops(enable_method); |
282 | 349 | ||
283 | if (!smp_enable_ops[cpu]) { | 350 | if (!smp_enable_ops[cpu]) { |
284 | pr_err("CPU %d: invalid enable-method property: %s\n", | 351 | pr_err("%s: invalid enable-method property: %s\n", |
285 | cpu, enable_method); | 352 | dn->full_name, enable_method); |
286 | goto next; | 353 | goto next; |
287 | } | 354 | } |
288 | 355 | ||
289 | if (smp_enable_ops[cpu]->init_cpu(dn, cpu)) | 356 | if (smp_enable_ops[cpu]->init_cpu(dn, cpu)) |
290 | goto next; | 357 | goto next; |
291 | 358 | ||
292 | set_cpu_possible(cpu, true); | 359 | pr_debug("cpu logical map 0x%llx\n", hwid); |
360 | cpu_logical_map(cpu) = hwid; | ||
293 | next: | 361 | next: |
294 | cpu++; | 362 | cpu++; |
295 | } | 363 | } |
@@ -298,6 +366,19 @@ next: | |||
298 | if (cpu > NR_CPUS) | 366 | if (cpu > NR_CPUS) |
299 | pr_warning("no. of cores (%d) greater than configured maximum of %d - clipping\n", | 367 | pr_warning("no. of cores (%d) greater than configured maximum of %d - clipping\n", |
300 | cpu, NR_CPUS); | 368 | cpu, NR_CPUS); |
369 | |||
370 | if (!bootcpu_valid) { | ||
371 | pr_err("DT missing boot CPU MPIDR, not enabling secondaries\n"); | ||
372 | return; | ||
373 | } | ||
374 | |||
375 | /* | ||
376 | * All the cpus that made it to the cpu_logical_map have been | ||
377 | * validated so set them as possible cpus. | ||
378 | */ | ||
379 | for (i = 0; i < NR_CPUS; i++) | ||
380 | if (cpu_logical_map(i) != INVALID_HWID) | ||
381 | set_cpu_possible(i, true); | ||
301 | } | 382 | } |
302 | 383 | ||
303 | void __init smp_prepare_cpus(unsigned int max_cpus) | 384 | void __init smp_prepare_cpus(unsigned int max_cpus) |
diff --git a/arch/arm64/kernel/smp_psci.c b/arch/arm64/kernel/smp_psci.c index 112091684c22..0c533301be77 100644 --- a/arch/arm64/kernel/smp_psci.c +++ b/arch/arm64/kernel/smp_psci.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/smp.h> | 21 | #include <linux/smp.h> |
22 | 22 | ||
23 | #include <asm/psci.h> | 23 | #include <asm/psci.h> |
24 | #include <asm/smp_plat.h> | ||
24 | 25 | ||
25 | static int __init smp_psci_init_cpu(struct device_node *dn, int cpu) | 26 | static int __init smp_psci_init_cpu(struct device_node *dn, int cpu) |
26 | { | 27 | { |
@@ -36,7 +37,7 @@ static int __init smp_psci_prepare_cpu(int cpu) | |||
36 | return -ENODEV; | 37 | return -ENODEV; |
37 | } | 38 | } |
38 | 39 | ||
39 | err = psci_ops.cpu_on(cpu, __pa(secondary_holding_pen)); | 40 | err = psci_ops.cpu_on(cpu_logical_map(cpu), __pa(secondary_holding_pen)); |
40 | if (err) { | 41 | if (err) { |
41 | pr_err("psci: failed to boot CPU%d (%d)\n", cpu, err); | 42 | pr_err("psci: failed to boot CPU%d (%d)\n", cpu, err); |
42 | return err; | 43 | return err; |
@@ -47,6 +48,6 @@ static int __init smp_psci_prepare_cpu(int cpu) | |||
47 | 48 | ||
48 | const struct smp_enable_ops smp_psci_ops __initconst = { | 49 | const struct smp_enable_ops smp_psci_ops __initconst = { |
49 | .name = "psci", | 50 | .name = "psci", |
50 | .init_cpu = smp_psci_init_cpu, | 51 | .init_cpu = smp_psci_init_cpu, |
51 | .prepare_cpu = smp_psci_prepare_cpu, | 52 | .prepare_cpu = smp_psci_prepare_cpu, |
52 | }; | 53 | }; |
diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile index 2fb7f6092aae..59acc0ef0462 100644 --- a/arch/arm64/lib/Makefile +++ b/arch/arm64/lib/Makefile | |||
@@ -1,4 +1,6 @@ | |||
1 | lib-y := bitops.o delay.o \ | 1 | lib-y := bitops.o delay.o \ |
2 | strncpy_from_user.o strnlen_user.o clear_user.o \ | 2 | strncpy_from_user.o strnlen_user.o clear_user.o \ |
3 | copy_from_user.o copy_to_user.o copy_in_user.o \ | 3 | copy_from_user.o copy_to_user.o copy_in_user.o \ |
4 | copy_page.o clear_page.o | 4 | copy_page.o clear_page.o \ |
5 | memchr.o memcpy.o memmove.o memset.o \ | ||
6 | strchr.o strrchr.o | ||
diff --git a/arch/arm64/lib/bitops.S b/arch/arm64/lib/bitops.S new file mode 100644 index 000000000000..36216d30cb9a --- /dev/null +++ b/arch/arm64/lib/bitops.S | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * Based on arch/arm/lib/bitops.h | ||
3 | * | ||
4 | * Copyright (C) 2013 ARM Ltd. | ||
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 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #include <linux/linkage.h> | ||
20 | #include <asm/assembler.h> | ||
21 | |||
22 | /* | ||
23 | * x0: bits 5:0 bit offset | ||
24 | * bits 63:6 word offset | ||
25 | * x1: address | ||
26 | */ | ||
27 | .macro bitop, name, instr | ||
28 | ENTRY( \name ) | ||
29 | and x3, x0, #63 // Get bit offset | ||
30 | eor x0, x0, x3 // Clear low bits | ||
31 | mov x2, #1 | ||
32 | add x1, x1, x0, lsr #3 // Get word offset | ||
33 | lsl x3, x2, x3 // Create mask | ||
34 | 1: ldxr x2, [x1] | ||
35 | \instr x2, x2, x3 | ||
36 | stxr w0, x2, [x1] | ||
37 | cbnz w0, 1b | ||
38 | ret | ||
39 | ENDPROC(\name ) | ||
40 | .endm | ||
41 | |||
42 | .macro testop, name, instr | ||
43 | ENTRY( \name ) | ||
44 | and x3, x0, #63 // Get bit offset | ||
45 | eor x0, x0, x3 // Clear low bits | ||
46 | mov x2, #1 | ||
47 | add x1, x1, x0, lsr #3 // Get word offset | ||
48 | lsl x4, x2, x3 // Create mask | ||
49 | 1: ldaxr x2, [x1] | ||
50 | lsr x0, x2, x3 // Save old value of bit | ||
51 | \instr x2, x2, x4 // toggle bit | ||
52 | stlxr w5, x2, [x1] | ||
53 | cbnz w5, 1b | ||
54 | and x0, x0, #1 | ||
55 | 3: ret | ||
56 | ENDPROC(\name ) | ||
57 | .endm | ||
58 | |||
59 | /* | ||
60 | * Atomic bit operations. | ||
61 | */ | ||
62 | bitop change_bit, eor | ||
63 | bitop clear_bit, bic | ||
64 | bitop set_bit, orr | ||
65 | |||
66 | testop test_and_change_bit, eor | ||
67 | testop test_and_clear_bit, bic | ||
68 | testop test_and_set_bit, orr | ||
diff --git a/arch/arm64/lib/memchr.S b/arch/arm64/lib/memchr.S new file mode 100644 index 000000000000..8636b7549163 --- /dev/null +++ b/arch/arm64/lib/memchr.S | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * Based on arch/arm/lib/memchr.S | ||
3 | * | ||
4 | * Copyright (C) 1995-2000 Russell King | ||
5 | * Copyright (C) 2013 ARM Ltd. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include <linux/linkage.h> | ||
21 | #include <asm/assembler.h> | ||
22 | |||
23 | /* | ||
24 | * Find a character in an area of memory. | ||
25 | * | ||
26 | * Parameters: | ||
27 | * x0 - buf | ||
28 | * x1 - c | ||
29 | * x2 - n | ||
30 | * Returns: | ||
31 | * x0 - address of first occurrence of 'c' or 0 | ||
32 | */ | ||
33 | ENTRY(memchr) | ||
34 | and w1, w1, #0xff | ||
35 | 1: subs x2, x2, #1 | ||
36 | b.mi 2f | ||
37 | ldrb w3, [x0], #1 | ||
38 | cmp w3, w1 | ||
39 | b.ne 1b | ||
40 | sub x0, x0, #1 | ||
41 | ret | ||
42 | 2: mov x0, #0 | ||
43 | ret | ||
44 | ENDPROC(memchr) | ||
diff --git a/arch/arm64/lib/memcpy.S b/arch/arm64/lib/memcpy.S new file mode 100644 index 000000000000..27b5003609b6 --- /dev/null +++ b/arch/arm64/lib/memcpy.S | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 ARM Ltd. | ||
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 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/linkage.h> | ||
18 | #include <asm/assembler.h> | ||
19 | |||
20 | /* | ||
21 | * Copy a buffer from src to dest (alignment handled by the hardware) | ||
22 | * | ||
23 | * Parameters: | ||
24 | * x0 - dest | ||
25 | * x1 - src | ||
26 | * x2 - n | ||
27 | * Returns: | ||
28 | * x0 - dest | ||
29 | */ | ||
30 | ENTRY(memcpy) | ||
31 | mov x4, x0 | ||
32 | subs x2, x2, #8 | ||
33 | b.mi 2f | ||
34 | 1: ldr x3, [x1], #8 | ||
35 | subs x2, x2, #8 | ||
36 | str x3, [x4], #8 | ||
37 | b.pl 1b | ||
38 | 2: adds x2, x2, #4 | ||
39 | b.mi 3f | ||
40 | ldr w3, [x1], #4 | ||
41 | sub x2, x2, #4 | ||
42 | str w3, [x4], #4 | ||
43 | 3: adds x2, x2, #2 | ||
44 | b.mi 4f | ||
45 | ldrh w3, [x1], #2 | ||
46 | sub x2, x2, #2 | ||
47 | strh w3, [x4], #2 | ||
48 | 4: adds x2, x2, #1 | ||
49 | b.mi 5f | ||
50 | ldrb w3, [x1] | ||
51 | strb w3, [x4] | ||
52 | 5: ret | ||
53 | ENDPROC(memcpy) | ||
diff --git a/arch/arm64/lib/memmove.S b/arch/arm64/lib/memmove.S new file mode 100644 index 000000000000..b79fdfa42d39 --- /dev/null +++ b/arch/arm64/lib/memmove.S | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 ARM Ltd. | ||
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 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/linkage.h> | ||
18 | #include <asm/assembler.h> | ||
19 | |||
20 | /* | ||
21 | * Move a buffer from src to test (alignment handled by the hardware). | ||
22 | * If dest <= src, call memcpy, otherwise copy in reverse order. | ||
23 | * | ||
24 | * Parameters: | ||
25 | * x0 - dest | ||
26 | * x1 - src | ||
27 | * x2 - n | ||
28 | * Returns: | ||
29 | * x0 - dest | ||
30 | */ | ||
31 | ENTRY(memmove) | ||
32 | cmp x0, x1 | ||
33 | b.ls memcpy | ||
34 | add x4, x0, x2 | ||
35 | add x1, x1, x2 | ||
36 | subs x2, x2, #8 | ||
37 | b.mi 2f | ||
38 | 1: ldr x3, [x1, #-8]! | ||
39 | subs x2, x2, #8 | ||
40 | str x3, [x4, #-8]! | ||
41 | b.pl 1b | ||
42 | 2: adds x2, x2, #4 | ||
43 | b.mi 3f | ||
44 | ldr w3, [x1, #-4]! | ||
45 | sub x2, x2, #4 | ||
46 | str w3, [x4, #-4]! | ||
47 | 3: adds x2, x2, #2 | ||
48 | b.mi 4f | ||
49 | ldrh w3, [x1, #-2]! | ||
50 | sub x2, x2, #2 | ||
51 | strh w3, [x4, #-2]! | ||
52 | 4: adds x2, x2, #1 | ||
53 | b.mi 5f | ||
54 | ldrb w3, [x1, #-1] | ||
55 | strb w3, [x4, #-1] | ||
56 | 5: ret | ||
57 | ENDPROC(memmove) | ||
diff --git a/arch/arm64/lib/memset.S b/arch/arm64/lib/memset.S new file mode 100644 index 000000000000..87e4a68fbbbc --- /dev/null +++ b/arch/arm64/lib/memset.S | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 ARM Ltd. | ||
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 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/linkage.h> | ||
18 | #include <asm/assembler.h> | ||
19 | |||
20 | /* | ||
21 | * Fill in the buffer with character c (alignment handled by the hardware) | ||
22 | * | ||
23 | * Parameters: | ||
24 | * x0 - buf | ||
25 | * x1 - c | ||
26 | * x2 - n | ||
27 | * Returns: | ||
28 | * x0 - buf | ||
29 | */ | ||
30 | ENTRY(memset) | ||
31 | mov x4, x0 | ||
32 | and w1, w1, #0xff | ||
33 | orr w1, w1, w1, lsl #8 | ||
34 | orr w1, w1, w1, lsl #16 | ||
35 | orr x1, x1, x1, lsl #32 | ||
36 | subs x2, x2, #8 | ||
37 | b.mi 2f | ||
38 | 1: str x1, [x4], #8 | ||
39 | subs x2, x2, #8 | ||
40 | b.pl 1b | ||
41 | 2: adds x2, x2, #4 | ||
42 | b.mi 3f | ||
43 | sub x2, x2, #4 | ||
44 | str w1, [x4], #4 | ||
45 | 3: adds x2, x2, #2 | ||
46 | b.mi 4f | ||
47 | sub x2, x2, #2 | ||
48 | strh w1, [x4], #2 | ||
49 | 4: adds x2, x2, #1 | ||
50 | b.mi 5f | ||
51 | strb w1, [x4] | ||
52 | 5: ret | ||
53 | ENDPROC(memset) | ||
diff --git a/arch/arm64/lib/strchr.S b/arch/arm64/lib/strchr.S new file mode 100644 index 000000000000..dae0cf5591f9 --- /dev/null +++ b/arch/arm64/lib/strchr.S | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * Based on arch/arm/lib/strchr.S | ||
3 | * | ||
4 | * Copyright (C) 1995-2000 Russell King | ||
5 | * Copyright (C) 2013 ARM Ltd. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include <linux/linkage.h> | ||
21 | #include <asm/assembler.h> | ||
22 | |||
23 | /* | ||
24 | * Find the first occurrence of a character in a string. | ||
25 | * | ||
26 | * Parameters: | ||
27 | * x0 - str | ||
28 | * x1 - c | ||
29 | * Returns: | ||
30 | * x0 - address of first occurrence of 'c' or 0 | ||
31 | */ | ||
32 | ENTRY(strchr) | ||
33 | and w1, w1, #0xff | ||
34 | 1: ldrb w2, [x0], #1 | ||
35 | cmp w2, w1 | ||
36 | ccmp w2, wzr, #4, ne | ||
37 | b.ne 1b | ||
38 | sub x0, x0, #1 | ||
39 | cmp w2, w1 | ||
40 | csel x0, x0, xzr, eq | ||
41 | ret | ||
42 | ENDPROC(strchr) | ||
diff --git a/arch/arm64/lib/strrchr.S b/arch/arm64/lib/strrchr.S new file mode 100644 index 000000000000..61eabd9a289a --- /dev/null +++ b/arch/arm64/lib/strrchr.S | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * Based on arch/arm/lib/strrchr.S | ||
3 | * | ||
4 | * Copyright (C) 1995-2000 Russell King | ||
5 | * Copyright (C) 2013 ARM Ltd. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include <linux/linkage.h> | ||
21 | #include <asm/assembler.h> | ||
22 | |||
23 | /* | ||
24 | * Find the last occurrence of a character in a string. | ||
25 | * | ||
26 | * Parameters: | ||
27 | * x0 - str | ||
28 | * x1 - c | ||
29 | * Returns: | ||
30 | * x0 - address of last occurrence of 'c' or 0 | ||
31 | */ | ||
32 | ENTRY(strrchr) | ||
33 | mov x3, #0 | ||
34 | and w1, w1, #0xff | ||
35 | 1: ldrb w2, [x0], #1 | ||
36 | cbz w2, 2f | ||
37 | cmp w2, w1 | ||
38 | b.ne 1b | ||
39 | sub x3, x0, #1 | ||
40 | b 1b | ||
41 | 2: mov x0, x3 | ||
42 | ret | ||
43 | ENDPROC(strrchr) | ||
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index afadae6682ed..52638171d6fd 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c | |||
@@ -57,16 +57,16 @@ void show_pte(struct mm_struct *mm, unsigned long addr) | |||
57 | pmd_t *pmd; | 57 | pmd_t *pmd; |
58 | pte_t *pte; | 58 | pte_t *pte; |
59 | 59 | ||
60 | if (pgd_none_or_clear_bad(pgd)) | 60 | if (pgd_none(*pgd) || pgd_bad(*pgd)) |
61 | break; | 61 | break; |
62 | 62 | ||
63 | pud = pud_offset(pgd, addr); | 63 | pud = pud_offset(pgd, addr); |
64 | if (pud_none_or_clear_bad(pud)) | 64 | if (pud_none(*pud) || pud_bad(*pud)) |
65 | break; | 65 | break; |
66 | 66 | ||
67 | pmd = pmd_offset(pud, addr); | 67 | pmd = pmd_offset(pud, addr); |
68 | printk(", *pmd=%016llx", pmd_val(*pmd)); | 68 | printk(", *pmd=%016llx", pmd_val(*pmd)); |
69 | if (pmd_none_or_clear_bad(pmd)) | 69 | if (pmd_none(*pmd) || pmd_bad(*pmd)) |
70 | break; | 70 | break; |
71 | 71 | ||
72 | pte = pte_offset_map(pmd, addr); | 72 | pte = pte_offset_map(pmd, addr); |
diff --git a/drivers/net/ethernet/smsc/Kconfig b/drivers/net/ethernet/smsc/Kconfig index 5a689af516e9..bb4c1674ff99 100644 --- a/drivers/net/ethernet/smsc/Kconfig +++ b/drivers/net/ethernet/smsc/Kconfig | |||
@@ -5,7 +5,7 @@ | |||
5 | config NET_VENDOR_SMSC | 5 | config NET_VENDOR_SMSC |
6 | bool "SMC (SMSC)/Western Digital devices" | 6 | bool "SMC (SMSC)/Western Digital devices" |
7 | default y | 7 | default y |
8 | depends on ARM || ISA || MAC || ARM || MIPS || M32R || SUPERH || \ | 8 | depends on ARM || ISA || MAC || ARM64 || MIPS || M32R || SUPERH || \ |
9 | BLACKFIN || MN10300 || COLDFIRE || PCI || PCMCIA | 9 | BLACKFIN || MN10300 || COLDFIRE || PCI || PCMCIA |
10 | ---help--- | 10 | ---help--- |
11 | If you have a network (Ethernet) card belonging to this class, say Y | 11 | If you have a network (Ethernet) card belonging to this class, say Y |
@@ -40,7 +40,7 @@ config SMC91X | |||
40 | select NET_CORE | 40 | select NET_CORE |
41 | select MII | 41 | select MII |
42 | depends on (ARM || M32R || SUPERH || MIPS || BLACKFIN || \ | 42 | depends on (ARM || M32R || SUPERH || MIPS || BLACKFIN || \ |
43 | MN10300 || COLDFIRE) | 43 | MN10300 || COLDFIRE || ARM64) |
44 | ---help--- | 44 | ---help--- |
45 | This is a driver for SMC's 91x series of Ethernet chipsets, | 45 | This is a driver for SMC's 91x series of Ethernet chipsets, |
46 | including the SMC91C94 and the SMC91C111. Say Y if you want it | 46 | including the SMC91C94 and the SMC91C111. Say Y if you want it |