diff options
205 files changed, 6897 insertions, 1772 deletions
diff --git a/Documentation/ABI/stable/sysfs-devices-system-cpu b/Documentation/ABI/stable/sysfs-devices-system-cpu new file mode 100644 index 000000000000..33c133e2a631 --- /dev/null +++ b/Documentation/ABI/stable/sysfs-devices-system-cpu | |||
@@ -0,0 +1,25 @@ | |||
1 | What: /sys/devices/system/cpu/dscr_default | ||
2 | Date: 13-May-2014 | ||
3 | KernelVersion: v3.15.0 | ||
4 | Contact: | ||
5 | Description: Writes are equivalent to writing to | ||
6 | /sys/devices/system/cpu/cpuN/dscr on all CPUs. | ||
7 | Reads return the last written value or 0. | ||
8 | This value is not a global default: it is a way to set | ||
9 | all per-CPU defaults at the same time. | ||
10 | Values: 64 bit unsigned integer (bit field) | ||
11 | |||
12 | What: /sys/devices/system/cpu/cpu[0-9]+/dscr | ||
13 | Date: 13-May-2014 | ||
14 | KernelVersion: v3.15.0 | ||
15 | Contact: | ||
16 | Description: Default value for the Data Stream Control Register (DSCR) on | ||
17 | a CPU. | ||
18 | This default value is used when the kernel is executing and | ||
19 | for any process that has not set the DSCR itself. | ||
20 | If a process ever sets the DSCR (via direct access to the | ||
21 | SPR) that value will be persisted for that process and used | ||
22 | on any CPU where it executes (overriding the value described | ||
23 | here). | ||
24 | If set by a process it will be inherited by child processes. | ||
25 | Values: 64 bit unsigned integer (bit field) | ||
diff --git a/Documentation/devicetree/bindings/clock/corenet-clock.txt b/Documentation/devicetree/bindings/clock/qoriq-clock.txt index 24711af48e30..5666812fc42b 100644 --- a/Documentation/devicetree/bindings/clock/corenet-clock.txt +++ b/Documentation/devicetree/bindings/clock/qoriq-clock.txt | |||
@@ -7,6 +7,14 @@ which can then be passed to a variety of internal logic, including | |||
7 | cores and peripheral IP blocks. | 7 | cores and peripheral IP blocks. |
8 | Please refer to the Reference Manual for details. | 8 | Please refer to the Reference Manual for details. |
9 | 9 | ||
10 | All references to "1.0" and "2.0" refer to the QorIQ chassis version to | ||
11 | which the chip complies. | ||
12 | |||
13 | Chassis Version Example Chips | ||
14 | --------------- ------------- | ||
15 | 1.0 p4080, p5020, p5040 | ||
16 | 2.0 t4240, b4860, t1040 | ||
17 | |||
10 | 1. Clock Block Binding | 18 | 1. Clock Block Binding |
11 | 19 | ||
12 | Required properties: | 20 | Required properties: |
@@ -85,7 +93,7 @@ Example for clock block and clock provider: | |||
85 | #clock-cells = <0>; | 93 | #clock-cells = <0>; |
86 | compatible = "fsl,qoriq-sysclk-1.0"; | 94 | compatible = "fsl,qoriq-sysclk-1.0"; |
87 | clock-output-names = "sysclk"; | 95 | clock-output-names = "sysclk"; |
88 | } | 96 | }; |
89 | 97 | ||
90 | pll0: pll0@800 { | 98 | pll0: pll0@800 { |
91 | #clock-cells = <1>; | 99 | #clock-cells = <1>; |
diff --git a/Documentation/devicetree/bindings/mfd/bfticu.txt b/Documentation/devicetree/bindings/mfd/bfticu.txt new file mode 100644 index 000000000000..65c90776c620 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/bfticu.txt | |||
@@ -0,0 +1,25 @@ | |||
1 | KEYMILE bfticu Chassis Management FPGA | ||
2 | |||
3 | The bfticu is a multifunction device that manages the whole chassis. | ||
4 | Its main functionality is to collect IRQs from the whole chassis and signals | ||
5 | them to a single controller. | ||
6 | |||
7 | Required properties: | ||
8 | - compatible: "keymile,bfticu" | ||
9 | - interrupt-controller: the bfticu FPGA is an interrupt controller | ||
10 | - interrupts: the main IRQ line to signal the collected IRQs | ||
11 | - #interrupt-cells : is 2 and their usage is compliant to the 2 cells variant | ||
12 | of Documentation/devicetree/bindings/interrupt-controller/interrupts.txt | ||
13 | - interrupt-parent: the parent IRQ ctrl the main IRQ is connected to | ||
14 | - reg: access on the parent local bus (chip select, offset in chip select, size) | ||
15 | |||
16 | Example: | ||
17 | |||
18 | chassis-mgmt@3,0 { | ||
19 | compatible = "keymile,bfticu"; | ||
20 | interrupt-controller; | ||
21 | #interrupt-cells = <2>; | ||
22 | reg = <3 0 0x100>; | ||
23 | interrupt-parent = <&mpic>; | ||
24 | interrupts = <6 1 0 0>; | ||
25 | }; | ||
diff --git a/Documentation/devicetree/bindings/mfd/qriox.txt b/Documentation/devicetree/bindings/mfd/qriox.txt new file mode 100644 index 000000000000..f301e2d4ce76 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/qriox.txt | |||
@@ -0,0 +1,17 @@ | |||
1 | KEYMILE qrio Board Control CPLD | ||
2 | |||
3 | The qrio is a multifunction device that controls the KEYMILE boards based on | ||
4 | the kmp204x design. | ||
5 | It is consists of a reset controller, watchdog timer, LEDs, and 2 IRQ capable | ||
6 | GPIO blocks. | ||
7 | |||
8 | Required properties: | ||
9 | - compatible: "keymile,qriox" | ||
10 | - reg: access on the parent local bus (chip select, offset in chip select, size) | ||
11 | |||
12 | Example: | ||
13 | |||
14 | board-control@1,0 { | ||
15 | compatible = "keymile,qriox"; | ||
16 | reg = <1 0 0x80>; | ||
17 | }; | ||
diff --git a/Documentation/devicetree/bindings/powerpc/4xx/akebono.txt b/Documentation/devicetree/bindings/powerpc/4xx/akebono.txt new file mode 100644 index 000000000000..db939210e29d --- /dev/null +++ b/Documentation/devicetree/bindings/powerpc/4xx/akebono.txt | |||
@@ -0,0 +1,54 @@ | |||
1 | |||
2 | IBM Akebono board device tree | ||
3 | ============================= | ||
4 | |||
5 | The IBM Akebono board is a development board for the PPC476GTR SoC. | ||
6 | |||
7 | 0) The root node | ||
8 | |||
9 | Required properties: | ||
10 | |||
11 | - model : "ibm,akebono". | ||
12 | - compatible : "ibm,akebono" , "ibm,476gtr". | ||
13 | |||
14 | 1.a) The Secure Digital Host Controller Interface (SDHCI) node | ||
15 | |||
16 | Represent the Secure Digital Host Controller Interfaces. | ||
17 | |||
18 | Required properties: | ||
19 | |||
20 | - compatible : should be "ibm,476gtr-sdhci","generic-sdhci". | ||
21 | - reg : should contain the SDHCI registers location and length. | ||
22 | - interrupt-parent : a phandle for the interrupt controller. | ||
23 | - interrupts : should contain the SDHCI interrupt. | ||
24 | |||
25 | 1.b) The Advanced Host Controller Interface (AHCI) SATA node | ||
26 | |||
27 | Represents the advanced host controller SATA interface. | ||
28 | |||
29 | Required properties: | ||
30 | |||
31 | - compatible : should be "ibm,476gtr-ahci". | ||
32 | - reg : should contain the AHCI registers location and length. | ||
33 | - interrupt-parent : a phandle for the interrupt controller. | ||
34 | - interrupts : should contain the AHCI interrupt. | ||
35 | |||
36 | 1.c) The FPGA node | ||
37 | |||
38 | The Akebono board stores some board information such as the revision | ||
39 | number in an FPGA which is represented by this node. | ||
40 | |||
41 | Required properties: | ||
42 | |||
43 | - compatible : should be "ibm,akebono-fpga". | ||
44 | - reg : should contain the FPGA registers location and length. | ||
45 | |||
46 | 1.d) The AVR node | ||
47 | |||
48 | The Akebono board has an Atmel AVR microprocessor attached to the I2C | ||
49 | bus as a power controller for the board. | ||
50 | |||
51 | Required properties: | ||
52 | |||
53 | - compatible : should be "ibm,akebono-avr". | ||
54 | - reg : should contain the I2C bus address for the AVR. | ||
diff --git a/Documentation/devicetree/bindings/powerpc/4xx/hsta.txt b/Documentation/devicetree/bindings/powerpc/4xx/hsta.txt new file mode 100644 index 000000000000..c737c8338705 --- /dev/null +++ b/Documentation/devicetree/bindings/powerpc/4xx/hsta.txt | |||
@@ -0,0 +1,19 @@ | |||
1 | |||
2 | ppc476gtr High Speed Serial Assist (HSTA) node | ||
3 | ============================================== | ||
4 | |||
5 | The 476gtr SoC contains a high speed serial assist module attached | ||
6 | between the plb4 and plb6 system buses to provide high speed data | ||
7 | transfer between memory and system peripherals as well as support for | ||
8 | PCI message signalled interrupts. | ||
9 | |||
10 | Currently only the MSI support is used by Linux using the following | ||
11 | device tree entries: | ||
12 | |||
13 | Require properties: | ||
14 | - compatible : "ibm,476gtr-hsta-msi", "ibm,hsta-msi" | ||
15 | - reg : register mapping for the HSTA MSI space | ||
16 | - interrupt-parent : parent controller for mapping interrupts | ||
17 | - interrupts : ordered interrupt mapping for each MSI in the register | ||
18 | space. The first interrupt should be associated with a | ||
19 | register offset of 0x00, the second to 0x10, etc. | ||
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/board.txt b/Documentation/devicetree/bindings/powerpc/fsl/board.txt index 380914e965e0..700dec4774fa 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/board.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/board.txt | |||
@@ -67,3 +67,20 @@ Example: | |||
67 | gpio-controller; | 67 | gpio-controller; |
68 | }; | 68 | }; |
69 | }; | 69 | }; |
70 | |||
71 | * Freescale on-board FPGA connected on I2C bus | ||
72 | |||
73 | Some Freescale boards like BSC9132QDS have on board FPGA connected on | ||
74 | the i2c bus. | ||
75 | |||
76 | Required properties: | ||
77 | - compatible: Should be a board-specific string followed by a string | ||
78 | indicating the type of FPGA. Example: | ||
79 | "fsl,<board>-fpga", "fsl,fpga-qixis-i2c" | ||
80 | - reg: Should contain the address of the FPGA | ||
81 | |||
82 | Example: | ||
83 | fpga: fpga@66 { | ||
84 | compatible = "fsl,bsc9132qds-fpga", "fsl,fpga-qixis-i2c"; | ||
85 | reg = <0x66>; | ||
86 | }; | ||
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/ccf.txt b/Documentation/devicetree/bindings/powerpc/fsl/ccf.txt new file mode 100644 index 000000000000..454da7e08acd --- /dev/null +++ b/Documentation/devicetree/bindings/powerpc/fsl/ccf.txt | |||
@@ -0,0 +1,46 @@ | |||
1 | Freescale CoreNet Coherency Fabric(CCF) Device Tree Binding | ||
2 | |||
3 | DESCRIPTION | ||
4 | |||
5 | The CoreNet coherency fabric is a fabric-oriented, connectivity infrastructure | ||
6 | that enables the implementation of coherent, multicore systems. | ||
7 | |||
8 | Required properties: | ||
9 | |||
10 | - compatible: <string list> | ||
11 | fsl,corenet1-cf - CoreNet coherency fabric version 1. | ||
12 | Example chips: T4240, B4860 | ||
13 | |||
14 | fsl,corenet2-cf - CoreNet coherency fabric version 2. | ||
15 | Example chips: P5040, P5020, P4080, P3041, P2041 | ||
16 | |||
17 | fsl,corenet-cf - Used to represent the common registers | ||
18 | between CCF version 1 and CCF version 2. This compatible | ||
19 | is retained for compatibility reasons, as it was already | ||
20 | used for both CCF version 1 chips and CCF version 2 | ||
21 | chips. It should be specified after either | ||
22 | "fsl,corenet1-cf" or "fsl,corenet2-cf". | ||
23 | |||
24 | - reg: <prop-encoded-array> | ||
25 | A standard property. Represents the CCF registers. | ||
26 | |||
27 | - interrupts: <prop-encoded-array> | ||
28 | Interrupt mapping for CCF error interrupt. | ||
29 | |||
30 | - fsl,ccf-num-csdids: <u32> | ||
31 | Specifies the number of Coherency Subdomain ID Port Mapping | ||
32 | Registers that are supported by the CCF. | ||
33 | |||
34 | - fsl,ccf-num-snoopids: <u32> | ||
35 | Specifies the number of Snoop ID Port Mapping Registers that | ||
36 | are supported by CCF. | ||
37 | |||
38 | Example: | ||
39 | |||
40 | corenet-cf@18000 { | ||
41 | compatible = "fsl,corenet2-cf", "fsl,corenet-cf"; | ||
42 | reg = <0x18000 0x1000>; | ||
43 | interrupts = <16 2 1 31>; | ||
44 | fsl,ccf-num-csdids = <32>; | ||
45 | fsl,ccf-num-snoopids = <32>; | ||
46 | }; | ||
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/cpus.txt b/Documentation/devicetree/bindings/powerpc/fsl/cpus.txt index 922c30ad90d1..f8cd2397aa04 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/cpus.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/cpus.txt | |||
@@ -20,3 +20,14 @@ PROPERTIES | |||
20 | a property named fsl,eref-[CAT], where [CAT] is the abbreviated category | 20 | a property named fsl,eref-[CAT], where [CAT] is the abbreviated category |
21 | name with all uppercase letters converted to lowercase, indicates that | 21 | name with all uppercase letters converted to lowercase, indicates that |
22 | the category is supported by the implementation. | 22 | the category is supported by the implementation. |
23 | |||
24 | - fsl,portid-mapping | ||
25 | Usage: optional | ||
26 | Value type: <u32> | ||
27 | Definition: The Coherency Subdomain ID Port Mapping Registers and | ||
28 | Snoop ID Port Mapping registers, which are part of the CoreNet | ||
29 | Coherency fabric (CCF), provide a CoreNet Coherency Subdomain | ||
30 | ID/CoreNet Snoop ID to cpu mapping functions. Certain bits from | ||
31 | these registers should be set if the coresponding CPU should be | ||
32 | snooped. This property defines a bitmask which selects the bit | ||
33 | that should be set if this cpu should be snooped. | ||
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/pamu.txt b/Documentation/devicetree/bindings/powerpc/fsl/pamu.txt index 1f5e329f756c..c2b2899885f2 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/pamu.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/pamu.txt | |||
@@ -34,6 +34,15 @@ Optional properties: | |||
34 | for legacy drivers. | 34 | for legacy drivers. |
35 | - interrupt-parent : <phandle> | 35 | - interrupt-parent : <phandle> |
36 | Phandle to interrupt controller | 36 | Phandle to interrupt controller |
37 | - fsl,portid-mapping : <u32> | ||
38 | The Coherency Subdomain ID Port Mapping Registers and | ||
39 | Snoop ID Port Mapping registers, which are part of the | ||
40 | CoreNet Coherency fabric (CCF), provide a CoreNet | ||
41 | Coherency Subdomain ID/CoreNet Snoop ID to pamu mapping | ||
42 | functions. Certain bits from these registers should be | ||
43 | set if PAMUs should be snooped. This property defines | ||
44 | a bitmask which selects the bits that should be set if | ||
45 | PAMUs should be snooped. | ||
37 | 46 | ||
38 | Child nodes: | 47 | Child nodes: |
39 | 48 | ||
@@ -88,6 +97,7 @@ Example: | |||
88 | compatible = "fsl,pamu-v1.0", "fsl,pamu"; | 97 | compatible = "fsl,pamu-v1.0", "fsl,pamu"; |
89 | reg = <0x20000 0x5000>; | 98 | reg = <0x20000 0x5000>; |
90 | ranges = <0 0x20000 0x5000>; | 99 | ranges = <0 0x20000 0x5000>; |
100 | fsl,portid-mapping = <0xf80000>; | ||
91 | #address-cells = <1>; | 101 | #address-cells = <1>; |
92 | #size-cells = <1>; | 102 | #size-cells = <1>; |
93 | interrupts = < | 103 | interrupts = < |
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 5261271046ce..4d7f3758d1b4 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt | |||
@@ -142,3 +142,4 @@ wm Wondermedia Technologies, Inc. | |||
142 | xes Extreme Engineering Solutions (X-ES) | 142 | xes Extreme Engineering Solutions (X-ES) |
143 | xlnx Xilinx | 143 | xlnx Xilinx |
144 | zyxel ZyXEL Communications Corp. | 144 | zyxel ZyXEL Communications Corp. |
145 | zarlink Zarlink Semiconductor | ||
diff --git a/Documentation/powerpc/cpu_families.txt b/Documentation/powerpc/cpu_families.txt new file mode 100644 index 000000000000..fc08e22feb1a --- /dev/null +++ b/Documentation/powerpc/cpu_families.txt | |||
@@ -0,0 +1,221 @@ | |||
1 | CPU Families | ||
2 | ============ | ||
3 | |||
4 | This document tries to summarise some of the different cpu families that exist | ||
5 | and are supported by arch/powerpc. | ||
6 | |||
7 | |||
8 | Book3S (aka sPAPR) | ||
9 | ------------------ | ||
10 | |||
11 | - Hash MMU | ||
12 | - Mix of 32 & 64 bit | ||
13 | |||
14 | +--------------+ +----------------+ | ||
15 | | Old POWER | --------------> | RS64 (threads) | | ||
16 | +--------------+ +----------------+ | ||
17 | | | ||
18 | | | ||
19 | v | ||
20 | +--------------+ +----------------+ +------+ | ||
21 | | 601 | --------------> | 603 | ---> | e300 | | ||
22 | +--------------+ +----------------+ +------+ | ||
23 | | | | ||
24 | | | | ||
25 | v v | ||
26 | +--------------+ +----------------+ +-------+ | ||
27 | | 604 | | 750 (G3) | ---> | 750CX | | ||
28 | +--------------+ +----------------+ +-------+ | ||
29 | | | | | ||
30 | | | | | ||
31 | v v v | ||
32 | +--------------+ +----------------+ +-------+ | ||
33 | | 620 (64 bit) | | 7400 | | 750CL | | ||
34 | +--------------+ +----------------+ +-------+ | ||
35 | | | | | ||
36 | | | | | ||
37 | v v v | ||
38 | +--------------+ +----------------+ +-------+ | ||
39 | | POWER3/630 | | 7410 | | 750FX | | ||
40 | +--------------+ +----------------+ +-------+ | ||
41 | | | | ||
42 | | | | ||
43 | v v | ||
44 | +--------------+ +----------------+ | ||
45 | | POWER3+ | | 7450 | | ||
46 | +--------------+ +----------------+ | ||
47 | | | | ||
48 | | | | ||
49 | v v | ||
50 | +--------------+ +----------------+ | ||
51 | | POWER4 | | 7455 | | ||
52 | +--------------+ +----------------+ | ||
53 | | | | ||
54 | | | | ||
55 | v v | ||
56 | +--------------+ +-------+ +----------------+ | ||
57 | | POWER4+ | --> | 970 | | 7447 | | ||
58 | +--------------+ +-------+ +----------------+ | ||
59 | | | | | ||
60 | | | | | ||
61 | v v v | ||
62 | +--------------+ +-------+ +----------------+ | ||
63 | | POWER5 | | 970FX | | 7448 | | ||
64 | +--------------+ +-------+ +----------------+ | ||
65 | | | | | ||
66 | | | | | ||
67 | v v v | ||
68 | +--------------+ +-------+ +----------------+ | ||
69 | | POWER5+ | | 970MP | | e600 | | ||
70 | +--------------+ +-------+ +----------------+ | ||
71 | | | ||
72 | | | ||
73 | v | ||
74 | +--------------+ | ||
75 | | POWER5++ | | ||
76 | +--------------+ | ||
77 | | | ||
78 | | | ||
79 | v | ||
80 | +--------------+ +-------+ | ||
81 | | POWER6 | <-?-> | Cell | | ||
82 | +--------------+ +-------+ | ||
83 | | | ||
84 | | | ||
85 | v | ||
86 | +--------------+ | ||
87 | | POWER7 | | ||
88 | +--------------+ | ||
89 | | | ||
90 | | | ||
91 | v | ||
92 | +--------------+ | ||
93 | | POWER7+ | | ||
94 | +--------------+ | ||
95 | | | ||
96 | | | ||
97 | v | ||
98 | +--------------+ | ||
99 | | POWER8 | | ||
100 | +--------------+ | ||
101 | |||
102 | |||
103 | +---------------+ | ||
104 | | PA6T (64 bit) | | ||
105 | +---------------+ | ||
106 | |||
107 | |||
108 | IBM BookE | ||
109 | --------- | ||
110 | |||
111 | - Software loaded TLB. | ||
112 | - All 32 bit | ||
113 | |||
114 | +--------------+ | ||
115 | | 401 | | ||
116 | +--------------+ | ||
117 | | | ||
118 | | | ||
119 | v | ||
120 | +--------------+ | ||
121 | | 403 | | ||
122 | +--------------+ | ||
123 | | | ||
124 | | | ||
125 | v | ||
126 | +--------------+ | ||
127 | | 405 | | ||
128 | +--------------+ | ||
129 | | | ||
130 | | | ||
131 | v | ||
132 | +--------------+ | ||
133 | | 440 | | ||
134 | +--------------+ | ||
135 | | | ||
136 | | | ||
137 | v | ||
138 | +--------------+ +----------------+ | ||
139 | | 450 | --> | BG/P | | ||
140 | +--------------+ +----------------+ | ||
141 | | | ||
142 | | | ||
143 | v | ||
144 | +--------------+ | ||
145 | | 460 | | ||
146 | +--------------+ | ||
147 | | | ||
148 | | | ||
149 | v | ||
150 | +--------------+ | ||
151 | | 476 | | ||
152 | +--------------+ | ||
153 | |||
154 | |||
155 | Motorola/Freescale 8xx | ||
156 | ---------------------- | ||
157 | |||
158 | - Software loaded with hardware assist. | ||
159 | - All 32 bit | ||
160 | |||
161 | +-------------+ | ||
162 | | MPC8xx Core | | ||
163 | +-------------+ | ||
164 | |||
165 | |||
166 | Freescale BookE | ||
167 | --------------- | ||
168 | |||
169 | - Software loaded TLB. | ||
170 | - e6500 adds HW loaded indirect TLB entries. | ||
171 | - Mix of 32 & 64 bit | ||
172 | |||
173 | +--------------+ | ||
174 | | e200 | | ||
175 | +--------------+ | ||
176 | |||
177 | |||
178 | +--------------------------------+ | ||
179 | | e500 | | ||
180 | +--------------------------------+ | ||
181 | | | ||
182 | | | ||
183 | v | ||
184 | +--------------------------------+ | ||
185 | | e500v2 | | ||
186 | +--------------------------------+ | ||
187 | | | ||
188 | | | ||
189 | v | ||
190 | +--------------------------------+ | ||
191 | | e500mc (Book3e) | | ||
192 | +--------------------------------+ | ||
193 | | | ||
194 | | | ||
195 | v | ||
196 | +--------------------------------+ | ||
197 | | e5500 (64 bit) | | ||
198 | +--------------------------------+ | ||
199 | | | ||
200 | | | ||
201 | v | ||
202 | +--------------------------------+ | ||
203 | | e6500 (HW TLB) (Multithreaded) | | ||
204 | +--------------------------------+ | ||
205 | |||
206 | |||
207 | IBM A2 core | ||
208 | ----------- | ||
209 | |||
210 | - Book3E, software loaded TLB + HW loaded indirect TLB entries. | ||
211 | - 64 bit | ||
212 | |||
213 | +--------------+ +----------------+ | ||
214 | | A2 core | --> | WSP | | ||
215 | +--------------+ +----------------+ | ||
216 | | | ||
217 | | | ||
218 | v | ||
219 | +--------------+ | ||
220 | | BG/Q | | ||
221 | +--------------+ | ||
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index e0998997943b..bd6dd6ed3a9f 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -453,6 +453,14 @@ config NODES_SHIFT | |||
453 | default "4" | 453 | default "4" |
454 | depends on NEED_MULTIPLE_NODES | 454 | depends on NEED_MULTIPLE_NODES |
455 | 455 | ||
456 | config USE_PERCPU_NUMA_NODE_ID | ||
457 | def_bool y | ||
458 | depends on NUMA | ||
459 | |||
460 | config HAVE_MEMORYLESS_NODES | ||
461 | def_bool y | ||
462 | depends on NUMA | ||
463 | |||
456 | config ARCH_SELECT_MEMORY_MODEL | 464 | config ARCH_SELECT_MEMORY_MODEL |
457 | def_bool y | 465 | def_bool y |
458 | depends on PPC64 | 466 | depends on PPC64 |
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index ce4c68a4a823..5687e299d0a5 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -113,8 +113,13 @@ else | |||
113 | endif | 113 | endif |
114 | endif | 114 | endif |
115 | 115 | ||
116 | CFLAGS-$(CONFIG_PPC64) := -mtraceback=no -mcall-aixdesc | 116 | CFLAGS-$(CONFIG_PPC64) := -mtraceback=no |
117 | CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv1) | 117 | ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y) |
118 | CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv2,-mcall-aixdesc) | ||
119 | AFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv2) | ||
120 | else | ||
121 | CFLAGS-$(CONFIG_PPC64) += -mcall-aixdesc | ||
122 | endif | ||
118 | CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcmodel=medium,-mminimal-toc) | 123 | CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcmodel=medium,-mminimal-toc) |
119 | CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mno-pointers-to-nested-functions) | 124 | CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mno-pointers-to-nested-functions) |
120 | CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 $(MULTIPLEWORD) | 125 | CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 $(MULTIPLEWORD) |
@@ -153,7 +158,7 @@ CFLAGS-$(CONFIG_TUNE_CELL) += $(call cc-option,-mtune=cell) | |||
153 | asinstr := $(call as-instr,lis 9$(comma)foo@high,-DHAVE_AS_ATHIGH=1) | 158 | asinstr := $(call as-instr,lis 9$(comma)foo@high,-DHAVE_AS_ATHIGH=1) |
154 | 159 | ||
155 | KBUILD_CPPFLAGS += -Iarch/$(ARCH) $(asinstr) | 160 | KBUILD_CPPFLAGS += -Iarch/$(ARCH) $(asinstr) |
156 | KBUILD_AFLAGS += -Iarch/$(ARCH) | 161 | KBUILD_AFLAGS += -Iarch/$(ARCH) $(AFLAGS-y) |
157 | KBUILD_CFLAGS += -msoft-float -pipe -Iarch/$(ARCH) $(CFLAGS-y) | 162 | KBUILD_CFLAGS += -msoft-float -pipe -Iarch/$(ARCH) $(CFLAGS-y) |
158 | CPP = $(CC) -E $(KBUILD_CFLAGS) | 163 | CPP = $(CC) -E $(KBUILD_CFLAGS) |
159 | 164 | ||
@@ -161,6 +166,11 @@ CHECKFLAGS += -m$(CONFIG_WORD_SIZE) -D__powerpc__ -D__powerpc$(CONFIG_WORD_SIZE) | |||
161 | 166 | ||
162 | KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o | 167 | KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o |
163 | 168 | ||
169 | ifeq ($(CONFIG_476FPE_ERR46),y) | ||
170 | KBUILD_LDFLAGS_MODULE += --ppc476-workaround \ | ||
171 | -T $(srctree)/arch/powerpc/platforms/44x/ppc476_modules.lds | ||
172 | endif | ||
173 | |||
164 | # No AltiVec or VSX instructions when building kernel | 174 | # No AltiVec or VSX instructions when building kernel |
165 | KBUILD_CFLAGS += $(call cc-option,-mno-altivec) | 175 | KBUILD_CFLAGS += $(call cc-option,-mno-altivec) |
166 | KBUILD_CFLAGS += $(call cc-option,-mno-vsx) | 176 | KBUILD_CFLAGS += $(call cc-option,-mno-vsx) |
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index a1f8c7f1ec60..426dce7ae7c4 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile | |||
@@ -22,8 +22,14 @@ all: $(obj)/zImage | |||
22 | BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ | 22 | BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ |
23 | -fno-strict-aliasing -Os -msoft-float -pipe \ | 23 | -fno-strict-aliasing -Os -msoft-float -pipe \ |
24 | -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ | 24 | -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ |
25 | -isystem $(shell $(CROSS32CC) -print-file-name=include) \ | 25 | -isystem $(shell $(CROSS32CC) -print-file-name=include) |
26 | -mbig-endian | 26 | ifdef CONFIG_PPC64_BOOT_WRAPPER |
27 | BOOTCFLAGS += -m64 | ||
28 | endif | ||
29 | ifdef CONFIG_CPU_BIG_ENDIAN | ||
30 | BOOTCFLAGS += -mbig-endian | ||
31 | endif | ||
32 | |||
27 | BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc | 33 | BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc |
28 | 34 | ||
29 | ifdef CONFIG_DEBUG_INFO | 35 | ifdef CONFIG_DEBUG_INFO |
@@ -47,6 +53,7 @@ $(obj)/cuboot-acadia.o: BOOTCFLAGS += -mcpu=405 | |||
47 | $(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405 | 53 | $(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405 |
48 | $(obj)/treeboot-iss4xx.o: BOOTCFLAGS += -mcpu=405 | 54 | $(obj)/treeboot-iss4xx.o: BOOTCFLAGS += -mcpu=405 |
49 | $(obj)/treeboot-currituck.o: BOOTCFLAGS += -mcpu=405 | 55 | $(obj)/treeboot-currituck.o: BOOTCFLAGS += -mcpu=405 |
56 | $(obj)/treeboot-akebono.o: BOOTCFLAGS += -mcpu=405 | ||
50 | $(obj)/virtex405-head.o: BOOTAFLAGS += -mcpu=405 | 57 | $(obj)/virtex405-head.o: BOOTAFLAGS += -mcpu=405 |
51 | 58 | ||
52 | 59 | ||
@@ -86,6 +93,7 @@ src-plat-$(CONFIG_44x) += treeboot-ebony.c cuboot-ebony.c treeboot-bamboo.c \ | |||
86 | cuboot-taishan.c cuboot-katmai.c \ | 93 | cuboot-taishan.c cuboot-katmai.c \ |
87 | cuboot-warp.c cuboot-yosemite.c \ | 94 | cuboot-warp.c cuboot-yosemite.c \ |
88 | treeboot-iss4xx.c treeboot-currituck.c \ | 95 | treeboot-iss4xx.c treeboot-currituck.c \ |
96 | treeboot-akebono.c \ | ||
89 | simpleboot.c fixed-head.S virtex.c | 97 | simpleboot.c fixed-head.S virtex.c |
90 | src-plat-$(CONFIG_8xx) += cuboot-8xx.c fixed-head.S ep88xc.c redboot-8xx.c | 98 | src-plat-$(CONFIG_8xx) += cuboot-8xx.c fixed-head.S ep88xc.c redboot-8xx.c |
91 | src-plat-$(CONFIG_PPC_MPC52xx) += cuboot-52xx.c | 99 | src-plat-$(CONFIG_PPC_MPC52xx) += cuboot-52xx.c |
@@ -99,6 +107,11 @@ src-plat-$(CONFIG_EMBEDDED6xx) += cuboot-pq2.c cuboot-mpc7448hpc2.c \ | |||
99 | src-plat-$(CONFIG_AMIGAONE) += cuboot-amigaone.c | 107 | src-plat-$(CONFIG_AMIGAONE) += cuboot-amigaone.c |
100 | src-plat-$(CONFIG_PPC_PS3) += ps3-head.S ps3-hvcall.S ps3.c | 108 | src-plat-$(CONFIG_PPC_PS3) += ps3-head.S ps3-hvcall.S ps3.c |
101 | src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c epapr-wrapper.c | 109 | src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c epapr-wrapper.c |
110 | src-plat-$(CONFIG_PPC_PSERIES) += pseries-head.S | ||
111 | src-plat-$(CONFIG_PPC_POWERNV) += pseries-head.S | ||
112 | src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) += pseries-head.S | ||
113 | src-plat-$(CONFIG_PPC_CELLEB) += pseries-head.S | ||
114 | src-plat-$(CONFIG_PPC_CELL_QPACE) += pseries-head.S | ||
102 | 115 | ||
103 | src-wlib := $(sort $(src-wlib-y)) | 116 | src-wlib := $(sort $(src-wlib-y)) |
104 | src-plat := $(sort $(src-plat-y)) | 117 | src-plat := $(sort $(src-plat-y)) |
@@ -137,7 +150,11 @@ $(addprefix $(obj)/,$(libfdt) $(libfdtheader)): $(obj)/%: $(srctree)/scripts/dtc | |||
137 | $(obj)/empty.c: | 150 | $(obj)/empty.c: |
138 | @touch $@ | 151 | @touch $@ |
139 | 152 | ||
140 | $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds: $(obj)/%: $(srctree)/$(src)/%.S | 153 | $(obj)/zImage.lds: $(obj)/%: $(srctree)/$(src)/%.S |
154 | $(CROSS32CC) $(cpp_flags) -E -Wp,-MD,$(depfile) -P -Upowerpc \ | ||
155 | -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $< | ||
156 | |||
157 | $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds : $(obj)/%: $(srctree)/$(src)/%.S | ||
141 | @cp $< $@ | 158 | @cp $< $@ |
142 | 159 | ||
143 | clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \ | 160 | clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \ |
@@ -235,6 +252,7 @@ image-$(CONFIG_YOSEMITE) += cuImage.yosemite | |||
235 | image-$(CONFIG_ISS4xx) += treeImage.iss4xx \ | 252 | image-$(CONFIG_ISS4xx) += treeImage.iss4xx \ |
236 | treeImage.iss4xx-mpic | 253 | treeImage.iss4xx-mpic |
237 | image-$(CONFIG_CURRITUCK) += treeImage.currituck | 254 | image-$(CONFIG_CURRITUCK) += treeImage.currituck |
255 | image-$(CONFIG_AKEBONO) += treeImage.akebono | ||
238 | 256 | ||
239 | # Board ports in arch/powerpc/platform/8xx/Kconfig | 257 | # Board ports in arch/powerpc/platform/8xx/Kconfig |
240 | image-$(CONFIG_MPC86XADS) += cuImage.mpc866ads | 258 | image-$(CONFIG_MPC86XADS) += cuImage.mpc866ads |
diff --git a/arch/powerpc/boot/addnote.c b/arch/powerpc/boot/addnote.c index 349b5530d2c4..9d9f6f334d3c 100644 --- a/arch/powerpc/boot/addnote.c +++ b/arch/powerpc/boot/addnote.c | |||
@@ -6,6 +6,8 @@ | |||
6 | * | 6 | * |
7 | * Copyright 2000 Paul Mackerras. | 7 | * Copyright 2000 Paul Mackerras. |
8 | * | 8 | * |
9 | * Adapted for 64 bit little endian images by Andrew Tauferner. | ||
10 | * | ||
9 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU General Public License | 12 | * modify it under the terms of the GNU General Public License |
11 | * as published by the Free Software Foundation; either version | 13 | * as published by the Free Software Foundation; either version |
@@ -55,36 +57,61 @@ unsigned int rpanote[N_RPA_DESCR] = { | |||
55 | 57 | ||
56 | #define ROUNDUP(len) (((len) + 3) & ~3) | 58 | #define ROUNDUP(len) (((len) + 3) & ~3) |
57 | 59 | ||
58 | unsigned char buf[512]; | 60 | unsigned char buf[1024]; |
61 | #define ELFDATA2LSB 1 | ||
62 | #define ELFDATA2MSB 2 | ||
63 | static int e_data = ELFDATA2MSB; | ||
64 | #define ELFCLASS32 1 | ||
65 | #define ELFCLASS64 2 | ||
66 | static int e_class = ELFCLASS32; | ||
59 | 67 | ||
60 | #define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1])) | 68 | #define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1])) |
61 | #define GET_32BE(off) ((GET_16BE(off) << 16) + GET_16BE((off)+2)) | 69 | #define GET_32BE(off) ((GET_16BE(off) << 16U) + GET_16BE((off)+2U)) |
62 | 70 | #define GET_64BE(off) ((((unsigned long long)GET_32BE(off)) << 32ULL) + \ | |
63 | #define PUT_16BE(off, v) (buf[off] = ((v) >> 8) & 0xff, \ | 71 | ((unsigned long long)GET_32BE((off)+4ULL))) |
64 | buf[(off) + 1] = (v) & 0xff) | 72 | #define PUT_16BE(off, v)(buf[off] = ((v) >> 8) & 0xff, \ |
65 | #define PUT_32BE(off, v) (PUT_16BE((off), (v) >> 16), \ | 73 | buf[(off) + 1] = (v) & 0xff) |
66 | PUT_16BE((off) + 2, (v))) | 74 | #define PUT_32BE(off, v)(PUT_16BE((off), (v) >> 16L), PUT_16BE((off) + 2, (v))) |
75 | #define PUT_64BE(off, v)((PUT_32BE((off), (v) >> 32L), \ | ||
76 | PUT_32BE((off) + 4, (v)))) | ||
77 | |||
78 | #define GET_16LE(off) ((buf[off]) + (buf[(off)+1] << 8)) | ||
79 | #define GET_32LE(off) (GET_16LE(off) + (GET_16LE((off)+2U) << 16U)) | ||
80 | #define GET_64LE(off) ((unsigned long long)GET_32LE(off) + \ | ||
81 | (((unsigned long long)GET_32LE((off)+4ULL)) << 32ULL)) | ||
82 | #define PUT_16LE(off, v) (buf[off] = (v) & 0xff, \ | ||
83 | buf[(off) + 1] = ((v) >> 8) & 0xff) | ||
84 | #define PUT_32LE(off, v) (PUT_16LE((off), (v)), PUT_16LE((off) + 2, (v) >> 16L)) | ||
85 | #define PUT_64LE(off, v) (PUT_32LE((off), (v)), PUT_32LE((off) + 4, (v) >> 32L)) | ||
86 | |||
87 | #define GET_16(off) (e_data == ELFDATA2MSB ? GET_16BE(off) : GET_16LE(off)) | ||
88 | #define GET_32(off) (e_data == ELFDATA2MSB ? GET_32BE(off) : GET_32LE(off)) | ||
89 | #define GET_64(off) (e_data == ELFDATA2MSB ? GET_64BE(off) : GET_64LE(off)) | ||
90 | #define PUT_16(off, v) (e_data == ELFDATA2MSB ? PUT_16BE(off, v) : \ | ||
91 | PUT_16LE(off, v)) | ||
92 | #define PUT_32(off, v) (e_data == ELFDATA2MSB ? PUT_32BE(off, v) : \ | ||
93 | PUT_32LE(off, v)) | ||
94 | #define PUT_64(off, v) (e_data == ELFDATA2MSB ? PUT_64BE(off, v) : \ | ||
95 | PUT_64LE(off, v)) | ||
67 | 96 | ||
68 | /* Structure of an ELF file */ | 97 | /* Structure of an ELF file */ |
69 | #define E_IDENT 0 /* ELF header */ | 98 | #define E_IDENT 0 /* ELF header */ |
70 | #define E_PHOFF 28 | 99 | #define E_PHOFF (e_class == ELFCLASS32 ? 28 : 32) |
71 | #define E_PHENTSIZE 42 | 100 | #define E_PHENTSIZE (e_class == ELFCLASS32 ? 42 : 54) |
72 | #define E_PHNUM 44 | 101 | #define E_PHNUM (e_class == ELFCLASS32 ? 44 : 56) |
73 | #define E_HSIZE 52 /* size of ELF header */ | 102 | #define E_HSIZE (e_class == ELFCLASS32 ? 52 : 64) |
74 | 103 | ||
75 | #define EI_MAGIC 0 /* offsets in E_IDENT area */ | 104 | #define EI_MAGIC 0 /* offsets in E_IDENT area */ |
76 | #define EI_CLASS 4 | 105 | #define EI_CLASS 4 |
77 | #define EI_DATA 5 | 106 | #define EI_DATA 5 |
78 | 107 | ||
79 | #define PH_TYPE 0 /* ELF program header */ | 108 | #define PH_TYPE 0 /* ELF program header */ |
80 | #define PH_OFFSET 4 | 109 | #define PH_OFFSET (e_class == ELFCLASS32 ? 4 : 8) |
81 | #define PH_FILESZ 16 | 110 | #define PH_FILESZ (e_class == ELFCLASS32 ? 16 : 32) |
82 | #define PH_HSIZE 32 /* size of program header */ | 111 | #define PH_HSIZE (e_class == ELFCLASS32 ? 32 : 56) |
83 | 112 | ||
84 | #define PT_NOTE 4 /* Program header type = note */ | 113 | #define PT_NOTE 4 /* Program header type = note */ |
85 | 114 | ||
86 | #define ELFCLASS32 1 | ||
87 | #define ELFDATA2MSB 2 | ||
88 | 115 | ||
89 | unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' }; | 116 | unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' }; |
90 | 117 | ||
@@ -92,8 +119,8 @@ int | |||
92 | main(int ac, char **av) | 119 | main(int ac, char **av) |
93 | { | 120 | { |
94 | int fd, n, i; | 121 | int fd, n, i; |
95 | int ph, ps, np; | 122 | unsigned long ph, ps, np; |
96 | int nnote, nnote2, ns; | 123 | long nnote, nnote2, ns; |
97 | 124 | ||
98 | if (ac != 2) { | 125 | if (ac != 2) { |
99 | fprintf(stderr, "Usage: %s elf-file\n", av[0]); | 126 | fprintf(stderr, "Usage: %s elf-file\n", av[0]); |
@@ -114,26 +141,27 @@ main(int ac, char **av) | |||
114 | exit(1); | 141 | exit(1); |
115 | } | 142 | } |
116 | 143 | ||
117 | if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0) | 144 | if (memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0) |
145 | goto notelf; | ||
146 | e_class = buf[E_IDENT+EI_CLASS]; | ||
147 | if (e_class != ELFCLASS32 && e_class != ELFCLASS64) | ||
148 | goto notelf; | ||
149 | e_data = buf[E_IDENT+EI_DATA]; | ||
150 | if (e_data != ELFDATA2MSB && e_data != ELFDATA2LSB) | ||
151 | goto notelf; | ||
152 | if (n < E_HSIZE) | ||
118 | goto notelf; | 153 | goto notelf; |
119 | 154 | ||
120 | if (buf[E_IDENT+EI_CLASS] != ELFCLASS32 | 155 | ph = (e_class == ELFCLASS32 ? GET_32(E_PHOFF) : GET_64(E_PHOFF)); |
121 | || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) { | 156 | ps = GET_16(E_PHENTSIZE); |
122 | fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n", | 157 | np = GET_16(E_PHNUM); |
123 | av[1]); | ||
124 | exit(1); | ||
125 | } | ||
126 | |||
127 | ph = GET_32BE(E_PHOFF); | ||
128 | ps = GET_16BE(E_PHENTSIZE); | ||
129 | np = GET_16BE(E_PHNUM); | ||
130 | if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) | 158 | if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) |
131 | goto notelf; | 159 | goto notelf; |
132 | if (ph + (np + 2) * ps + nnote + nnote2 > n) | 160 | if (ph + (np + 2) * ps + nnote + nnote2 > n) |
133 | goto nospace; | 161 | goto nospace; |
134 | 162 | ||
135 | for (i = 0; i < np; ++i) { | 163 | for (i = 0; i < np; ++i) { |
136 | if (GET_32BE(ph + PH_TYPE) == PT_NOTE) { | 164 | if (GET_32(ph + PH_TYPE) == PT_NOTE) { |
137 | fprintf(stderr, "%s already has a note entry\n", | 165 | fprintf(stderr, "%s already has a note entry\n", |
138 | av[1]); | 166 | av[1]); |
139 | exit(0); | 167 | exit(0); |
@@ -148,15 +176,22 @@ main(int ac, char **av) | |||
148 | 176 | ||
149 | /* fill in the program header entry */ | 177 | /* fill in the program header entry */ |
150 | ns = ph + 2 * ps; | 178 | ns = ph + 2 * ps; |
151 | PUT_32BE(ph + PH_TYPE, PT_NOTE); | 179 | PUT_32(ph + PH_TYPE, PT_NOTE); |
152 | PUT_32BE(ph + PH_OFFSET, ns); | 180 | if (e_class == ELFCLASS32) |
153 | PUT_32BE(ph + PH_FILESZ, nnote); | 181 | PUT_32(ph + PH_OFFSET, ns); |
182 | else | ||
183 | PUT_64(ph + PH_OFFSET, ns); | ||
184 | |||
185 | if (e_class == ELFCLASS32) | ||
186 | PUT_32(ph + PH_FILESZ, nnote); | ||
187 | else | ||
188 | PUT_64(ph + PH_FILESZ, nnote); | ||
154 | 189 | ||
155 | /* fill in the note area we point to */ | 190 | /* fill in the note area we point to */ |
156 | /* XXX we should probably make this a proper section */ | 191 | /* XXX we should probably make this a proper section */ |
157 | PUT_32BE(ns, strlen(arch) + 1); | 192 | PUT_32(ns, strlen(arch) + 1); |
158 | PUT_32BE(ns + 4, N_DESCR * 4); | 193 | PUT_32(ns + 4, N_DESCR * 4); |
159 | PUT_32BE(ns + 8, 0x1275); | 194 | PUT_32(ns + 8, 0x1275); |
160 | strcpy((char *) &buf[ns + 12], arch); | 195 | strcpy((char *) &buf[ns + 12], arch); |
161 | ns += 12 + strlen(arch) + 1; | 196 | ns += 12 + strlen(arch) + 1; |
162 | for (i = 0; i < N_DESCR; ++i, ns += 4) | 197 | for (i = 0; i < N_DESCR; ++i, ns += 4) |
@@ -164,21 +199,28 @@ main(int ac, char **av) | |||
164 | 199 | ||
165 | /* fill in the second program header entry and the RPA note area */ | 200 | /* fill in the second program header entry and the RPA note area */ |
166 | ph += ps; | 201 | ph += ps; |
167 | PUT_32BE(ph + PH_TYPE, PT_NOTE); | 202 | PUT_32(ph + PH_TYPE, PT_NOTE); |
168 | PUT_32BE(ph + PH_OFFSET, ns); | 203 | if (e_class == ELFCLASS32) |
169 | PUT_32BE(ph + PH_FILESZ, nnote2); | 204 | PUT_32(ph + PH_OFFSET, ns); |
205 | else | ||
206 | PUT_64(ph + PH_OFFSET, ns); | ||
207 | |||
208 | if (e_class == ELFCLASS32) | ||
209 | PUT_32(ph + PH_FILESZ, nnote); | ||
210 | else | ||
211 | PUT_64(ph + PH_FILESZ, nnote2); | ||
170 | 212 | ||
171 | /* fill in the note area we point to */ | 213 | /* fill in the note area we point to */ |
172 | PUT_32BE(ns, strlen(rpaname) + 1); | 214 | PUT_32(ns, strlen(rpaname) + 1); |
173 | PUT_32BE(ns + 4, sizeof(rpanote)); | 215 | PUT_32(ns + 4, sizeof(rpanote)); |
174 | PUT_32BE(ns + 8, 0x12759999); | 216 | PUT_32(ns + 8, 0x12759999); |
175 | strcpy((char *) &buf[ns + 12], rpaname); | 217 | strcpy((char *) &buf[ns + 12], rpaname); |
176 | ns += 12 + ROUNDUP(strlen(rpaname) + 1); | 218 | ns += 12 + ROUNDUP(strlen(rpaname) + 1); |
177 | for (i = 0; i < N_RPA_DESCR; ++i, ns += 4) | 219 | for (i = 0; i < N_RPA_DESCR; ++i, ns += 4) |
178 | PUT_32BE(ns, rpanote[i]); | 220 | PUT_32BE(ns, rpanote[i]); |
179 | 221 | ||
180 | /* Update the number of program headers */ | 222 | /* Update the number of program headers */ |
181 | PUT_16BE(E_PHNUM, np + 2); | 223 | PUT_16(E_PHNUM, np + 2); |
182 | 224 | ||
183 | /* write back */ | 225 | /* write back */ |
184 | lseek(fd, (long) 0, SEEK_SET); | 226 | lseek(fd, (long) 0, SEEK_SET); |
diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S index 0f7428a37efb..14de4f8778a7 100644 --- a/arch/powerpc/boot/crt0.S +++ b/arch/powerpc/boot/crt0.S | |||
@@ -1,17 +1,20 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) Paul Mackerras 1997. | 2 | * Copyright (C) Paul Mackerras 1997. |
3 | * | 3 | * |
4 | * Adapted for 64 bit LE PowerPC by Andrew Tauferner | ||
5 | * | ||
4 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
6 | * as published by the Free Software Foundation; either version | 8 | * as published by the Free Software Foundation; either version |
7 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
8 | * | 10 | * |
9 | * NOTE: this code runs in 32 bit mode, is position-independent, | ||
10 | * and is packaged as ELF32. | ||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include "ppc_asm.h" | 13 | #include "ppc_asm.h" |
14 | 14 | ||
15 | RELA = 7 | ||
16 | RELACOUNT = 0x6ffffff9 | ||
17 | |||
15 | .text | 18 | .text |
16 | /* A procedure descriptor used when booting this as a COFF file. | 19 | /* A procedure descriptor used when booting this as a COFF file. |
17 | * When making COFF, this comes first in the link and we're | 20 | * When making COFF, this comes first in the link and we're |
@@ -21,6 +24,20 @@ | |||
21 | _zimage_start_opd: | 24 | _zimage_start_opd: |
22 | .long 0x500000, 0, 0, 0 | 25 | .long 0x500000, 0, 0, 0 |
23 | 26 | ||
27 | #ifdef __powerpc64__ | ||
28 | .balign 8 | ||
29 | p_start: .llong _start | ||
30 | p_etext: .llong _etext | ||
31 | p_bss_start: .llong __bss_start | ||
32 | p_end: .llong _end | ||
33 | |||
34 | p_toc: .llong __toc_start + 0x8000 - p_base | ||
35 | p_dyn: .llong __dynamic_start - p_base | ||
36 | p_rela: .llong __rela_dyn_start - p_base | ||
37 | p_prom: .llong 0 | ||
38 | .weak _platform_stack_top | ||
39 | p_pstack: .llong _platform_stack_top | ||
40 | #else | ||
24 | p_start: .long _start | 41 | p_start: .long _start |
25 | p_etext: .long _etext | 42 | p_etext: .long _etext |
26 | p_bss_start: .long __bss_start | 43 | p_bss_start: .long __bss_start |
@@ -28,6 +45,7 @@ p_end: .long _end | |||
28 | 45 | ||
29 | .weak _platform_stack_top | 46 | .weak _platform_stack_top |
30 | p_pstack: .long _platform_stack_top | 47 | p_pstack: .long _platform_stack_top |
48 | #endif | ||
31 | 49 | ||
32 | .weak _zimage_start | 50 | .weak _zimage_start |
33 | .globl _zimage_start | 51 | .globl _zimage_start |
@@ -38,6 +56,7 @@ _zimage_start_lib: | |||
38 | and the address where we're running. */ | 56 | and the address where we're running. */ |
39 | bl .+4 | 57 | bl .+4 |
40 | p_base: mflr r10 /* r10 now points to runtime addr of p_base */ | 58 | p_base: mflr r10 /* r10 now points to runtime addr of p_base */ |
59 | #ifndef __powerpc64__ | ||
41 | /* grab the link address of the dynamic section in r11 */ | 60 | /* grab the link address of the dynamic section in r11 */ |
42 | addis r11,r10,(_GLOBAL_OFFSET_TABLE_-p_base)@ha | 61 | addis r11,r10,(_GLOBAL_OFFSET_TABLE_-p_base)@ha |
43 | lwz r11,(_GLOBAL_OFFSET_TABLE_-p_base)@l(r11) | 62 | lwz r11,(_GLOBAL_OFFSET_TABLE_-p_base)@l(r11) |
@@ -51,8 +70,6 @@ p_base: mflr r10 /* r10 now points to runtime addr of p_base */ | |||
51 | 70 | ||
52 | /* The dynamic section contains a series of tagged entries. | 71 | /* The dynamic section contains a series of tagged entries. |
53 | * We need the RELA and RELACOUNT entries. */ | 72 | * We need the RELA and RELACOUNT entries. */ |
54 | RELA = 7 | ||
55 | RELACOUNT = 0x6ffffff9 | ||
56 | li r9,0 | 73 | li r9,0 |
57 | li r0,0 | 74 | li r0,0 |
58 | 9: lwz r8,0(r12) /* get tag */ | 75 | 9: lwz r8,0(r12) /* get tag */ |
@@ -120,9 +137,164 @@ RELACOUNT = 0x6ffffff9 | |||
120 | li r0,0 | 137 | li r0,0 |
121 | stwu r0,-16(r1) /* establish a stack frame */ | 138 | stwu r0,-16(r1) /* establish a stack frame */ |
122 | 6: | 139 | 6: |
140 | #else /* __powerpc64__ */ | ||
141 | /* Save the prom pointer at p_prom. */ | ||
142 | std r5,(p_prom-p_base)(r10) | ||
143 | |||
144 | /* Set r2 to the TOC. */ | ||
145 | ld r2,(p_toc-p_base)(r10) | ||
146 | add r2,r2,r10 | ||
147 | |||
148 | /* Grab the link address of the dynamic section in r11. */ | ||
149 | ld r11,-32768(r2) | ||
150 | cmpwi r11,0 | ||
151 | beq 3f /* if not linked -pie then no dynamic section */ | ||
152 | |||
153 | ld r11,(p_dyn-p_base)(r10) | ||
154 | add r11,r11,r10 | ||
155 | ld r9,(p_rela-p_base)(r10) | ||
156 | add r9,r9,r10 | ||
123 | 157 | ||
158 | li r7,0 | ||
159 | li r8,0 | ||
160 | 9: ld r6,0(r11) /* get tag */ | ||
161 | cmpdi r6,0 | ||
162 | beq 12f /* end of list */ | ||
163 | cmpdi r6,RELA | ||
164 | bne 10f | ||
165 | ld r7,8(r11) /* get RELA pointer in r7 */ | ||
166 | b 11f | ||
167 | 10: addis r6,r6,(-RELACOUNT)@ha | ||
168 | cmpdi r6,RELACOUNT@l | ||
169 | bne 11f | ||
170 | ld r8,8(r11) /* get RELACOUNT value in r8 */ | ||
171 | 11: addi r11,r11,16 | ||
172 | b 9b | ||
173 | 12: | ||
174 | cmpdi r7,0 /* check we have both RELA and RELACOUNT */ | ||
175 | cmpdi cr1,r8,0 | ||
176 | beq 3f | ||
177 | beq cr1,3f | ||
178 | |||
179 | /* Calcuate the runtime offset. */ | ||
180 | subf r7,r7,r9 | ||
181 | |||
182 | /* Run through the list of relocations and process the | ||
183 | * R_PPC64_RELATIVE ones. */ | ||
184 | mtctr r8 | ||
185 | 13: ld r0,8(r9) /* ELF64_R_TYPE(reloc->r_info) */ | ||
186 | cmpdi r0,22 /* R_PPC64_RELATIVE */ | ||
187 | bne 3f | ||
188 | ld r6,0(r9) /* reloc->r_offset */ | ||
189 | ld r0,16(r9) /* reloc->r_addend */ | ||
190 | add r0,r0,r7 | ||
191 | stdx r0,r7,r6 | ||
192 | addi r9,r9,24 | ||
193 | bdnz 13b | ||
194 | |||
195 | /* Do a cache flush for our text, in case the loader didn't */ | ||
196 | 3: ld r9,p_start-p_base(r10) /* note: these are relocated now */ | ||
197 | ld r8,p_etext-p_base(r10) | ||
198 | 4: dcbf r0,r9 | ||
199 | icbi r0,r9 | ||
200 | addi r9,r9,0x20 | ||
201 | cmpld cr0,r9,r8 | ||
202 | blt 4b | ||
203 | sync | ||
204 | isync | ||
205 | |||
206 | /* Clear the BSS */ | ||
207 | ld r9,p_bss_start-p_base(r10) | ||
208 | ld r8,p_end-p_base(r10) | ||
209 | li r0,0 | ||
210 | 5: std r0,0(r9) | ||
211 | addi r9,r9,8 | ||
212 | cmpld cr0,r9,r8 | ||
213 | blt 5b | ||
214 | |||
215 | /* Possibly set up a custom stack */ | ||
216 | ld r8,p_pstack-p_base(r10) | ||
217 | cmpdi r8,0 | ||
218 | beq 6f | ||
219 | ld r1,0(r8) | ||
220 | li r0,0 | ||
221 | stdu r0,-16(r1) /* establish a stack frame */ | ||
222 | 6: | ||
223 | #endif /* __powerpc64__ */ | ||
124 | /* Call platform_init() */ | 224 | /* Call platform_init() */ |
125 | bl platform_init | 225 | bl platform_init |
126 | 226 | ||
127 | /* Call start */ | 227 | /* Call start */ |
128 | b start | 228 | b start |
229 | |||
230 | #ifdef __powerpc64__ | ||
231 | |||
232 | #define PROM_FRAME_SIZE 512 | ||
233 | #define SAVE_GPR(n, base) std n,8*(n)(base) | ||
234 | #define REST_GPR(n, base) ld n,8*(n)(base) | ||
235 | #define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base) | ||
236 | #define SAVE_4GPRS(n, base) SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base) | ||
237 | #define SAVE_8GPRS(n, base) SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base) | ||
238 | #define SAVE_10GPRS(n, base) SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base) | ||
239 | #define REST_2GPRS(n, base) REST_GPR(n, base); REST_GPR(n+1, base) | ||
240 | #define REST_4GPRS(n, base) REST_2GPRS(n, base); REST_2GPRS(n+2, base) | ||
241 | #define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base) | ||
242 | #define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base) | ||
243 | |||
244 | /* prom handles the jump into and return from firmware. The prom args pointer | ||
245 | is loaded in r3. */ | ||
246 | .globl prom | ||
247 | prom: | ||
248 | mflr r0 | ||
249 | std r0,16(r1) | ||
250 | stdu r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */ | ||
251 | |||
252 | SAVE_GPR(2, r1) | ||
253 | SAVE_GPR(13, r1) | ||
254 | SAVE_8GPRS(14, r1) | ||
255 | SAVE_10GPRS(22, r1) | ||
256 | mfcr r10 | ||
257 | std r10,8*32(r1) | ||
258 | mfmsr r10 | ||
259 | std r10,8*33(r1) | ||
260 | |||
261 | /* remove MSR_LE from msr but keep MSR_SF */ | ||
262 | mfmsr r10 | ||
263 | rldicr r10,r10,0,62 | ||
264 | mtsrr1 r10 | ||
265 | |||
266 | /* Load FW address, set LR to label 1, and jump to FW */ | ||
267 | bl 0f | ||
268 | 0: mflr r10 | ||
269 | addi r11,r10,(1f-0b) | ||
270 | mtlr r11 | ||
271 | |||
272 | ld r10,(p_prom-0b)(r10) | ||
273 | mtsrr0 r10 | ||
274 | |||
275 | rfid | ||
276 | |||
277 | 1: /* Return from OF */ | ||
278 | FIXUP_ENDIAN | ||
279 | |||
280 | /* Restore registers and return. */ | ||
281 | rldicl r1,r1,0,32 | ||
282 | |||
283 | /* Restore the MSR (back to 64 bits) */ | ||
284 | ld r10,8*(33)(r1) | ||
285 | mtmsr r10 | ||
286 | isync | ||
287 | |||
288 | /* Restore other registers */ | ||
289 | REST_GPR(2, r1) | ||
290 | REST_GPR(13, r1) | ||
291 | REST_8GPRS(14, r1) | ||
292 | REST_10GPRS(22, r1) | ||
293 | ld r10,8*32(r1) | ||
294 | mtcr r10 | ||
295 | |||
296 | addi r1,r1,PROM_FRAME_SIZE | ||
297 | ld r0,16(r1) | ||
298 | mtlr r0 | ||
299 | blr | ||
300 | #endif | ||
diff --git a/arch/powerpc/boot/dcr.h b/arch/powerpc/boot/dcr.h index cc73f7a95e26..bf8f4ede1928 100644 --- a/arch/powerpc/boot/dcr.h +++ b/arch/powerpc/boot/dcr.h | |||
@@ -15,6 +15,10 @@ | |||
15 | asm volatile("mfdcrx %0,%1" : "=r"(rval) : "r"(rn)); \ | 15 | asm volatile("mfdcrx %0,%1" : "=r"(rval) : "r"(rn)); \ |
16 | rval; \ | 16 | rval; \ |
17 | }) | 17 | }) |
18 | #define mtdcrx(rn, val) \ | ||
19 | ({ \ | ||
20 | asm volatile("mtdcrx %0,%1" : : "r"(rn), "r" (val)); \ | ||
21 | }) | ||
18 | 22 | ||
19 | /* 440GP/440GX SDRAM controller DCRs */ | 23 | /* 440GP/440GX SDRAM controller DCRs */ |
20 | #define DCRN_SDRAM0_CFGADDR 0x010 | 24 | #define DCRN_SDRAM0_CFGADDR 0x010 |
diff --git a/arch/powerpc/boot/dts/akebono.dts b/arch/powerpc/boot/dts/akebono.dts new file mode 100644 index 000000000000..f92ecfed3d2f --- /dev/null +++ b/arch/powerpc/boot/dts/akebono.dts | |||
@@ -0,0 +1,415 @@ | |||
1 | /* | ||
2 | * Device Tree Source for IBM Embedded PPC 476 Platform | ||
3 | * | ||
4 | * Copyright © 2013 Tony Breeds IBM Corporation | ||
5 | * Copyright © 2013 Alistair Popple IBM Corporation | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public | ||
8 | * License version 2. This program is licensed "as is" without | ||
9 | * any warranty of any kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | /dts-v1/; | ||
13 | |||
14 | /memreserve/ 0x01f00000 0x00100000; // spin table | ||
15 | |||
16 | / { | ||
17 | #address-cells = <2>; | ||
18 | #size-cells = <2>; | ||
19 | model = "ibm,akebono"; | ||
20 | compatible = "ibm,akebono", "ibm,476gtr"; | ||
21 | dcr-parent = <&{/cpus/cpu@0}>; | ||
22 | |||
23 | aliases { | ||
24 | serial0 = &UART0; | ||
25 | }; | ||
26 | |||
27 | cpus { | ||
28 | #address-cells = <1>; | ||
29 | #size-cells = <0>; | ||
30 | |||
31 | cpu@0 { | ||
32 | device_type = "cpu"; | ||
33 | model = "PowerPC,476"; | ||
34 | reg = <0>; | ||
35 | clock-frequency = <1600000000>; // 1.6 GHz | ||
36 | timebase-frequency = <100000000>; // 100Mhz | ||
37 | i-cache-line-size = <32>; | ||
38 | d-cache-line-size = <32>; | ||
39 | i-cache-size = <32768>; | ||
40 | d-cache-size = <32768>; | ||
41 | dcr-controller; | ||
42 | dcr-access-method = "native"; | ||
43 | status = "ok"; | ||
44 | }; | ||
45 | cpu@1 { | ||
46 | device_type = "cpu"; | ||
47 | model = "PowerPC,476"; | ||
48 | reg = <1>; | ||
49 | clock-frequency = <1600000000>; // 1.6 GHz | ||
50 | timebase-frequency = <100000000>; // 100Mhz | ||
51 | i-cache-line-size = <32>; | ||
52 | d-cache-line-size = <32>; | ||
53 | i-cache-size = <32768>; | ||
54 | d-cache-size = <32768>; | ||
55 | dcr-controller; | ||
56 | dcr-access-method = "native"; | ||
57 | status = "disabled"; | ||
58 | enable-method = "spin-table"; | ||
59 | cpu-release-addr = <0x0 0x01f00000>; | ||
60 | }; | ||
61 | }; | ||
62 | |||
63 | memory { | ||
64 | device_type = "memory"; | ||
65 | reg = <0x0 0x0 0x0 0x0>; // filled in by zImage | ||
66 | }; | ||
67 | |||
68 | MPIC: interrupt-controller { | ||
69 | compatible = "chrp,open-pic"; | ||
70 | interrupt-controller; | ||
71 | dcr-reg = <0xffc00000 0x00040000>; | ||
72 | #address-cells = <0>; | ||
73 | #size-cells = <0>; | ||
74 | #interrupt-cells = <2>; | ||
75 | single-cpu-affinity; | ||
76 | }; | ||
77 | |||
78 | plb { | ||
79 | compatible = "ibm,plb6"; | ||
80 | #address-cells = <2>; | ||
81 | #size-cells = <2>; | ||
82 | ranges; | ||
83 | clock-frequency = <200000000>; // 200Mhz | ||
84 | |||
85 | HSTA0: hsta@310000e0000 { | ||
86 | compatible = "ibm,476gtr-hsta-msi", "ibm,hsta-msi"; | ||
87 | reg = <0x310 0x000e0000 0x0 0xf0>; | ||
88 | interrupt-parent = <&MPIC>; | ||
89 | interrupts = <108 0 | ||
90 | 109 0 | ||
91 | 110 0 | ||
92 | 111 0 | ||
93 | 112 0 | ||
94 | 113 0 | ||
95 | 114 0 | ||
96 | 115 0 | ||
97 | 116 0 | ||
98 | 117 0 | ||
99 | 118 0 | ||
100 | 119 0 | ||
101 | 120 0 | ||
102 | 121 0 | ||
103 | 122 0 | ||
104 | 123 0>; | ||
105 | }; | ||
106 | |||
107 | MAL0: mcmal { | ||
108 | compatible = "ibm,mcmal-476gtr", "ibm,mcmal2"; | ||
109 | dcr-reg = <0xc0000000 0x062>; | ||
110 | num-tx-chans = <1>; | ||
111 | num-rx-chans = <1>; | ||
112 | #address-cells = <0>; | ||
113 | #size-cells = <0>; | ||
114 | interrupt-parent = <&MPIC>; | ||
115 | interrupts = < /*TXEOB*/ 77 0x4 | ||
116 | /*RXEOB*/ 78 0x4 | ||
117 | /*SERR*/ 76 0x4 | ||
118 | /*TXDE*/ 79 0x4 | ||
119 | /*RXDE*/ 80 0x4>; | ||
120 | }; | ||
121 | |||
122 | SATA0: sata@30000010000 { | ||
123 | compatible = "ibm,476gtr-ahci"; | ||
124 | reg = <0x300 0x00010000 0x0 0x10000>; | ||
125 | interrupt-parent = <&MPIC>; | ||
126 | interrupts = <93 2>; | ||
127 | }; | ||
128 | |||
129 | EHCI0: ehci@30010000000 { | ||
130 | compatible = "ibm,476gtr-ehci", "generic-ehci"; | ||
131 | reg = <0x300 0x10000000 0x0 0x10000>; | ||
132 | interrupt-parent = <&MPIC>; | ||
133 | interrupts = <85 2>; | ||
134 | }; | ||
135 | |||
136 | SD0: sd@30000000000 { | ||
137 | compatible = "ibm,476gtr-sdhci", "generic-sdhci"; | ||
138 | reg = <0x300 0x00000000 0x0 0x10000>; | ||
139 | interrupts = <91 2>; | ||
140 | interrupt-parent = <&MPIC>; | ||
141 | }; | ||
142 | |||
143 | OHCI0: ohci@30010010000 { | ||
144 | compatible = "ibm,476gtr-ohci", "generic-ohci"; | ||
145 | reg = <0x300 0x10010000 0x0 0x10000>; | ||
146 | interrupt-parent = <&MPIC>; | ||
147 | interrupts = <89 1>; | ||
148 | }; | ||
149 | |||
150 | OHCI1: ohci@30010020000 { | ||
151 | compatible = "ibm,476gtr-ohci", "generic-ohci"; | ||
152 | reg = <0x300 0x10020000 0x0 0x10000>; | ||
153 | interrupt-parent = <&MPIC>; | ||
154 | interrupts = <88 1>; | ||
155 | }; | ||
156 | |||
157 | POB0: opb { | ||
158 | compatible = "ibm,opb-4xx", "ibm,opb"; | ||
159 | #address-cells = <1>; | ||
160 | #size-cells = <1>; | ||
161 | /* Wish there was a nicer way of specifying a full | ||
162 | * 32-bit range | ||
163 | */ | ||
164 | ranges = <0x00000000 0x0000033f 0x00000000 0x80000000 | ||
165 | 0x80000000 0x0000033f 0x80000000 0x80000000>; | ||
166 | clock-frequency = <100000000>; | ||
167 | |||
168 | RGMII0: emac-rgmii-wol@50004 { | ||
169 | compatible = "ibm,rgmii-wol-476gtr", "ibm,rgmii-wol"; | ||
170 | reg = <0x50004 0x00000008>; | ||
171 | has-mdio; | ||
172 | }; | ||
173 | |||
174 | EMAC0: ethernet@30000 { | ||
175 | device_type = "network"; | ||
176 | compatible = "ibm,emac-476gtr", "ibm,emac4sync"; | ||
177 | interrupt-parent = <&EMAC0>; | ||
178 | interrupts = <0x0 0x1>; | ||
179 | #interrupt-cells = <1>; | ||
180 | #address-cells = <0>; | ||
181 | #size-cells = <0>; | ||
182 | interrupt-map = </*Status*/ 0x0 &MPIC 81 0x4 | ||
183 | /*Wake*/ 0x1 &MPIC 82 0x4>; | ||
184 | reg = <0x30000 0x78>; | ||
185 | |||
186 | /* local-mac-address will normally be added by | ||
187 | * the wrapper. If your device doesn't support | ||
188 | * passing data to the wrapper (in the form | ||
189 | * local-mac-addr=<hwaddr>) then you will need | ||
190 | * to set it manually here. */ | ||
191 | //local-mac-address = [000000000000]; | ||
192 | |||
193 | mal-device = <&MAL0>; | ||
194 | mal-tx-channel = <0>; | ||
195 | mal-rx-channel = <0>; | ||
196 | cell-index = <0>; | ||
197 | max-frame-size = <9000>; | ||
198 | rx-fifo-size = <4096>; | ||
199 | tx-fifo-size = <2048>; | ||
200 | rx-fifo-size-gige = <16384>; | ||
201 | phy-mode = "rgmii"; | ||
202 | phy-map = <0x00000000>; | ||
203 | rgmii-wol-device = <&RGMII0>; | ||
204 | has-inverted-stacr-oc; | ||
205 | has-new-stacr-staopc; | ||
206 | }; | ||
207 | |||
208 | UART0: serial@10000 { | ||
209 | device_type = "serial"; | ||
210 | compatible = "ns16750", "ns16550"; | ||
211 | reg = <0x10000 0x00000008>; | ||
212 | virtual-reg = <0xe8010000>; | ||
213 | clock-frequency = <1851851>; | ||
214 | current-speed = <38400>; | ||
215 | interrupt-parent = <&MPIC>; | ||
216 | interrupts = <39 2>; | ||
217 | }; | ||
218 | |||
219 | IIC0: i2c@00000000 { | ||
220 | compatible = "ibm,iic-476gtr", "ibm,iic"; | ||
221 | reg = <0x0 0x00000020>; | ||
222 | interrupt-parent = <&MPIC>; | ||
223 | interrupts = <37 2>; | ||
224 | #address-cells = <1>; | ||
225 | #size-cells = <0>; | ||
226 | rtc@68 { | ||
227 | compatible = "stm,m41t80", "m41st85"; | ||
228 | reg = <0x68>; | ||
229 | }; | ||
230 | }; | ||
231 | |||
232 | IIC1: i2c@00000100 { | ||
233 | compatible = "ibm,iic-476gtr", "ibm,iic"; | ||
234 | reg = <0x100 0x00000020>; | ||
235 | interrupt-parent = <&MPIC>; | ||
236 | interrupts = <38 2>; | ||
237 | #address-cells = <1>; | ||
238 | #size-cells = <0>; | ||
239 | avr@58 { | ||
240 | compatible = "ibm,akebono-avr"; | ||
241 | reg = <0x58>; | ||
242 | }; | ||
243 | }; | ||
244 | |||
245 | FPGA0: fpga@ebc00000 { | ||
246 | compatible = "ibm,akebono-fpga"; | ||
247 | reg = <0xebc00000 0x8>; | ||
248 | }; | ||
249 | }; | ||
250 | |||
251 | PCIE0: pciex@10100000000 { | ||
252 | device_type = "pci"; | ||
253 | #interrupt-cells = <1>; | ||
254 | #size-cells = <2>; | ||
255 | #address-cells = <3>; | ||
256 | compatible = "ibm,plb-pciex-476fpe", "ibm,plb-pciex"; | ||
257 | primary; | ||
258 | port = <0x0>; /* port number */ | ||
259 | reg = <0x00000101 0x00000000 0x0 0x10000000 /* Config space access */ | ||
260 | 0x00000100 0x00000000 0x0 0x00001000>; /* UTL Registers space access */ | ||
261 | dcr-reg = <0xc0 0x20>; | ||
262 | |||
263 | // pci_space < pci_addr > < cpu_addr > < size > | ||
264 | ranges = <0x02000000 0x00000000 0x80000000 0x00000110 0x80000000 0x0 0x80000000 | ||
265 | 0x01000000 0x0 0x0 0x00000140 0x0 0x0 0x00010000>; | ||
266 | |||
267 | /* Inbound starting at 0x0 to 0x40000000000. In order to use MSI | ||
268 | * PCI devices must be able to write to the HSTA module. | ||
269 | */ | ||
270 | dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x400 0x0>; | ||
271 | |||
272 | /* This drives busses 0 to 0xf */ | ||
273 | bus-range = <0x0 0xf>; | ||
274 | |||
275 | /* Legacy interrupts (note the weird polarity, the bridge seems | ||
276 | * to invert PCIe legacy interrupts). | ||
277 | * We are de-swizzling here because the numbers are actually for | ||
278 | * port of the root complex virtual P2P bridge. But I want | ||
279 | * to avoid putting a node for it in the tree, so the numbers | ||
280 | * below are basically de-swizzled numbers. | ||
281 | * The real slot is on idsel 0, so the swizzling is 1:1 | ||
282 | */ | ||
283 | interrupt-map-mask = <0x0 0x0 0x0 0x7>; | ||
284 | interrupt-map = < | ||
285 | 0x0 0x0 0x0 0x1 &MPIC 45 0x2 /* int A */ | ||
286 | 0x0 0x0 0x0 0x2 &MPIC 46 0x2 /* int B */ | ||
287 | 0x0 0x0 0x0 0x3 &MPIC 47 0x2 /* int C */ | ||
288 | 0x0 0x0 0x0 0x4 &MPIC 48 0x2 /* int D */>; | ||
289 | }; | ||
290 | |||
291 | PCIE1: pciex@20100000000 { | ||
292 | device_type = "pci"; | ||
293 | #interrupt-cells = <1>; | ||
294 | #size-cells = <2>; | ||
295 | #address-cells = <3>; | ||
296 | compatible = "ibm,plb-pciex-476fpe", "ibm,plb-pciex"; | ||
297 | primary; | ||
298 | port = <0x1>; /* port number */ | ||
299 | reg = <0x00000201 0x00000000 0x0 0x10000000 /* Config space access */ | ||
300 | 0x00000200 0x00000000 0x0 0x00001000>; /* UTL Registers space access */ | ||
301 | dcr-reg = <0x100 0x20>; | ||
302 | |||
303 | // pci_space < pci_addr > < cpu_addr > < size > | ||
304 | ranges = <0x02000000 0x00000000 0x80000000 0x00000210 0x80000000 0x0 0x80000000 | ||
305 | 0x01000000 0x0 0x0 0x00000240 0x0 0x0 0x00010000>; | ||
306 | |||
307 | /* Inbound starting at 0x0 to 0x40000000000. In order to use MSI | ||
308 | * PCI devices must be able to write to the HSTA module. | ||
309 | */ | ||
310 | dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x400 0x0>; | ||
311 | |||
312 | /* This drives busses 0 to 0xf */ | ||
313 | bus-range = <0x0 0xf>; | ||
314 | |||
315 | /* Legacy interrupts (note the weird polarity, the bridge seems | ||
316 | * to invert PCIe legacy interrupts). | ||
317 | * We are de-swizzling here because the numbers are actually for | ||
318 | * port of the root complex virtual P2P bridge. But I want | ||
319 | * to avoid putting a node for it in the tree, so the numbers | ||
320 | * below are basically de-swizzled numbers. | ||
321 | * The real slot is on idsel 0, so the swizzling is 1:1 | ||
322 | */ | ||
323 | interrupt-map-mask = <0x0 0x0 0x0 0x7>; | ||
324 | interrupt-map = < | ||
325 | 0x0 0x0 0x0 0x1 &MPIC 53 0x2 /* int A */ | ||
326 | 0x0 0x0 0x0 0x2 &MPIC 54 0x2 /* int B */ | ||
327 | 0x0 0x0 0x0 0x3 &MPIC 55 0x2 /* int C */ | ||
328 | 0x0 0x0 0x0 0x4 &MPIC 56 0x2 /* int D */>; | ||
329 | }; | ||
330 | |||
331 | PCIE2: pciex@18100000000 { | ||
332 | device_type = "pci"; | ||
333 | #interrupt-cells = <1>; | ||
334 | #size-cells = <2>; | ||
335 | #address-cells = <3>; | ||
336 | compatible = "ibm,plb-pciex-476fpe", "ibm,plb-pciex"; | ||
337 | primary; | ||
338 | port = <0x2>; /* port number */ | ||
339 | reg = <0x00000181 0x00000000 0x0 0x10000000 /* Config space access */ | ||
340 | 0x00000180 0x00000000 0x0 0x00001000>; /* UTL Registers space access */ | ||
341 | dcr-reg = <0xe0 0x20>; | ||
342 | |||
343 | // pci_space < pci_addr > < cpu_addr > < size > | ||
344 | ranges = <0x02000000 0x00000000 0x80000000 0x00000190 0x80000000 0x0 0x80000000 | ||
345 | 0x01000000 0x0 0x0 0x000001c0 0x0 0x0 0x00010000>; | ||
346 | |||
347 | /* Inbound starting at 0x0 to 0x40000000000. In order to use MSI | ||
348 | * PCI devices must be able to write to the HSTA module. | ||
349 | */ | ||
350 | dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x400 0x0>; | ||
351 | |||
352 | /* This drives busses 0 to 0xf */ | ||
353 | bus-range = <0x0 0xf>; | ||
354 | |||
355 | /* Legacy interrupts (note the weird polarity, the bridge seems | ||
356 | * to invert PCIe legacy interrupts). | ||
357 | * We are de-swizzling here because the numbers are actually for | ||
358 | * port of the root complex virtual P2P bridge. But I want | ||
359 | * to avoid putting a node for it in the tree, so the numbers | ||
360 | * below are basically de-swizzled numbers. | ||
361 | * The real slot is on idsel 0, so the swizzling is 1:1 | ||
362 | */ | ||
363 | interrupt-map-mask = <0x0 0x0 0x0 0x7>; | ||
364 | interrupt-map = < | ||
365 | 0x0 0x0 0x0 0x1 &MPIC 61 0x2 /* int A */ | ||
366 | 0x0 0x0 0x0 0x2 &MPIC 62 0x2 /* int B */ | ||
367 | 0x0 0x0 0x0 0x3 &MPIC 63 0x2 /* int C */ | ||
368 | 0x0 0x0 0x0 0x4 &MPIC 64 0x2 /* int D */>; | ||
369 | }; | ||
370 | |||
371 | PCIE3: pciex@28100000000 { | ||
372 | device_type = "pci"; | ||
373 | #interrupt-cells = <1>; | ||
374 | #size-cells = <2>; | ||
375 | #address-cells = <3>; | ||
376 | compatible = "ibm,plb-pciex-476fpe", "ibm,plb-pciex"; | ||
377 | primary; | ||
378 | port = <0x3>; /* port number */ | ||
379 | reg = <0x00000281 0x00000000 0x0 0x10000000 /* Config space access */ | ||
380 | 0x00000280 0x00000000 0x0 0x00001000>; /* UTL Registers space access */ | ||
381 | dcr-reg = <0x120 0x20>; | ||
382 | |||
383 | // pci_space < pci_addr > < cpu_addr > < size > | ||
384 | ranges = <0x02000000 0x00000000 0x80000000 0x00000290 0x80000000 0x0 0x80000000 | ||
385 | 0x01000000 0x0 0x0 0x000002c0 0x0 0x0 0x00010000>; | ||
386 | |||
387 | /* Inbound starting at 0x0 to 0x40000000000. In order to use MSI | ||
388 | * PCI devices must be able to write to the HSTA module. | ||
389 | */ | ||
390 | dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x400 0x0>; | ||
391 | |||
392 | /* This drives busses 0 to 0xf */ | ||
393 | bus-range = <0x0 0xf>; | ||
394 | |||
395 | /* Legacy interrupts (note the weird polarity, the bridge seems | ||
396 | * to invert PCIe legacy interrupts). | ||
397 | * We are de-swizzling here because the numbers are actually for | ||
398 | * port of the root complex virtual P2P bridge. But I want | ||
399 | * to avoid putting a node for it in the tree, so the numbers | ||
400 | * below are basically de-swizzled numbers. | ||
401 | * The real slot is on idsel 0, so the swizzling is 1:1 | ||
402 | */ | ||
403 | interrupt-map-mask = <0x0 0x0 0x0 0x7>; | ||
404 | interrupt-map = < | ||
405 | 0x0 0x0 0x0 0x1 &MPIC 69 0x2 /* int A */ | ||
406 | 0x0 0x0 0x0 0x2 &MPIC 70 0x2 /* int B */ | ||
407 | 0x0 0x0 0x0 0x3 &MPIC 71 0x2 /* int C */ | ||
408 | 0x0 0x0 0x0 0x4 &MPIC 72 0x2 /* int D */>; | ||
409 | }; | ||
410 | }; | ||
411 | |||
412 | chosen { | ||
413 | linux,stdout-path = &UART0; | ||
414 | }; | ||
415 | }; | ||
diff --git a/arch/powerpc/boot/dts/b4860emu.dts b/arch/powerpc/boot/dts/b4860emu.dts index 7290021f2dfc..85646b4f96e1 100644 --- a/arch/powerpc/boot/dts/b4860emu.dts +++ b/arch/powerpc/boot/dts/b4860emu.dts | |||
@@ -61,21 +61,25 @@ | |||
61 | device_type = "cpu"; | 61 | device_type = "cpu"; |
62 | reg = <0 1>; | 62 | reg = <0 1>; |
63 | next-level-cache = <&L2>; | 63 | next-level-cache = <&L2>; |
64 | fsl,portid-mapping = <0x80000000>; | ||
64 | }; | 65 | }; |
65 | cpu1: PowerPC,e6500@2 { | 66 | cpu1: PowerPC,e6500@2 { |
66 | device_type = "cpu"; | 67 | device_type = "cpu"; |
67 | reg = <2 3>; | 68 | reg = <2 3>; |
68 | next-level-cache = <&L2>; | 69 | next-level-cache = <&L2>; |
70 | fsl,portid-mapping = <0x80000000>; | ||
69 | }; | 71 | }; |
70 | cpu2: PowerPC,e6500@4 { | 72 | cpu2: PowerPC,e6500@4 { |
71 | device_type = "cpu"; | 73 | device_type = "cpu"; |
72 | reg = <4 5>; | 74 | reg = <4 5>; |
73 | next-level-cache = <&L2>; | 75 | next-level-cache = <&L2>; |
76 | fsl,portid-mapping = <0x80000000>; | ||
74 | }; | 77 | }; |
75 | cpu3: PowerPC,e6500@6 { | 78 | cpu3: PowerPC,e6500@6 { |
76 | device_type = "cpu"; | 79 | device_type = "cpu"; |
77 | reg = <6 7>; | 80 | reg = <6 7>; |
78 | next-level-cache = <&L2>; | 81 | next-level-cache = <&L2>; |
82 | fsl,portid-mapping = <0x80000000>; | ||
79 | }; | 83 | }; |
80 | }; | 84 | }; |
81 | }; | 85 | }; |
@@ -157,7 +161,7 @@ | |||
157 | }; | 161 | }; |
158 | 162 | ||
159 | corenet-cf@18000 { | 163 | corenet-cf@18000 { |
160 | compatible = "fsl,b4-corenet-cf"; | 164 | compatible = "fsl,corenet2-cf", "fsl,corenet-cf"; |
161 | reg = <0x18000 0x1000>; | 165 | reg = <0x18000 0x1000>; |
162 | interrupts = <16 2 1 0>; | 166 | interrupts = <16 2 1 0>; |
163 | fsl,ccf-num-csdids = <32>; | 167 | fsl,ccf-num-csdids = <32>; |
@@ -167,6 +171,7 @@ | |||
167 | iommu@20000 { | 171 | iommu@20000 { |
168 | compatible = "fsl,pamu-v1.0", "fsl,pamu"; | 172 | compatible = "fsl,pamu-v1.0", "fsl,pamu"; |
169 | reg = <0x20000 0x4000>; | 173 | reg = <0x20000 0x4000>; |
174 | fsl,portid-mapping = <0x8000>; | ||
170 | #address-cells = <1>; | 175 | #address-cells = <1>; |
171 | #size-cells = <1>; | 176 | #size-cells = <1>; |
172 | interrupts = < | 177 | interrupts = < |
diff --git a/arch/powerpc/boot/dts/bsc9132qds.dts b/arch/powerpc/boot/dts/bsc9132qds.dts new file mode 100644 index 000000000000..6cab1062bc74 --- /dev/null +++ b/arch/powerpc/boot/dts/bsc9132qds.dts | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * BSC9132 QDS Device Tree Source | ||
3 | * | ||
4 | * Copyright 2014 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | /include/ "fsl/bsc9132si-pre.dtsi" | ||
13 | |||
14 | / { | ||
15 | model = "fsl,bsc9132qds"; | ||
16 | compatible = "fsl,bsc9132qds"; | ||
17 | |||
18 | memory { | ||
19 | device_type = "memory"; | ||
20 | }; | ||
21 | |||
22 | ifc: ifc@ff71e000 { | ||
23 | /* NOR, NAND Flash on board */ | ||
24 | ranges = <0x0 0x0 0x0 0x88000000 0x08000000 | ||
25 | 0x1 0x0 0x0 0xff800000 0x00010000>; | ||
26 | reg = <0x0 0xff71e000 0x0 0x2000>; | ||
27 | }; | ||
28 | |||
29 | soc: soc@ff700000 { | ||
30 | ranges = <0x0 0x0 0xff700000 0x100000>; | ||
31 | }; | ||
32 | }; | ||
33 | |||
34 | /include/ "bsc9132qds.dtsi" | ||
35 | /include/ "fsl/bsc9132si-post.dtsi" | ||
diff --git a/arch/powerpc/boot/dts/bsc9132qds.dtsi b/arch/powerpc/boot/dts/bsc9132qds.dtsi new file mode 100644 index 000000000000..af8e88830221 --- /dev/null +++ b/arch/powerpc/boot/dts/bsc9132qds.dtsi | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | * BSC9132 QDS Device Tree Source stub (no addresses or top-level ranges) | ||
3 | * | ||
4 | * Copyright 2014 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions are met: | ||
8 | * * Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * * Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * * Neither the name of Freescale Semiconductor nor the | ||
14 | * names of its contributors may be used to endorse or promote products | ||
15 | * derived from this software without specific prior written permission. | ||
16 | * | ||
17 | * | ||
18 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
19 | * GNU General Public License ("GPL") as published by the Free Software | ||
20 | * Foundation, either version 2 of that License or (at your option) any | ||
21 | * later version. | ||
22 | * | ||
23 | * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY | ||
24 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
26 | * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY | ||
27 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
28 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
29 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
30 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | &ifc { | ||
36 | nor@0,0 { | ||
37 | #address-cells = <1>; | ||
38 | #size-cells = <1>; | ||
39 | compatible = "cfi-flash"; | ||
40 | reg = <0x0 0x0 0x8000000>; | ||
41 | bank-width = <2>; | ||
42 | device-width = <1>; | ||
43 | }; | ||
44 | |||
45 | nand@1,0 { | ||
46 | #address-cells = <1>; | ||
47 | #size-cells = <1>; | ||
48 | compatible = "fsl,ifc-nand"; | ||
49 | reg = <0x1 0x0 0x4000>; | ||
50 | }; | ||
51 | }; | ||
52 | |||
53 | &soc { | ||
54 | spi@7000 { | ||
55 | flash@0 { | ||
56 | #address-cells = <1>; | ||
57 | #size-cells = <1>; | ||
58 | compatible = "spansion,s25sl12801"; | ||
59 | reg = <0>; | ||
60 | spi-max-frequency = <30000000>; | ||
61 | }; | ||
62 | }; | ||
63 | |||
64 | i2c@3000 { | ||
65 | fpga: fpga@66 { | ||
66 | compatible = "fsl,bsc9132qds-fpga", "fsl,fpga-qixis-i2c"; | ||
67 | reg = <0x66>; | ||
68 | }; | ||
69 | }; | ||
70 | |||
71 | usb@22000 { | ||
72 | phy_type = "ulpi"; | ||
73 | }; | ||
74 | |||
75 | mdio@24000 { | ||
76 | phy0: ethernet-phy@0 { | ||
77 | reg = <0x0>; | ||
78 | }; | ||
79 | |||
80 | phy1: ethernet-phy@1 { | ||
81 | reg = <0x1>; | ||
82 | }; | ||
83 | |||
84 | tbi0: tbi-phy@11 { | ||
85 | reg = <0x1f>; | ||
86 | device_type = "tbi-phy"; | ||
87 | }; | ||
88 | }; | ||
89 | |||
90 | enet0: ethernet@b0000 { | ||
91 | phy-handle = <&phy0>; | ||
92 | tbi-handle = <&tbi0>; | ||
93 | phy-connection-type = "sgmii"; | ||
94 | }; | ||
95 | |||
96 | enet1: ethernet@b1000 { | ||
97 | phy-handle = <&phy1>; | ||
98 | tbi-handle = <&tbi0>; | ||
99 | phy-connection-type = "sgmii"; | ||
100 | }; | ||
101 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi index 60566f9927be..d67894459ac8 100644 --- a/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi | |||
@@ -76,10 +76,6 @@ | |||
76 | compatible = "fsl,b4420-l3-cache-controller", "cache"; | 76 | compatible = "fsl,b4420-l3-cache-controller", "cache"; |
77 | }; | 77 | }; |
78 | 78 | ||
79 | corenet-cf@18000 { | ||
80 | compatible = "fsl,b4420-corenet-cf"; | ||
81 | }; | ||
82 | |||
83 | guts: global-utilities@e0000 { | 79 | guts: global-utilities@e0000 { |
84 | compatible = "fsl,b4420-device-config", "fsl,qoriq-device-config-2.0"; | 80 | compatible = "fsl,b4420-device-config", "fsl,qoriq-device-config-2.0"; |
85 | }; | 81 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi b/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi index 2419731c2c54..338af7e39dd9 100644 --- a/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi | |||
@@ -66,12 +66,14 @@ | |||
66 | reg = <0 1>; | 66 | reg = <0 1>; |
67 | clocks = <&mux0>; | 67 | clocks = <&mux0>; |
68 | next-level-cache = <&L2>; | 68 | next-level-cache = <&L2>; |
69 | fsl,portid-mapping = <0x80000000>; | ||
69 | }; | 70 | }; |
70 | cpu1: PowerPC,e6500@2 { | 71 | cpu1: PowerPC,e6500@2 { |
71 | device_type = "cpu"; | 72 | device_type = "cpu"; |
72 | reg = <2 3>; | 73 | reg = <2 3>; |
73 | clocks = <&mux0>; | 74 | clocks = <&mux0>; |
74 | next-level-cache = <&L2>; | 75 | next-level-cache = <&L2>; |
76 | fsl,portid-mapping = <0x80000000>; | ||
75 | }; | 77 | }; |
76 | }; | 78 | }; |
77 | }; | 79 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi index cbc354b05117..582381dba1d7 100644 --- a/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi | |||
@@ -120,10 +120,6 @@ | |||
120 | compatible = "fsl,b4860-l3-cache-controller", "cache"; | 120 | compatible = "fsl,b4860-l3-cache-controller", "cache"; |
121 | }; | 121 | }; |
122 | 122 | ||
123 | corenet-cf@18000 { | ||
124 | compatible = "fsl,b4860-corenet-cf"; | ||
125 | }; | ||
126 | |||
127 | guts: global-utilities@e0000 { | 123 | guts: global-utilities@e0000 { |
128 | compatible = "fsl,b4860-device-config", "fsl,qoriq-device-config-2.0"; | 124 | compatible = "fsl,b4860-device-config", "fsl,qoriq-device-config-2.0"; |
129 | }; | 125 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi b/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi index 142ac862cacf..1948f73fd26b 100644 --- a/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi | |||
@@ -66,24 +66,28 @@ | |||
66 | reg = <0 1>; | 66 | reg = <0 1>; |
67 | clocks = <&mux0>; | 67 | clocks = <&mux0>; |
68 | next-level-cache = <&L2>; | 68 | next-level-cache = <&L2>; |
69 | fsl,portid-mapping = <0x80000000>; | ||
69 | }; | 70 | }; |
70 | cpu1: PowerPC,e6500@2 { | 71 | cpu1: PowerPC,e6500@2 { |
71 | device_type = "cpu"; | 72 | device_type = "cpu"; |
72 | reg = <2 3>; | 73 | reg = <2 3>; |
73 | clocks = <&mux0>; | 74 | clocks = <&mux0>; |
74 | next-level-cache = <&L2>; | 75 | next-level-cache = <&L2>; |
76 | fsl,portid-mapping = <0x80000000>; | ||
75 | }; | 77 | }; |
76 | cpu2: PowerPC,e6500@4 { | 78 | cpu2: PowerPC,e6500@4 { |
77 | device_type = "cpu"; | 79 | device_type = "cpu"; |
78 | reg = <4 5>; | 80 | reg = <4 5>; |
79 | clocks = <&mux0>; | 81 | clocks = <&mux0>; |
80 | next-level-cache = <&L2>; | 82 | next-level-cache = <&L2>; |
83 | fsl,portid-mapping = <0x80000000>; | ||
81 | }; | 84 | }; |
82 | cpu3: PowerPC,e6500@6 { | 85 | cpu3: PowerPC,e6500@6 { |
83 | device_type = "cpu"; | 86 | device_type = "cpu"; |
84 | reg = <6 7>; | 87 | reg = <6 7>; |
85 | clocks = <&mux0>; | 88 | clocks = <&mux0>; |
86 | next-level-cache = <&L2>; | 89 | next-level-cache = <&L2>; |
90 | fsl,portid-mapping = <0x80000000>; | ||
87 | }; | 91 | }; |
88 | }; | 92 | }; |
89 | }; | 93 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/b4si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4si-post.dtsi index 4f6e48277c46..1a54ba71f685 100644 --- a/arch/powerpc/boot/dts/fsl/b4si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/b4si-post.dtsi | |||
@@ -158,7 +158,7 @@ | |||
158 | }; | 158 | }; |
159 | 159 | ||
160 | corenet-cf@18000 { | 160 | corenet-cf@18000 { |
161 | compatible = "fsl,b4-corenet-cf"; | 161 | compatible = "fsl,corenet2-cf", "fsl,corenet-cf"; |
162 | reg = <0x18000 0x1000>; | 162 | reg = <0x18000 0x1000>; |
163 | interrupts = <16 2 1 0>; | 163 | interrupts = <16 2 1 0>; |
164 | fsl,ccf-num-csdids = <32>; | 164 | fsl,ccf-num-csdids = <32>; |
@@ -168,6 +168,7 @@ | |||
168 | iommu@20000 { | 168 | iommu@20000 { |
169 | compatible = "fsl,pamu-v1.0", "fsl,pamu"; | 169 | compatible = "fsl,pamu-v1.0", "fsl,pamu"; |
170 | reg = <0x20000 0x4000>; | 170 | reg = <0x20000 0x4000>; |
171 | fsl,portid-mapping = <0x8000>; | ||
171 | #address-cells = <1>; | 172 | #address-cells = <1>; |
172 | #size-cells = <1>; | 173 | #size-cells = <1>; |
173 | interrupts = < | 174 | interrupts = < |
diff --git a/arch/powerpc/boot/dts/fsl/bsc9132si-post.dtsi b/arch/powerpc/boot/dts/fsl/bsc9132si-post.dtsi new file mode 100644 index 000000000000..c72307198140 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/bsc9132si-post.dtsi | |||
@@ -0,0 +1,185 @@ | |||
1 | /* | ||
2 | * BSC9132 Silicon/SoC Device Tree Source (post include) | ||
3 | * | ||
4 | * Copyright 2014 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions are met: | ||
8 | * * Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * * Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * * Neither the name of Freescale Semiconductor nor the | ||
14 | * names of its contributors may be used to endorse or promote products | ||
15 | * derived from this software without specific prior written permission. | ||
16 | * | ||
17 | * | ||
18 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
19 | * GNU General Public License ("GPL") as published by the Free Software | ||
20 | * Foundation, either version 2 of that License or (at your option) any | ||
21 | * later version. | ||
22 | * | ||
23 | * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY | ||
24 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
26 | * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY | ||
27 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
28 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
29 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
30 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | &ifc { | ||
36 | #address-cells = <2>; | ||
37 | #size-cells = <1>; | ||
38 | compatible = "fsl,ifc", "simple-bus"; | ||
39 | /* FIXME: Test whether interrupts are split */ | ||
40 | interrupts = <16 2 0 0 20 2 0 0>; | ||
41 | }; | ||
42 | |||
43 | &soc { | ||
44 | #address-cells = <1>; | ||
45 | #size-cells = <1>; | ||
46 | device_type = "soc"; | ||
47 | compatible = "fsl,bsc9132-immr", "simple-bus"; | ||
48 | bus-frequency = <0>; // Filled out by uboot. | ||
49 | |||
50 | ecm-law@0 { | ||
51 | compatible = "fsl,ecm-law"; | ||
52 | reg = <0x0 0x1000>; | ||
53 | fsl,num-laws = <12>; | ||
54 | }; | ||
55 | |||
56 | ecm@1000 { | ||
57 | compatible = "fsl,bsc9132-ecm", "fsl,ecm"; | ||
58 | reg = <0x1000 0x1000>; | ||
59 | interrupts = <16 2 0 0>; | ||
60 | }; | ||
61 | |||
62 | memory-controller@2000 { | ||
63 | compatible = "fsl,bsc9132-memory-controller"; | ||
64 | reg = <0x2000 0x1000>; | ||
65 | interrupts = <16 2 1 8>; | ||
66 | }; | ||
67 | |||
68 | /include/ "pq3-i2c-0.dtsi" | ||
69 | i2c@3000 { | ||
70 | interrupts = <17 2 0 0>; | ||
71 | }; | ||
72 | |||
73 | /include/ "pq3-i2c-1.dtsi" | ||
74 | i2c@3100 { | ||
75 | interrupts = <17 2 0 0>; | ||
76 | }; | ||
77 | |||
78 | /include/ "pq3-duart-0.dtsi" | ||
79 | serial0: serial@4500 { | ||
80 | interrupts = <18 2 0 0>; | ||
81 | }; | ||
82 | |||
83 | serial1: serial@4600 { | ||
84 | interrupts = <18 2 0 0 >; | ||
85 | }; | ||
86 | /include/ "pq3-espi-0.dtsi" | ||
87 | spi0: spi@7000 { | ||
88 | fsl,espi-num-chipselects = <1>; | ||
89 | interrupts = <22 0x2 0 0>; | ||
90 | }; | ||
91 | |||
92 | /include/ "pq3-gpio-0.dtsi" | ||
93 | gpio-controller@f000 { | ||
94 | interrupts = <19 0x2 0 0>; | ||
95 | }; | ||
96 | |||
97 | L2: l2-cache-controller@20000 { | ||
98 | compatible = "fsl,bsc9132-l2-cache-controller"; | ||
99 | reg = <0x20000 0x1000>; | ||
100 | cache-line-size = <32>; // 32 bytes | ||
101 | cache-size = <0x40000>; // L2,256K | ||
102 | interrupts = <16 2 1 0>; | ||
103 | }; | ||
104 | |||
105 | /include/ "pq3-dma-0.dtsi" | ||
106 | |||
107 | dma@21300 { | ||
108 | |||
109 | dma-channel@0 { | ||
110 | interrupts = <62 2 0 0>; | ||
111 | }; | ||
112 | |||
113 | dma-channel@80 { | ||
114 | interrupts = <63 2 0 0>; | ||
115 | }; | ||
116 | |||
117 | dma-channel@100 { | ||
118 | interrupts = <64 2 0 0>; | ||
119 | }; | ||
120 | |||
121 | dma-channel@180 { | ||
122 | interrupts = <65 2 0 0>; | ||
123 | }; | ||
124 | }; | ||
125 | |||
126 | /include/ "pq3-usb2-dr-0.dtsi" | ||
127 | usb@22000 { | ||
128 | compatible = "fsl-usb2-dr","fsl-usb2-dr-v2.2"; | ||
129 | interrupts = <40 0x2 0 0>; | ||
130 | }; | ||
131 | |||
132 | /include/ "pq3-esdhc-0.dtsi" | ||
133 | sdhc@2e000 { | ||
134 | fsl,sdhci-auto-cmd12; | ||
135 | interrupts = <41 0x2 0 0>; | ||
136 | }; | ||
137 | |||
138 | /include/ "pq3-sec4.4-0.dtsi" | ||
139 | crypto@30000 { | ||
140 | interrupts = <57 2 0 0>; | ||
141 | |||
142 | sec_jr0: jr@1000 { | ||
143 | interrupts = <58 2 0 0>; | ||
144 | }; | ||
145 | |||
146 | sec_jr1: jr@2000 { | ||
147 | interrupts = <59 2 0 0>; | ||
148 | }; | ||
149 | |||
150 | sec_jr2: jr@3000 { | ||
151 | interrupts = <60 2 0 0>; | ||
152 | }; | ||
153 | |||
154 | sec_jr3: jr@4000 { | ||
155 | interrupts = <61 2 0 0>; | ||
156 | }; | ||
157 | }; | ||
158 | |||
159 | /include/ "pq3-mpic.dtsi" | ||
160 | /include/ "pq3-mpic-timer-B.dtsi" | ||
161 | |||
162 | /include/ "pq3-etsec2-0.dtsi" | ||
163 | enet0: ethernet@b0000 { | ||
164 | queue-group@b0000 { | ||
165 | fsl,rx-bit-map = <0xff>; | ||
166 | fsl,tx-bit-map = <0xff>; | ||
167 | interrupts = <26 2 0 0 27 2 0 0 28 2 0 0>; | ||
168 | }; | ||
169 | }; | ||
170 | |||
171 | /include/ "pq3-etsec2-1.dtsi" | ||
172 | enet1: ethernet@b1000 { | ||
173 | queue-group@b1000 { | ||
174 | fsl,rx-bit-map = <0xff>; | ||
175 | fsl,tx-bit-map = <0xff>; | ||
176 | interrupts = <33 2 0 0 34 2 0 0 35 2 0 0>; | ||
177 | }; | ||
178 | }; | ||
179 | |||
180 | global-utilities@e0000 { | ||
181 | compatible = "fsl,bsc9132-guts"; | ||
182 | reg = <0xe0000 0x1000>; | ||
183 | fsl,has-rstcr; | ||
184 | }; | ||
185 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/bsc9132si-pre.dtsi b/arch/powerpc/boot/dts/fsl/bsc9132si-pre.dtsi new file mode 100644 index 000000000000..301a9dba5790 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/bsc9132si-pre.dtsi | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | * BSC9132 Silicon/SoC Device Tree Source (pre include) | ||
3 | * | ||
4 | * Copyright 2014 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions are met: | ||
8 | * * Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * * Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * * Neither the name of Freescale Semiconductor nor the | ||
14 | * names of its contributors may be used to endorse or promote products | ||
15 | * derived from this software without specific prior written permission. | ||
16 | * | ||
17 | * | ||
18 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
19 | * GNU General Public License ("GPL") as published by the Free Software | ||
20 | * Foundation, either version 2 of that License or (at your option) any | ||
21 | * later version. | ||
22 | * | ||
23 | * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY | ||
24 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
26 | * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY | ||
27 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
28 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
29 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
30 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | /dts-v1/; | ||
36 | |||
37 | /include/ "e500v2_power_isa.dtsi" | ||
38 | |||
39 | / { | ||
40 | #address-cells = <2>; | ||
41 | #size-cells = <2>; | ||
42 | interrupt-parent = <&mpic>; | ||
43 | |||
44 | aliases { | ||
45 | serial0 = &serial0; | ||
46 | ethernet0 = &enet0; | ||
47 | ethernet1 = &enet1; | ||
48 | }; | ||
49 | |||
50 | cpus { | ||
51 | #address-cells = <1>; | ||
52 | #size-cells = <0>; | ||
53 | |||
54 | cpu0: PowerPC,e500v2@0 { | ||
55 | device_type = "cpu"; | ||
56 | reg = <0x0>; | ||
57 | next-level-cache = <&L2>; | ||
58 | }; | ||
59 | |||
60 | cpu1: PowerPC,e500v2@1 { | ||
61 | device_type = "cpu"; | ||
62 | reg = <0x1>; | ||
63 | next-level-cache = <&L2>; | ||
64 | }; | ||
65 | }; | ||
66 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi index e2987a33083c..5290df83ff30 100644 --- a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi | |||
@@ -246,7 +246,7 @@ | |||
246 | }; | 246 | }; |
247 | 247 | ||
248 | corenet-cf@18000 { | 248 | corenet-cf@18000 { |
249 | compatible = "fsl,corenet-cf"; | 249 | compatible = "fsl,corenet1-cf", "fsl,corenet-cf"; |
250 | reg = <0x18000 0x1000>; | 250 | reg = <0x18000 0x1000>; |
251 | interrupts = <16 2 1 31>; | 251 | interrupts = <16 2 1 31>; |
252 | fsl,ccf-num-csdids = <32>; | 252 | fsl,ccf-num-csdids = <32>; |
@@ -262,6 +262,7 @@ | |||
262 | interrupts = < | 262 | interrupts = < |
263 | 24 2 0 0 | 263 | 24 2 0 0 |
264 | 16 2 1 30>; | 264 | 16 2 1 30>; |
265 | fsl,portid-mapping = <0x0f000000>; | ||
265 | 266 | ||
266 | pamu0: pamu@0 { | 267 | pamu0: pamu@0 { |
267 | reg = <0 0x1000>; | 268 | reg = <0 0x1000>; |
diff --git a/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi index 22f3b14517de..b1ea147f2995 100644 --- a/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi | |||
@@ -83,6 +83,7 @@ | |||
83 | reg = <0>; | 83 | reg = <0>; |
84 | clocks = <&mux0>; | 84 | clocks = <&mux0>; |
85 | next-level-cache = <&L2_0>; | 85 | next-level-cache = <&L2_0>; |
86 | fsl,portid-mapping = <0x80000000>; | ||
86 | L2_0: l2-cache { | 87 | L2_0: l2-cache { |
87 | next-level-cache = <&cpc>; | 88 | next-level-cache = <&cpc>; |
88 | }; | 89 | }; |
@@ -92,6 +93,7 @@ | |||
92 | reg = <1>; | 93 | reg = <1>; |
93 | clocks = <&mux1>; | 94 | clocks = <&mux1>; |
94 | next-level-cache = <&L2_1>; | 95 | next-level-cache = <&L2_1>; |
96 | fsl,portid-mapping = <0x40000000>; | ||
95 | L2_1: l2-cache { | 97 | L2_1: l2-cache { |
96 | next-level-cache = <&cpc>; | 98 | next-level-cache = <&cpc>; |
97 | }; | 99 | }; |
@@ -101,6 +103,7 @@ | |||
101 | reg = <2>; | 103 | reg = <2>; |
102 | clocks = <&mux2>; | 104 | clocks = <&mux2>; |
103 | next-level-cache = <&L2_2>; | 105 | next-level-cache = <&L2_2>; |
106 | fsl,portid-mapping = <0x20000000>; | ||
104 | L2_2: l2-cache { | 107 | L2_2: l2-cache { |
105 | next-level-cache = <&cpc>; | 108 | next-level-cache = <&cpc>; |
106 | }; | 109 | }; |
@@ -110,6 +113,7 @@ | |||
110 | reg = <3>; | 113 | reg = <3>; |
111 | clocks = <&mux3>; | 114 | clocks = <&mux3>; |
112 | next-level-cache = <&L2_3>; | 115 | next-level-cache = <&L2_3>; |
116 | fsl,portid-mapping = <0x10000000>; | ||
113 | L2_3: l2-cache { | 117 | L2_3: l2-cache { |
114 | next-level-cache = <&cpc>; | 118 | next-level-cache = <&cpc>; |
115 | }; | 119 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi b/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi index 7af6d45fd998..cd63cb1b1042 100644 --- a/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi | |||
@@ -273,7 +273,7 @@ | |||
273 | }; | 273 | }; |
274 | 274 | ||
275 | corenet-cf@18000 { | 275 | corenet-cf@18000 { |
276 | compatible = "fsl,corenet-cf"; | 276 | compatible = "fsl,corenet1-cf", "fsl,corenet-cf"; |
277 | reg = <0x18000 0x1000>; | 277 | reg = <0x18000 0x1000>; |
278 | interrupts = <16 2 1 31>; | 278 | interrupts = <16 2 1 31>; |
279 | fsl,ccf-num-csdids = <32>; | 279 | fsl,ccf-num-csdids = <32>; |
@@ -289,6 +289,7 @@ | |||
289 | interrupts = < | 289 | interrupts = < |
290 | 24 2 0 0 | 290 | 24 2 0 0 |
291 | 16 2 1 30>; | 291 | 16 2 1 30>; |
292 | fsl,portid-mapping = <0x0f000000>; | ||
292 | 293 | ||
293 | pamu0: pamu@0 { | 294 | pamu0: pamu@0 { |
294 | reg = <0 0x1000>; | 295 | reg = <0 0x1000>; |
diff --git a/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi index 468e8be8ac6f..dc5f4b362c24 100644 --- a/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi | |||
@@ -84,6 +84,7 @@ | |||
84 | reg = <0>; | 84 | reg = <0>; |
85 | clocks = <&mux0>; | 85 | clocks = <&mux0>; |
86 | next-level-cache = <&L2_0>; | 86 | next-level-cache = <&L2_0>; |
87 | fsl,portid-mapping = <0x80000000>; | ||
87 | L2_0: l2-cache { | 88 | L2_0: l2-cache { |
88 | next-level-cache = <&cpc>; | 89 | next-level-cache = <&cpc>; |
89 | }; | 90 | }; |
@@ -93,6 +94,7 @@ | |||
93 | reg = <1>; | 94 | reg = <1>; |
94 | clocks = <&mux1>; | 95 | clocks = <&mux1>; |
95 | next-level-cache = <&L2_1>; | 96 | next-level-cache = <&L2_1>; |
97 | fsl,portid-mapping = <0x40000000>; | ||
96 | L2_1: l2-cache { | 98 | L2_1: l2-cache { |
97 | next-level-cache = <&cpc>; | 99 | next-level-cache = <&cpc>; |
98 | }; | 100 | }; |
@@ -102,6 +104,7 @@ | |||
102 | reg = <2>; | 104 | reg = <2>; |
103 | clocks = <&mux2>; | 105 | clocks = <&mux2>; |
104 | next-level-cache = <&L2_2>; | 106 | next-level-cache = <&L2_2>; |
107 | fsl,portid-mapping = <0x20000000>; | ||
105 | L2_2: l2-cache { | 108 | L2_2: l2-cache { |
106 | next-level-cache = <&cpc>; | 109 | next-level-cache = <&cpc>; |
107 | }; | 110 | }; |
@@ -111,6 +114,7 @@ | |||
111 | reg = <3>; | 114 | reg = <3>; |
112 | clocks = <&mux3>; | 115 | clocks = <&mux3>; |
113 | next-level-cache = <&L2_3>; | 116 | next-level-cache = <&L2_3>; |
117 | fsl,portid-mapping = <0x10000000>; | ||
114 | L2_3: l2-cache { | 118 | L2_3: l2-cache { |
115 | next-level-cache = <&cpc>; | 119 | next-level-cache = <&cpc>; |
116 | }; | 120 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi b/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi index 2415e1f1d3fa..12947ccddf25 100644 --- a/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi | |||
@@ -281,7 +281,7 @@ | |||
281 | }; | 281 | }; |
282 | 282 | ||
283 | corenet-cf@18000 { | 283 | corenet-cf@18000 { |
284 | compatible = "fsl,corenet-cf"; | 284 | compatible = "fsl,corenet1-cf", "fsl,corenet-cf"; |
285 | reg = <0x18000 0x1000>; | 285 | reg = <0x18000 0x1000>; |
286 | interrupts = <16 2 1 31>; | 286 | interrupts = <16 2 1 31>; |
287 | fsl,ccf-num-csdids = <32>; | 287 | fsl,ccf-num-csdids = <32>; |
@@ -297,6 +297,7 @@ | |||
297 | interrupts = < | 297 | interrupts = < |
298 | 24 2 0 0 | 298 | 24 2 0 0 |
299 | 16 2 1 30>; | 299 | 16 2 1 30>; |
300 | fsl,portid-mapping = <0x00f80000>; | ||
300 | 301 | ||
301 | pamu0: pamu@0 { | 302 | pamu0: pamu@0 { |
302 | reg = <0 0x1000>; | 303 | reg = <0 0x1000>; |
diff --git a/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi index 0040b5a5379e..38bde0958672 100644 --- a/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi | |||
@@ -83,6 +83,7 @@ | |||
83 | reg = <0>; | 83 | reg = <0>; |
84 | clocks = <&mux0>; | 84 | clocks = <&mux0>; |
85 | next-level-cache = <&L2_0>; | 85 | next-level-cache = <&L2_0>; |
86 | fsl,portid-mapping = <0x80000000>; | ||
86 | L2_0: l2-cache { | 87 | L2_0: l2-cache { |
87 | next-level-cache = <&cpc>; | 88 | next-level-cache = <&cpc>; |
88 | }; | 89 | }; |
@@ -92,6 +93,7 @@ | |||
92 | reg = <1>; | 93 | reg = <1>; |
93 | clocks = <&mux1>; | 94 | clocks = <&mux1>; |
94 | next-level-cache = <&L2_1>; | 95 | next-level-cache = <&L2_1>; |
96 | fsl,portid-mapping = <0x40000000>; | ||
95 | L2_1: l2-cache { | 97 | L2_1: l2-cache { |
96 | next-level-cache = <&cpc>; | 98 | next-level-cache = <&cpc>; |
97 | }; | 99 | }; |
@@ -101,6 +103,7 @@ | |||
101 | reg = <2>; | 103 | reg = <2>; |
102 | clocks = <&mux2>; | 104 | clocks = <&mux2>; |
103 | next-level-cache = <&L2_2>; | 105 | next-level-cache = <&L2_2>; |
106 | fsl,portid-mapping = <0x20000000>; | ||
104 | L2_2: l2-cache { | 107 | L2_2: l2-cache { |
105 | next-level-cache = <&cpc>; | 108 | next-level-cache = <&cpc>; |
106 | }; | 109 | }; |
@@ -110,6 +113,7 @@ | |||
110 | reg = <3>; | 113 | reg = <3>; |
111 | clocks = <&mux3>; | 114 | clocks = <&mux3>; |
112 | next-level-cache = <&L2_3>; | 115 | next-level-cache = <&L2_3>; |
116 | fsl,portid-mapping = <0x10000000>; | ||
113 | L2_3: l2-cache { | 117 | L2_3: l2-cache { |
114 | next-level-cache = <&cpc>; | 118 | next-level-cache = <&cpc>; |
115 | }; | 119 | }; |
@@ -119,6 +123,7 @@ | |||
119 | reg = <4>; | 123 | reg = <4>; |
120 | clocks = <&mux4>; | 124 | clocks = <&mux4>; |
121 | next-level-cache = <&L2_4>; | 125 | next-level-cache = <&L2_4>; |
126 | fsl,portid-mapping = <0x08000000>; | ||
122 | L2_4: l2-cache { | 127 | L2_4: l2-cache { |
123 | next-level-cache = <&cpc>; | 128 | next-level-cache = <&cpc>; |
124 | }; | 129 | }; |
@@ -128,6 +133,7 @@ | |||
128 | reg = <5>; | 133 | reg = <5>; |
129 | clocks = <&mux5>; | 134 | clocks = <&mux5>; |
130 | next-level-cache = <&L2_5>; | 135 | next-level-cache = <&L2_5>; |
136 | fsl,portid-mapping = <0x04000000>; | ||
131 | L2_5: l2-cache { | 137 | L2_5: l2-cache { |
132 | next-level-cache = <&cpc>; | 138 | next-level-cache = <&cpc>; |
133 | }; | 139 | }; |
@@ -137,6 +143,7 @@ | |||
137 | reg = <6>; | 143 | reg = <6>; |
138 | clocks = <&mux6>; | 144 | clocks = <&mux6>; |
139 | next-level-cache = <&L2_6>; | 145 | next-level-cache = <&L2_6>; |
146 | fsl,portid-mapping = <0x02000000>; | ||
140 | L2_6: l2-cache { | 147 | L2_6: l2-cache { |
141 | next-level-cache = <&cpc>; | 148 | next-level-cache = <&cpc>; |
142 | }; | 149 | }; |
@@ -146,6 +153,7 @@ | |||
146 | reg = <7>; | 153 | reg = <7>; |
147 | clocks = <&mux7>; | 154 | clocks = <&mux7>; |
148 | next-level-cache = <&L2_7>; | 155 | next-level-cache = <&L2_7>; |
156 | fsl,portid-mapping = <0x01000000>; | ||
149 | L2_7: l2-cache { | 157 | L2_7: l2-cache { |
150 | next-level-cache = <&cpc>; | 158 | next-level-cache = <&cpc>; |
151 | }; | 159 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi index 2985de4ad6be..4c4a2b0436b2 100644 --- a/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi | |||
@@ -278,7 +278,7 @@ | |||
278 | }; | 278 | }; |
279 | 279 | ||
280 | corenet-cf@18000 { | 280 | corenet-cf@18000 { |
281 | compatible = "fsl,corenet-cf"; | 281 | compatible = "fsl,corenet1-cf", "fsl,corenet-cf"; |
282 | reg = <0x18000 0x1000>; | 282 | reg = <0x18000 0x1000>; |
283 | interrupts = <16 2 1 31>; | 283 | interrupts = <16 2 1 31>; |
284 | fsl,ccf-num-csdids = <32>; | 284 | fsl,ccf-num-csdids = <32>; |
@@ -294,6 +294,7 @@ | |||
294 | interrupts = < | 294 | interrupts = < |
295 | 24 2 0 0 | 295 | 24 2 0 0 |
296 | 16 2 1 30>; | 296 | 16 2 1 30>; |
297 | fsl,portid-mapping = <0x3c000000>; | ||
297 | 298 | ||
298 | pamu0: pamu@0 { | 299 | pamu0: pamu@0 { |
299 | reg = <0 0x1000>; | 300 | reg = <0 0x1000>; |
diff --git a/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi index fe1a2e6613b4..1cc61e126e4c 100644 --- a/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi | |||
@@ -90,6 +90,7 @@ | |||
90 | reg = <0>; | 90 | reg = <0>; |
91 | clocks = <&mux0>; | 91 | clocks = <&mux0>; |
92 | next-level-cache = <&L2_0>; | 92 | next-level-cache = <&L2_0>; |
93 | fsl,portid-mapping = <0x80000000>; | ||
93 | L2_0: l2-cache { | 94 | L2_0: l2-cache { |
94 | next-level-cache = <&cpc>; | 95 | next-level-cache = <&cpc>; |
95 | }; | 96 | }; |
@@ -99,6 +100,7 @@ | |||
99 | reg = <1>; | 100 | reg = <1>; |
100 | clocks = <&mux1>; | 101 | clocks = <&mux1>; |
101 | next-level-cache = <&L2_1>; | 102 | next-level-cache = <&L2_1>; |
103 | fsl,portid-mapping = <0x40000000>; | ||
102 | L2_1: l2-cache { | 104 | L2_1: l2-cache { |
103 | next-level-cache = <&cpc>; | 105 | next-level-cache = <&cpc>; |
104 | }; | 106 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi index 546a899efe20..67296fdd9698 100644 --- a/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi | |||
@@ -233,7 +233,7 @@ | |||
233 | }; | 233 | }; |
234 | 234 | ||
235 | corenet-cf@18000 { | 235 | corenet-cf@18000 { |
236 | compatible = "fsl,corenet-cf"; | 236 | compatible = "fsl,corenet1-cf", "fsl,corenet-cf"; |
237 | reg = <0x18000 0x1000>; | 237 | reg = <0x18000 0x1000>; |
238 | interrupts = <16 2 1 31>; | 238 | interrupts = <16 2 1 31>; |
239 | fsl,ccf-num-csdids = <32>; | 239 | fsl,ccf-num-csdids = <32>; |
@@ -248,6 +248,7 @@ | |||
248 | #size-cells = <1>; | 248 | #size-cells = <1>; |
249 | interrupts = <24 2 0 0 | 249 | interrupts = <24 2 0 0 |
250 | 16 2 1 30>; | 250 | 16 2 1 30>; |
251 | fsl,portid-mapping = <0x0f800000>; | ||
251 | 252 | ||
252 | pamu0: pamu@0 { | 253 | pamu0: pamu@0 { |
253 | reg = <0 0x1000>; | 254 | reg = <0 0x1000>; |
diff --git a/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi index 3674686687cb..b048a2be05a8 100644 --- a/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi | |||
@@ -83,6 +83,7 @@ | |||
83 | reg = <0>; | 83 | reg = <0>; |
84 | clocks = <&mux0>; | 84 | clocks = <&mux0>; |
85 | next-level-cache = <&L2_0>; | 85 | next-level-cache = <&L2_0>; |
86 | fsl,portid-mapping = <0x80000000>; | ||
86 | L2_0: l2-cache { | 87 | L2_0: l2-cache { |
87 | next-level-cache = <&cpc>; | 88 | next-level-cache = <&cpc>; |
88 | }; | 89 | }; |
@@ -92,6 +93,7 @@ | |||
92 | reg = <1>; | 93 | reg = <1>; |
93 | clocks = <&mux1>; | 94 | clocks = <&mux1>; |
94 | next-level-cache = <&L2_1>; | 95 | next-level-cache = <&L2_1>; |
96 | fsl,portid-mapping = <0x40000000>; | ||
95 | L2_1: l2-cache { | 97 | L2_1: l2-cache { |
96 | next-level-cache = <&cpc>; | 98 | next-level-cache = <&cpc>; |
97 | }; | 99 | }; |
@@ -101,6 +103,7 @@ | |||
101 | reg = <2>; | 103 | reg = <2>; |
102 | clocks = <&mux2>; | 104 | clocks = <&mux2>; |
103 | next-level-cache = <&L2_2>; | 105 | next-level-cache = <&L2_2>; |
106 | fsl,portid-mapping = <0x20000000>; | ||
104 | L2_2: l2-cache { | 107 | L2_2: l2-cache { |
105 | next-level-cache = <&cpc>; | 108 | next-level-cache = <&cpc>; |
106 | }; | 109 | }; |
@@ -110,6 +113,7 @@ | |||
110 | reg = <3>; | 113 | reg = <3>; |
111 | clocks = <&mux3>; | 114 | clocks = <&mux3>; |
112 | next-level-cache = <&L2_3>; | 115 | next-level-cache = <&L2_3>; |
116 | fsl,portid-mapping = <0x10000000>; | ||
113 | L2_3: l2-cache { | 117 | L2_3: l2-cache { |
114 | next-level-cache = <&cpc>; | 118 | next-level-cache = <&cpc>; |
115 | }; | 119 | }; |
diff --git a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi new file mode 100644 index 000000000000..12e597eea3c8 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi | |||
@@ -0,0 +1,430 @@ | |||
1 | /* | ||
2 | * T1040 Silicon/SoC Device Tree Source (post include) | ||
3 | * | ||
4 | * Copyright 2013 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions are met: | ||
8 | * * Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * * Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * * Neither the name of Freescale Semiconductor nor the | ||
14 | * names of its contributors may be used to endorse or promote products | ||
15 | * derived from this software without specific prior written permission. | ||
16 | * | ||
17 | * | ||
18 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
19 | * GNU General Public License ("GPL") as published by the Free Software | ||
20 | * Foundation, either version 2 of that License or (at your option) any | ||
21 | * later version. | ||
22 | * | ||
23 | * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY | ||
24 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
26 | * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY | ||
27 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
28 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
29 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
30 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | &ifc { | ||
36 | #address-cells = <2>; | ||
37 | #size-cells = <1>; | ||
38 | compatible = "fsl,ifc", "simple-bus"; | ||
39 | interrupts = <25 2 0 0>; | ||
40 | }; | ||
41 | |||
42 | &pci0 { | ||
43 | compatible = "fsl,t1040-pcie", "fsl,qoriq-pcie-v2.4", "fsl,qoriq-pcie"; | ||
44 | device_type = "pci"; | ||
45 | #size-cells = <2>; | ||
46 | #address-cells = <3>; | ||
47 | bus-range = <0x0 0xff>; | ||
48 | interrupts = <20 2 0 0>; | ||
49 | fsl,iommu-parent = <&pamu0>; | ||
50 | pcie@0 { | ||
51 | reg = <0 0 0 0 0>; | ||
52 | #interrupt-cells = <1>; | ||
53 | #size-cells = <2>; | ||
54 | #address-cells = <3>; | ||
55 | device_type = "pci"; | ||
56 | interrupts = <20 2 0 0>; | ||
57 | interrupt-map-mask = <0xf800 0 0 7>; | ||
58 | interrupt-map = < | ||
59 | /* IDSEL 0x0 */ | ||
60 | 0000 0 0 1 &mpic 40 1 0 0 | ||
61 | 0000 0 0 2 &mpic 1 1 0 0 | ||
62 | 0000 0 0 3 &mpic 2 1 0 0 | ||
63 | 0000 0 0 4 &mpic 3 1 0 0 | ||
64 | >; | ||
65 | }; | ||
66 | }; | ||
67 | |||
68 | &pci1 { | ||
69 | compatible = "fsl,t1040-pcie", "fsl,qoriq-pcie-v2.4", "fsl,qoriq-pcie"; | ||
70 | device_type = "pci"; | ||
71 | #size-cells = <2>; | ||
72 | #address-cells = <3>; | ||
73 | bus-range = <0 0xff>; | ||
74 | interrupts = <21 2 0 0>; | ||
75 | fsl,iommu-parent = <&pamu0>; | ||
76 | pcie@0 { | ||
77 | reg = <0 0 0 0 0>; | ||
78 | #interrupt-cells = <1>; | ||
79 | #size-cells = <2>; | ||
80 | #address-cells = <3>; | ||
81 | device_type = "pci"; | ||
82 | interrupts = <21 2 0 0>; | ||
83 | interrupt-map-mask = <0xf800 0 0 7>; | ||
84 | interrupt-map = < | ||
85 | /* IDSEL 0x0 */ | ||
86 | 0000 0 0 1 &mpic 41 1 0 0 | ||
87 | 0000 0 0 2 &mpic 5 1 0 0 | ||
88 | 0000 0 0 3 &mpic 6 1 0 0 | ||
89 | 0000 0 0 4 &mpic 7 1 0 0 | ||
90 | >; | ||
91 | }; | ||
92 | }; | ||
93 | |||
94 | &pci2 { | ||
95 | compatible = "fsl,t1040-pcie", "fsl,qoriq-pcie-v2.4", "fsl,qoriq-pcie"; | ||
96 | device_type = "pci"; | ||
97 | #size-cells = <2>; | ||
98 | #address-cells = <3>; | ||
99 | bus-range = <0x0 0xff>; | ||
100 | interrupts = <22 2 0 0>; | ||
101 | fsl,iommu-parent = <&pamu0>; | ||
102 | pcie@0 { | ||
103 | reg = <0 0 0 0 0>; | ||
104 | #interrupt-cells = <1>; | ||
105 | #size-cells = <2>; | ||
106 | #address-cells = <3>; | ||
107 | device_type = "pci"; | ||
108 | interrupts = <22 2 0 0>; | ||
109 | interrupt-map-mask = <0xf800 0 0 7>; | ||
110 | interrupt-map = < | ||
111 | /* IDSEL 0x0 */ | ||
112 | 0000 0 0 1 &mpic 42 1 0 0 | ||
113 | 0000 0 0 2 &mpic 9 1 0 0 | ||
114 | 0000 0 0 3 &mpic 10 1 0 0 | ||
115 | 0000 0 0 4 &mpic 11 1 0 0 | ||
116 | >; | ||
117 | }; | ||
118 | }; | ||
119 | |||
120 | &pci3 { | ||
121 | compatible = "fsl,t1040-pcie", "fsl,qoriq-pcie-v2.4", "fsl,qoriq-pcie"; | ||
122 | device_type = "pci"; | ||
123 | #size-cells = <2>; | ||
124 | #address-cells = <3>; | ||
125 | bus-range = <0x0 0xff>; | ||
126 | interrupts = <23 2 0 0>; | ||
127 | fsl,iommu-parent = <&pamu0>; | ||
128 | pcie@0 { | ||
129 | reg = <0 0 0 0 0>; | ||
130 | #interrupt-cells = <1>; | ||
131 | #size-cells = <2>; | ||
132 | #address-cells = <3>; | ||
133 | device_type = "pci"; | ||
134 | interrupts = <23 2 0 0>; | ||
135 | interrupt-map-mask = <0xf800 0 0 7>; | ||
136 | interrupt-map = < | ||
137 | /* IDSEL 0x0 */ | ||
138 | 0000 0 0 1 &mpic 43 1 0 0 | ||
139 | 0000 0 0 2 &mpic 0 1 0 0 | ||
140 | 0000 0 0 3 &mpic 4 1 0 0 | ||
141 | 0000 0 0 4 &mpic 8 1 0 0 | ||
142 | >; | ||
143 | }; | ||
144 | }; | ||
145 | |||
146 | &dcsr { | ||
147 | #address-cells = <1>; | ||
148 | #size-cells = <1>; | ||
149 | compatible = "fsl,dcsr", "simple-bus"; | ||
150 | |||
151 | dcsr-epu@0 { | ||
152 | compatible = "fsl,t1040-dcsr-epu", "fsl,dcsr-epu"; | ||
153 | interrupts = <52 2 0 0 | ||
154 | 84 2 0 0 | ||
155 | 85 2 0 0>; | ||
156 | reg = <0x0 0x1000>; | ||
157 | }; | ||
158 | dcsr-npc { | ||
159 | compatible = "fsl,t1040-dcsr-cnpc", "fsl,dcsr-cnpc"; | ||
160 | reg = <0x1000 0x1000 0x1002000 0x10000>; | ||
161 | }; | ||
162 | dcsr-nxc@2000 { | ||
163 | compatible = "fsl,dcsr-nxc"; | ||
164 | reg = <0x2000 0x1000>; | ||
165 | }; | ||
166 | dcsr-corenet { | ||
167 | compatible = "fsl,dcsr-corenet"; | ||
168 | reg = <0x8000 0x1000 0x1A000 0x1000>; | ||
169 | }; | ||
170 | dcsr-dpaa@9000 { | ||
171 | compatible = "fsl,t1040-dcsr-dpaa", "fsl,dcsr-dpaa"; | ||
172 | reg = <0x9000 0x1000>; | ||
173 | }; | ||
174 | dcsr-ocn@11000 { | ||
175 | compatible = "fsl,t1040-dcsr-ocn", "fsl,dcsr-ocn"; | ||
176 | reg = <0x11000 0x1000>; | ||
177 | }; | ||
178 | dcsr-ddr@12000 { | ||
179 | compatible = "fsl,dcsr-ddr"; | ||
180 | dev-handle = <&ddr1>; | ||
181 | reg = <0x12000 0x1000>; | ||
182 | }; | ||
183 | dcsr-nal@18000 { | ||
184 | compatible = "fsl,t1040-dcsr-nal", "fsl,dcsr-nal"; | ||
185 | reg = <0x18000 0x1000>; | ||
186 | }; | ||
187 | dcsr-rcpm@22000 { | ||
188 | compatible = "fsl,t1040-dcsr-rcpm", "fsl,dcsr-rcpm"; | ||
189 | reg = <0x22000 0x1000>; | ||
190 | }; | ||
191 | dcsr-snpc@30000 { | ||
192 | compatible = "fsl,t1040-dcsr-snpc", "fsl,dcsr-snpc"; | ||
193 | reg = <0x30000 0x1000 0x1022000 0x10000>; | ||
194 | }; | ||
195 | dcsr-snpc@31000 { | ||
196 | compatible = "fsl,t1040-dcsr-snpc", "fsl,dcsr-snpc"; | ||
197 | reg = <0x31000 0x1000 0x1042000 0x10000>; | ||
198 | }; | ||
199 | dcsr-cpu-sb-proxy@100000 { | ||
200 | compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
201 | cpu-handle = <&cpu0>; | ||
202 | reg = <0x100000 0x1000 0x101000 0x1000>; | ||
203 | }; | ||
204 | dcsr-cpu-sb-proxy@108000 { | ||
205 | compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
206 | cpu-handle = <&cpu1>; | ||
207 | reg = <0x108000 0x1000 0x109000 0x1000>; | ||
208 | }; | ||
209 | dcsr-cpu-sb-proxy@110000 { | ||
210 | compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
211 | cpu-handle = <&cpu2>; | ||
212 | reg = <0x110000 0x1000 0x111000 0x1000>; | ||
213 | }; | ||
214 | dcsr-cpu-sb-proxy@118000 { | ||
215 | compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; | ||
216 | cpu-handle = <&cpu3>; | ||
217 | reg = <0x118000 0x1000 0x119000 0x1000>; | ||
218 | }; | ||
219 | }; | ||
220 | |||
221 | &soc { | ||
222 | #address-cells = <1>; | ||
223 | #size-cells = <1>; | ||
224 | device_type = "soc"; | ||
225 | compatible = "simple-bus"; | ||
226 | |||
227 | soc-sram-error { | ||
228 | compatible = "fsl,soc-sram-error"; | ||
229 | interrupts = <16 2 1 29>; | ||
230 | }; | ||
231 | |||
232 | corenet-law@0 { | ||
233 | compatible = "fsl,corenet-law"; | ||
234 | reg = <0x0 0x1000>; | ||
235 | fsl,num-laws = <16>; | ||
236 | }; | ||
237 | |||
238 | ddr1: memory-controller@8000 { | ||
239 | compatible = "fsl,qoriq-memory-controller-v5.0", | ||
240 | "fsl,qoriq-memory-controller"; | ||
241 | reg = <0x8000 0x1000>; | ||
242 | interrupts = <16 2 1 23>; | ||
243 | }; | ||
244 | |||
245 | cpc: l3-cache-controller@10000 { | ||
246 | compatible = "fsl,t1040-l3-cache-controller", "cache"; | ||
247 | reg = <0x10000 0x1000>; | ||
248 | interrupts = <16 2 1 27>; | ||
249 | }; | ||
250 | |||
251 | corenet-cf@18000 { | ||
252 | compatible = "fsl,corenet2-cf", "fsl,corenet-cf"; | ||
253 | reg = <0x18000 0x1000>; | ||
254 | interrupts = <16 2 1 31>; | ||
255 | fsl,ccf-num-csdids = <32>; | ||
256 | fsl,ccf-num-snoopids = <32>; | ||
257 | }; | ||
258 | |||
259 | iommu@20000 { | ||
260 | compatible = "fsl,pamu-v1.0", "fsl,pamu"; | ||
261 | reg = <0x20000 0x1000>; | ||
262 | ranges = <0 0x20000 0x1000>; | ||
263 | #address-cells = <1>; | ||
264 | #size-cells = <1>; | ||
265 | interrupts = < | ||
266 | 24 2 0 0 | ||
267 | 16 2 1 30>; | ||
268 | pamu0: pamu@0 { | ||
269 | reg = <0 0x1000>; | ||
270 | fsl,primary-cache-geometry = <128 1>; | ||
271 | fsl,secondary-cache-geometry = <16 2>; | ||
272 | }; | ||
273 | }; | ||
274 | |||
275 | /include/ "qoriq-mpic.dtsi" | ||
276 | |||
277 | guts: global-utilities@e0000 { | ||
278 | compatible = "fsl,t1040-device-config", "fsl,qoriq-device-config-2.0"; | ||
279 | reg = <0xe0000 0xe00>; | ||
280 | fsl,has-rstcr; | ||
281 | fsl,liodn-bits = <12>; | ||
282 | }; | ||
283 | |||
284 | clockgen: global-utilities@e1000 { | ||
285 | compatible = "fsl,t1040-clockgen", "fsl,qoriq-clockgen-2.0"; | ||
286 | ranges = <0x0 0xe1000 0x1000>; | ||
287 | reg = <0xe1000 0x1000>; | ||
288 | #address-cells = <1>; | ||
289 | #size-cells = <1>; | ||
290 | |||
291 | sysclk: sysclk { | ||
292 | #clock-cells = <0>; | ||
293 | compatible = "fsl,qoriq-sysclk-2.0"; | ||
294 | clock-output-names = "sysclk", "fixed-clock"; | ||
295 | }; | ||
296 | |||
297 | |||
298 | pll0: pll0@800 { | ||
299 | #clock-cells = <1>; | ||
300 | reg = <0x800 4>; | ||
301 | compatible = "fsl,qoriq-core-pll-2.0"; | ||
302 | clocks = <&sysclk>; | ||
303 | clock-output-names = "pll0", "pll0-div2", "pll0-div4"; | ||
304 | }; | ||
305 | |||
306 | pll1: pll1@820 { | ||
307 | #clock-cells = <1>; | ||
308 | reg = <0x820 4>; | ||
309 | compatible = "fsl,qoriq-core-pll-2.0"; | ||
310 | clocks = <&sysclk>; | ||
311 | clock-output-names = "pll1", "pll1-div2", "pll1-div4"; | ||
312 | }; | ||
313 | |||
314 | mux0: mux0@0 { | ||
315 | #clock-cells = <0>; | ||
316 | reg = <0x0 4>; | ||
317 | compatible = "fsl,qoriq-core-mux-2.0"; | ||
318 | clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>, | ||
319 | <&pll1 0>, <&pll1 1>, <&pll1 2>; | ||
320 | clock-names = "pll0", "pll0-div2", "pll1-div4", | ||
321 | "pll1", "pll1-div2", "pll1-div4"; | ||
322 | clock-output-names = "cmux0"; | ||
323 | }; | ||
324 | |||
325 | mux1: mux1@20 { | ||
326 | #clock-cells = <0>; | ||
327 | reg = <0x20 4>; | ||
328 | compatible = "fsl,qoriq-core-mux-2.0"; | ||
329 | clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>, | ||
330 | <&pll1 0>, <&pll1 1>, <&pll1 2>; | ||
331 | clock-names = "pll0", "pll0-div2", "pll1-div4", | ||
332 | "pll1", "pll1-div2", "pll1-div4"; | ||
333 | clock-output-names = "cmux1"; | ||
334 | }; | ||
335 | |||
336 | mux2: mux2@40 { | ||
337 | #clock-cells = <0>; | ||
338 | reg = <0x40 4>; | ||
339 | compatible = "fsl,qoriq-core-mux-2.0"; | ||
340 | clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>, | ||
341 | <&pll1 0>, <&pll1 1>, <&pll1 2>; | ||
342 | clock-names = "pll0", "pll0-div2", "pll1-div4", | ||
343 | "pll1", "pll1-div2", "pll1-div4"; | ||
344 | clock-output-names = "cmux2"; | ||
345 | }; | ||
346 | |||
347 | mux3: mux3@60 { | ||
348 | #clock-cells = <0>; | ||
349 | reg = <0x60 4>; | ||
350 | compatible = "fsl,qoriq-core-mux-2.0"; | ||
351 | clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>, | ||
352 | <&pll1 0>, <&pll1 1>, <&pll1 2>; | ||
353 | clock-names = "pll0_0", "pll0_1", "pll0_2", | ||
354 | "pll1_0", "pll1_1", "pll1_2"; | ||
355 | clock-output-names = "cmux3"; | ||
356 | }; | ||
357 | }; | ||
358 | |||
359 | rcpm: global-utilities@e2000 { | ||
360 | compatible = "fsl,t1040-rcpm", "fsl,qoriq-rcpm-2.0"; | ||
361 | reg = <0xe2000 0x1000>; | ||
362 | }; | ||
363 | |||
364 | sfp: sfp@e8000 { | ||
365 | compatible = "fsl,t1040-sfp"; | ||
366 | reg = <0xe8000 0x1000>; | ||
367 | }; | ||
368 | |||
369 | serdes: serdes@ea000 { | ||
370 | compatible = "fsl,t1040-serdes"; | ||
371 | reg = <0xea000 0x4000>; | ||
372 | }; | ||
373 | |||
374 | /include/ "elo3-dma-0.dtsi" | ||
375 | /include/ "elo3-dma-1.dtsi" | ||
376 | /include/ "qoriq-espi-0.dtsi" | ||
377 | spi@110000 { | ||
378 | fsl,espi-num-chipselects = <4>; | ||
379 | }; | ||
380 | |||
381 | /include/ "qoriq-esdhc-0.dtsi" | ||
382 | sdhc@114000 { | ||
383 | compatible = "fsl,t1040-esdhc", "fsl,esdhc"; | ||
384 | fsl,iommu-parent = <&pamu0>; | ||
385 | fsl,liodn-reg = <&guts 0x530>; /* eSDHCLIODNR */ | ||
386 | sdhci,auto-cmd12; | ||
387 | }; | ||
388 | /include/ "qoriq-i2c-0.dtsi" | ||
389 | /include/ "qoriq-i2c-1.dtsi" | ||
390 | /include/ "qoriq-duart-0.dtsi" | ||
391 | /include/ "qoriq-duart-1.dtsi" | ||
392 | /include/ "qoriq-gpio-0.dtsi" | ||
393 | /include/ "qoriq-gpio-1.dtsi" | ||
394 | /include/ "qoriq-gpio-2.dtsi" | ||
395 | /include/ "qoriq-gpio-3.dtsi" | ||
396 | /include/ "qoriq-usb2-mph-0.dtsi" | ||
397 | usb0: usb@210000 { | ||
398 | compatible = "fsl-usb2-mph-v2.4", "fsl-usb2-mph"; | ||
399 | fsl,iommu-parent = <&pamu0>; | ||
400 | fsl,liodn-reg = <&guts 0x520>; /* USB1LIODNR */ | ||
401 | phy_type = "utmi"; | ||
402 | port0; | ||
403 | }; | ||
404 | /include/ "qoriq-usb2-dr-0.dtsi" | ||
405 | usb1: usb@211000 { | ||
406 | compatible = "fsl-usb2-dr-v2.4", "fsl-usb2-dr"; | ||
407 | fsl,iommu-parent = <&pamu0>; | ||
408 | fsl,liodn-reg = <&guts 0x524>; /* USB2LIODNR */ | ||
409 | dr_mode = "host"; | ||
410 | phy_type = "utmi"; | ||
411 | }; | ||
412 | |||
413 | display@180000 { | ||
414 | compatible = "fsl,t1040-diu", "fsl,diu"; | ||
415 | reg = <0x180000 1000>; | ||
416 | interrupts = <74 2 0 0>; | ||
417 | }; | ||
418 | |||
419 | /include/ "qoriq-sata2-0.dtsi" | ||
420 | sata@220000 { | ||
421 | fsl,iommu-parent = <&pamu0>; | ||
422 | fsl,liodn-reg = <&guts 0x550>; /* SATA1LIODNR */ | ||
423 | }; | ||
424 | /include/ "qoriq-sata2-1.dtsi" | ||
425 | sata@221000 { | ||
426 | fsl,iommu-parent = <&pamu0>; | ||
427 | fsl,liodn-reg = <&guts 0x554>; /* SATA2LIODNR */ | ||
428 | }; | ||
429 | /include/ "qoriq-sec5.0-0.dtsi" | ||
430 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/t1042si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1042si-post.dtsi new file mode 100644 index 000000000000..319b74f29724 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/t1042si-post.dtsi | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * T1042 Silicon/SoC Device Tree Source (post include) | ||
3 | * | ||
4 | * Copyright 2013 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions are met: | ||
8 | * * Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * * Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * * Neither the name of Freescale Semiconductor nor the | ||
14 | * names of its contributors may be used to endorse or promote products | ||
15 | * derived from this software without specific prior written permission. | ||
16 | * | ||
17 | * | ||
18 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
19 | * GNU General Public License ("GPL") as published by the Free Software | ||
20 | * Foundation, either version 2 of that License or (at your option) any | ||
21 | * later version. | ||
22 | * | ||
23 | * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY | ||
24 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
26 | * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY | ||
27 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
28 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
29 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
30 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | /include/ "t1040si-post.dtsi" | ||
36 | |||
37 | /* Place holder for ethernet related device tree nodes */ | ||
diff --git a/arch/powerpc/boot/dts/fsl/t104xsi-pre.dtsi b/arch/powerpc/boot/dts/fsl/t104xsi-pre.dtsi new file mode 100644 index 000000000000..bbb7025ca9c2 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/t104xsi-pre.dtsi | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | * T1040/T1042 Silicon/SoC Device Tree Source (pre include) | ||
3 | * | ||
4 | * Copyright 2013 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions are met: | ||
8 | * * Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * * Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * * Neither the name of Freescale Semiconductor nor the | ||
14 | * names of its contributors may be used to endorse or promote products | ||
15 | * derived from this software without specific prior written permission. | ||
16 | * | ||
17 | * | ||
18 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
19 | * GNU General Public License ("GPL") as published by the Free Software | ||
20 | * Foundation, either version 2 of that License or (at your option) any | ||
21 | * later version. | ||
22 | * | ||
23 | * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY | ||
24 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
26 | * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY | ||
27 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
28 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
29 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
30 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | /dts-v1/; | ||
36 | |||
37 | /include/ "e5500_power_isa.dtsi" | ||
38 | |||
39 | / { | ||
40 | #address-cells = <2>; | ||
41 | #size-cells = <2>; | ||
42 | interrupt-parent = <&mpic>; | ||
43 | |||
44 | aliases { | ||
45 | ccsr = &soc; | ||
46 | dcsr = &dcsr; | ||
47 | |||
48 | serial0 = &serial0; | ||
49 | serial1 = &serial1; | ||
50 | serial2 = &serial2; | ||
51 | serial3 = &serial3; | ||
52 | pci0 = &pci0; | ||
53 | pci1 = &pci1; | ||
54 | pci2 = &pci2; | ||
55 | pci3 = &pci3; | ||
56 | usb0 = &usb0; | ||
57 | usb1 = &usb1; | ||
58 | sdhc = &sdhc; | ||
59 | |||
60 | crypto = &crypto; | ||
61 | }; | ||
62 | |||
63 | cpus { | ||
64 | #address-cells = <1>; | ||
65 | #size-cells = <0>; | ||
66 | |||
67 | cpu0: PowerPC,e5500@0 { | ||
68 | device_type = "cpu"; | ||
69 | reg = <0>; | ||
70 | clocks = <&mux0>; | ||
71 | next-level-cache = <&L2_1>; | ||
72 | L2_1: l2-cache { | ||
73 | next-level-cache = <&cpc>; | ||
74 | }; | ||
75 | }; | ||
76 | cpu1: PowerPC,e5500@1 { | ||
77 | device_type = "cpu"; | ||
78 | reg = <1>; | ||
79 | clocks = <&mux1>; | ||
80 | next-level-cache = <&L2_2>; | ||
81 | L2_2: l2-cache { | ||
82 | next-level-cache = <&cpc>; | ||
83 | }; | ||
84 | }; | ||
85 | cpu2: PowerPC,e5500@2 { | ||
86 | device_type = "cpu"; | ||
87 | reg = <2>; | ||
88 | clocks = <&mux2>; | ||
89 | next-level-cache = <&L2_3>; | ||
90 | L2_3: l2-cache { | ||
91 | next-level-cache = <&cpc>; | ||
92 | }; | ||
93 | }; | ||
94 | cpu3: PowerPC,e5500@3 { | ||
95 | device_type = "cpu"; | ||
96 | reg = <3>; | ||
97 | clocks = <&mux3>; | ||
98 | next-level-cache = <&L2_4>; | ||
99 | L2_4: l2-cache { | ||
100 | next-level-cache = <&cpc>; | ||
101 | }; | ||
102 | }; | ||
103 | }; | ||
104 | }; | ||
diff --git a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi index f99d74ff11b4..793669baa13e 100644 --- a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi | |||
@@ -343,7 +343,7 @@ | |||
343 | }; | 343 | }; |
344 | 344 | ||
345 | corenet-cf@18000 { | 345 | corenet-cf@18000 { |
346 | compatible = "fsl,corenet-cf"; | 346 | compatible = "fsl,corenet2-cf", "fsl,corenet-cf"; |
347 | reg = <0x18000 0x1000>; | 347 | reg = <0x18000 0x1000>; |
348 | interrupts = <16 2 1 31>; | 348 | interrupts = <16 2 1 31>; |
349 | fsl,ccf-num-csdids = <32>; | 349 | fsl,ccf-num-csdids = <32>; |
@@ -353,6 +353,7 @@ | |||
353 | iommu@20000 { | 353 | iommu@20000 { |
354 | compatible = "fsl,pamu-v1.0", "fsl,pamu"; | 354 | compatible = "fsl,pamu-v1.0", "fsl,pamu"; |
355 | reg = <0x20000 0x6000>; | 355 | reg = <0x20000 0x6000>; |
356 | fsl,portid-mapping = <0x8000>; | ||
356 | interrupts = < | 357 | interrupts = < |
357 | 24 2 0 0 | 358 | 24 2 0 0 |
358 | 16 2 1 30>; | 359 | 16 2 1 30>; |
diff --git a/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi index 0b8ccc5b4a46..d2f157edbe81 100644 --- a/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi | |||
@@ -69,72 +69,84 @@ | |||
69 | reg = <0 1>; | 69 | reg = <0 1>; |
70 | clocks = <&mux0>; | 70 | clocks = <&mux0>; |
71 | next-level-cache = <&L2_1>; | 71 | next-level-cache = <&L2_1>; |
72 | fsl,portid-mapping = <0x80000000>; | ||
72 | }; | 73 | }; |
73 | cpu1: PowerPC,e6500@2 { | 74 | cpu1: PowerPC,e6500@2 { |
74 | device_type = "cpu"; | 75 | device_type = "cpu"; |
75 | reg = <2 3>; | 76 | reg = <2 3>; |
76 | clocks = <&mux0>; | 77 | clocks = <&mux0>; |
77 | next-level-cache = <&L2_1>; | 78 | next-level-cache = <&L2_1>; |
79 | fsl,portid-mapping = <0x80000000>; | ||
78 | }; | 80 | }; |
79 | cpu2: PowerPC,e6500@4 { | 81 | cpu2: PowerPC,e6500@4 { |
80 | device_type = "cpu"; | 82 | device_type = "cpu"; |
81 | reg = <4 5>; | 83 | reg = <4 5>; |
82 | clocks = <&mux0>; | 84 | clocks = <&mux0>; |
83 | next-level-cache = <&L2_1>; | 85 | next-level-cache = <&L2_1>; |
86 | fsl,portid-mapping = <0x80000000>; | ||
84 | }; | 87 | }; |
85 | cpu3: PowerPC,e6500@6 { | 88 | cpu3: PowerPC,e6500@6 { |
86 | device_type = "cpu"; | 89 | device_type = "cpu"; |
87 | reg = <6 7>; | 90 | reg = <6 7>; |
88 | clocks = <&mux0>; | 91 | clocks = <&mux0>; |
89 | next-level-cache = <&L2_1>; | 92 | next-level-cache = <&L2_1>; |
93 | fsl,portid-mapping = <0x80000000>; | ||
90 | }; | 94 | }; |
91 | cpu4: PowerPC,e6500@8 { | 95 | cpu4: PowerPC,e6500@8 { |
92 | device_type = "cpu"; | 96 | device_type = "cpu"; |
93 | reg = <8 9>; | 97 | reg = <8 9>; |
94 | clocks = <&mux1>; | 98 | clocks = <&mux1>; |
95 | next-level-cache = <&L2_2>; | 99 | next-level-cache = <&L2_2>; |
100 | fsl,portid-mapping = <0x40000000>; | ||
96 | }; | 101 | }; |
97 | cpu5: PowerPC,e6500@10 { | 102 | cpu5: PowerPC,e6500@10 { |
98 | device_type = "cpu"; | 103 | device_type = "cpu"; |
99 | reg = <10 11>; | 104 | reg = <10 11>; |
100 | clocks = <&mux1>; | 105 | clocks = <&mux1>; |
101 | next-level-cache = <&L2_2>; | 106 | next-level-cache = <&L2_2>; |
107 | fsl,portid-mapping = <0x40000000>; | ||
102 | }; | 108 | }; |
103 | cpu6: PowerPC,e6500@12 { | 109 | cpu6: PowerPC,e6500@12 { |
104 | device_type = "cpu"; | 110 | device_type = "cpu"; |
105 | reg = <12 13>; | 111 | reg = <12 13>; |
106 | clocks = <&mux1>; | 112 | clocks = <&mux1>; |
107 | next-level-cache = <&L2_2>; | 113 | next-level-cache = <&L2_2>; |
114 | fsl,portid-mapping = <0x40000000>; | ||
108 | }; | 115 | }; |
109 | cpu7: PowerPC,e6500@14 { | 116 | cpu7: PowerPC,e6500@14 { |
110 | device_type = "cpu"; | 117 | device_type = "cpu"; |
111 | reg = <14 15>; | 118 | reg = <14 15>; |
112 | clocks = <&mux1>; | 119 | clocks = <&mux1>; |
113 | next-level-cache = <&L2_2>; | 120 | next-level-cache = <&L2_2>; |
121 | fsl,portid-mapping = <0x40000000>; | ||
114 | }; | 122 | }; |
115 | cpu8: PowerPC,e6500@16 { | 123 | cpu8: PowerPC,e6500@16 { |
116 | device_type = "cpu"; | 124 | device_type = "cpu"; |
117 | reg = <16 17>; | 125 | reg = <16 17>; |
118 | clocks = <&mux2>; | 126 | clocks = <&mux2>; |
119 | next-level-cache = <&L2_3>; | 127 | next-level-cache = <&L2_3>; |
128 | fsl,portid-mapping = <0x20000000>; | ||
120 | }; | 129 | }; |
121 | cpu9: PowerPC,e6500@18 { | 130 | cpu9: PowerPC,e6500@18 { |
122 | device_type = "cpu"; | 131 | device_type = "cpu"; |
123 | reg = <18 19>; | 132 | reg = <18 19>; |
124 | clocks = <&mux2>; | 133 | clocks = <&mux2>; |
125 | next-level-cache = <&L2_3>; | 134 | next-level-cache = <&L2_3>; |
135 | fsl,portid-mapping = <0x20000000>; | ||
126 | }; | 136 | }; |
127 | cpu10: PowerPC,e6500@20 { | 137 | cpu10: PowerPC,e6500@20 { |
128 | device_type = "cpu"; | 138 | device_type = "cpu"; |
129 | reg = <20 21>; | 139 | reg = <20 21>; |
130 | clocks = <&mux2>; | 140 | clocks = <&mux2>; |
131 | next-level-cache = <&L2_3>; | 141 | next-level-cache = <&L2_3>; |
142 | fsl,portid-mapping = <0x20000000>; | ||
132 | }; | 143 | }; |
133 | cpu11: PowerPC,e6500@22 { | 144 | cpu11: PowerPC,e6500@22 { |
134 | device_type = "cpu"; | 145 | device_type = "cpu"; |
135 | reg = <22 23>; | 146 | reg = <22 23>; |
136 | clocks = <&mux2>; | 147 | clocks = <&mux2>; |
137 | next-level-cache = <&L2_3>; | 148 | next-level-cache = <&L2_3>; |
149 | fsl,portid-mapping = <0x20000000>; | ||
138 | }; | 150 | }; |
139 | }; | 151 | }; |
140 | }; | 152 | }; |
diff --git a/arch/powerpc/boot/dts/kmcoge4.dts b/arch/powerpc/boot/dts/kmcoge4.dts new file mode 100644 index 000000000000..89b4119f3b19 --- /dev/null +++ b/arch/powerpc/boot/dts/kmcoge4.dts | |||
@@ -0,0 +1,152 @@ | |||
1 | /* | ||
2 | * Keymile kmcoge4 Device Tree Source, based on the P2041RDB DTS | ||
3 | * | ||
4 | * (C) Copyright 2014 | ||
5 | * Valentin Longchamp, Keymile AG, valentin.longchamp@keymile.com | ||
6 | * | ||
7 | * Copyright 2011 Freescale Semiconductor Inc. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | */ | ||
14 | |||
15 | /include/ "fsl/p2041si-pre.dtsi" | ||
16 | |||
17 | / { | ||
18 | model = "keymile,kmcoge4"; | ||
19 | compatible = "keymile,kmcoge4", "keymile,kmp204x"; | ||
20 | #address-cells = <2>; | ||
21 | #size-cells = <2>; | ||
22 | interrupt-parent = <&mpic>; | ||
23 | |||
24 | memory { | ||
25 | device_type = "memory"; | ||
26 | }; | ||
27 | |||
28 | dcsr: dcsr@f00000000 { | ||
29 | ranges = <0x00000000 0xf 0x00000000 0x01008000>; | ||
30 | }; | ||
31 | |||
32 | soc: soc@ffe000000 { | ||
33 | ranges = <0x00000000 0xf 0xfe000000 0x1000000>; | ||
34 | reg = <0xf 0xfe000000 0 0x00001000>; | ||
35 | spi@110000 { | ||
36 | flash@0 { | ||
37 | #address-cells = <1>; | ||
38 | #size-cells = <1>; | ||
39 | compatible = "spansion,s25fl256s1"; | ||
40 | reg = <0>; | ||
41 | spi-max-frequency = <20000000>; /* input clock */ | ||
42 | }; | ||
43 | |||
44 | network_clock@1 { | ||
45 | compatible = "zarlink,zl30343"; | ||
46 | reg = <1>; | ||
47 | spi-max-frequency = <8000000>; | ||
48 | }; | ||
49 | |||
50 | flash@2 { | ||
51 | #address-cells = <1>; | ||
52 | #size-cells = <1>; | ||
53 | compatible = "micron,m25p32"; | ||
54 | reg = <2>; | ||
55 | spi-max-frequency = <15000000>; | ||
56 | }; | ||
57 | }; | ||
58 | |||
59 | i2c@119000 { | ||
60 | status = "disabled"; | ||
61 | }; | ||
62 | |||
63 | i2c@119100 { | ||
64 | status = "disabled"; | ||
65 | }; | ||
66 | |||
67 | usb0: usb@210000 { | ||
68 | status = "disabled"; | ||
69 | }; | ||
70 | |||
71 | usb1: usb@211000 { | ||
72 | status = "disabled"; | ||
73 | }; | ||
74 | |||
75 | sata@220000 { | ||
76 | status = "disabled"; | ||
77 | }; | ||
78 | |||
79 | sata@221000 { | ||
80 | status = "disabled"; | ||
81 | }; | ||
82 | }; | ||
83 | |||
84 | rio: rapidio@ffe0c0000 { | ||
85 | status = "disabled"; | ||
86 | }; | ||
87 | |||
88 | lbc: localbus@ffe124000 { | ||
89 | reg = <0xf 0xfe124000 0 0x1000>; | ||
90 | ranges = <0 0 0xf 0xffa00000 0x00040000 /* LB 0 */ | ||
91 | 1 0 0xf 0xfb000000 0x00010000 /* LB 1 */ | ||
92 | 2 0 0xf 0xd0000000 0x10000000 /* LB 2 */ | ||
93 | 3 0 0xf 0xe0000000 0x10000000>; /* LB 3 */ | ||
94 | |||
95 | nand@0,0 { | ||
96 | #address-cells = <1>; | ||
97 | #size-cells = <1>; | ||
98 | compatible = "fsl,elbc-fcm-nand"; | ||
99 | reg = <0 0 0x40000>; | ||
100 | }; | ||
101 | |||
102 | board-control@1,0 { | ||
103 | compatible = "keymile,qriox"; | ||
104 | reg = <1 0 0x80>; | ||
105 | }; | ||
106 | |||
107 | chassis-mgmt@3,0 { | ||
108 | compatible = "keymile,bfticu"; | ||
109 | interrupt-controller; | ||
110 | #interrupt-cells = <2>; | ||
111 | reg = <3 0 0x100>; | ||
112 | interrupt-parent = <&mpic>; | ||
113 | interrupts = <6 1 0 0>; | ||
114 | }; | ||
115 | }; | ||
116 | |||
117 | pci0: pcie@ffe200000 { | ||
118 | reg = <0xf 0xfe200000 0 0x1000>; | ||
119 | ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000 | ||
120 | 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>; | ||
121 | pcie@0 { | ||
122 | ranges = <0x02000000 0 0xe0000000 | ||
123 | 0x02000000 0 0xe0000000 | ||
124 | 0 0x20000000 | ||
125 | |||
126 | 0x01000000 0 0x00000000 | ||
127 | 0x01000000 0 0x00000000 | ||
128 | 0 0x00010000>; | ||
129 | }; | ||
130 | }; | ||
131 | |||
132 | pci1: pcie@ffe201000 { | ||
133 | status = "disabled"; | ||
134 | }; | ||
135 | |||
136 | pci2: pcie@ffe202000 { | ||
137 | reg = <0xf 0xfe202000 0 0x1000>; | ||
138 | ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x20000000 | ||
139 | 0x01000000 0 0x00000000 0xf 0xf8010000 0 0x00010000>; | ||
140 | pcie@0 { | ||
141 | ranges = <0x02000000 0 0xe0000000 | ||
142 | 0x02000000 0 0xe0000000 | ||
143 | 0 0x20000000 | ||
144 | |||
145 | 0x01000000 0 0x00000000 | ||
146 | 0x01000000 0 0x00000000 | ||
147 | 0 0x00010000>; | ||
148 | }; | ||
149 | }; | ||
150 | }; | ||
151 | |||
152 | /include/ "fsl/p2041si-post.dtsi" | ||
diff --git a/arch/powerpc/boot/dts/oca4080.dts b/arch/powerpc/boot/dts/oca4080.dts new file mode 100644 index 000000000000..3d4c751d1608 --- /dev/null +++ b/arch/powerpc/boot/dts/oca4080.dts | |||
@@ -0,0 +1,118 @@ | |||
1 | /* | ||
2 | * OCA4080 Device Tree Source | ||
3 | * | ||
4 | * Copyright 2014 Prodrive Technologies B.V. | ||
5 | * | ||
6 | * Based on: | ||
7 | * P4080DS Device Tree Source | ||
8 | * Copyright 2009-2011 Freescale Semiconductor Inc. | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or without | ||
11 | * modification, are permitted provided that the following conditions are met: | ||
12 | * * Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * * Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in the | ||
16 | * documentation and/or other materials provided with the distribution. | ||
17 | * * Neither the name of Freescale Semiconductor nor the | ||
18 | * names of its contributors may be used to endorse or promote products | ||
19 | * derived from this software without specific prior written permission. | ||
20 | * | ||
21 | * | ||
22 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
23 | * GNU General Public License ("GPL") as published by the Free Software | ||
24 | * Foundation, either version 2 of that License or (at your option) any | ||
25 | * later version. | ||
26 | * | ||
27 | * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY | ||
28 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
29 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
30 | * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY | ||
31 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
32 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
33 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
34 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
35 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
36 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
37 | */ | ||
38 | |||
39 | /include/ "fsl/p4080si-pre.dtsi" | ||
40 | |||
41 | / { | ||
42 | model = "fsl,OCA4080"; | ||
43 | compatible = "fsl,OCA4080"; | ||
44 | #address-cells = <2>; | ||
45 | #size-cells = <2>; | ||
46 | interrupt-parent = <&mpic>; | ||
47 | |||
48 | memory { | ||
49 | device_type = "memory"; | ||
50 | }; | ||
51 | |||
52 | dcsr: dcsr@f00000000 { | ||
53 | ranges = <0x00000000 0xf 0x00000000 0x01008000>; | ||
54 | }; | ||
55 | |||
56 | soc: soc@ffe000000 { | ||
57 | ranges = <0x00000000 0xf 0xfe000000 0x1000000>; | ||
58 | reg = <0xf 0xfe000000 0 0x00001000>; | ||
59 | |||
60 | i2c@118000 { | ||
61 | status = "disabled"; | ||
62 | }; | ||
63 | |||
64 | i2c@118100 { | ||
65 | status = "disabled"; | ||
66 | }; | ||
67 | |||
68 | i2c@119000 { | ||
69 | status = "disabled"; | ||
70 | }; | ||
71 | |||
72 | i2c@119100 { | ||
73 | status = "disabled"; | ||
74 | }; | ||
75 | |||
76 | usb0: usb@210000 { | ||
77 | status = "disabled"; | ||
78 | }; | ||
79 | |||
80 | usb1: usb@211000 { | ||
81 | status = "disabled"; | ||
82 | }; | ||
83 | }; | ||
84 | |||
85 | rio: rapidio@ffe0c0000 { | ||
86 | reg = <0xf 0xfe0c0000 0 0x11000>; | ||
87 | |||
88 | port1 { | ||
89 | ranges = <0 0 0xc 0x20000000 0 0x10000000>; | ||
90 | }; | ||
91 | }; | ||
92 | |||
93 | lbc: localbus@ffe124000 { | ||
94 | reg = <0xf 0xfe124000 0 0x1000>; | ||
95 | ranges = <0 0 0xf 0xef800000 0x800000>; | ||
96 | |||
97 | flash@0,0 { | ||
98 | compatible = "cfi-flash"; | ||
99 | reg = <0 0 0x00800000>; | ||
100 | bank-width = <2>; | ||
101 | device-width = <2>; | ||
102 | }; | ||
103 | }; | ||
104 | |||
105 | pci0: pcie@ffe200000 { | ||
106 | status = "disabled"; | ||
107 | }; | ||
108 | |||
109 | pci1: pcie@ffe201000 { | ||
110 | status = "disabled"; | ||
111 | }; | ||
112 | |||
113 | pci2: pcie@ffe202000 { | ||
114 | status = "disabled"; | ||
115 | }; | ||
116 | }; | ||
117 | |||
118 | /include/ "fsl/p4080si-post.dtsi" | ||
diff --git a/arch/powerpc/boot/dts/p1023rds.dts b/arch/powerpc/boot/dts/p1023rds.dts deleted file mode 100644 index beb6cb12e59d..000000000000 --- a/arch/powerpc/boot/dts/p1023rds.dts +++ /dev/null | |||
@@ -1,219 +0,0 @@ | |||
1 | /* | ||
2 | * P1023 RDS Device Tree Source | ||
3 | * | ||
4 | * Copyright 2010-2011 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * Author: Roy Zang <tie-fei.zang@freescale.com> | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions are met: | ||
10 | * * Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * * Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
15 | * * Neither the name of Freescale Semiconductor nor the | ||
16 | * names of its contributors may be used to endorse or promote products | ||
17 | * derived from this software without specific prior written permission. | ||
18 | * | ||
19 | * | ||
20 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
21 | * GNU General Public License ("GPL") as published by the Free Software | ||
22 | * Foundation, either version 2 of that License or (at your option) any | ||
23 | * later version. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY | ||
26 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
27 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
28 | * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY | ||
29 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
30 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
31 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
32 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
33 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
34 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
35 | */ | ||
36 | |||
37 | /include/ "fsl/p1023si-pre.dtsi" | ||
38 | |||
39 | / { | ||
40 | model = "fsl,P1023"; | ||
41 | compatible = "fsl,P1023RDS"; | ||
42 | #address-cells = <2>; | ||
43 | #size-cells = <2>; | ||
44 | interrupt-parent = <&mpic>; | ||
45 | |||
46 | memory { | ||
47 | device_type = "memory"; | ||
48 | }; | ||
49 | |||
50 | soc: soc@ff600000 { | ||
51 | ranges = <0x0 0x0 0xff600000 0x200000>; | ||
52 | |||
53 | i2c@3000 { | ||
54 | rtc@68 { | ||
55 | compatible = "dallas,ds1374"; | ||
56 | reg = <0x68>; | ||
57 | }; | ||
58 | }; | ||
59 | |||
60 | spi@7000 { | ||
61 | fsl_dataflash@0 { | ||
62 | #address-cells = <1>; | ||
63 | #size-cells = <1>; | ||
64 | compatible = "atmel,at45db081d"; | ||
65 | reg = <0>; | ||
66 | spi-max-frequency = <40000000>; /* input clock */ | ||
67 | partition@u-boot { | ||
68 | /* 512KB for u-boot Bootloader Image */ | ||
69 | label = "u-boot-spi"; | ||
70 | reg = <0x00000000 0x00080000>; | ||
71 | read-only; | ||
72 | }; | ||
73 | partition@dtb { | ||
74 | /* 512KB for DTB Image */ | ||
75 | label = "dtb-spi"; | ||
76 | reg = <0x00080000 0x00080000>; | ||
77 | read-only; | ||
78 | }; | ||
79 | }; | ||
80 | }; | ||
81 | |||
82 | usb@22000 { | ||
83 | dr_mode = "host"; | ||
84 | phy_type = "ulpi"; | ||
85 | }; | ||
86 | }; | ||
87 | |||
88 | lbc: localbus@ff605000 { | ||
89 | reg = <0 0xff605000 0 0x1000>; | ||
90 | |||
91 | /* NOR Flash, BCSR */ | ||
92 | ranges = <0x0 0x0 0x0 0xee000000 0x02000000 | ||
93 | 0x1 0x0 0x0 0xe0000000 0x00008000>; | ||
94 | |||
95 | nor@0,0 { | ||
96 | #address-cells = <1>; | ||
97 | #size-cells = <1>; | ||
98 | compatible = "cfi-flash"; | ||
99 | reg = <0x0 0x0 0x02000000>; | ||
100 | bank-width = <2>; | ||
101 | device-width = <1>; | ||
102 | partition@0 { | ||
103 | label = "ramdisk"; | ||
104 | reg = <0x00000000 0x01c00000>; | ||
105 | }; | ||
106 | partition@1c00000 { | ||
107 | label = "kernel"; | ||
108 | reg = <0x01c00000 0x002e0000>; | ||
109 | }; | ||
110 | partiton@1ee0000 { | ||
111 | label = "dtb"; | ||
112 | reg = <0x01ee0000 0x00020000>; | ||
113 | }; | ||
114 | partition@1f00000 { | ||
115 | label = "firmware"; | ||
116 | reg = <0x01f00000 0x00080000>; | ||
117 | read-only; | ||
118 | }; | ||
119 | partition@1f80000 { | ||
120 | label = "u-boot"; | ||
121 | reg = <0x01f80000 0x00080000>; | ||
122 | read-only; | ||
123 | }; | ||
124 | }; | ||
125 | |||
126 | fpga@1,0 { | ||
127 | #address-cells = <1>; | ||
128 | #size-cells = <1>; | ||
129 | compatible = "fsl,p1023rds-fpga"; | ||
130 | reg = <1 0 0x8000>; | ||
131 | ranges = <0 1 0 0x8000>; | ||
132 | |||
133 | bcsr@20 { | ||
134 | compatible = "fsl,p1023rds-bcsr"; | ||
135 | reg = <0x20 0x20>; | ||
136 | }; | ||
137 | }; | ||
138 | }; | ||
139 | |||
140 | pci0: pcie@ff60a000 { | ||
141 | reg = <0 0xff60a000 0 0x1000>; | ||
142 | ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000 | ||
143 | 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>; | ||
144 | pcie@0 { | ||
145 | /* IRQ[0:3] are pulled up on board, set to active-low */ | ||
146 | interrupt-map-mask = <0xf800 0 0 7>; | ||
147 | interrupt-map = < | ||
148 | /* IDSEL 0x0 */ | ||
149 | 0000 0 0 1 &mpic 0 1 0 0 | ||
150 | 0000 0 0 2 &mpic 1 1 0 0 | ||
151 | 0000 0 0 3 &mpic 2 1 0 0 | ||
152 | 0000 0 0 4 &mpic 3 1 0 0 | ||
153 | >; | ||
154 | ranges = <0x2000000 0x0 0xc0000000 | ||
155 | 0x2000000 0x0 0xc0000000 | ||
156 | 0x0 0x20000000 | ||
157 | |||
158 | 0x1000000 0x0 0x0 | ||
159 | 0x1000000 0x0 0x0 | ||
160 | 0x0 0x100000>; | ||
161 | }; | ||
162 | }; | ||
163 | |||
164 | board_pci1: pci1: pcie@ff609000 { | ||
165 | reg = <0 0xff609000 0 0x1000>; | ||
166 | ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 | ||
167 | 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>; | ||
168 | pcie@0 { | ||
169 | /* | ||
170 | * IRQ[4:6] only for PCIe, set to active-high, | ||
171 | * IRQ[7] is pulled up on board, set to active-low | ||
172 | */ | ||
173 | interrupt-map-mask = <0xf800 0 0 7>; | ||
174 | interrupt-map = < | ||
175 | /* IDSEL 0x0 */ | ||
176 | 0000 0 0 1 &mpic 4 2 0 0 | ||
177 | 0000 0 0 2 &mpic 5 2 0 0 | ||
178 | 0000 0 0 3 &mpic 6 2 0 0 | ||
179 | 0000 0 0 4 &mpic 7 1 0 0 | ||
180 | >; | ||
181 | ranges = <0x2000000 0x0 0xa0000000 | ||
182 | 0x2000000 0x0 0xa0000000 | ||
183 | 0x0 0x20000000 | ||
184 | |||
185 | 0x1000000 0x0 0x0 | ||
186 | 0x1000000 0x0 0x0 | ||
187 | 0x0 0x100000>; | ||
188 | }; | ||
189 | }; | ||
190 | |||
191 | pci2: pcie@ff60b000 { | ||
192 | reg = <0 0xff60b000 0 0x1000>; | ||
193 | ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000 | ||
194 | 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>; | ||
195 | pcie@0 { | ||
196 | /* | ||
197 | * IRQ[8:10] are pulled up on board, set to active-low | ||
198 | * IRQ[11] only for PCIe, set to active-high, | ||
199 | */ | ||
200 | interrupt-map-mask = <0xf800 0 0 7>; | ||
201 | interrupt-map = < | ||
202 | /* IDSEL 0x0 */ | ||
203 | 0000 0 0 1 &mpic 8 1 0 0 | ||
204 | 0000 0 0 2 &mpic 9 1 0 0 | ||
205 | 0000 0 0 3 &mpic 10 1 0 0 | ||
206 | 0000 0 0 4 &mpic 11 2 0 0 | ||
207 | >; | ||
208 | ranges = <0x2000000 0x0 0x80000000 | ||
209 | 0x2000000 0x0 0x80000000 | ||
210 | 0x0 0x20000000 | ||
211 | |||
212 | 0x1000000 0x0 0x0 | ||
213 | 0x1000000 0x0 0x0 | ||
214 | 0x0 0x100000>; | ||
215 | }; | ||
216 | }; | ||
217 | }; | ||
218 | |||
219 | /include/ "fsl/p1023si-post.dtsi" | ||
diff --git a/arch/powerpc/boot/dts/t1040qds.dts b/arch/powerpc/boot/dts/t1040qds.dts new file mode 100644 index 000000000000..973c29c2f56e --- /dev/null +++ b/arch/powerpc/boot/dts/t1040qds.dts | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * T1040QDS Device Tree Source | ||
3 | * | ||
4 | * Copyright 2013 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions are met: | ||
8 | * * Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * * Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * * Neither the name of Freescale Semiconductor nor the | ||
14 | * names of its contributors may be used to endorse or promote products | ||
15 | * derived from this software without specific prior written permission. | ||
16 | * | ||
17 | * | ||
18 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
19 | * GNU General Public License ("GPL") as published by the Free Software | ||
20 | * Foundation, either version 2 of that License or (at your option) any | ||
21 | * later version. | ||
22 | * | ||
23 | * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY | ||
24 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
26 | * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY | ||
27 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
28 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
29 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
30 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | /include/ "fsl/t104xsi-pre.dtsi" | ||
36 | /include/ "t104xqds.dtsi" | ||
37 | |||
38 | / { | ||
39 | model = "fsl,T1040QDS"; | ||
40 | compatible = "fsl,T1040QDS"; | ||
41 | #address-cells = <2>; | ||
42 | #size-cells = <2>; | ||
43 | interrupt-parent = <&mpic>; | ||
44 | }; | ||
45 | |||
46 | /include/ "fsl/t1040si-post.dtsi" | ||
diff --git a/arch/powerpc/boot/dts/t1042qds.dts b/arch/powerpc/boot/dts/t1042qds.dts new file mode 100644 index 000000000000..45bd03752154 --- /dev/null +++ b/arch/powerpc/boot/dts/t1042qds.dts | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * T1042QDS Device Tree Source | ||
3 | * | ||
4 | * Copyright 2013 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions are met: | ||
8 | * * Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * * Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * * Neither the name of Freescale Semiconductor nor the | ||
14 | * names of its contributors may be used to endorse or promote products | ||
15 | * derived from this software without specific prior written permission. | ||
16 | * | ||
17 | * | ||
18 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
19 | * GNU General Public License ("GPL") as published by the Free Software | ||
20 | * Foundation, either version 2 of that License or (at your option) any | ||
21 | * later version. | ||
22 | * | ||
23 | * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY | ||
24 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
26 | * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY | ||
27 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
28 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
29 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
30 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | /include/ "fsl/t104xsi-pre.dtsi" | ||
36 | /include/ "t104xqds.dtsi" | ||
37 | |||
38 | / { | ||
39 | model = "fsl,T1042QDS"; | ||
40 | compatible = "fsl,T1042QDS"; | ||
41 | #address-cells = <2>; | ||
42 | #size-cells = <2>; | ||
43 | interrupt-parent = <&mpic>; | ||
44 | }; | ||
45 | |||
46 | /include/ "fsl/t1042si-post.dtsi" | ||
diff --git a/arch/powerpc/boot/dts/t104xqds.dtsi b/arch/powerpc/boot/dts/t104xqds.dtsi new file mode 100644 index 000000000000..234f4b596c5b --- /dev/null +++ b/arch/powerpc/boot/dts/t104xqds.dtsi | |||
@@ -0,0 +1,166 @@ | |||
1 | /* | ||
2 | * T104xQDS Device Tree Source | ||
3 | * | ||
4 | * Copyright 2013 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions are met: | ||
8 | * * Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * * Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * * Neither the name of Freescale Semiconductor nor the | ||
14 | * names of its contributors may be used to endorse or promote products | ||
15 | * derived from this software without specific prior written permission. | ||
16 | * | ||
17 | * | ||
18 | * ALTERNATIVELY, this software may be distributed under the terms of the | ||
19 | * GNU General Public License ("GPL") as published by the Free Software | ||
20 | * Foundation, either version 2 of that License or (at your option) any | ||
21 | * later version. | ||
22 | * | ||
23 | * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY | ||
24 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
26 | * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY | ||
27 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
28 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
29 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
30 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | / { | ||
36 | model = "fsl,T1040QDS"; | ||
37 | #address-cells = <2>; | ||
38 | #size-cells = <2>; | ||
39 | interrupt-parent = <&mpic>; | ||
40 | |||
41 | ifc: localbus@ffe124000 { | ||
42 | reg = <0xf 0xfe124000 0 0x2000>; | ||
43 | ranges = <0 0 0xf 0xe8000000 0x08000000 | ||
44 | 2 0 0xf 0xff800000 0x00010000 | ||
45 | 3 0 0xf 0xffdf0000 0x00008000>; | ||
46 | |||
47 | nor@0,0 { | ||
48 | #address-cells = <1>; | ||
49 | #size-cells = <1>; | ||
50 | compatible = "cfi-flash"; | ||
51 | reg = <0x0 0x0 0x8000000>; | ||
52 | |||
53 | bank-width = <2>; | ||
54 | device-width = <1>; | ||
55 | }; | ||
56 | |||
57 | nand@2,0 { | ||
58 | #address-cells = <1>; | ||
59 | #size-cells = <1>; | ||
60 | compatible = "fsl,ifc-nand"; | ||
61 | reg = <0x2 0x0 0x10000>; | ||
62 | }; | ||
63 | |||
64 | board-control@3,0 { | ||
65 | #address-cells = <1>; | ||
66 | #size-cells = <1>; | ||
67 | compatible = "fsl,fpga-qixis"; | ||
68 | reg = <3 0 0x300>; | ||
69 | }; | ||
70 | }; | ||
71 | |||
72 | memory { | ||
73 | device_type = "memory"; | ||
74 | }; | ||
75 | |||
76 | dcsr: dcsr@f00000000 { | ||
77 | ranges = <0x00000000 0xf 0x00000000 0x01072000>; | ||
78 | }; | ||
79 | |||
80 | soc: soc@ffe000000 { | ||
81 | ranges = <0x00000000 0xf 0xfe000000 0x1000000>; | ||
82 | reg = <0xf 0xfe000000 0 0x00001000>; | ||
83 | |||
84 | spi@110000 { | ||
85 | flash@0 { | ||
86 | #address-cells = <1>; | ||
87 | #size-cells = <1>; | ||
88 | compatible = "micron,n25q128a11"; | ||
89 | reg = <0>; | ||
90 | spi-max-frequency = <10000000>; /* input clock */ | ||
91 | }; | ||
92 | }; | ||
93 | |||
94 | i2c@118000 { | ||
95 | pca9547@77 { | ||
96 | compatible = "philips,pca9547"; | ||
97 | reg = <0x77>; | ||
98 | }; | ||
99 | rtc@68 { | ||
100 | compatible = "dallas,ds3232"; | ||
101 | reg = <0x68>; | ||
102 | interrupts = <0x1 0x1 0 0>; | ||
103 | }; | ||
104 | }; | ||
105 | }; | ||
106 | |||
107 | pci0: pcie@ffe240000 { | ||
108 | reg = <0xf 0xfe240000 0 0x10000>; | ||
109 | ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x10000000 | ||
110 | 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>; | ||
111 | pcie@0 { | ||
112 | ranges = <0x02000000 0 0xe0000000 | ||
113 | 0x02000000 0 0xe0000000 | ||
114 | 0 0x10000000 | ||
115 | |||
116 | 0x01000000 0 0x00000000 | ||
117 | 0x01000000 0 0x00000000 | ||
118 | 0 0x00010000>; | ||
119 | }; | ||
120 | }; | ||
121 | |||
122 | pci1: pcie@ffe250000 { | ||
123 | reg = <0xf 0xfe250000 0 0x10000>; | ||
124 | ranges = <0x02000000 0x0 0xe0000000 0xc 0x10000000 0x0 0x10000000 | ||
125 | 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>; | ||
126 | pcie@0 { | ||
127 | ranges = <0x02000000 0 0xe0000000 | ||
128 | 0x02000000 0 0xe0000000 | ||
129 | 0 0x10000000 | ||
130 | |||
131 | 0x01000000 0 0x00000000 | ||
132 | 0x01000000 0 0x00000000 | ||
133 | 0 0x00010000>; | ||
134 | }; | ||
135 | }; | ||
136 | |||
137 | pci2: pcie@ffe260000 { | ||
138 | reg = <0xf 0xfe260000 0 0x10000>; | ||
139 | ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x10000000 | ||
140 | 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>; | ||
141 | pcie@0 { | ||
142 | ranges = <0x02000000 0 0xe0000000 | ||
143 | 0x02000000 0 0xe0000000 | ||
144 | 0 0x10000000 | ||
145 | |||
146 | 0x01000000 0 0x00000000 | ||
147 | 0x01000000 0 0x00000000 | ||
148 | 0 0x00010000>; | ||
149 | }; | ||
150 | }; | ||
151 | |||
152 | pci3: pcie@ffe270000 { | ||
153 | reg = <0xf 0xfe270000 0 0x10000>; | ||
154 | ranges = <0x02000000 0 0xe0000000 0xc 0x30000000 0 0x10000000 | ||
155 | 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>; | ||
156 | pcie@0 { | ||
157 | ranges = <0x02000000 0 0xe0000000 | ||
158 | 0x02000000 0 0xe0000000 | ||
159 | 0 0x10000000 | ||
160 | |||
161 | 0x01000000 0 0x00000000 | ||
162 | 0x01000000 0 0x00000000 | ||
163 | 0 0x00010000>; | ||
164 | }; | ||
165 | }; | ||
166 | }; | ||
diff --git a/arch/powerpc/boot/dts/t4240emu.dts b/arch/powerpc/boot/dts/t4240emu.dts index ee24ab335598..bc12127a03fb 100644 --- a/arch/powerpc/boot/dts/t4240emu.dts +++ b/arch/powerpc/boot/dts/t4240emu.dts | |||
@@ -60,63 +60,75 @@ | |||
60 | device_type = "cpu"; | 60 | device_type = "cpu"; |
61 | reg = <0 1>; | 61 | reg = <0 1>; |
62 | next-level-cache = <&L2_1>; | 62 | next-level-cache = <&L2_1>; |
63 | fsl,portid-mapping = <0x80000000>; | ||
63 | }; | 64 | }; |
64 | cpu1: PowerPC,e6500@2 { | 65 | cpu1: PowerPC,e6500@2 { |
65 | device_type = "cpu"; | 66 | device_type = "cpu"; |
66 | reg = <2 3>; | 67 | reg = <2 3>; |
67 | next-level-cache = <&L2_1>; | 68 | next-level-cache = <&L2_1>; |
69 | fsl,portid-mapping = <0x80000000>; | ||
68 | }; | 70 | }; |
69 | cpu2: PowerPC,e6500@4 { | 71 | cpu2: PowerPC,e6500@4 { |
70 | device_type = "cpu"; | 72 | device_type = "cpu"; |
71 | reg = <4 5>; | 73 | reg = <4 5>; |
72 | next-level-cache = <&L2_1>; | 74 | next-level-cache = <&L2_1>; |
75 | fsl,portid-mapping = <0x80000000>; | ||
73 | }; | 76 | }; |
74 | cpu3: PowerPC,e6500@6 { | 77 | cpu3: PowerPC,e6500@6 { |
75 | device_type = "cpu"; | 78 | device_type = "cpu"; |
76 | reg = <6 7>; | 79 | reg = <6 7>; |
77 | next-level-cache = <&L2_1>; | 80 | next-level-cache = <&L2_1>; |
81 | fsl,portid-mapping = <0x80000000>; | ||
78 | }; | 82 | }; |
79 | 83 | ||
80 | cpu4: PowerPC,e6500@8 { | 84 | cpu4: PowerPC,e6500@8 { |
81 | device_type = "cpu"; | 85 | device_type = "cpu"; |
82 | reg = <8 9>; | 86 | reg = <8 9>; |
83 | next-level-cache = <&L2_2>; | 87 | next-level-cache = <&L2_2>; |
88 | fsl,portid-mapping = <0x40000000>; | ||
84 | }; | 89 | }; |
85 | cpu5: PowerPC,e6500@10 { | 90 | cpu5: PowerPC,e6500@10 { |
86 | device_type = "cpu"; | 91 | device_type = "cpu"; |
87 | reg = <10 11>; | 92 | reg = <10 11>; |
88 | next-level-cache = <&L2_2>; | 93 | next-level-cache = <&L2_2>; |
94 | fsl,portid-mapping = <0x40000000>; | ||
89 | }; | 95 | }; |
90 | cpu6: PowerPC,e6500@12 { | 96 | cpu6: PowerPC,e6500@12 { |
91 | device_type = "cpu"; | 97 | device_type = "cpu"; |
92 | reg = <12 13>; | 98 | reg = <12 13>; |
93 | next-level-cache = <&L2_2>; | 99 | next-level-cache = <&L2_2>; |
100 | fsl,portid-mapping = <0x40000000>; | ||
94 | }; | 101 | }; |
95 | cpu7: PowerPC,e6500@14 { | 102 | cpu7: PowerPC,e6500@14 { |
96 | device_type = "cpu"; | 103 | device_type = "cpu"; |
97 | reg = <14 15>; | 104 | reg = <14 15>; |
98 | next-level-cache = <&L2_2>; | 105 | next-level-cache = <&L2_2>; |
106 | fsl,portid-mapping = <0x40000000>; | ||
99 | }; | 107 | }; |
100 | 108 | ||
101 | cpu8: PowerPC,e6500@16 { | 109 | cpu8: PowerPC,e6500@16 { |
102 | device_type = "cpu"; | 110 | device_type = "cpu"; |
103 | reg = <16 17>; | 111 | reg = <16 17>; |
104 | next-level-cache = <&L2_3>; | 112 | next-level-cache = <&L2_3>; |
113 | fsl,portid-mapping = <0x20000000>; | ||
105 | }; | 114 | }; |
106 | cpu9: PowerPC,e6500@18 { | 115 | cpu9: PowerPC,e6500@18 { |
107 | device_type = "cpu"; | 116 | device_type = "cpu"; |
108 | reg = <18 19>; | 117 | reg = <18 19>; |
109 | next-level-cache = <&L2_3>; | 118 | next-level-cache = <&L2_3>; |
119 | fsl,portid-mapping = <0x20000000>; | ||
110 | }; | 120 | }; |
111 | cpu10: PowerPC,e6500@20 { | 121 | cpu10: PowerPC,e6500@20 { |
112 | device_type = "cpu"; | 122 | device_type = "cpu"; |
113 | reg = <20 21>; | 123 | reg = <20 21>; |
114 | next-level-cache = <&L2_3>; | 124 | next-level-cache = <&L2_3>; |
125 | fsl,portid-mapping = <0x20000000>; | ||
115 | }; | 126 | }; |
116 | cpu11: PowerPC,e6500@22 { | 127 | cpu11: PowerPC,e6500@22 { |
117 | device_type = "cpu"; | 128 | device_type = "cpu"; |
118 | reg = <22 23>; | 129 | reg = <22 23>; |
119 | next-level-cache = <&L2_3>; | 130 | next-level-cache = <&L2_3>; |
131 | fsl,portid-mapping = <0x20000000>; | ||
120 | }; | 132 | }; |
121 | }; | 133 | }; |
122 | }; | 134 | }; |
@@ -213,7 +225,7 @@ | |||
213 | }; | 225 | }; |
214 | 226 | ||
215 | corenet-cf@18000 { | 227 | corenet-cf@18000 { |
216 | compatible = "fsl,corenet-cf"; | 228 | compatible = "fsl,corenet2-cf", "fsl,corenet-cf"; |
217 | reg = <0x18000 0x1000>; | 229 | reg = <0x18000 0x1000>; |
218 | interrupts = <16 2 1 31>; | 230 | interrupts = <16 2 1 31>; |
219 | fsl,ccf-num-csdids = <32>; | 231 | fsl,ccf-num-csdids = <32>; |
@@ -223,6 +235,7 @@ | |||
223 | iommu@20000 { | 235 | iommu@20000 { |
224 | compatible = "fsl,pamu-v1.0", "fsl,pamu"; | 236 | compatible = "fsl,pamu-v1.0", "fsl,pamu"; |
225 | reg = <0x20000 0x6000>; | 237 | reg = <0x20000 0x6000>; |
238 | fsl,portid-mapping = <0x8000>; | ||
226 | interrupts = < | 239 | interrupts = < |
227 | 24 2 0 0 | 240 | 24 2 0 0 |
228 | 16 2 1 30>; | 241 | 16 2 1 30>; |
diff --git a/arch/powerpc/boot/elf_util.c b/arch/powerpc/boot/elf_util.c index 1567a0c0f05c..316552dea4d8 100644 --- a/arch/powerpc/boot/elf_util.c +++ b/arch/powerpc/boot/elf_util.c | |||
@@ -26,7 +26,11 @@ int parse_elf64(void *hdr, struct elf_info *info) | |||
26 | elf64->e_ident[EI_MAG2] == ELFMAG2 && | 26 | elf64->e_ident[EI_MAG2] == ELFMAG2 && |
27 | elf64->e_ident[EI_MAG3] == ELFMAG3 && | 27 | elf64->e_ident[EI_MAG3] == ELFMAG3 && |
28 | elf64->e_ident[EI_CLASS] == ELFCLASS64 && | 28 | elf64->e_ident[EI_CLASS] == ELFCLASS64 && |
29 | #ifdef __LITTLE_ENDIAN__ | ||
30 | elf64->e_ident[EI_DATA] == ELFDATA2LSB && | ||
31 | #else | ||
29 | elf64->e_ident[EI_DATA] == ELFDATA2MSB && | 32 | elf64->e_ident[EI_DATA] == ELFDATA2MSB && |
33 | #endif | ||
30 | (elf64->e_type == ET_EXEC || | 34 | (elf64->e_type == ET_EXEC || |
31 | elf64->e_type == ET_DYN) && | 35 | elf64->e_type == ET_DYN) && |
32 | elf64->e_machine == EM_PPC64)) | 36 | elf64->e_machine == EM_PPC64)) |
diff --git a/arch/powerpc/boot/of.c b/arch/powerpc/boot/of.c index 62e2f43ec1df..7ca910cb2fc6 100644 --- a/arch/powerpc/boot/of.c +++ b/arch/powerpc/boot/of.c | |||
@@ -40,8 +40,8 @@ static void *of_try_claim(unsigned long size) | |||
40 | #ifdef DEBUG | 40 | #ifdef DEBUG |
41 | printf(" trying: 0x%08lx\n\r", claim_base); | 41 | printf(" trying: 0x%08lx\n\r", claim_base); |
42 | #endif | 42 | #endif |
43 | addr = (unsigned long)of_claim(claim_base, size, 0); | 43 | addr = (unsigned long) of_claim(claim_base, size, 0); |
44 | if ((void *)addr != (void *)-1) | 44 | if (addr != PROM_ERROR) |
45 | break; | 45 | break; |
46 | } | 46 | } |
47 | if (addr == 0) | 47 | if (addr == 0) |
diff --git a/arch/powerpc/boot/of.h b/arch/powerpc/boot/of.h index e4c68f7391c5..c8c1750aba0c 100644 --- a/arch/powerpc/boot/of.h +++ b/arch/powerpc/boot/of.h | |||
@@ -1,12 +1,15 @@ | |||
1 | #ifndef _PPC_BOOT_OF_H_ | 1 | #ifndef _PPC_BOOT_OF_H_ |
2 | #define _PPC_BOOT_OF_H_ | 2 | #define _PPC_BOOT_OF_H_ |
3 | 3 | ||
4 | #include "swab.h" | ||
5 | |||
4 | typedef void *phandle; | 6 | typedef void *phandle; |
5 | typedef void *ihandle; | 7 | typedef u32 ihandle; |
6 | 8 | ||
7 | void of_init(void *promptr); | 9 | void of_init(void *promptr); |
8 | int of_call_prom(const char *service, int nargs, int nret, ...); | 10 | int of_call_prom(const char *service, int nargs, int nret, ...); |
9 | void *of_claim(unsigned long virt, unsigned long size, unsigned long align); | 11 | unsigned int of_claim(unsigned long virt, unsigned long size, |
12 | unsigned long align); | ||
10 | void *of_vmlinux_alloc(unsigned long size); | 13 | void *of_vmlinux_alloc(unsigned long size); |
11 | void of_exit(void); | 14 | void of_exit(void); |
12 | void *of_finddevice(const char *name); | 15 | void *of_finddevice(const char *name); |
@@ -18,4 +21,16 @@ int of_setprop(const void *phandle, const char *name, const void *buf, | |||
18 | /* Console functions */ | 21 | /* Console functions */ |
19 | void of_console_init(void); | 22 | void of_console_init(void); |
20 | 23 | ||
24 | typedef u32 __be32; | ||
25 | |||
26 | #ifdef __LITTLE_ENDIAN__ | ||
27 | #define cpu_to_be32(x) swab32(x) | ||
28 | #define be32_to_cpu(x) swab32(x) | ||
29 | #else | ||
30 | #define cpu_to_be32(x) (x) | ||
31 | #define be32_to_cpu(x) (x) | ||
32 | #endif | ||
33 | |||
34 | #define PROM_ERROR (-1u) | ||
35 | |||
21 | #endif /* _PPC_BOOT_OF_H_ */ | 36 | #endif /* _PPC_BOOT_OF_H_ */ |
diff --git a/arch/powerpc/boot/ofconsole.c b/arch/powerpc/boot/ofconsole.c index ce0e02424453..8b754702460a 100644 --- a/arch/powerpc/boot/ofconsole.c +++ b/arch/powerpc/boot/ofconsole.c | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | #include "of.h" | 19 | #include "of.h" |
20 | 20 | ||
21 | static void *of_stdout_handle; | 21 | static unsigned int of_stdout_handle; |
22 | 22 | ||
23 | static int of_console_open(void) | 23 | static int of_console_open(void) |
24 | { | 24 | { |
@@ -27,8 +27,10 @@ static int of_console_open(void) | |||
27 | if (((devp = of_finddevice("/chosen")) != NULL) | 27 | if (((devp = of_finddevice("/chosen")) != NULL) |
28 | && (of_getprop(devp, "stdout", &of_stdout_handle, | 28 | && (of_getprop(devp, "stdout", &of_stdout_handle, |
29 | sizeof(of_stdout_handle)) | 29 | sizeof(of_stdout_handle)) |
30 | == sizeof(of_stdout_handle))) | 30 | == sizeof(of_stdout_handle))) { |
31 | of_stdout_handle = be32_to_cpu(of_stdout_handle); | ||
31 | return 0; | 32 | return 0; |
33 | } | ||
32 | 34 | ||
33 | return -1; | 35 | return -1; |
34 | } | 36 | } |
diff --git a/arch/powerpc/boot/oflib.c b/arch/powerpc/boot/oflib.c index b0ec9cf3eaaf..46c98a47d949 100644 --- a/arch/powerpc/boot/oflib.c +++ b/arch/powerpc/boot/oflib.c | |||
@@ -16,74 +16,83 @@ | |||
16 | 16 | ||
17 | #include "of.h" | 17 | #include "of.h" |
18 | 18 | ||
19 | typedef u32 prom_arg_t; | ||
20 | |||
21 | /* The following structure is used to communicate with open firmware. | ||
22 | * All arguments in and out are in big endian format. */ | ||
23 | struct prom_args { | ||
24 | __be32 service; /* Address of service name string. */ | ||
25 | __be32 nargs; /* Number of input arguments. */ | ||
26 | __be32 nret; /* Number of output arguments. */ | ||
27 | __be32 args[10]; /* Input/output arguments. */ | ||
28 | }; | ||
29 | |||
30 | #ifdef __powerpc64__ | ||
31 | extern int prom(void *); | ||
32 | #else | ||
19 | static int (*prom) (void *); | 33 | static int (*prom) (void *); |
34 | #endif | ||
20 | 35 | ||
21 | void of_init(void *promptr) | 36 | void of_init(void *promptr) |
22 | { | 37 | { |
38 | #ifndef __powerpc64__ | ||
23 | prom = (int (*)(void *))promptr; | 39 | prom = (int (*)(void *))promptr; |
40 | #endif | ||
24 | } | 41 | } |
25 | 42 | ||
43 | #define ADDR(x) (u32)(unsigned long)(x) | ||
44 | |||
26 | int of_call_prom(const char *service, int nargs, int nret, ...) | 45 | int of_call_prom(const char *service, int nargs, int nret, ...) |
27 | { | 46 | { |
28 | int i; | 47 | int i; |
29 | struct prom_args { | 48 | struct prom_args args; |
30 | const char *service; | ||
31 | int nargs; | ||
32 | int nret; | ||
33 | unsigned int args[12]; | ||
34 | } args; | ||
35 | va_list list; | 49 | va_list list; |
36 | 50 | ||
37 | args.service = service; | 51 | args.service = cpu_to_be32(ADDR(service)); |
38 | args.nargs = nargs; | 52 | args.nargs = cpu_to_be32(nargs); |
39 | args.nret = nret; | 53 | args.nret = cpu_to_be32(nret); |
40 | 54 | ||
41 | va_start(list, nret); | 55 | va_start(list, nret); |
42 | for (i = 0; i < nargs; i++) | 56 | for (i = 0; i < nargs; i++) |
43 | args.args[i] = va_arg(list, unsigned int); | 57 | args.args[i] = cpu_to_be32(va_arg(list, prom_arg_t)); |
44 | va_end(list); | 58 | va_end(list); |
45 | 59 | ||
46 | for (i = 0; i < nret; i++) | 60 | for (i = 0; i < nret; i++) |
47 | args.args[nargs+i] = 0; | 61 | args.args[nargs+i] = 0; |
48 | 62 | ||
49 | if (prom(&args) < 0) | 63 | if (prom(&args) < 0) |
50 | return -1; | 64 | return PROM_ERROR; |
51 | 65 | ||
52 | return (nret > 0)? args.args[nargs]: 0; | 66 | return (nret > 0) ? be32_to_cpu(args.args[nargs]) : 0; |
53 | } | 67 | } |
54 | 68 | ||
55 | static int of_call_prom_ret(const char *service, int nargs, int nret, | 69 | static int of_call_prom_ret(const char *service, int nargs, int nret, |
56 | unsigned int *rets, ...) | 70 | prom_arg_t *rets, ...) |
57 | { | 71 | { |
58 | int i; | 72 | int i; |
59 | struct prom_args { | 73 | struct prom_args args; |
60 | const char *service; | ||
61 | int nargs; | ||
62 | int nret; | ||
63 | unsigned int args[12]; | ||
64 | } args; | ||
65 | va_list list; | 74 | va_list list; |
66 | 75 | ||
67 | args.service = service; | 76 | args.service = cpu_to_be32(ADDR(service)); |
68 | args.nargs = nargs; | 77 | args.nargs = cpu_to_be32(nargs); |
69 | args.nret = nret; | 78 | args.nret = cpu_to_be32(nret); |
70 | 79 | ||
71 | va_start(list, rets); | 80 | va_start(list, rets); |
72 | for (i = 0; i < nargs; i++) | 81 | for (i = 0; i < nargs; i++) |
73 | args.args[i] = va_arg(list, unsigned int); | 82 | args.args[i] = cpu_to_be32(va_arg(list, prom_arg_t)); |
74 | va_end(list); | 83 | va_end(list); |
75 | 84 | ||
76 | for (i = 0; i < nret; i++) | 85 | for (i = 0; i < nret; i++) |
77 | args.args[nargs+i] = 0; | 86 | args.args[nargs+i] = 0; |
78 | 87 | ||
79 | if (prom(&args) < 0) | 88 | if (prom(&args) < 0) |
80 | return -1; | 89 | return PROM_ERROR; |
81 | 90 | ||
82 | if (rets != (void *) 0) | 91 | if (rets != NULL) |
83 | for (i = 1; i < nret; ++i) | 92 | for (i = 1; i < nret; ++i) |
84 | rets[i-1] = args.args[nargs+i]; | 93 | rets[i-1] = be32_to_cpu(args.args[nargs+i]); |
85 | 94 | ||
86 | return (nret > 0)? args.args[nargs]: 0; | 95 | return (nret > 0) ? be32_to_cpu(args.args[nargs]) : 0; |
87 | } | 96 | } |
88 | 97 | ||
89 | /* returns true if s2 is a prefix of s1 */ | 98 | /* returns true if s2 is a prefix of s1 */ |
@@ -103,7 +112,7 @@ static int string_match(const char *s1, const char *s2) | |||
103 | */ | 112 | */ |
104 | static int need_map = -1; | 113 | static int need_map = -1; |
105 | static ihandle chosen_mmu; | 114 | static ihandle chosen_mmu; |
106 | static phandle memory; | 115 | static ihandle memory; |
107 | 116 | ||
108 | static int check_of_version(void) | 117 | static int check_of_version(void) |
109 | { | 118 | { |
@@ -132,10 +141,10 @@ static int check_of_version(void) | |||
132 | printf("no mmu\n"); | 141 | printf("no mmu\n"); |
133 | return 0; | 142 | return 0; |
134 | } | 143 | } |
135 | memory = (ihandle) of_call_prom("open", 1, 1, "/memory"); | 144 | memory = of_call_prom("open", 1, 1, "/memory"); |
136 | if (memory == (ihandle) -1) { | 145 | if (memory == PROM_ERROR) { |
137 | memory = (ihandle) of_call_prom("open", 1, 1, "/memory@0"); | 146 | memory = of_call_prom("open", 1, 1, "/memory@0"); |
138 | if (memory == (ihandle) -1) { | 147 | if (memory == PROM_ERROR) { |
139 | printf("no memory node\n"); | 148 | printf("no memory node\n"); |
140 | return 0; | 149 | return 0; |
141 | } | 150 | } |
@@ -144,40 +153,41 @@ static int check_of_version(void) | |||
144 | return 1; | 153 | return 1; |
145 | } | 154 | } |
146 | 155 | ||
147 | void *of_claim(unsigned long virt, unsigned long size, unsigned long align) | 156 | unsigned int of_claim(unsigned long virt, unsigned long size, |
157 | unsigned long align) | ||
148 | { | 158 | { |
149 | int ret; | 159 | int ret; |
150 | unsigned int result; | 160 | prom_arg_t result; |
151 | 161 | ||
152 | if (need_map < 0) | 162 | if (need_map < 0) |
153 | need_map = check_of_version(); | 163 | need_map = check_of_version(); |
154 | if (align || !need_map) | 164 | if (align || !need_map) |
155 | return (void *) of_call_prom("claim", 3, 1, virt, size, align); | 165 | return of_call_prom("claim", 3, 1, virt, size, align); |
156 | 166 | ||
157 | ret = of_call_prom_ret("call-method", 5, 2, &result, "claim", memory, | 167 | ret = of_call_prom_ret("call-method", 5, 2, &result, "claim", memory, |
158 | align, size, virt); | 168 | align, size, virt); |
159 | if (ret != 0 || result == -1) | 169 | if (ret != 0 || result == -1) |
160 | return (void *) -1; | 170 | return -1; |
161 | ret = of_call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu, | 171 | ret = of_call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu, |
162 | align, size, virt); | 172 | align, size, virt); |
163 | /* 0x12 == coherent + read/write */ | 173 | /* 0x12 == coherent + read/write */ |
164 | ret = of_call_prom("call-method", 6, 1, "map", chosen_mmu, | 174 | ret = of_call_prom("call-method", 6, 1, "map", chosen_mmu, |
165 | 0x12, size, virt, virt); | 175 | 0x12, size, virt, virt); |
166 | return (void *) virt; | 176 | return virt; |
167 | } | 177 | } |
168 | 178 | ||
169 | void *of_vmlinux_alloc(unsigned long size) | 179 | void *of_vmlinux_alloc(unsigned long size) |
170 | { | 180 | { |
171 | unsigned long start = (unsigned long)_start, end = (unsigned long)_end; | 181 | unsigned long start = (unsigned long)_start, end = (unsigned long)_end; |
172 | void *addr; | 182 | unsigned long addr; |
173 | void *p; | 183 | void *p; |
174 | 184 | ||
175 | /* With some older POWER4 firmware we need to claim the area the kernel | 185 | /* With some older POWER4 firmware we need to claim the area the kernel |
176 | * will reside in. Newer firmwares don't need this so we just ignore | 186 | * will reside in. Newer firmwares don't need this so we just ignore |
177 | * the return value. | 187 | * the return value. |
178 | */ | 188 | */ |
179 | addr = of_claim(start, end - start, 0); | 189 | addr = (unsigned long) of_claim(start, end - start, 0); |
180 | printf("Trying to claim from 0x%lx to 0x%lx (0x%lx) got %p\r\n", | 190 | printf("Trying to claim from 0x%lx to 0x%lx (0x%lx) got %lx\r\n", |
181 | start, end, end - start, addr); | 191 | start, end, end - start, addr); |
182 | 192 | ||
183 | p = malloc(size); | 193 | p = malloc(size); |
@@ -197,7 +207,7 @@ void of_exit(void) | |||
197 | */ | 207 | */ |
198 | void *of_finddevice(const char *name) | 208 | void *of_finddevice(const char *name) |
199 | { | 209 | { |
200 | return (phandle) of_call_prom("finddevice", 1, 1, name); | 210 | return (void *) (unsigned long) of_call_prom("finddevice", 1, 1, name); |
201 | } | 211 | } |
202 | 212 | ||
203 | int of_getprop(const void *phandle, const char *name, void *buf, | 213 | int of_getprop(const void *phandle, const char *name, void *buf, |
diff --git a/arch/powerpc/boot/ppc_asm.h b/arch/powerpc/boot/ppc_asm.h index eb0e98be69e0..35ea60c1f070 100644 --- a/arch/powerpc/boot/ppc_asm.h +++ b/arch/powerpc/boot/ppc_asm.h | |||
@@ -62,4 +62,16 @@ | |||
62 | #define SPRN_TBRL 268 | 62 | #define SPRN_TBRL 268 |
63 | #define SPRN_TBRU 269 | 63 | #define SPRN_TBRU 269 |
64 | 64 | ||
65 | #define FIXUP_ENDIAN \ | ||
66 | tdi 0, 0, 0x48; /* Reverse endian of b . + 8 */ \ | ||
67 | b $+36; /* Skip trampoline if endian is good */ \ | ||
68 | .long 0x05009f42; /* bcl 20,31,$+4 */ \ | ||
69 | .long 0xa602487d; /* mflr r10 */ \ | ||
70 | .long 0x1c004a39; /* addi r10,r10,28 */ \ | ||
71 | .long 0xa600607d; /* mfmsr r11 */ \ | ||
72 | .long 0x01006b69; /* xori r11,r11,1 */ \ | ||
73 | .long 0xa6035a7d; /* mtsrr0 r10 */ \ | ||
74 | .long 0xa6037b7d; /* mtsrr1 r11 */ \ | ||
75 | .long 0x2400004c /* rfid */ | ||
76 | |||
65 | #endif /* _PPC64_PPC_ASM_H */ | 77 | #endif /* _PPC64_PPC_ASM_H */ |
diff --git a/arch/powerpc/boot/pseries-head.S b/arch/powerpc/boot/pseries-head.S new file mode 100644 index 000000000000..6ef6e02e80f9 --- /dev/null +++ b/arch/powerpc/boot/pseries-head.S | |||
@@ -0,0 +1,8 @@ | |||
1 | #include "ppc_asm.h" | ||
2 | |||
3 | .text | ||
4 | |||
5 | .globl _zimage_start | ||
6 | _zimage_start: | ||
7 | FIXUP_ENDIAN | ||
8 | b _zimage_start_lib | ||
diff --git a/arch/powerpc/boot/stdio.c b/arch/powerpc/boot/stdio.c index 5b57800bbc67..a701261b1781 100644 --- a/arch/powerpc/boot/stdio.c +++ b/arch/powerpc/boot/stdio.c | |||
@@ -21,6 +21,18 @@ size_t strnlen(const char * s, size_t count) | |||
21 | return sc - s; | 21 | return sc - s; |
22 | } | 22 | } |
23 | 23 | ||
24 | #ifdef __powerpc64__ | ||
25 | |||
26 | # define do_div(n, base) ({ \ | ||
27 | unsigned int __base = (base); \ | ||
28 | unsigned int __rem; \ | ||
29 | __rem = ((unsigned long long)(n)) % __base; \ | ||
30 | (n) = ((unsigned long long)(n)) / __base; \ | ||
31 | __rem; \ | ||
32 | }) | ||
33 | |||
34 | #else | ||
35 | |||
24 | extern unsigned int __div64_32(unsigned long long *dividend, | 36 | extern unsigned int __div64_32(unsigned long long *dividend, |
25 | unsigned int divisor); | 37 | unsigned int divisor); |
26 | 38 | ||
@@ -39,6 +51,8 @@ extern unsigned int __div64_32(unsigned long long *dividend, | |||
39 | __rem; \ | 51 | __rem; \ |
40 | }) | 52 | }) |
41 | 53 | ||
54 | #endif /* __powerpc64__ */ | ||
55 | |||
42 | static int skip_atoi(const char **s) | 56 | static int skip_atoi(const char **s) |
43 | { | 57 | { |
44 | int i, c; | 58 | int i, c; |
diff --git a/arch/powerpc/boot/swab.h b/arch/powerpc/boot/swab.h new file mode 100644 index 000000000000..d0e1431084ca --- /dev/null +++ b/arch/powerpc/boot/swab.h | |||
@@ -0,0 +1,29 @@ | |||
1 | #ifndef _PPC_BOOT_SWAB_H_ | ||
2 | #define _PPC_BOOT_SWAB_H_ | ||
3 | |||
4 | static inline u16 swab16(u16 x) | ||
5 | { | ||
6 | return ((x & (u16)0x00ffU) << 8) | | ||
7 | ((x & (u16)0xff00U) >> 8); | ||
8 | } | ||
9 | |||
10 | static inline u32 swab32(u32 x) | ||
11 | { | ||
12 | return ((x & (u32)0x000000ffUL) << 24) | | ||
13 | ((x & (u32)0x0000ff00UL) << 8) | | ||
14 | ((x & (u32)0x00ff0000UL) >> 8) | | ||
15 | ((x & (u32)0xff000000UL) >> 24); | ||
16 | } | ||
17 | |||
18 | static inline u64 swab64(u64 x) | ||
19 | { | ||
20 | return (u64)((x & (u64)0x00000000000000ffULL) << 56) | | ||
21 | (u64)((x & (u64)0x000000000000ff00ULL) << 40) | | ||
22 | (u64)((x & (u64)0x0000000000ff0000ULL) << 24) | | ||
23 | (u64)((x & (u64)0x00000000ff000000ULL) << 8) | | ||
24 | (u64)((x & (u64)0x000000ff00000000ULL) >> 8) | | ||
25 | (u64)((x & (u64)0x0000ff0000000000ULL) >> 24) | | ||
26 | (u64)((x & (u64)0x00ff000000000000ULL) >> 40) | | ||
27 | (u64)((x & (u64)0xff00000000000000ULL) >> 56); | ||
28 | } | ||
29 | #endif /* _PPC_BOOT_SWAB_H_ */ | ||
diff --git a/arch/powerpc/boot/treeboot-akebono.c b/arch/powerpc/boot/treeboot-akebono.c new file mode 100644 index 000000000000..b73174c34fe4 --- /dev/null +++ b/arch/powerpc/boot/treeboot-akebono.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /* | ||
2 | * Copyright © 2013 Tony Breeds IBM Corporation | ||
3 | * Copyright © 2013 Alistair Popple IBM Corporation | ||
4 | * | ||
5 | * Based on earlier code: | ||
6 | * Copyright (C) Paul Mackerras 1997. | ||
7 | * | ||
8 | * Matt Porter <mporter@kernel.crashing.org> | ||
9 | * Copyright 2002-2005 MontaVista Software Inc. | ||
10 | * | ||
11 | * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> | ||
12 | * Copyright (c) 2003, 2004 Zultys Technologies | ||
13 | * | ||
14 | * Copyright 2007 David Gibson, IBM Corporation. | ||
15 | * Copyright 2010 Ben. Herrenschmidt, IBM Corporation. | ||
16 | * Copyright © 2011 David Kleikamp IBM Corporation | ||
17 | * | ||
18 | * This program is free software; you can redistribute it and/or | ||
19 | * modify it under the terms of the GNU General Public License | ||
20 | * as published by the Free Software Foundation; either version | ||
21 | * 2 of the License, or (at your option) any later version. | ||
22 | */ | ||
23 | #include <stdarg.h> | ||
24 | #include <stddef.h> | ||
25 | #include "types.h" | ||
26 | #include "elf.h" | ||
27 | #include "string.h" | ||
28 | #include "stdlib.h" | ||
29 | #include "stdio.h" | ||
30 | #include "page.h" | ||
31 | #include "ops.h" | ||
32 | #include "reg.h" | ||
33 | #include "io.h" | ||
34 | #include "dcr.h" | ||
35 | #include "4xx.h" | ||
36 | #include "44x.h" | ||
37 | #include "libfdt.h" | ||
38 | |||
39 | BSS_STACK(4096); | ||
40 | |||
41 | #define SPRN_PIR 0x11E /* Processor Indentification Register */ | ||
42 | #define USERDATA_LEN 256 /* Length of userdata passed in by PIBS */ | ||
43 | #define MAX_RANKS 0x4 | ||
44 | #define DDR3_MR0CF 0x80010011U | ||
45 | #define CCTL0_MCO2 0x8000080FU | ||
46 | #define CCTL0_MCO3 0x80000810U | ||
47 | #define CCTL0_MCO4 0x80000811U | ||
48 | #define CCTL0_MCO5 0x80000812U | ||
49 | #define CCTL0_MCO6 0x80000813U | ||
50 | |||
51 | static unsigned long long ibm_akebono_memsize; | ||
52 | static long long unsigned mac_addr; | ||
53 | |||
54 | static unsigned long long ibm_akebono_detect_memsize(void) | ||
55 | { | ||
56 | u32 reg; | ||
57 | unsigned i; | ||
58 | unsigned long long memsize = 0; | ||
59 | |||
60 | for (i = 0; i < MAX_RANKS; i++) { | ||
61 | reg = mfdcrx(DDR3_MR0CF + i); | ||
62 | |||
63 | if (!(reg & 1)) | ||
64 | continue; | ||
65 | |||
66 | reg &= 0x0000f000; | ||
67 | reg >>= 12; | ||
68 | memsize += (0x800000ULL << reg); | ||
69 | } | ||
70 | |||
71 | return memsize; | ||
72 | } | ||
73 | |||
74 | static void ibm_akebono_fixups(void) | ||
75 | { | ||
76 | void *emac; | ||
77 | u32 reg; | ||
78 | |||
79 | dt_fixup_memory(0x0ULL, ibm_akebono_memsize); | ||
80 | |||
81 | /* Fixup the SD timeout frequency */ | ||
82 | mtdcrx(CCTL0_MCO4, 0x1); | ||
83 | |||
84 | /* Disable SD high-speed mode (which seems to be broken) */ | ||
85 | reg = mfdcrx(CCTL0_MCO2) & ~0x2; | ||
86 | mtdcrx(CCTL0_MCO2, reg); | ||
87 | |||
88 | /* Set the MAC address */ | ||
89 | emac = finddevice("/plb/opb/ethernet"); | ||
90 | if (emac > 0) { | ||
91 | if (mac_addr) | ||
92 | setprop(emac, "local-mac-address", | ||
93 | ((u8 *) &mac_addr) + 2 , 6); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | void platform_init(char *userdata) | ||
98 | { | ||
99 | unsigned long end_of_ram, avail_ram; | ||
100 | u32 pir_reg; | ||
101 | int node, size; | ||
102 | const u32 *timebase; | ||
103 | int len, i, userdata_len; | ||
104 | char *end; | ||
105 | |||
106 | userdata[USERDATA_LEN - 1] = '\0'; | ||
107 | userdata_len = strlen(userdata); | ||
108 | for (i = 0; i < userdata_len - 15; i++) { | ||
109 | if (strncmp(&userdata[i], "local-mac-addr=", 15) == 0) { | ||
110 | if (i > 0 && userdata[i - 1] != ' ') { | ||
111 | /* We've only found a substring ending | ||
112 | * with local-mac-addr so this isn't | ||
113 | * our mac address. */ | ||
114 | continue; | ||
115 | } | ||
116 | |||
117 | mac_addr = strtoull(&userdata[i + 15], &end, 16); | ||
118 | |||
119 | /* Remove the "local-mac-addr=<...>" from the kernel | ||
120 | * command line, including the tailing space if | ||
121 | * present. */ | ||
122 | if (*end == ' ') | ||
123 | end++; | ||
124 | |||
125 | len = ((int) end) - ((int) &userdata[i]); | ||
126 | memmove(&userdata[i], end, | ||
127 | userdata_len - (len + i) + 1); | ||
128 | break; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | loader_info.cmdline = userdata; | ||
133 | loader_info.cmdline_len = 256; | ||
134 | |||
135 | ibm_akebono_memsize = ibm_akebono_detect_memsize(); | ||
136 | if (ibm_akebono_memsize >> 32) | ||
137 | end_of_ram = ~0UL; | ||
138 | else | ||
139 | end_of_ram = ibm_akebono_memsize; | ||
140 | avail_ram = end_of_ram - (unsigned long)_end; | ||
141 | |||
142 | simple_alloc_init(_end, avail_ram, 128, 64); | ||
143 | platform_ops.fixups = ibm_akebono_fixups; | ||
144 | platform_ops.exit = ibm44x_dbcr_reset; | ||
145 | pir_reg = mfspr(SPRN_PIR); | ||
146 | |||
147 | /* Make sure FDT blob is sane */ | ||
148 | if (fdt_check_header(_dtb_start) != 0) | ||
149 | fatal("Invalid device tree blob\n"); | ||
150 | |||
151 | node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type", | ||
152 | "cpu", sizeof("cpu")); | ||
153 | if (!node) | ||
154 | fatal("Cannot find cpu node\n"); | ||
155 | timebase = fdt_getprop(_dtb_start, node, "timebase-frequency", &size); | ||
156 | if (timebase && (size == 4)) | ||
157 | timebase_period_ns = 1000000000 / *timebase; | ||
158 | |||
159 | fdt_set_boot_cpuid_phys(_dtb_start, pir_reg); | ||
160 | fdt_init(_dtb_start); | ||
161 | |||
162 | serial_console_init(); | ||
163 | } | ||
diff --git a/arch/powerpc/boot/util.S b/arch/powerpc/boot/util.S index 6636b1d7821b..243b8497d58b 100644 --- a/arch/powerpc/boot/util.S +++ b/arch/powerpc/boot/util.S | |||
@@ -45,7 +45,7 @@ udelay: | |||
45 | mfspr r4,SPRN_PVR | 45 | mfspr r4,SPRN_PVR |
46 | srwi r4,r4,16 | 46 | srwi r4,r4,16 |
47 | cmpwi 0,r4,1 /* 601 ? */ | 47 | cmpwi 0,r4,1 /* 601 ? */ |
48 | bne .udelay_not_601 | 48 | bne .Ludelay_not_601 |
49 | 00: li r0,86 /* Instructions / microsecond? */ | 49 | 00: li r0,86 /* Instructions / microsecond? */ |
50 | mtctr r0 | 50 | mtctr r0 |
51 | 10: addi r0,r0,0 /* NOP */ | 51 | 10: addi r0,r0,0 /* NOP */ |
@@ -54,7 +54,7 @@ udelay: | |||
54 | bne 00b | 54 | bne 00b |
55 | blr | 55 | blr |
56 | 56 | ||
57 | .udelay_not_601: | 57 | .Ludelay_not_601: |
58 | mulli r4,r3,1000 /* nanoseconds */ | 58 | mulli r4,r3,1000 /* nanoseconds */ |
59 | /* Change r4 to be the number of ticks using: | 59 | /* Change r4 to be the number of ticks using: |
60 | * (nanoseconds + (timebase_period_ns - 1 )) / timebase_period_ns | 60 | * (nanoseconds + (timebase_period_ns - 1 )) / timebase_period_ns |
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index d27a25518b01..ae0f88ec4a32 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper | |||
@@ -40,6 +40,7 @@ cacheit= | |||
40 | binary= | 40 | binary= |
41 | gzip=.gz | 41 | gzip=.gz |
42 | pie= | 42 | pie= |
43 | format= | ||
43 | 44 | ||
44 | # cross-compilation prefix | 45 | # cross-compilation prefix |
45 | CROSS= | 46 | CROSS= |
@@ -136,6 +137,14 @@ if [ -z "$kernel" ]; then | |||
136 | kernel=vmlinux | 137 | kernel=vmlinux |
137 | fi | 138 | fi |
138 | 139 | ||
140 | elfformat="`${CROSS}objdump -p "$kernel" | grep 'file format' | awk '{print $4}'`" | ||
141 | case "$elfformat" in | ||
142 | elf64-powerpcle) format=elf64lppc ;; | ||
143 | elf64-powerpc) format=elf32ppc ;; | ||
144 | elf32-powerpc) format=elf32ppc ;; | ||
145 | esac | ||
146 | |||
147 | |||
139 | platformo=$object/"$platform".o | 148 | platformo=$object/"$platform".o |
140 | lds=$object/zImage.lds | 149 | lds=$object/zImage.lds |
141 | ext=strip | 150 | ext=strip |
@@ -152,8 +161,12 @@ of) | |||
152 | make_space=n | 161 | make_space=n |
153 | ;; | 162 | ;; |
154 | pseries) | 163 | pseries) |
155 | platformo="$object/of.o $object/epapr.o" | 164 | platformo="$object/pseries-head.o $object/of.o $object/epapr.o" |
156 | link_address='0x4000000' | 165 | link_address='0x4000000' |
166 | if [ "$format" != "elf32ppc" ]; then | ||
167 | link_address= | ||
168 | pie=-pie | ||
169 | fi | ||
157 | make_space=n | 170 | make_space=n |
158 | ;; | 171 | ;; |
159 | maple) | 172 | maple) |
@@ -257,6 +270,9 @@ gamecube|wii) | |||
257 | treeboot-currituck) | 270 | treeboot-currituck) |
258 | link_address='0x1000000' | 271 | link_address='0x1000000' |
259 | ;; | 272 | ;; |
273 | treeboot-akebono) | ||
274 | link_address='0x1000000' | ||
275 | ;; | ||
260 | treeboot-iss4xx-mpic) | 276 | treeboot-iss4xx-mpic) |
261 | platformo="$object/treeboot-iss4xx.o" | 277 | platformo="$object/treeboot-iss4xx.o" |
262 | ;; | 278 | ;; |
@@ -379,7 +395,7 @@ if [ "$platform" != "miboot" ]; then | |||
379 | if [ -n "$link_address" ] ; then | 395 | if [ -n "$link_address" ] ; then |
380 | text_start="-Ttext $link_address" | 396 | text_start="-Ttext $link_address" |
381 | fi | 397 | fi |
382 | ${CROSS}ld -m elf32ppc -T $lds $text_start $pie -o "$ofile" \ | 398 | ${CROSS}ld -m $format -T $lds $text_start $pie -o "$ofile" \ |
383 | $platformo $tmp $object/wrapper.a | 399 | $platformo $tmp $object/wrapper.a |
384 | rm $tmp | 400 | rm $tmp |
385 | fi | 401 | fi |
diff --git a/arch/powerpc/boot/zImage.lds.S b/arch/powerpc/boot/zImage.lds.S index 2bd8731f1365..861e72109df2 100644 --- a/arch/powerpc/boot/zImage.lds.S +++ b/arch/powerpc/boot/zImage.lds.S | |||
@@ -1,4 +1,10 @@ | |||
1 | #include <asm-generic/vmlinux.lds.h> | ||
2 | |||
3 | #ifdef CONFIG_PPC64_BOOT_WRAPPER | ||
4 | OUTPUT_ARCH(powerpc:common64) | ||
5 | #else | ||
1 | OUTPUT_ARCH(powerpc:common) | 6 | OUTPUT_ARCH(powerpc:common) |
7 | #endif | ||
2 | ENTRY(_zimage_start) | 8 | ENTRY(_zimage_start) |
3 | EXTERN(_zimage_start) | 9 | EXTERN(_zimage_start) |
4 | SECTIONS | 10 | SECTIONS |
@@ -16,7 +22,9 @@ SECTIONS | |||
16 | *(.rodata*) | 22 | *(.rodata*) |
17 | *(.data*) | 23 | *(.data*) |
18 | *(.sdata*) | 24 | *(.sdata*) |
25 | #ifndef CONFIG_PPC64_BOOT_WRAPPER | ||
19 | *(.got2) | 26 | *(.got2) |
27 | #endif | ||
20 | } | 28 | } |
21 | .dynsym : { *(.dynsym) } | 29 | .dynsym : { *(.dynsym) } |
22 | .dynstr : { *(.dynstr) } | 30 | .dynstr : { *(.dynstr) } |
@@ -27,7 +35,13 @@ SECTIONS | |||
27 | } | 35 | } |
28 | .hash : { *(.hash) } | 36 | .hash : { *(.hash) } |
29 | .interp : { *(.interp) } | 37 | .interp : { *(.interp) } |
30 | .rela.dyn : { *(.rela*) } | 38 | .rela.dyn : |
39 | { | ||
40 | #ifdef CONFIG_PPC64_BOOT_WRAPPER | ||
41 | __rela_dyn_start = .; | ||
42 | #endif | ||
43 | *(.rela*) | ||
44 | } | ||
31 | 45 | ||
32 | . = ALIGN(8); | 46 | . = ALIGN(8); |
33 | .kernel:dtb : | 47 | .kernel:dtb : |
@@ -53,6 +67,15 @@ SECTIONS | |||
53 | _initrd_end = .; | 67 | _initrd_end = .; |
54 | } | 68 | } |
55 | 69 | ||
70 | #ifdef CONFIG_PPC64_BOOT_WRAPPER | ||
71 | .got : | ||
72 | { | ||
73 | __toc_start = .; | ||
74 | *(.got) | ||
75 | *(.toc) | ||
76 | } | ||
77 | #endif | ||
78 | |||
56 | . = ALIGN(4096); | 79 | . = ALIGN(4096); |
57 | .bss : | 80 | .bss : |
58 | { | 81 | { |
diff --git a/arch/powerpc/configs/44x/akebono_defconfig b/arch/powerpc/configs/44x/akebono_defconfig new file mode 100644 index 000000000000..7e2530cd9d30 --- /dev/null +++ b/arch/powerpc/configs/44x/akebono_defconfig | |||
@@ -0,0 +1,148 @@ | |||
1 | CONFIG_44x=y | ||
2 | CONFIG_SMP=y | ||
3 | CONFIG_SYSVIPC=y | ||
4 | CONFIG_POSIX_MQUEUE=y | ||
5 | CONFIG_LOG_BUF_SHIFT=14 | ||
6 | CONFIG_BLK_DEV_INITRD=y | ||
7 | CONFIG_RD_BZIP2=y | ||
8 | CONFIG_RD_LZMA=y | ||
9 | CONFIG_RD_XZ=y | ||
10 | CONFIG_EXPERT=y | ||
11 | CONFIG_KALLSYMS_ALL=y | ||
12 | # CONFIG_SLUB_CPU_PARTIAL is not set | ||
13 | CONFIG_PROFILING=y | ||
14 | CONFIG_OPROFILE=y | ||
15 | CONFIG_MODULES=y | ||
16 | CONFIG_MODULE_UNLOAD=y | ||
17 | # CONFIG_BLK_DEV_BSG is not set | ||
18 | # CONFIG_POWERNV_MSI is not set | ||
19 | CONFIG_PPC_47x=y | ||
20 | # CONFIG_EBONY is not set | ||
21 | CONFIG_AKEBONO=y | ||
22 | CONFIG_HIGHMEM=y | ||
23 | CONFIG_HZ_100=y | ||
24 | CONFIG_IRQ_ALL_CPUS=y | ||
25 | # CONFIG_COMPACTION is not set | ||
26 | CONFIG_CMDLINE_BOOL=y | ||
27 | CONFIG_CMDLINE="" | ||
28 | # CONFIG_SUSPEND is not set | ||
29 | CONFIG_PCI_MSI=y | ||
30 | CONFIG_NET=y | ||
31 | CONFIG_PACKET=y | ||
32 | CONFIG_UNIX=y | ||
33 | CONFIG_INET=y | ||
34 | CONFIG_IP_PNP=y | ||
35 | CONFIG_IP_PNP_DHCP=y | ||
36 | CONFIG_IP_PNP_BOOTP=y | ||
37 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
38 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
39 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
40 | # CONFIG_INET_LRO is not set | ||
41 | # CONFIG_IPV6 is not set | ||
42 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
43 | CONFIG_DEVTMPFS=y | ||
44 | CONFIG_DEVTMPFS_MOUNT=y | ||
45 | CONFIG_CONNECTOR=y | ||
46 | CONFIG_MTD=y | ||
47 | CONFIG_MTD_BLOCK=y | ||
48 | CONFIG_MTD_JEDECPROBE=y | ||
49 | CONFIG_MTD_CFI_AMDSTD=y | ||
50 | CONFIG_MTD_PHYSMAP_OF=y | ||
51 | CONFIG_PROC_DEVICETREE=y | ||
52 | CONFIG_BLK_DEV_RAM=y | ||
53 | CONFIG_BLK_DEV_RAM_SIZE=35000 | ||
54 | # CONFIG_SCSI_PROC_FS is not set | ||
55 | CONFIG_BLK_DEV_SD=y | ||
56 | # CONFIG_SCSI_LOWLEVEL is not set | ||
57 | # CONFIG_SATA_PMP is not set | ||
58 | # CONFIG_ATA_SFF is not set | ||
59 | # CONFIG_NET_VENDOR_3COM is not set | ||
60 | # CONFIG_NET_VENDOR_ADAPTEC is not set | ||
61 | # CONFIG_NET_VENDOR_ALTEON is not set | ||
62 | # CONFIG_NET_VENDOR_AMD is not set | ||
63 | # CONFIG_NET_VENDOR_ARC is not set | ||
64 | # CONFIG_NET_VENDOR_ATHEROS is not set | ||
65 | # CONFIG_NET_CADENCE is not set | ||
66 | # CONFIG_NET_VENDOR_BROADCOM is not set | ||
67 | # CONFIG_NET_VENDOR_BROCADE is not set | ||
68 | # CONFIG_NET_VENDOR_CHELSIO is not set | ||
69 | # CONFIG_NET_VENDOR_CISCO is not set | ||
70 | # CONFIG_NET_VENDOR_DEC is not set | ||
71 | # CONFIG_NET_VENDOR_DLINK is not set | ||
72 | # CONFIG_NET_VENDOR_EMULEX is not set | ||
73 | # CONFIG_NET_VENDOR_EXAR is not set | ||
74 | # CONFIG_NET_VENDOR_HP is not set | ||
75 | CONFIG_IBM_EMAC=y | ||
76 | # CONFIG_NET_VENDOR_MARVELL is not set | ||
77 | # CONFIG_NET_VENDOR_MELLANOX is not set | ||
78 | # CONFIG_NET_VENDOR_MICREL is not set | ||
79 | # CONFIG_NET_VENDOR_MYRI is not set | ||
80 | # CONFIG_NET_VENDOR_NATSEMI is not set | ||
81 | # CONFIG_NET_VENDOR_NVIDIA is not set | ||
82 | # CONFIG_NET_VENDOR_OKI is not set | ||
83 | # CONFIG_NET_VENDOR_QLOGIC is not set | ||
84 | # CONFIG_NET_VENDOR_REALTEK is not set | ||
85 | # CONFIG_NET_VENDOR_RDC is not set | ||
86 | # CONFIG_NET_VENDOR_SEEQ is not set | ||
87 | # CONFIG_NET_VENDOR_SILAN is not set | ||
88 | # CONFIG_NET_VENDOR_SIS is not set | ||
89 | # CONFIG_NET_VENDOR_SMSC is not set | ||
90 | # CONFIG_NET_VENDOR_STMICRO is not set | ||
91 | # CONFIG_NET_VENDOR_SUN is not set | ||
92 | # CONFIG_NET_VENDOR_TEHUTI is not set | ||
93 | # CONFIG_NET_VENDOR_TI is not set | ||
94 | # CONFIG_NET_VENDOR_VIA is not set | ||
95 | # CONFIG_NET_VENDOR_WIZNET is not set | ||
96 | # CONFIG_NET_VENDOR_XILINX is not set | ||
97 | # CONFIG_KEYBOARD_ATKBD is not set | ||
98 | # CONFIG_MOUSE_PS2 is not set | ||
99 | # CONFIG_SERIO is not set | ||
100 | # CONFIG_VT is not set | ||
101 | CONFIG_SERIAL_8250=y | ||
102 | # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set | ||
103 | CONFIG_SERIAL_8250_CONSOLE=y | ||
104 | CONFIG_SERIAL_8250_EXTENDED=y | ||
105 | CONFIG_SERIAL_8250_SHARE_IRQ=y | ||
106 | CONFIG_SERIAL_OF_PLATFORM=y | ||
107 | # CONFIG_HW_RANDOM is not set | ||
108 | CONFIG_I2C_CHARDEV=y | ||
109 | # CONFIG_HWMON is not set | ||
110 | CONFIG_THERMAL=y | ||
111 | # CONFIG_USB_DEFAULT_PERSIST is not set | ||
112 | CONFIG_USB_EHCI_HCD=y | ||
113 | CONFIG_USB_OHCI_HCD=y | ||
114 | # CONFIG_USB_OHCI_HCD_PCI is not set | ||
115 | CONFIG_USB_STORAGE=y | ||
116 | CONFIG_MMC=y | ||
117 | CONFIG_RTC_CLASS=y | ||
118 | CONFIG_RTC_DRV_M41T80=y | ||
119 | CONFIG_EXT2_FS=y | ||
120 | CONFIG_EXT3_FS=y | ||
121 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
122 | CONFIG_EXT3_FS_POSIX_ACL=y | ||
123 | CONFIG_EXT3_FS_SECURITY=y | ||
124 | # CONFIG_DNOTIFY is not set | ||
125 | # CONFIG_INOTIFY_USER is not set | ||
126 | CONFIG_VFAT_FS=y | ||
127 | CONFIG_PROC_KCORE=y | ||
128 | CONFIG_TMPFS=y | ||
129 | CONFIG_CRAMFS=y | ||
130 | # CONFIG_NETWORK_FILESYSTEMS is not set | ||
131 | CONFIG_NLS_DEFAULT="n" | ||
132 | CONFIG_NLS_CODEPAGE_437=y | ||
133 | CONFIG_NLS_ISO8859_1=y | ||
134 | CONFIG_DEBUG_INFO=y | ||
135 | CONFIG_DEBUG_FS=y | ||
136 | CONFIG_MAGIC_SYSRQ=y | ||
137 | CONFIG_DETECT_HUNG_TASK=y | ||
138 | CONFIG_XMON=y | ||
139 | CONFIG_XMON_DEFAULT=y | ||
140 | CONFIG_PPC_EARLY_DEBUG=y | ||
141 | CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0x00010000 | ||
142 | CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x33f | ||
143 | CONFIG_CRYPTO_PCBC=y | ||
144 | CONFIG_CRYPTO_MD5=y | ||
145 | CONFIG_CRYPTO_SHA1_PPC=y | ||
146 | CONFIG_CRYPTO_DES=y | ||
147 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
148 | # CONFIG_CRYPTO_HW is not set | ||
diff --git a/arch/powerpc/configs/85xx/kmp204x_defconfig b/arch/powerpc/configs/85xx/kmp204x_defconfig new file mode 100644 index 000000000000..e9a81e5ba273 --- /dev/null +++ b/arch/powerpc/configs/85xx/kmp204x_defconfig | |||
@@ -0,0 +1,225 @@ | |||
1 | CONFIG_PPC_85xx=y | ||
2 | CONFIG_SMP=y | ||
3 | CONFIG_NR_CPUS=8 | ||
4 | CONFIG_SYSVIPC=y | ||
5 | CONFIG_POSIX_MQUEUE=y | ||
6 | CONFIG_AUDIT=y | ||
7 | CONFIG_NO_HZ=y | ||
8 | CONFIG_HIGH_RES_TIMERS=y | ||
9 | CONFIG_BSD_PROCESS_ACCT=y | ||
10 | CONFIG_IKCONFIG=y | ||
11 | CONFIG_IKCONFIG_PROC=y | ||
12 | CONFIG_LOG_BUF_SHIFT=14 | ||
13 | CONFIG_CGROUPS=y | ||
14 | CONFIG_CGROUP_SCHED=y | ||
15 | CONFIG_RELAY=y | ||
16 | CONFIG_BLK_DEV_INITRD=y | ||
17 | CONFIG_KALLSYMS_ALL=y | ||
18 | CONFIG_EMBEDDED=y | ||
19 | CONFIG_PERF_EVENTS=y | ||
20 | CONFIG_SLAB=y | ||
21 | CONFIG_MODULES=y | ||
22 | CONFIG_MODULE_UNLOAD=y | ||
23 | CONFIG_MODULE_FORCE_UNLOAD=y | ||
24 | CONFIG_MODVERSIONS=y | ||
25 | # CONFIG_BLK_DEV_BSG is not set | ||
26 | CONFIG_PARTITION_ADVANCED=y | ||
27 | CONFIG_MAC_PARTITION=y | ||
28 | CONFIG_CORENET_GENERIC=y | ||
29 | CONFIG_MPIC_MSGR=y | ||
30 | CONFIG_HIGHMEM=y | ||
31 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
32 | CONFIG_BINFMT_MISC=m | ||
33 | CONFIG_KEXEC=y | ||
34 | CONFIG_FORCE_MAX_ZONEORDER=13 | ||
35 | CONFIG_PCI=y | ||
36 | CONFIG_PCIEPORTBUS=y | ||
37 | # CONFIG_PCIEASPM is not set | ||
38 | CONFIG_PCI_MSI=y | ||
39 | CONFIG_ADVANCED_OPTIONS=y | ||
40 | CONFIG_LOWMEM_SIZE_BOOL=y | ||
41 | CONFIG_LOWMEM_SIZE=0x20000000 | ||
42 | CONFIG_NET=y | ||
43 | CONFIG_PACKET=y | ||
44 | CONFIG_UNIX=y | ||
45 | CONFIG_XFRM_USER=y | ||
46 | CONFIG_XFRM_SUB_POLICY=y | ||
47 | CONFIG_XFRM_STATISTICS=y | ||
48 | CONFIG_NET_KEY=y | ||
49 | CONFIG_NET_KEY_MIGRATE=y | ||
50 | CONFIG_INET=y | ||
51 | CONFIG_IP_MULTICAST=y | ||
52 | CONFIG_IP_ADVANCED_ROUTER=y | ||
53 | CONFIG_IP_MULTIPLE_TABLES=y | ||
54 | CONFIG_IP_ROUTE_MULTIPATH=y | ||
55 | CONFIG_IP_ROUTE_VERBOSE=y | ||
56 | CONFIG_IP_PNP=y | ||
57 | CONFIG_IP_PNP_DHCP=y | ||
58 | CONFIG_IP_PNP_BOOTP=y | ||
59 | CONFIG_IP_PNP_RARP=y | ||
60 | CONFIG_NET_IPIP=y | ||
61 | CONFIG_IP_MROUTE=y | ||
62 | CONFIG_IP_PIMSM_V1=y | ||
63 | CONFIG_IP_PIMSM_V2=y | ||
64 | CONFIG_INET_AH=y | ||
65 | CONFIG_INET_ESP=y | ||
66 | CONFIG_INET_IPCOMP=y | ||
67 | # CONFIG_INET_LRO is not set | ||
68 | CONFIG_IPV6=y | ||
69 | CONFIG_IP_SCTP=m | ||
70 | CONFIG_TIPC=y | ||
71 | CONFIG_NET_SCHED=y | ||
72 | CONFIG_NET_SCH_CBQ=y | ||
73 | CONFIG_NET_SCH_HTB=y | ||
74 | CONFIG_NET_SCH_HFSC=y | ||
75 | CONFIG_NET_SCH_PRIO=y | ||
76 | CONFIG_NET_SCH_MULTIQ=y | ||
77 | CONFIG_NET_SCH_RED=y | ||
78 | CONFIG_NET_SCH_SFQ=y | ||
79 | CONFIG_NET_SCH_TEQL=y | ||
80 | CONFIG_NET_SCH_TBF=y | ||
81 | CONFIG_NET_SCH_GRED=y | ||
82 | CONFIG_NET_CLS_BASIC=y | ||
83 | CONFIG_NET_CLS_TCINDEX=y | ||
84 | CONFIG_NET_CLS_U32=y | ||
85 | CONFIG_CLS_U32_PERF=y | ||
86 | CONFIG_CLS_U32_MARK=y | ||
87 | CONFIG_NET_CLS_FLOW=y | ||
88 | CONFIG_NET_CLS_CGROUP=y | ||
89 | CONFIG_UEVENT_HELPER_PATH="/sbin/mdev" | ||
90 | CONFIG_DEVTMPFS=y | ||
91 | CONFIG_MTD=y | ||
92 | CONFIG_MTD_CMDLINE_PARTS=y | ||
93 | CONFIG_MTD_BLOCK=y | ||
94 | CONFIG_MTD_CFI=y | ||
95 | CONFIG_MTD_CFI_AMDSTD=y | ||
96 | CONFIG_MTD_PHYSMAP_OF=y | ||
97 | CONFIG_MTD_M25P80=y | ||
98 | CONFIG_MTD_PHRAM=y | ||
99 | CONFIG_MTD_NAND=y | ||
100 | CONFIG_MTD_NAND_ECC_BCH=y | ||
101 | CONFIG_MTD_NAND_FSL_ELBC=y | ||
102 | CONFIG_MTD_UBI=y | ||
103 | CONFIG_MTD_UBI_GLUEBI=y | ||
104 | CONFIG_BLK_DEV_LOOP=y | ||
105 | CONFIG_BLK_DEV_RAM=y | ||
106 | CONFIG_BLK_DEV_RAM_COUNT=2 | ||
107 | CONFIG_BLK_DEV_RAM_SIZE=2048 | ||
108 | CONFIG_EEPROM_AT24=y | ||
109 | CONFIG_SCSI=y | ||
110 | CONFIG_BLK_DEV_SD=y | ||
111 | CONFIG_CHR_DEV_ST=y | ||
112 | CONFIG_BLK_DEV_SR=y | ||
113 | CONFIG_CHR_DEV_SG=y | ||
114 | CONFIG_SCSI_MULTI_LUN=y | ||
115 | CONFIG_SCSI_LOGGING=y | ||
116 | CONFIG_SCSI_SYM53C8XX_2=y | ||
117 | CONFIG_NETDEVICES=y | ||
118 | # CONFIG_NET_VENDOR_3COM is not set | ||
119 | # CONFIG_NET_VENDOR_ADAPTEC is not set | ||
120 | # CONFIG_NET_VENDOR_ALTEON is not set | ||
121 | # CONFIG_NET_VENDOR_AMD is not set | ||
122 | # CONFIG_NET_VENDOR_ATHEROS is not set | ||
123 | # CONFIG_NET_CADENCE is not set | ||
124 | # CONFIG_NET_VENDOR_BROADCOM is not set | ||
125 | # CONFIG_NET_VENDOR_BROCADE is not set | ||
126 | # CONFIG_NET_VENDOR_CHELSIO is not set | ||
127 | # CONFIG_NET_VENDOR_CISCO is not set | ||
128 | # CONFIG_NET_VENDOR_DEC is not set | ||
129 | # CONFIG_NET_VENDOR_DLINK is not set | ||
130 | # CONFIG_NET_VENDOR_EMULEX is not set | ||
131 | # CONFIG_NET_VENDOR_EXAR is not set | ||
132 | CONFIG_FSL_PQ_MDIO=y | ||
133 | CONFIG_FSL_XGMAC_MDIO=y | ||
134 | # CONFIG_NET_VENDOR_HP is not set | ||
135 | # CONFIG_NET_VENDOR_INTEL is not set | ||
136 | # CONFIG_NET_VENDOR_MARVELL is not set | ||
137 | # CONFIG_NET_VENDOR_MELLANOX is not set | ||
138 | # CONFIG_NET_VENDOR_MICREL is not set | ||
139 | # CONFIG_NET_VENDOR_MICROCHIP is not set | ||
140 | # CONFIG_NET_VENDOR_MYRI is not set | ||
141 | # CONFIG_NET_VENDOR_NATSEMI is not set | ||
142 | # CONFIG_NET_VENDOR_NVIDIA is not set | ||
143 | # CONFIG_NET_VENDOR_OKI is not set | ||
144 | # CONFIG_NET_PACKET_ENGINE is not set | ||
145 | # CONFIG_NET_VENDOR_QLOGIC is not set | ||
146 | # CONFIG_NET_VENDOR_REALTEK is not set | ||
147 | # CONFIG_NET_VENDOR_RDC is not set | ||
148 | # CONFIG_NET_VENDOR_SEEQ is not set | ||
149 | # CONFIG_NET_VENDOR_SILAN is not set | ||
150 | # CONFIG_NET_VENDOR_SIS is not set | ||
151 | # CONFIG_NET_VENDOR_SMSC is not set | ||
152 | # CONFIG_NET_VENDOR_STMICRO is not set | ||
153 | # CONFIG_NET_VENDOR_SUN is not set | ||
154 | # CONFIG_NET_VENDOR_TEHUTI is not set | ||
155 | # CONFIG_NET_VENDOR_TI is not set | ||
156 | # CONFIG_NET_VENDOR_VIA is not set | ||
157 | # CONFIG_NET_VENDOR_WIZNET is not set | ||
158 | # CONFIG_NET_VENDOR_XILINX is not set | ||
159 | CONFIG_MARVELL_PHY=y | ||
160 | CONFIG_VITESSE_PHY=y | ||
161 | CONFIG_FIXED_PHY=y | ||
162 | # CONFIG_WLAN is not set | ||
163 | # CONFIG_INPUT_MOUSEDEV is not set | ||
164 | # CONFIG_INPUT_KEYBOARD is not set | ||
165 | # CONFIG_INPUT_MOUSE is not set | ||
166 | CONFIG_SERIO_LIBPS2=y | ||
167 | # CONFIG_LEGACY_PTYS is not set | ||
168 | CONFIG_PPC_EPAPR_HV_BYTECHAN=y | ||
169 | CONFIG_SERIAL_8250=y | ||
170 | CONFIG_SERIAL_8250_CONSOLE=y | ||
171 | CONFIG_SERIAL_8250_MANY_PORTS=y | ||
172 | CONFIG_SERIAL_8250_DETECT_IRQ=y | ||
173 | CONFIG_SERIAL_8250_RSA=y | ||
174 | CONFIG_NVRAM=y | ||
175 | CONFIG_I2C=y | ||
176 | CONFIG_I2C_CHARDEV=y | ||
177 | CONFIG_I2C_MUX=y | ||
178 | CONFIG_I2C_MUX_PCA954x=y | ||
179 | CONFIG_I2C_MPC=y | ||
180 | CONFIG_SPI=y | ||
181 | CONFIG_SPI_FSL_SPI=y | ||
182 | CONFIG_SPI_FSL_ESPI=y | ||
183 | CONFIG_SPI_SPIDEV=m | ||
184 | CONFIG_PTP_1588_CLOCK=y | ||
185 | # CONFIG_HWMON is not set | ||
186 | # CONFIG_USB_SUPPORT is not set | ||
187 | CONFIG_EDAC=y | ||
188 | CONFIG_EDAC_MM_EDAC=y | ||
189 | CONFIG_EDAC_MPC85XX=y | ||
190 | CONFIG_RTC_CLASS=y | ||
191 | CONFIG_RTC_DRV_DS3232=y | ||
192 | CONFIG_RTC_DRV_CMOS=y | ||
193 | CONFIG_UIO=y | ||
194 | CONFIG_STAGING=y | ||
195 | # CONFIG_NET_VENDOR_SILICOM is not set | ||
196 | CONFIG_CLK_PPC_CORENET=y | ||
197 | CONFIG_EXT2_FS=y | ||
198 | CONFIG_NTFS_FS=y | ||
199 | CONFIG_PROC_KCORE=y | ||
200 | CONFIG_TMPFS=y | ||
201 | CONFIG_JFFS2_FS=y | ||
202 | CONFIG_UBIFS_FS=y | ||
203 | CONFIG_CRAMFS=y | ||
204 | CONFIG_SQUASHFS=y | ||
205 | CONFIG_SQUASHFS_XZ=y | ||
206 | CONFIG_NFS_FS=y | ||
207 | CONFIG_NFS_V4=y | ||
208 | CONFIG_ROOT_NFS=y | ||
209 | CONFIG_NLS_ISO8859_1=y | ||
210 | CONFIG_NLS_UTF8=m | ||
211 | CONFIG_CRC_ITU_T=m | ||
212 | CONFIG_DEBUG_INFO=y | ||
213 | CONFIG_MAGIC_SYSRQ=y | ||
214 | CONFIG_DEBUG_SHIRQ=y | ||
215 | CONFIG_DETECT_HUNG_TASK=y | ||
216 | CONFIG_SCHEDSTATS=y | ||
217 | CONFIG_RCU_TRACE=y | ||
218 | CONFIG_UPROBE_EVENT=y | ||
219 | CONFIG_CRYPTO_NULL=y | ||
220 | CONFIG_CRYPTO_PCBC=m | ||
221 | CONFIG_CRYPTO_MD4=y | ||
222 | CONFIG_CRYPTO_SHA256=y | ||
223 | CONFIG_CRYPTO_SHA512=y | ||
224 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
225 | CONFIG_CRYPTO_DEV_FSL_CAAM=y | ||
diff --git a/arch/powerpc/configs/corenet32_smp_defconfig b/arch/powerpc/configs/corenet32_smp_defconfig index bbd794deb6eb..c19ff057d0f9 100644 --- a/arch/powerpc/configs/corenet32_smp_defconfig +++ b/arch/powerpc/configs/corenet32_smp_defconfig | |||
@@ -72,6 +72,7 @@ CONFIG_MTD_CMDLINE_PARTS=y | |||
72 | CONFIG_MTD_CHAR=y | 72 | CONFIG_MTD_CHAR=y |
73 | CONFIG_MTD_BLOCK=y | 73 | CONFIG_MTD_BLOCK=y |
74 | CONFIG_MTD_CFI=y | 74 | CONFIG_MTD_CFI=y |
75 | CONFIG_MTD_CFI_INTELEXT=y | ||
75 | CONFIG_MTD_CFI_AMDSTD=y | 76 | CONFIG_MTD_CFI_AMDSTD=y |
76 | CONFIG_MTD_PHYSMAP_OF=y | 77 | CONFIG_MTD_PHYSMAP_OF=y |
77 | CONFIG_MTD_M25P80=y | 78 | CONFIG_MTD_M25P80=y |
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig index 19f0fbe5ba4b..55765c8cb08f 100644 --- a/arch/powerpc/configs/mpc85xx_defconfig +++ b/arch/powerpc/configs/mpc85xx_defconfig | |||
@@ -32,7 +32,6 @@ CONFIG_P1010_RDB=y | |||
32 | CONFIG_P1022_DS=y | 32 | CONFIG_P1022_DS=y |
33 | CONFIG_P1022_RDK=y | 33 | CONFIG_P1022_RDK=y |
34 | CONFIG_P1023_RDB=y | 34 | CONFIG_P1023_RDB=y |
35 | CONFIG_P1023_RDS=y | ||
36 | CONFIG_SOCRATES=y | 35 | CONFIG_SOCRATES=y |
37 | CONFIG_KSI8560=y | 36 | CONFIG_KSI8560=y |
38 | CONFIG_XES_MPC85xx=y | 37 | CONFIG_XES_MPC85xx=y |
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig index 062312e1fe1a..5c6ecdc0f70e 100644 --- a/arch/powerpc/configs/mpc85xx_smp_defconfig +++ b/arch/powerpc/configs/mpc85xx_smp_defconfig | |||
@@ -35,7 +35,6 @@ CONFIG_P1010_RDB=y | |||
35 | CONFIG_P1022_DS=y | 35 | CONFIG_P1022_DS=y |
36 | CONFIG_P1022_RDK=y | 36 | CONFIG_P1022_RDK=y |
37 | CONFIG_P1023_RDB=y | 37 | CONFIG_P1023_RDB=y |
38 | CONFIG_P1023_RDS=y | ||
39 | CONFIG_SOCRATES=y | 38 | CONFIG_SOCRATES=y |
40 | CONFIG_KSI8560=y | 39 | CONFIG_KSI8560=y |
41 | CONFIG_XES_MPC85xx=y | 40 | CONFIG_XES_MPC85xx=y |
diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h index 97e02f985df8..37991e154ef8 100644 --- a/arch/powerpc/include/asm/code-patching.h +++ b/arch/powerpc/include/asm/code-patching.h | |||
@@ -42,15 +42,47 @@ void __patch_exception(int exc, unsigned long addr); | |||
42 | } while (0) | 42 | } while (0) |
43 | #endif | 43 | #endif |
44 | 44 | ||
45 | #define OP_RT_RA_MASK 0xffff0000UL | ||
46 | #define LIS_R2 0x3c020000UL | ||
47 | #define ADDIS_R2_R12 0x3c4c0000UL | ||
48 | #define ADDI_R2_R2 0x38420000UL | ||
49 | |||
45 | static inline unsigned long ppc_function_entry(void *func) | 50 | static inline unsigned long ppc_function_entry(void *func) |
46 | { | 51 | { |
47 | #ifdef CONFIG_PPC64 | 52 | #if defined(CONFIG_PPC64) |
53 | #if defined(_CALL_ELF) && _CALL_ELF == 2 | ||
54 | u32 *insn = func; | ||
55 | |||
56 | /* | ||
57 | * A PPC64 ABIv2 function may have a local and a global entry | ||
58 | * point. We need to use the local entry point when patching | ||
59 | * functions, so identify and step over the global entry point | ||
60 | * sequence. | ||
61 | * | ||
62 | * The global entry point sequence is always of the form: | ||
63 | * | ||
64 | * addis r2,r12,XXXX | ||
65 | * addi r2,r2,XXXX | ||
66 | * | ||
67 | * A linker optimisation may convert the addis to lis: | ||
68 | * | ||
69 | * lis r2,XXXX | ||
70 | * addi r2,r2,XXXX | ||
71 | */ | ||
72 | if ((((*insn & OP_RT_RA_MASK) == ADDIS_R2_R12) || | ||
73 | ((*insn & OP_RT_RA_MASK) == LIS_R2)) && | ||
74 | ((*(insn+1) & OP_RT_RA_MASK) == ADDI_R2_R2)) | ||
75 | return (unsigned long)(insn + 2); | ||
76 | else | ||
77 | return (unsigned long)func; | ||
78 | #else | ||
48 | /* | 79 | /* |
49 | * On PPC64 the function pointer actually points to the function's | 80 | * On PPC64 ABIv1 the function pointer actually points to the |
50 | * descriptor. The first entry in the descriptor is the address | 81 | * function's descriptor. The first entry in the descriptor is the |
51 | * of the function text. | 82 | * address of the function text. |
52 | */ | 83 | */ |
53 | return ((func_descr_t *)func)->entry; | 84 | return ((func_descr_t *)func)->entry; |
85 | #endif | ||
54 | #else | 86 | #else |
55 | return (unsigned long)func; | 87 | return (unsigned long)func; |
56 | #endif | 88 | #endif |
diff --git a/arch/powerpc/include/asm/context_tracking.h b/arch/powerpc/include/asm/context_tracking.h index b6f5a33b8ee2..40014921ffff 100644 --- a/arch/powerpc/include/asm/context_tracking.h +++ b/arch/powerpc/include/asm/context_tracking.h | |||
@@ -2,9 +2,9 @@ | |||
2 | #define _ASM_POWERPC_CONTEXT_TRACKING_H | 2 | #define _ASM_POWERPC_CONTEXT_TRACKING_H |
3 | 3 | ||
4 | #ifdef CONFIG_CONTEXT_TRACKING | 4 | #ifdef CONFIG_CONTEXT_TRACKING |
5 | #define SCHEDULE_USER bl .schedule_user | 5 | #define SCHEDULE_USER bl schedule_user |
6 | #else | 6 | #else |
7 | #define SCHEDULE_USER bl .schedule | 7 | #define SCHEDULE_USER bl schedule |
8 | #endif | 8 | #endif |
9 | 9 | ||
10 | #endif | 10 | #endif |
diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h index ac3eedb9b74a..2bf8e9307be9 100644 --- a/arch/powerpc/include/asm/cputhreads.h +++ b/arch/powerpc/include/asm/cputhreads.h | |||
@@ -18,10 +18,12 @@ | |||
18 | 18 | ||
19 | #ifdef CONFIG_SMP | 19 | #ifdef CONFIG_SMP |
20 | extern int threads_per_core; | 20 | extern int threads_per_core; |
21 | extern int threads_per_subcore; | ||
21 | extern int threads_shift; | 22 | extern int threads_shift; |
22 | extern cpumask_t threads_core_mask; | 23 | extern cpumask_t threads_core_mask; |
23 | #else | 24 | #else |
24 | #define threads_per_core 1 | 25 | #define threads_per_core 1 |
26 | #define threads_per_subcore 1 | ||
25 | #define threads_shift 0 | 27 | #define threads_shift 0 |
26 | #define threads_core_mask (CPU_MASK_CPU0) | 28 | #define threads_core_mask (CPU_MASK_CPU0) |
27 | #endif | 29 | #endif |
@@ -74,6 +76,11 @@ static inline int cpu_thread_in_core(int cpu) | |||
74 | return cpu & (threads_per_core - 1); | 76 | return cpu & (threads_per_core - 1); |
75 | } | 77 | } |
76 | 78 | ||
79 | static inline int cpu_thread_in_subcore(int cpu) | ||
80 | { | ||
81 | return cpu & (threads_per_subcore - 1); | ||
82 | } | ||
83 | |||
77 | static inline int cpu_first_thread_sibling(int cpu) | 84 | static inline int cpu_first_thread_sibling(int cpu) |
78 | { | 85 | { |
79 | return cpu & ~(threads_per_core - 1); | 86 | return cpu & ~(threads_per_core - 1); |
diff --git a/arch/powerpc/include/asm/debug.h b/arch/powerpc/include/asm/debug.h index d2516308ed1e..a954e4975049 100644 --- a/arch/powerpc/include/asm/debug.h +++ b/arch/powerpc/include/asm/debug.h | |||
@@ -46,7 +46,8 @@ static inline int debugger_break_match(struct pt_regs *regs) { return 0; } | |||
46 | static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; } | 46 | static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; } |
47 | #endif | 47 | #endif |
48 | 48 | ||
49 | int set_breakpoint(struct arch_hw_breakpoint *brk); | 49 | void set_breakpoint(struct arch_hw_breakpoint *brk); |
50 | void __set_breakpoint(struct arch_hw_breakpoint *brk); | ||
50 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS | 51 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS |
51 | extern void do_send_trap(struct pt_regs *regs, unsigned long address, | 52 | extern void do_send_trap(struct pt_regs *regs, unsigned long address, |
52 | unsigned long error_code, int signal_code, int brkpt); | 53 | unsigned long error_code, int signal_code, int brkpt); |
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index d4dd41fb951b..b76f58c124ca 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h | |||
@@ -32,6 +32,22 @@ struct device_node; | |||
32 | 32 | ||
33 | #ifdef CONFIG_EEH | 33 | #ifdef CONFIG_EEH |
34 | 34 | ||
35 | /* EEH subsystem flags */ | ||
36 | #define EEH_ENABLED 0x1 /* EEH enabled */ | ||
37 | #define EEH_FORCE_DISABLED 0x2 /* EEH disabled */ | ||
38 | #define EEH_PROBE_MODE_DEV 0x4 /* From PCI device */ | ||
39 | #define EEH_PROBE_MODE_DEVTREE 0x8 /* From device tree */ | ||
40 | |||
41 | /* | ||
42 | * Delay for PE reset, all in ms | ||
43 | * | ||
44 | * PCI specification has reset hold time of 100 milliseconds. | ||
45 | * We have 250 milliseconds here. The PCI bus settlement time | ||
46 | * is specified as 1.5 seconds and we have 1.8 seconds. | ||
47 | */ | ||
48 | #define EEH_PE_RST_HOLD_TIME 250 | ||
49 | #define EEH_PE_RST_SETTLE_TIME 1800 | ||
50 | |||
35 | /* | 51 | /* |
36 | * The struct is used to trace PE related EEH functionality. | 52 | * The struct is used to trace PE related EEH functionality. |
37 | * In theory, there will have one instance of the struct to | 53 | * In theory, there will have one instance of the struct to |
@@ -53,7 +69,7 @@ struct device_node; | |||
53 | 69 | ||
54 | #define EEH_PE_ISOLATED (1 << 0) /* Isolated PE */ | 70 | #define EEH_PE_ISOLATED (1 << 0) /* Isolated PE */ |
55 | #define EEH_PE_RECOVERING (1 << 1) /* Recovering PE */ | 71 | #define EEH_PE_RECOVERING (1 << 1) /* Recovering PE */ |
56 | #define EEH_PE_PHB_DEAD (1 << 2) /* Dead PHB */ | 72 | #define EEH_PE_RESET (1 << 2) /* PE reset in progress */ |
57 | 73 | ||
58 | #define EEH_PE_KEEP (1 << 8) /* Keep PE on hotplug */ | 74 | #define EEH_PE_KEEP (1 << 8) /* Keep PE on hotplug */ |
59 | 75 | ||
@@ -92,6 +108,7 @@ struct eeh_pe { | |||
92 | 108 | ||
93 | #define EEH_DEV_NO_HANDLER (1 << 8) /* No error handler */ | 109 | #define EEH_DEV_NO_HANDLER (1 << 8) /* No error handler */ |
94 | #define EEH_DEV_SYSFS (1 << 9) /* Sysfs created */ | 110 | #define EEH_DEV_SYSFS (1 << 9) /* Sysfs created */ |
111 | #define EEH_DEV_REMOVED (1 << 10) /* Removed permanently */ | ||
95 | 112 | ||
96 | struct eeh_dev { | 113 | struct eeh_dev { |
97 | int mode; /* EEH mode */ | 114 | int mode; /* EEH mode */ |
@@ -99,7 +116,9 @@ struct eeh_dev { | |||
99 | int config_addr; /* Config address */ | 116 | int config_addr; /* Config address */ |
100 | int pe_config_addr; /* PE config address */ | 117 | int pe_config_addr; /* PE config address */ |
101 | u32 config_space[16]; /* Saved PCI config space */ | 118 | u32 config_space[16]; /* Saved PCI config space */ |
102 | u8 pcie_cap; /* Saved PCIe capability */ | 119 | int pcix_cap; /* Saved PCIx capability */ |
120 | int pcie_cap; /* Saved PCIe capability */ | ||
121 | int aer_cap; /* Saved AER capability */ | ||
103 | struct eeh_pe *pe; /* Associated PE */ | 122 | struct eeh_pe *pe; /* Associated PE */ |
104 | struct list_head list; /* Form link list in the PE */ | 123 | struct list_head list; /* Form link list in the PE */ |
105 | struct pci_controller *phb; /* Associated PHB */ | 124 | struct pci_controller *phb; /* Associated PHB */ |
@@ -171,37 +190,40 @@ struct eeh_ops { | |||
171 | int (*restore_config)(struct device_node *dn); | 190 | int (*restore_config)(struct device_node *dn); |
172 | }; | 191 | }; |
173 | 192 | ||
193 | extern int eeh_subsystem_flags; | ||
174 | extern struct eeh_ops *eeh_ops; | 194 | extern struct eeh_ops *eeh_ops; |
175 | extern bool eeh_subsystem_enabled; | ||
176 | extern raw_spinlock_t confirm_error_lock; | 195 | extern raw_spinlock_t confirm_error_lock; |
177 | extern int eeh_probe_mode; | ||
178 | 196 | ||
179 | static inline bool eeh_enabled(void) | 197 | static inline bool eeh_enabled(void) |
180 | { | 198 | { |
181 | return eeh_subsystem_enabled; | 199 | if ((eeh_subsystem_flags & EEH_FORCE_DISABLED) || |
200 | !(eeh_subsystem_flags & EEH_ENABLED)) | ||
201 | return false; | ||
202 | |||
203 | return true; | ||
182 | } | 204 | } |
183 | 205 | ||
184 | static inline void eeh_set_enable(bool mode) | 206 | static inline void eeh_set_enable(bool mode) |
185 | { | 207 | { |
186 | eeh_subsystem_enabled = mode; | 208 | if (mode) |
209 | eeh_subsystem_flags |= EEH_ENABLED; | ||
210 | else | ||
211 | eeh_subsystem_flags &= ~EEH_ENABLED; | ||
187 | } | 212 | } |
188 | 213 | ||
189 | #define EEH_PROBE_MODE_DEV (1<<0) /* From PCI device */ | ||
190 | #define EEH_PROBE_MODE_DEVTREE (1<<1) /* From device tree */ | ||
191 | |||
192 | static inline void eeh_probe_mode_set(int flag) | 214 | static inline void eeh_probe_mode_set(int flag) |
193 | { | 215 | { |
194 | eeh_probe_mode = flag; | 216 | eeh_subsystem_flags |= flag; |
195 | } | 217 | } |
196 | 218 | ||
197 | static inline int eeh_probe_mode_devtree(void) | 219 | static inline int eeh_probe_mode_devtree(void) |
198 | { | 220 | { |
199 | return (eeh_probe_mode == EEH_PROBE_MODE_DEVTREE); | 221 | return (eeh_subsystem_flags & EEH_PROBE_MODE_DEVTREE); |
200 | } | 222 | } |
201 | 223 | ||
202 | static inline int eeh_probe_mode_dev(void) | 224 | static inline int eeh_probe_mode_dev(void) |
203 | { | 225 | { |
204 | return (eeh_probe_mode == EEH_PROBE_MODE_DEV); | 226 | return (eeh_subsystem_flags & EEH_PROBE_MODE_DEV); |
205 | } | 227 | } |
206 | 228 | ||
207 | static inline void eeh_serialize_lock(unsigned long *flags) | 229 | static inline void eeh_serialize_lock(unsigned long *flags) |
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h index 935b5e7a1436..888d8f3f2524 100644 --- a/arch/powerpc/include/asm/elf.h +++ b/arch/powerpc/include/asm/elf.h | |||
@@ -90,6 +90,8 @@ typedef elf_vrregset_t elf_fpxregset_t; | |||
90 | do { \ | 90 | do { \ |
91 | if (((ex).e_flags & 0x3) == 2) \ | 91 | if (((ex).e_flags & 0x3) == 2) \ |
92 | set_thread_flag(TIF_ELF2ABI); \ | 92 | set_thread_flag(TIF_ELF2ABI); \ |
93 | else \ | ||
94 | clear_thread_flag(TIF_ELF2ABI); \ | ||
93 | if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ | 95 | if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ |
94 | set_thread_flag(TIF_32BIT); \ | 96 | set_thread_flag(TIF_32BIT); \ |
95 | else \ | 97 | else \ |
diff --git a/arch/powerpc/include/asm/exception-64e.h b/arch/powerpc/include/asm/exception-64e.h index a563d9afd179..a8b52b61043f 100644 --- a/arch/powerpc/include/asm/exception-64e.h +++ b/arch/powerpc/include/asm/exception-64e.h | |||
@@ -174,10 +174,10 @@ exc_##label##_book3e: | |||
174 | mtlr r16; | 174 | mtlr r16; |
175 | #define TLB_MISS_STATS_D(name) \ | 175 | #define TLB_MISS_STATS_D(name) \ |
176 | addi r9,r13,MMSTAT_DSTATS+name; \ | 176 | addi r9,r13,MMSTAT_DSTATS+name; \ |
177 | bl .tlb_stat_inc; | 177 | bl tlb_stat_inc; |
178 | #define TLB_MISS_STATS_I(name) \ | 178 | #define TLB_MISS_STATS_I(name) \ |
179 | addi r9,r13,MMSTAT_ISTATS+name; \ | 179 | addi r9,r13,MMSTAT_ISTATS+name; \ |
180 | bl .tlb_stat_inc; | 180 | bl tlb_stat_inc; |
181 | #define TLB_MISS_STATS_X(name) \ | 181 | #define TLB_MISS_STATS_X(name) \ |
182 | ld r8,PACA_EXTLB+EX_TLB_ESR(r13); \ | 182 | ld r8,PACA_EXTLB+EX_TLB_ESR(r13); \ |
183 | cmpdi cr2,r8,-1; \ | 183 | cmpdi cr2,r8,-1; \ |
@@ -185,7 +185,7 @@ exc_##label##_book3e: | |||
185 | addi r9,r13,MMSTAT_DSTATS+name; \ | 185 | addi r9,r13,MMSTAT_DSTATS+name; \ |
186 | b 62f; \ | 186 | b 62f; \ |
187 | 61: addi r9,r13,MMSTAT_ISTATS+name; \ | 187 | 61: addi r9,r13,MMSTAT_ISTATS+name; \ |
188 | 62: bl .tlb_stat_inc; | 188 | 62: bl tlb_stat_inc; |
189 | #define TLB_MISS_STATS_SAVE_INFO \ | 189 | #define TLB_MISS_STATS_SAVE_INFO \ |
190 | std r14,EX_TLB_ESR(r12); /* save ESR */ | 190 | std r14,EX_TLB_ESR(r12); /* save ESR */ |
191 | #define TLB_MISS_STATS_SAVE_INFO_BOLTED \ | 191 | #define TLB_MISS_STATS_SAVE_INFO_BOLTED \ |
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index aeaa56cd9b54..8f35cd7d59cc 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h | |||
@@ -517,7 +517,7 @@ label##_relon_hv: \ | |||
517 | #define DISABLE_INTS RECONCILE_IRQ_STATE(r10,r11) | 517 | #define DISABLE_INTS RECONCILE_IRQ_STATE(r10,r11) |
518 | 518 | ||
519 | #define ADD_NVGPRS \ | 519 | #define ADD_NVGPRS \ |
520 | bl .save_nvgprs | 520 | bl save_nvgprs |
521 | 521 | ||
522 | #define RUNLATCH_ON \ | 522 | #define RUNLATCH_ON \ |
523 | BEGIN_FTR_SECTION \ | 523 | BEGIN_FTR_SECTION \ |
diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h index 169d039ed402..e3661872fbea 100644 --- a/arch/powerpc/include/asm/ftrace.h +++ b/arch/powerpc/include/asm/ftrace.h | |||
@@ -61,6 +61,7 @@ struct dyn_arch_ftrace { | |||
61 | #endif | 61 | #endif |
62 | 62 | ||
63 | #if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) && !defined(__ASSEMBLY__) | 63 | #if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) && !defined(__ASSEMBLY__) |
64 | #if !defined(_CALL_ELF) || _CALL_ELF != 2 | ||
64 | #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME | 65 | #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME |
65 | static inline bool arch_syscall_match_sym_name(const char *sym, const char *name) | 66 | static inline bool arch_syscall_match_sym_name(const char *sym, const char *name) |
66 | { | 67 | { |
@@ -72,6 +73,7 @@ static inline bool arch_syscall_match_sym_name(const char *sym, const char *name | |||
72 | */ | 73 | */ |
73 | return !strcmp(sym + 4, name + 3); | 74 | return !strcmp(sym + 4, name + 3); |
74 | } | 75 | } |
76 | #endif | ||
75 | #endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_PPC64 && !__ASSEMBLY__ */ | 77 | #endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_PPC64 && !__ASSEMBLY__ */ |
76 | 78 | ||
77 | #endif /* _ASM_POWERPC_FTRACE */ | 79 | #endif /* _ASM_POWERPC_FTRACE */ |
diff --git a/arch/powerpc/include/asm/hw_breakpoint.h b/arch/powerpc/include/asm/hw_breakpoint.h index eb0f4ac75c4c..ac6432d9be46 100644 --- a/arch/powerpc/include/asm/hw_breakpoint.h +++ b/arch/powerpc/include/asm/hw_breakpoint.h | |||
@@ -79,7 +79,7 @@ static inline void hw_breakpoint_disable(void) | |||
79 | brk.address = 0; | 79 | brk.address = 0; |
80 | brk.type = 0; | 80 | brk.type = 0; |
81 | brk.len = 0; | 81 | brk.len = 0; |
82 | set_breakpoint(&brk); | 82 | __set_breakpoint(&brk); |
83 | } | 83 | } |
84 | extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs); | 84 | extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs); |
85 | 85 | ||
diff --git a/arch/powerpc/include/asm/irqflags.h b/arch/powerpc/include/asm/irqflags.h index f51a5580bfd0..e20eb95429a8 100644 --- a/arch/powerpc/include/asm/irqflags.h +++ b/arch/powerpc/include/asm/irqflags.h | |||
@@ -20,9 +20,9 @@ | |||
20 | */ | 20 | */ |
21 | #define TRACE_WITH_FRAME_BUFFER(func) \ | 21 | #define TRACE_WITH_FRAME_BUFFER(func) \ |
22 | mflr r0; \ | 22 | mflr r0; \ |
23 | stdu r1, -32(r1); \ | 23 | stdu r1, -STACK_FRAME_OVERHEAD(r1); \ |
24 | std r0, 16(r1); \ | 24 | std r0, 16(r1); \ |
25 | stdu r1, -32(r1); \ | 25 | stdu r1, -STACK_FRAME_OVERHEAD(r1); \ |
26 | bl func; \ | 26 | bl func; \ |
27 | ld r1, 0(r1); \ | 27 | ld r1, 0(r1); \ |
28 | ld r1, 0(r1); | 28 | ld r1, 0(r1); |
@@ -36,8 +36,8 @@ | |||
36 | * have to call a C function so call a wrapper that saves all the | 36 | * have to call a C function so call a wrapper that saves all the |
37 | * C-clobbered registers. | 37 | * C-clobbered registers. |
38 | */ | 38 | */ |
39 | #define TRACE_ENABLE_INTS TRACE_WITH_FRAME_BUFFER(.trace_hardirqs_on) | 39 | #define TRACE_ENABLE_INTS TRACE_WITH_FRAME_BUFFER(trace_hardirqs_on) |
40 | #define TRACE_DISABLE_INTS TRACE_WITH_FRAME_BUFFER(.trace_hardirqs_off) | 40 | #define TRACE_DISABLE_INTS TRACE_WITH_FRAME_BUFFER(trace_hardirqs_off) |
41 | 41 | ||
42 | /* | 42 | /* |
43 | * This is used by assembly code to soft-disable interrupts first and | 43 | * This is used by assembly code to soft-disable interrupts first and |
diff --git a/arch/powerpc/include/asm/kprobes.h b/arch/powerpc/include/asm/kprobes.h index 7b6feab6fd26..af15d4d8d604 100644 --- a/arch/powerpc/include/asm/kprobes.h +++ b/arch/powerpc/include/asm/kprobes.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/ptrace.h> | 30 | #include <linux/ptrace.h> |
31 | #include <linux/percpu.h> | 31 | #include <linux/percpu.h> |
32 | #include <asm/probes.h> | 32 | #include <asm/probes.h> |
33 | #include <asm/code-patching.h> | ||
33 | 34 | ||
34 | #define __ARCH_WANT_KPROBES_INSN_SLOT | 35 | #define __ARCH_WANT_KPROBES_INSN_SLOT |
35 | 36 | ||
@@ -56,9 +57,9 @@ typedef ppc_opcode_t kprobe_opcode_t; | |||
56 | if ((colon = strchr(name, ':')) != NULL) { \ | 57 | if ((colon = strchr(name, ':')) != NULL) { \ |
57 | colon++; \ | 58 | colon++; \ |
58 | if (*colon != '\0' && *colon != '.') \ | 59 | if (*colon != '\0' && *colon != '.') \ |
59 | addr = *(kprobe_opcode_t **)addr; \ | 60 | addr = (kprobe_opcode_t *)ppc_function_entry(addr); \ |
60 | } else if (name[0] != '.') \ | 61 | } else if (name[0] != '.') \ |
61 | addr = *(kprobe_opcode_t **)addr; \ | 62 | addr = (kprobe_opcode_t *)ppc_function_entry(addr); \ |
62 | } else { \ | 63 | } else { \ |
63 | char dot_name[KSYM_NAME_LEN]; \ | 64 | char dot_name[KSYM_NAME_LEN]; \ |
64 | dot_name[0] = '.'; \ | 65 | dot_name[0] = '.'; \ |
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 4a7cc453be0b..9c89cdd067a6 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h | |||
@@ -337,6 +337,10 @@ static inline void kvmppc_fast_vcpu_kick(struct kvm_vcpu *vcpu) | |||
337 | vcpu->kvm->arch.kvm_ops->fast_vcpu_kick(vcpu); | 337 | vcpu->kvm->arch.kvm_ops->fast_vcpu_kick(vcpu); |
338 | } | 338 | } |
339 | 339 | ||
340 | extern void kvm_hv_vm_activated(void); | ||
341 | extern void kvm_hv_vm_deactivated(void); | ||
342 | extern bool kvm_hv_mode_active(void); | ||
343 | |||
340 | #else | 344 | #else |
341 | static inline void __init kvm_cma_reserve(void) | 345 | static inline void __init kvm_cma_reserve(void) |
342 | {} | 346 | {} |
@@ -356,6 +360,9 @@ static inline void kvmppc_fast_vcpu_kick(struct kvm_vcpu *vcpu) | |||
356 | { | 360 | { |
357 | kvm_vcpu_kick(vcpu); | 361 | kvm_vcpu_kick(vcpu); |
358 | } | 362 | } |
363 | |||
364 | static inline bool kvm_hv_mode_active(void) { return false; } | ||
365 | |||
359 | #endif | 366 | #endif |
360 | 367 | ||
361 | #ifdef CONFIG_KVM_XICS | 368 | #ifdef CONFIG_KVM_XICS |
diff --git a/arch/powerpc/include/asm/linkage.h b/arch/powerpc/include/asm/linkage.h index b36f650a13ff..e3ad5c72724a 100644 --- a/arch/powerpc/include/asm/linkage.h +++ b/arch/powerpc/include/asm/linkage.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _ASM_POWERPC_LINKAGE_H | 2 | #define _ASM_POWERPC_LINKAGE_H |
3 | 3 | ||
4 | #ifdef CONFIG_PPC64 | 4 | #ifdef CONFIG_PPC64 |
5 | #if !defined(_CALL_ELF) || _CALL_ELF != 2 | ||
5 | #define cond_syscall(x) \ | 6 | #define cond_syscall(x) \ |
6 | asm ("\t.weak " #x "\n\t.set " #x ", sys_ni_syscall\n" \ | 7 | asm ("\t.weak " #x "\n\t.set " #x ", sys_ni_syscall\n" \ |
7 | "\t.weak ." #x "\n\t.set ." #x ", .sys_ni_syscall\n") | 8 | "\t.weak ." #x "\n\t.set ." #x ", .sys_ni_syscall\n") |
@@ -9,5 +10,6 @@ | |||
9 | asm ("\t.globl " #alias "\n\t.set " #alias ", " #name "\n" \ | 10 | asm ("\t.globl " #alias "\n\t.set " #alias ", " #name "\n" \ |
10 | "\t.globl ." #alias "\n\t.set ." #alias ", ." #name) | 11 | "\t.globl ." #alias "\n\t.set ." #alias ", ." #name) |
11 | #endif | 12 | #endif |
13 | #endif | ||
12 | 14 | ||
13 | #endif /* _ASM_POWERPC_LINKAGE_H */ | 15 | #endif /* _ASM_POWERPC_LINKAGE_H */ |
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 5b6c03f1058f..f92b0b54e921 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h | |||
@@ -98,6 +98,9 @@ struct machdep_calls { | |||
98 | void (*iommu_save)(void); | 98 | void (*iommu_save)(void); |
99 | void (*iommu_restore)(void); | 99 | void (*iommu_restore)(void); |
100 | #endif | 100 | #endif |
101 | #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE | ||
102 | unsigned long (*memory_block_size)(void); | ||
103 | #endif | ||
101 | #endif /* CONFIG_PPC64 */ | 104 | #endif /* CONFIG_PPC64 */ |
102 | 105 | ||
103 | void (*pci_dma_dev_setup)(struct pci_dev *dev); | 106 | void (*pci_dma_dev_setup)(struct pci_dev *dev); |
@@ -113,6 +116,8 @@ struct machdep_calls { | |||
113 | /* Optional, may be NULL. */ | 116 | /* Optional, may be NULL. */ |
114 | void (*show_cpuinfo)(struct seq_file *m); | 117 | void (*show_cpuinfo)(struct seq_file *m); |
115 | void (*show_percpuinfo)(struct seq_file *m, int i); | 118 | void (*show_percpuinfo)(struct seq_file *m, int i); |
119 | /* Returns the current operating frequency of "cpu" in Hz */ | ||
120 | unsigned long (*get_proc_freq)(unsigned int cpu); | ||
116 | 121 | ||
117 | void (*init_IRQ)(void); | 122 | void (*init_IRQ)(void); |
118 | 123 | ||
@@ -241,6 +246,9 @@ struct machdep_calls { | |||
241 | /* Called during PCI resource reassignment */ | 246 | /* Called during PCI resource reassignment */ |
242 | resource_size_t (*pcibios_window_alignment)(struct pci_bus *, unsigned long type); | 247 | resource_size_t (*pcibios_window_alignment)(struct pci_bus *, unsigned long type); |
243 | 248 | ||
249 | /* Reset the secondary bus of bridge */ | ||
250 | void (*pcibios_reset_secondary_bus)(struct pci_dev *dev); | ||
251 | |||
244 | /* Called to shutdown machine specific hardware not already controlled | 252 | /* Called to shutdown machine specific hardware not already controlled |
245 | * by other drivers. | 253 | * by other drivers. |
246 | */ | 254 | */ |
diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h index 49fa55bfbac4..dcfcad139bcc 100644 --- a/arch/powerpc/include/asm/module.h +++ b/arch/powerpc/include/asm/module.h | |||
@@ -35,6 +35,7 @@ struct mod_arch_specific { | |||
35 | #ifdef __powerpc64__ | 35 | #ifdef __powerpc64__ |
36 | unsigned int stubs_section; /* Index of stubs section in module */ | 36 | unsigned int stubs_section; /* Index of stubs section in module */ |
37 | unsigned int toc_section; /* What section is the TOC? */ | 37 | unsigned int toc_section; /* What section is the TOC? */ |
38 | bool toc_fixed; /* Have we fixed up .TOC.? */ | ||
38 | #ifdef CONFIG_DYNAMIC_FTRACE | 39 | #ifdef CONFIG_DYNAMIC_FTRACE |
39 | unsigned long toc; | 40 | unsigned long toc; |
40 | unsigned long tramp; | 41 | unsigned long tramp; |
@@ -77,6 +78,9 @@ struct mod_arch_specific { | |||
77 | # endif /* MODULE */ | 78 | # endif /* MODULE */ |
78 | #endif | 79 | #endif |
79 | 80 | ||
81 | bool is_module_trampoline(u32 *insns); | ||
82 | int module_trampoline_target(struct module *mod, u32 *trampoline, | ||
83 | unsigned long *target); | ||
80 | 84 | ||
81 | struct exception_table_entry; | 85 | struct exception_table_entry; |
82 | void sort_ex_table(struct exception_table_entry *start, | 86 | void sort_ex_table(struct exception_table_entry *start, |
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 66ad7a74116f..cb15cbb51600 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h | |||
@@ -154,6 +154,7 @@ extern int opal_enter_rtas(struct rtas_args *args, | |||
154 | #define OPAL_LPC_READ 67 | 154 | #define OPAL_LPC_READ 67 |
155 | #define OPAL_LPC_WRITE 68 | 155 | #define OPAL_LPC_WRITE 68 |
156 | #define OPAL_RETURN_CPU 69 | 156 | #define OPAL_RETURN_CPU 69 |
157 | #define OPAL_REINIT_CPUS 70 | ||
157 | #define OPAL_ELOG_READ 71 | 158 | #define OPAL_ELOG_READ 71 |
158 | #define OPAL_ELOG_WRITE 72 | 159 | #define OPAL_ELOG_WRITE 72 |
159 | #define OPAL_ELOG_ACK 73 | 160 | #define OPAL_ELOG_ACK 73 |
@@ -509,7 +510,7 @@ enum OpalMemErr_DynErrType { | |||
509 | struct OpalMemoryErrorData { | 510 | struct OpalMemoryErrorData { |
510 | enum OpalMemErr_Version version:8; /* 0x00 */ | 511 | enum OpalMemErr_Version version:8; /* 0x00 */ |
511 | enum OpalMemErrType type:8; /* 0x01 */ | 512 | enum OpalMemErrType type:8; /* 0x01 */ |
512 | uint16_t flags; /* 0x02 */ | 513 | __be16 flags; /* 0x02 */ |
513 | uint8_t reserved_1[4]; /* 0x04 */ | 514 | uint8_t reserved_1[4]; /* 0x04 */ |
514 | 515 | ||
515 | union { | 516 | union { |
@@ -517,15 +518,15 @@ struct OpalMemoryErrorData { | |||
517 | struct { | 518 | struct { |
518 | enum OpalMemErr_ResilErrType resil_err_type:8; | 519 | enum OpalMemErr_ResilErrType resil_err_type:8; |
519 | uint8_t reserved_1[7]; | 520 | uint8_t reserved_1[7]; |
520 | uint64_t physical_address_start; | 521 | __be64 physical_address_start; |
521 | uint64_t physical_address_end; | 522 | __be64 physical_address_end; |
522 | } resilience; | 523 | } resilience; |
523 | /* Dynamic memory deallocation error info */ | 524 | /* Dynamic memory deallocation error info */ |
524 | struct { | 525 | struct { |
525 | enum OpalMemErr_DynErrType dyn_err_type:8; | 526 | enum OpalMemErr_DynErrType dyn_err_type:8; |
526 | uint8_t reserved_1[7]; | 527 | uint8_t reserved_1[7]; |
527 | uint64_t physical_address_start; | 528 | __be64 physical_address_start; |
528 | uint64_t physical_address_end; | 529 | __be64 physical_address_end; |
529 | } dyn_dealloc; | 530 | } dyn_dealloc; |
530 | } u; | 531 | } u; |
531 | }; | 532 | }; |
@@ -725,6 +726,11 @@ struct OpalIoPhb3ErrorData { | |||
725 | uint64_t pestB[OPAL_PHB3_NUM_PEST_REGS]; | 726 | uint64_t pestB[OPAL_PHB3_NUM_PEST_REGS]; |
726 | }; | 727 | }; |
727 | 728 | ||
729 | enum { | ||
730 | OPAL_REINIT_CPUS_HILE_BE = (1 << 0), | ||
731 | OPAL_REINIT_CPUS_HILE_LE = (1 << 1), | ||
732 | }; | ||
733 | |||
728 | typedef struct oppanel_line { | 734 | typedef struct oppanel_line { |
729 | const char * line; | 735 | const char * line; |
730 | uint64_t line_len; | 736 | uint64_t line_len; |
@@ -849,6 +855,7 @@ int64_t opal_pci_next_error(uint64_t phb_id, uint64_t *first_frozen_pe, | |||
849 | uint16_t *pci_error_type, uint16_t *severity); | 855 | uint16_t *pci_error_type, uint16_t *severity); |
850 | int64_t opal_pci_poll(uint64_t phb_id); | 856 | int64_t opal_pci_poll(uint64_t phb_id); |
851 | int64_t opal_return_cpu(void); | 857 | int64_t opal_return_cpu(void); |
858 | int64_t opal_reinit_cpus(uint64_t flags); | ||
852 | 859 | ||
853 | int64_t opal_xscom_read(uint32_t gcid, uint64_t pcb_addr, __be64 *val); | 860 | int64_t opal_xscom_read(uint32_t gcid, uint64_t pcb_addr, __be64 *val); |
854 | int64_t opal_xscom_write(uint32_t gcid, uint64_t pcb_addr, uint64_t val); | 861 | int64_t opal_xscom_write(uint32_t gcid, uint64_t pcb_addr, uint64_t val); |
@@ -916,6 +923,7 @@ extern void opal_get_rtc_time(struct rtc_time *tm); | |||
916 | extern unsigned long opal_get_boot_time(void); | 923 | extern unsigned long opal_get_boot_time(void); |
917 | extern void opal_nvram_init(void); | 924 | extern void opal_nvram_init(void); |
918 | extern void opal_flash_init(void); | 925 | extern void opal_flash_init(void); |
926 | extern void opal_flash_term_callback(void); | ||
919 | extern int opal_elog_init(void); | 927 | extern int opal_elog_init(void); |
920 | extern void opal_platform_dump_init(void); | 928 | extern void opal_platform_dump_init(void); |
921 | extern void opal_sys_param_init(void); | 929 | extern void opal_sys_param_init(void); |
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index 8e956a0b6e85..bb0bd25f20d0 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h | |||
@@ -92,7 +92,10 @@ struct paca_struct { | |||
92 | struct slb_shadow *slb_shadow_ptr; | 92 | struct slb_shadow *slb_shadow_ptr; |
93 | struct dtl_entry *dispatch_log; | 93 | struct dtl_entry *dispatch_log; |
94 | struct dtl_entry *dispatch_log_end; | 94 | struct dtl_entry *dispatch_log_end; |
95 | #endif /* CONFIG_PPC_STD_MMU_64 */ | ||
96 | u64 dscr_default; /* per-CPU default DSCR */ | ||
95 | 97 | ||
98 | #ifdef CONFIG_PPC_STD_MMU_64 | ||
96 | /* | 99 | /* |
97 | * Now, starting in cacheline 2, the exception save areas | 100 | * Now, starting in cacheline 2, the exception save areas |
98 | */ | 101 | */ |
diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h index ed57fa7920c8..db1e2b8eff3c 100644 --- a/arch/powerpc/include/asm/ppc-pci.h +++ b/arch/powerpc/include/asm/ppc-pci.h | |||
@@ -58,6 +58,7 @@ int rtas_write_config(struct pci_dn *, int where, int size, u32 val); | |||
58 | int rtas_read_config(struct pci_dn *, int where, int size, u32 *val); | 58 | int rtas_read_config(struct pci_dn *, int where, int size, u32 *val); |
59 | void eeh_pe_state_mark(struct eeh_pe *pe, int state); | 59 | void eeh_pe_state_mark(struct eeh_pe *pe, int state); |
60 | void eeh_pe_state_clear(struct eeh_pe *pe, int state); | 60 | void eeh_pe_state_clear(struct eeh_pe *pe, int state); |
61 | void eeh_pe_dev_mode_mark(struct eeh_pe *pe, int mode); | ||
61 | 62 | ||
62 | void eeh_sysfs_add_device(struct pci_dev *pdev); | 63 | void eeh_sysfs_add_device(struct pci_dev *pdev); |
63 | void eeh_sysfs_remove_device(struct pci_dev *pdev); | 64 | void eeh_sysfs_remove_device(struct pci_dev *pdev); |
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index cded7c1278ef..9ea266eae33e 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h | |||
@@ -57,7 +57,7 @@ BEGIN_FW_FTR_SECTION; \ | |||
57 | LDX_BE r10,0,r10; /* get log write index */ \ | 57 | LDX_BE r10,0,r10; /* get log write index */ \ |
58 | cmpd cr1,r11,r10; \ | 58 | cmpd cr1,r11,r10; \ |
59 | beq+ cr1,33f; \ | 59 | beq+ cr1,33f; \ |
60 | bl .accumulate_stolen_time; \ | 60 | bl accumulate_stolen_time; \ |
61 | ld r12,_MSR(r1); \ | 61 | ld r12,_MSR(r1); \ |
62 | andi. r10,r12,MSR_PR; /* Restore cr0 (coming from user) */ \ | 62 | andi. r10,r12,MSR_PR; /* Restore cr0 (coming from user) */ \ |
63 | 33: \ | 63 | 33: \ |
@@ -189,57 +189,53 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) | |||
189 | #define __STK_REG(i) (112 + ((i)-14)*8) | 189 | #define __STK_REG(i) (112 + ((i)-14)*8) |
190 | #define STK_REG(i) __STK_REG(__REG_##i) | 190 | #define STK_REG(i) __STK_REG(__REG_##i) |
191 | 191 | ||
192 | #if defined(_CALL_ELF) && _CALL_ELF == 2 | ||
193 | #define STK_GOT 24 | ||
194 | #define __STK_PARAM(i) (32 + ((i)-3)*8) | ||
195 | #else | ||
196 | #define STK_GOT 40 | ||
192 | #define __STK_PARAM(i) (48 + ((i)-3)*8) | 197 | #define __STK_PARAM(i) (48 + ((i)-3)*8) |
198 | #endif | ||
193 | #define STK_PARAM(i) __STK_PARAM(__REG_##i) | 199 | #define STK_PARAM(i) __STK_PARAM(__REG_##i) |
194 | 200 | ||
195 | #define XGLUE(a,b) a##b | 201 | #if defined(_CALL_ELF) && _CALL_ELF == 2 |
196 | #define GLUE(a,b) XGLUE(a,b) | ||
197 | 202 | ||
198 | #define _GLOBAL(name) \ | 203 | #define _GLOBAL(name) \ |
199 | .section ".text"; \ | 204 | .section ".text"; \ |
200 | .align 2 ; \ | 205 | .align 2 ; \ |
206 | .type name,@function; \ | ||
201 | .globl name; \ | 207 | .globl name; \ |
202 | .globl GLUE(.,name); \ | 208 | name: |
203 | .section ".opd","aw"; \ | ||
204 | name: \ | ||
205 | .quad GLUE(.,name); \ | ||
206 | .quad .TOC.@tocbase; \ | ||
207 | .quad 0; \ | ||
208 | .previous; \ | ||
209 | .type GLUE(.,name),@function; \ | ||
210 | GLUE(.,name): | ||
211 | 209 | ||
212 | #define _INIT_GLOBAL(name) \ | 210 | #define _GLOBAL_TOC(name) \ |
213 | __REF; \ | 211 | .section ".text"; \ |
214 | .align 2 ; \ | 212 | .align 2 ; \ |
213 | .type name,@function; \ | ||
215 | .globl name; \ | 214 | .globl name; \ |
216 | .globl GLUE(.,name); \ | ||
217 | .section ".opd","aw"; \ | ||
218 | name: \ | 215 | name: \ |
219 | .quad GLUE(.,name); \ | 216 | 0: addis r2,r12,(.TOC.-0b)@ha; \ |
220 | .quad .TOC.@tocbase; \ | 217 | addi r2,r2,(.TOC.-0b)@l; \ |
221 | .quad 0; \ | 218 | .localentry name,.-name |
222 | .previous; \ | ||
223 | .type GLUE(.,name),@function; \ | ||
224 | GLUE(.,name): | ||
225 | 219 | ||
226 | #define _KPROBE(name) \ | 220 | #define _KPROBE(name) \ |
227 | .section ".kprobes.text","a"; \ | 221 | .section ".kprobes.text","a"; \ |
228 | .align 2 ; \ | 222 | .align 2 ; \ |
223 | .type name,@function; \ | ||
229 | .globl name; \ | 224 | .globl name; \ |
230 | .globl GLUE(.,name); \ | 225 | name: |
231 | .section ".opd","aw"; \ | 226 | |
232 | name: \ | 227 | #define DOTSYM(a) a |
233 | .quad GLUE(.,name); \ | 228 | |
234 | .quad .TOC.@tocbase; \ | 229 | #else |
235 | .quad 0; \ | 230 | |
236 | .previous; \ | 231 | #define XGLUE(a,b) a##b |
237 | .type GLUE(.,name),@function; \ | 232 | #define GLUE(a,b) XGLUE(a,b) |
238 | GLUE(.,name): | ||
239 | 233 | ||
240 | #define _STATIC(name) \ | 234 | #define _GLOBAL(name) \ |
241 | .section ".text"; \ | 235 | .section ".text"; \ |
242 | .align 2 ; \ | 236 | .align 2 ; \ |
237 | .globl name; \ | ||
238 | .globl GLUE(.,name); \ | ||
243 | .section ".opd","aw"; \ | 239 | .section ".opd","aw"; \ |
244 | name: \ | 240 | name: \ |
245 | .quad GLUE(.,name); \ | 241 | .quad GLUE(.,name); \ |
@@ -249,9 +245,13 @@ name: \ | |||
249 | .type GLUE(.,name),@function; \ | 245 | .type GLUE(.,name),@function; \ |
250 | GLUE(.,name): | 246 | GLUE(.,name): |
251 | 247 | ||
252 | #define _INIT_STATIC(name) \ | 248 | #define _GLOBAL_TOC(name) _GLOBAL(name) |
253 | __REF; \ | 249 | |
250 | #define _KPROBE(name) \ | ||
251 | .section ".kprobes.text","a"; \ | ||
254 | .align 2 ; \ | 252 | .align 2 ; \ |
253 | .globl name; \ | ||
254 | .globl GLUE(.,name); \ | ||
255 | .section ".opd","aw"; \ | 255 | .section ".opd","aw"; \ |
256 | name: \ | 256 | name: \ |
257 | .quad GLUE(.,name); \ | 257 | .quad GLUE(.,name); \ |
@@ -261,6 +261,10 @@ name: \ | |||
261 | .type GLUE(.,name),@function; \ | 261 | .type GLUE(.,name),@function; \ |
262 | GLUE(.,name): | 262 | GLUE(.,name): |
263 | 263 | ||
264 | #define DOTSYM(a) GLUE(.,a) | ||
265 | |||
266 | #endif | ||
267 | |||
264 | #else /* 32-bit */ | 268 | #else /* 32-bit */ |
265 | 269 | ||
266 | #define _ENTRY(n) \ | 270 | #define _ENTRY(n) \ |
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index d660dc36831a..6d59072e13a7 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h | |||
@@ -449,7 +449,7 @@ extern unsigned long cpuidle_disable; | |||
449 | enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF}; | 449 | enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF}; |
450 | 450 | ||
451 | extern int powersave_nap; /* set if nap mode can be used in idle loop */ | 451 | extern int powersave_nap; /* set if nap mode can be used in idle loop */ |
452 | extern void power7_nap(void); | 452 | extern void power7_nap(int check_irq); |
453 | extern void power7_sleep(void); | 453 | extern void power7_sleep(void); |
454 | extern void flush_instruction_cache(void); | 454 | extern void flush_instruction_cache(void); |
455 | extern void hard_reset_now(void); | 455 | extern void hard_reset_now(void); |
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 4852bcf270f3..bffd89d27301 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
@@ -215,6 +215,7 @@ | |||
215 | #define SPRN_TEXASR 0x82 /* Transaction EXception & Summary */ | 215 | #define SPRN_TEXASR 0x82 /* Transaction EXception & Summary */ |
216 | #define TEXASR_FS __MASK(63-36) /* Transaction Failure Summary */ | 216 | #define TEXASR_FS __MASK(63-36) /* Transaction Failure Summary */ |
217 | #define SPRN_TEXASRU 0x83 /* '' '' '' Upper 32 */ | 217 | #define SPRN_TEXASRU 0x83 /* '' '' '' Upper 32 */ |
218 | #define TEXASR_FS __MASK(63-36) /* TEXASR Failure Summary */ | ||
218 | #define SPRN_TFHAR 0x80 /* Transaction Failure Handler Addr */ | 219 | #define SPRN_TFHAR 0x80 /* Transaction Failure Handler Addr */ |
219 | #define SPRN_CTRLF 0x088 | 220 | #define SPRN_CTRLF 0x088 |
220 | #define SPRN_CTRLT 0x098 | 221 | #define SPRN_CTRLT 0x098 |
@@ -224,6 +225,7 @@ | |||
224 | #define CTRL_TE 0x00c00000 /* thread enable */ | 225 | #define CTRL_TE 0x00c00000 /* thread enable */ |
225 | #define CTRL_RUNLATCH 0x1 | 226 | #define CTRL_RUNLATCH 0x1 |
226 | #define SPRN_DAWR 0xB4 | 227 | #define SPRN_DAWR 0xB4 |
228 | #define SPRN_RPR 0xBA /* Relative Priority Register */ | ||
227 | #define SPRN_CIABR 0xBB | 229 | #define SPRN_CIABR 0xBB |
228 | #define CIABR_PRIV 0x3 | 230 | #define CIABR_PRIV 0x3 |
229 | #define CIABR_PRIV_USER 1 | 231 | #define CIABR_PRIV_USER 1 |
@@ -272,8 +274,10 @@ | |||
272 | #define SPRN_HSRR1 0x13B /* Hypervisor Save/Restore 1 */ | 274 | #define SPRN_HSRR1 0x13B /* Hypervisor Save/Restore 1 */ |
273 | #define SPRN_IC 0x350 /* Virtual Instruction Count */ | 275 | #define SPRN_IC 0x350 /* Virtual Instruction Count */ |
274 | #define SPRN_VTB 0x351 /* Virtual Time Base */ | 276 | #define SPRN_VTB 0x351 /* Virtual Time Base */ |
277 | #define SPRN_LDBAR 0x352 /* LD Base Address Register */ | ||
275 | #define SPRN_PMICR 0x354 /* Power Management Idle Control Reg */ | 278 | #define SPRN_PMICR 0x354 /* Power Management Idle Control Reg */ |
276 | #define SPRN_PMSR 0x355 /* Power Management Status Reg */ | 279 | #define SPRN_PMSR 0x355 /* Power Management Status Reg */ |
280 | #define SPRN_PMMAR 0x356 /* Power Management Memory Activity Register */ | ||
277 | #define SPRN_PMCR 0x374 /* Power Management Control Register */ | 281 | #define SPRN_PMCR 0x374 /* Power Management Control Register */ |
278 | 282 | ||
279 | /* HFSCR and FSCR bit numbers are the same */ | 283 | /* HFSCR and FSCR bit numbers are the same */ |
@@ -433,6 +437,12 @@ | |||
433 | #define HID0_BTCD (1<<1) /* Branch target cache disable */ | 437 | #define HID0_BTCD (1<<1) /* Branch target cache disable */ |
434 | #define HID0_NOPDST (1<<1) /* No-op dst, dstt, etc. instr. */ | 438 | #define HID0_NOPDST (1<<1) /* No-op dst, dstt, etc. instr. */ |
435 | #define HID0_NOPTI (1<<0) /* No-op dcbt and dcbst instr. */ | 439 | #define HID0_NOPTI (1<<0) /* No-op dcbt and dcbst instr. */ |
440 | /* POWER8 HID0 bits */ | ||
441 | #define HID0_POWER8_4LPARMODE __MASK(61) | ||
442 | #define HID0_POWER8_2LPARMODE __MASK(57) | ||
443 | #define HID0_POWER8_1TO2LPAR __MASK(52) | ||
444 | #define HID0_POWER8_1TO4LPAR __MASK(51) | ||
445 | #define HID0_POWER8_DYNLPARDIS __MASK(48) | ||
436 | 446 | ||
437 | #define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */ | 447 | #define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */ |
438 | #ifdef CONFIG_6xx | 448 | #ifdef CONFIG_6xx |
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h index 521790330672..a5e930aca804 100644 --- a/arch/powerpc/include/asm/sections.h +++ b/arch/powerpc/include/asm/sections.h | |||
@@ -50,6 +50,7 @@ static inline int overlaps_kvm_tmp(unsigned long start, unsigned long end) | |||
50 | #endif | 50 | #endif |
51 | } | 51 | } |
52 | 52 | ||
53 | #if !defined(_CALL_ELF) || _CALL_ELF != 2 | ||
53 | #undef dereference_function_descriptor | 54 | #undef dereference_function_descriptor |
54 | static inline void *dereference_function_descriptor(void *ptr) | 55 | static inline void *dereference_function_descriptor(void *ptr) |
55 | { | 56 | { |
@@ -60,6 +61,7 @@ static inline void *dereference_function_descriptor(void *ptr) | |||
60 | ptr = p; | 61 | ptr = p; |
61 | return ptr; | 62 | return ptr; |
62 | } | 63 | } |
64 | #endif | ||
63 | 65 | ||
64 | #endif | 66 | #endif |
65 | 67 | ||
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index ff51046b6466..5a6614a7f0b2 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h | |||
@@ -68,14 +68,6 @@ void generic_mach_cpu_die(void); | |||
68 | void generic_set_cpu_dead(unsigned int cpu); | 68 | void generic_set_cpu_dead(unsigned int cpu); |
69 | void generic_set_cpu_up(unsigned int cpu); | 69 | void generic_set_cpu_up(unsigned int cpu); |
70 | int generic_check_cpu_restart(unsigned int cpu); | 70 | int generic_check_cpu_restart(unsigned int cpu); |
71 | |||
72 | extern void inhibit_secondary_onlining(void); | ||
73 | extern void uninhibit_secondary_onlining(void); | ||
74 | |||
75 | #else /* HOTPLUG_CPU */ | ||
76 | static inline void inhibit_secondary_onlining(void) {} | ||
77 | static inline void uninhibit_secondary_onlining(void) {} | ||
78 | |||
79 | #endif | 71 | #endif |
80 | 72 | ||
81 | #ifdef CONFIG_PPC64 | 73 | #ifdef CONFIG_PPC64 |
diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h index 0dffad6bcc84..e40010abcaf1 100644 --- a/arch/powerpc/include/asm/string.h +++ b/arch/powerpc/include/asm/string.h | |||
@@ -10,9 +10,7 @@ | |||
10 | #define __HAVE_ARCH_STRNCMP | 10 | #define __HAVE_ARCH_STRNCMP |
11 | #define __HAVE_ARCH_STRCAT | 11 | #define __HAVE_ARCH_STRCAT |
12 | #define __HAVE_ARCH_MEMSET | 12 | #define __HAVE_ARCH_MEMSET |
13 | #ifdef __BIG_ENDIAN__ | ||
14 | #define __HAVE_ARCH_MEMCPY | 13 | #define __HAVE_ARCH_MEMCPY |
15 | #endif | ||
16 | #define __HAVE_ARCH_MEMMOVE | 14 | #define __HAVE_ARCH_MEMMOVE |
17 | #define __HAVE_ARCH_MEMCMP | 15 | #define __HAVE_ARCH_MEMCMP |
18 | #define __HAVE_ARCH_MEMCHR | 16 | #define __HAVE_ARCH_MEMCHR |
@@ -24,9 +22,7 @@ extern int strcmp(const char *,const char *); | |||
24 | extern int strncmp(const char *, const char *, __kernel_size_t); | 22 | extern int strncmp(const char *, const char *, __kernel_size_t); |
25 | extern char * strcat(char *, const char *); | 23 | extern char * strcat(char *, const char *); |
26 | extern void * memset(void *,int,__kernel_size_t); | 24 | extern void * memset(void *,int,__kernel_size_t); |
27 | #ifdef __BIG_ENDIAN__ | ||
28 | extern void * memcpy(void *,const void *,__kernel_size_t); | 25 | extern void * memcpy(void *,const void *,__kernel_size_t); |
29 | #endif | ||
30 | extern void * memmove(void *,const void *,__kernel_size_t); | 26 | extern void * memmove(void *,const void *,__kernel_size_t); |
31 | extern int memcmp(const void *,const void *,__kernel_size_t); | 27 | extern int memcmp(const void *,const void *,__kernel_size_t); |
32 | extern void * memchr(const void *,int,__kernel_size_t); | 28 | extern void * memchr(const void *,int,__kernel_size_t); |
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index ea4dc3a89c1f..babbeca6850f 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h | |||
@@ -62,7 +62,7 @@ COMPAT_SYS_SPU(fcntl) | |||
62 | SYSCALL(ni_syscall) | 62 | SYSCALL(ni_syscall) |
63 | SYSCALL_SPU(setpgid) | 63 | SYSCALL_SPU(setpgid) |
64 | SYSCALL(ni_syscall) | 64 | SYSCALL(ni_syscall) |
65 | SYSX(sys_ni_syscall,sys_olduname, sys_olduname) | 65 | SYSX(sys_ni_syscall,sys_olduname,sys_olduname) |
66 | SYSCALL_SPU(umask) | 66 | SYSCALL_SPU(umask) |
67 | SYSCALL_SPU(chroot) | 67 | SYSCALL_SPU(chroot) |
68 | COMPAT_SYS(ustat) | 68 | COMPAT_SYS(ustat) |
@@ -190,7 +190,7 @@ SYSCALL_SPU(getcwd) | |||
190 | SYSCALL_SPU(capget) | 190 | SYSCALL_SPU(capget) |
191 | SYSCALL_SPU(capset) | 191 | SYSCALL_SPU(capset) |
192 | COMPAT_SYS(sigaltstack) | 192 | COMPAT_SYS(sigaltstack) |
193 | COMPAT_SYS_SPU(sendfile) | 193 | SYSX_SPU(sys_sendfile64,compat_sys_sendfile,sys_sendfile) |
194 | SYSCALL(ni_syscall) | 194 | SYSCALL(ni_syscall) |
195 | SYSCALL(ni_syscall) | 195 | SYSCALL(ni_syscall) |
196 | PPC_SYS(vfork) | 196 | PPC_SYS(vfork) |
@@ -258,7 +258,7 @@ SYSCALL_SPU(tgkill) | |||
258 | COMPAT_SYS_SPU(utimes) | 258 | COMPAT_SYS_SPU(utimes) |
259 | COMPAT_SYS_SPU(statfs64) | 259 | COMPAT_SYS_SPU(statfs64) |
260 | COMPAT_SYS_SPU(fstatfs64) | 260 | COMPAT_SYS_SPU(fstatfs64) |
261 | SYSX(sys_ni_syscall, ppc_fadvise64_64, ppc_fadvise64_64) | 261 | SYSX(sys_ni_syscall,ppc_fadvise64_64,ppc_fadvise64_64) |
262 | PPC_SYS_SPU(rtas) | 262 | PPC_SYS_SPU(rtas) |
263 | OLDSYS(debug_setcontext) | 263 | OLDSYS(debug_setcontext) |
264 | SYSCALL(ni_syscall) | 264 | SYSCALL(ni_syscall) |
@@ -295,7 +295,7 @@ SYSCALL_SPU(mkdirat) | |||
295 | SYSCALL_SPU(mknodat) | 295 | SYSCALL_SPU(mknodat) |
296 | SYSCALL_SPU(fchownat) | 296 | SYSCALL_SPU(fchownat) |
297 | COMPAT_SYS_SPU(futimesat) | 297 | COMPAT_SYS_SPU(futimesat) |
298 | SYSX_SPU(sys_newfstatat, sys_fstatat64, sys_fstatat64) | 298 | SYSX_SPU(sys_newfstatat,sys_fstatat64,sys_fstatat64) |
299 | SYSCALL_SPU(unlinkat) | 299 | SYSCALL_SPU(unlinkat) |
300 | SYSCALL_SPU(renameat) | 300 | SYSCALL_SPU(renameat) |
301 | SYSCALL_SPU(linkat) | 301 | SYSCALL_SPU(linkat) |
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index 6c8a8c5a37a1..5f1048eaa5b6 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h | |||
@@ -16,19 +16,6 @@ struct device_node; | |||
16 | 16 | ||
17 | #include <asm/mmzone.h> | 17 | #include <asm/mmzone.h> |
18 | 18 | ||
19 | static inline int cpu_to_node(int cpu) | ||
20 | { | ||
21 | int nid; | ||
22 | |||
23 | nid = numa_cpu_lookup_table[cpu]; | ||
24 | |||
25 | /* | ||
26 | * During early boot, the numa-cpu lookup table might not have been | ||
27 | * setup for all CPUs yet. In such cases, default to node 0. | ||
28 | */ | ||
29 | return (nid < 0) ? 0 : nid; | ||
30 | } | ||
31 | |||
32 | #define parent_node(node) (node) | 19 | #define parent_node(node) (node) |
33 | 20 | ||
34 | #define cpumask_of_node(node) ((node) == -1 ? \ | 21 | #define cpumask_of_node(node) ((node) == -1 ? \ |
diff --git a/arch/powerpc/include/uapi/asm/Kbuild b/arch/powerpc/include/uapi/asm/Kbuild index 48be855ef37b..7a3f795ac218 100644 --- a/arch/powerpc/include/uapi/asm/Kbuild +++ b/arch/powerpc/include/uapi/asm/Kbuild | |||
@@ -15,7 +15,6 @@ header-y += ioctls.h | |||
15 | header-y += ipcbuf.h | 15 | header-y += ipcbuf.h |
16 | header-y += kvm.h | 16 | header-y += kvm.h |
17 | header-y += kvm_para.h | 17 | header-y += kvm_para.h |
18 | header-y += linkage.h | ||
19 | header-y += mman.h | 18 | header-y += mman.h |
20 | header-y += msgbuf.h | 19 | header-y += msgbuf.h |
21 | header-y += nvram.h | 20 | header-y += nvram.h |
diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h index 7e39c9146a71..59dad113897b 100644 --- a/arch/powerpc/include/uapi/asm/elf.h +++ b/arch/powerpc/include/uapi/asm/elf.h | |||
@@ -291,9 +291,17 @@ do { \ | |||
291 | #define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ | 291 | #define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ |
292 | #define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ | 292 | #define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ |
293 | #define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ | 293 | #define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ |
294 | #define R_PPC64_TLSGD 107 | ||
295 | #define R_PPC64_TLSLD 108 | ||
296 | #define R_PPC64_TOCSAVE 109 | ||
297 | |||
298 | #define R_PPC64_REL16 249 | ||
299 | #define R_PPC64_REL16_LO 250 | ||
300 | #define R_PPC64_REL16_HI 251 | ||
301 | #define R_PPC64_REL16_HA 252 | ||
294 | 302 | ||
295 | /* Keep this the last entry. */ | 303 | /* Keep this the last entry. */ |
296 | #define R_PPC64_NUM 107 | 304 | #define R_PPC64_NUM 253 |
297 | 305 | ||
298 | /* There's actually a third entry here, but it's unused */ | 306 | /* There's actually a third entry here, but it's unused */ |
299 | struct ppc64_opd_entry | 307 | struct ppc64_opd_entry |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 93e1465c8496..f5995a912213 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -248,6 +248,7 @@ int main(void) | |||
248 | #endif | 248 | #endif |
249 | DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); | 249 | DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); |
250 | DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state)); | 250 | DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state)); |
251 | DEFINE(PACA_DSCR, offsetof(struct paca_struct, dscr_default)); | ||
251 | DEFINE(PACA_STARTTIME, offsetof(struct paca_struct, starttime)); | 252 | DEFINE(PACA_STARTTIME, offsetof(struct paca_struct, starttime)); |
252 | DEFINE(PACA_STARTTIME_USER, offsetof(struct paca_struct, starttime_user)); | 253 | DEFINE(PACA_STARTTIME_USER, offsetof(struct paca_struct, starttime_user)); |
253 | DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time)); | 254 | DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time)); |
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S index cc2d8962e090..4f1393d20079 100644 --- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S +++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S | |||
@@ -94,12 +94,12 @@ _GLOBAL(setup_altivec_idle) | |||
94 | _GLOBAL(__setup_cpu_e6500) | 94 | _GLOBAL(__setup_cpu_e6500) |
95 | mflr r6 | 95 | mflr r6 |
96 | #ifdef CONFIG_PPC64 | 96 | #ifdef CONFIG_PPC64 |
97 | bl .setup_altivec_ivors | 97 | bl setup_altivec_ivors |
98 | /* Touch IVOR42 only if the CPU supports E.HV category */ | 98 | /* Touch IVOR42 only if the CPU supports E.HV category */ |
99 | mfspr r10,SPRN_MMUCFG | 99 | mfspr r10,SPRN_MMUCFG |
100 | rlwinm. r10,r10,0,MMUCFG_LPIDSIZE | 100 | rlwinm. r10,r10,0,MMUCFG_LPIDSIZE |
101 | beq 1f | 101 | beq 1f |
102 | bl .setup_lrat_ivor | 102 | bl setup_lrat_ivor |
103 | 1: | 103 | 1: |
104 | #endif | 104 | #endif |
105 | bl setup_pw20_idle | 105 | bl setup_pw20_idle |
@@ -164,15 +164,15 @@ _GLOBAL(__setup_cpu_e5500) | |||
164 | #ifdef CONFIG_PPC_BOOK3E_64 | 164 | #ifdef CONFIG_PPC_BOOK3E_64 |
165 | _GLOBAL(__restore_cpu_e6500) | 165 | _GLOBAL(__restore_cpu_e6500) |
166 | mflr r5 | 166 | mflr r5 |
167 | bl .setup_altivec_ivors | 167 | bl setup_altivec_ivors |
168 | /* Touch IVOR42 only if the CPU supports E.HV category */ | 168 | /* Touch IVOR42 only if the CPU supports E.HV category */ |
169 | mfspr r10,SPRN_MMUCFG | 169 | mfspr r10,SPRN_MMUCFG |
170 | rlwinm. r10,r10,0,MMUCFG_LPIDSIZE | 170 | rlwinm. r10,r10,0,MMUCFG_LPIDSIZE |
171 | beq 1f | 171 | beq 1f |
172 | bl .setup_lrat_ivor | 172 | bl setup_lrat_ivor |
173 | 1: | 173 | 1: |
174 | bl .setup_pw20_idle | 174 | bl setup_pw20_idle |
175 | bl .setup_altivec_idle | 175 | bl setup_altivec_idle |
176 | bl __restore_cpu_e5500 | 176 | bl __restore_cpu_e5500 |
177 | mtlr r5 | 177 | mtlr r5 |
178 | blr | 178 | blr |
@@ -181,9 +181,9 @@ _GLOBAL(__restore_cpu_e5500) | |||
181 | mflr r4 | 181 | mflr r4 |
182 | bl __e500_icache_setup | 182 | bl __e500_icache_setup |
183 | bl __e500_dcache_setup | 183 | bl __e500_dcache_setup |
184 | bl .__setup_base_ivors | 184 | bl __setup_base_ivors |
185 | bl .setup_perfmon_ivor | 185 | bl setup_perfmon_ivor |
186 | bl .setup_doorbell_ivors | 186 | bl setup_doorbell_ivors |
187 | /* | 187 | /* |
188 | * We only want to touch IVOR38-41 if we're running on hardware | 188 | * We only want to touch IVOR38-41 if we're running on hardware |
189 | * that supports category E.HV. The architectural way to determine | 189 | * that supports category E.HV. The architectural way to determine |
@@ -192,7 +192,7 @@ _GLOBAL(__restore_cpu_e5500) | |||
192 | mfspr r10,SPRN_MMUCFG | 192 | mfspr r10,SPRN_MMUCFG |
193 | rlwinm. r10,r10,0,MMUCFG_LPIDSIZE | 193 | rlwinm. r10,r10,0,MMUCFG_LPIDSIZE |
194 | beq 1f | 194 | beq 1f |
195 | bl .setup_ehv_ivors | 195 | bl setup_ehv_ivors |
196 | 1: | 196 | 1: |
197 | mtlr r4 | 197 | mtlr r4 |
198 | blr | 198 | blr |
@@ -201,9 +201,9 @@ _GLOBAL(__setup_cpu_e5500) | |||
201 | mflr r5 | 201 | mflr r5 |
202 | bl __e500_icache_setup | 202 | bl __e500_icache_setup |
203 | bl __e500_dcache_setup | 203 | bl __e500_dcache_setup |
204 | bl .__setup_base_ivors | 204 | bl __setup_base_ivors |
205 | bl .setup_perfmon_ivor | 205 | bl setup_perfmon_ivor |
206 | bl .setup_doorbell_ivors | 206 | bl setup_doorbell_ivors |
207 | /* | 207 | /* |
208 | * We only want to touch IVOR38-41 if we're running on hardware | 208 | * We only want to touch IVOR38-41 if we're running on hardware |
209 | * that supports category E.HV. The architectural way to determine | 209 | * that supports category E.HV. The architectural way to determine |
@@ -212,7 +212,7 @@ _GLOBAL(__setup_cpu_e5500) | |||
212 | mfspr r10,SPRN_MMUCFG | 212 | mfspr r10,SPRN_MMUCFG |
213 | rlwinm. r10,r10,0,MMUCFG_LPIDSIZE | 213 | rlwinm. r10,r10,0,MMUCFG_LPIDSIZE |
214 | beq 1f | 214 | beq 1f |
215 | bl .setup_ehv_ivors | 215 | bl setup_ehv_ivors |
216 | b 2f | 216 | b 2f |
217 | 1: | 217 | 1: |
218 | ld r10,CPU_SPEC_FEATURES(r4) | 218 | ld r10,CPU_SPEC_FEATURES(r4) |
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index e7b76a6bf150..7051ea3101b9 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c | |||
@@ -22,6 +22,7 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/debugfs.h> | ||
25 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
26 | #include <linux/init.h> | 27 | #include <linux/init.h> |
27 | #include <linux/list.h> | 28 | #include <linux/list.h> |
@@ -35,6 +36,7 @@ | |||
35 | #include <linux/of.h> | 36 | #include <linux/of.h> |
36 | 37 | ||
37 | #include <linux/atomic.h> | 38 | #include <linux/atomic.h> |
39 | #include <asm/debug.h> | ||
38 | #include <asm/eeh.h> | 40 | #include <asm/eeh.h> |
39 | #include <asm/eeh_event.h> | 41 | #include <asm/eeh_event.h> |
40 | #include <asm/io.h> | 42 | #include <asm/io.h> |
@@ -87,22 +89,21 @@ | |||
87 | /* Time to wait for a PCI slot to report status, in milliseconds */ | 89 | /* Time to wait for a PCI slot to report status, in milliseconds */ |
88 | #define PCI_BUS_RESET_WAIT_MSEC (5*60*1000) | 90 | #define PCI_BUS_RESET_WAIT_MSEC (5*60*1000) |
89 | 91 | ||
90 | /* Platform dependent EEH operations */ | ||
91 | struct eeh_ops *eeh_ops = NULL; | ||
92 | |||
93 | bool eeh_subsystem_enabled = false; | ||
94 | EXPORT_SYMBOL(eeh_subsystem_enabled); | ||
95 | |||
96 | /* | 92 | /* |
97 | * EEH probe mode support. The intention is to support multiple | 93 | * EEH probe mode support, which is part of the flags, |
98 | * platforms for EEH. Some platforms like pSeries do PCI emunation | 94 | * is to support multiple platforms for EEH. Some platforms |
99 | * based on device tree. However, other platforms like powernv probe | 95 | * like pSeries do PCI emunation based on device tree. |
100 | * PCI devices from hardware. The flag is used to distinguish that. | 96 | * However, other platforms like powernv probe PCI devices |
101 | * In addition, struct eeh_ops::probe would be invoked for particular | 97 | * from hardware. The flag is used to distinguish that. |
102 | * OF node or PCI device so that the corresponding PE would be created | 98 | * In addition, struct eeh_ops::probe would be invoked for |
103 | * there. | 99 | * particular OF node or PCI device so that the corresponding |
100 | * PE would be created there. | ||
104 | */ | 101 | */ |
105 | int eeh_probe_mode; | 102 | int eeh_subsystem_flags; |
103 | EXPORT_SYMBOL(eeh_subsystem_flags); | ||
104 | |||
105 | /* Platform dependent EEH operations */ | ||
106 | struct eeh_ops *eeh_ops = NULL; | ||
106 | 107 | ||
107 | /* Lock to avoid races due to multiple reports of an error */ | 108 | /* Lock to avoid races due to multiple reports of an error */ |
108 | DEFINE_RAW_SPINLOCK(confirm_error_lock); | 109 | DEFINE_RAW_SPINLOCK(confirm_error_lock); |
@@ -133,6 +134,15 @@ static struct eeh_stats eeh_stats; | |||
133 | 134 | ||
134 | #define IS_BRIDGE(class_code) (((class_code)<<16) == PCI_BASE_CLASS_BRIDGE) | 135 | #define IS_BRIDGE(class_code) (((class_code)<<16) == PCI_BASE_CLASS_BRIDGE) |
135 | 136 | ||
137 | static int __init eeh_setup(char *str) | ||
138 | { | ||
139 | if (!strcmp(str, "off")) | ||
140 | eeh_subsystem_flags |= EEH_FORCE_DISABLED; | ||
141 | |||
142 | return 1; | ||
143 | } | ||
144 | __setup("eeh=", eeh_setup); | ||
145 | |||
136 | /** | 146 | /** |
137 | * eeh_gather_pci_data - Copy assorted PCI config space registers to buff | 147 | * eeh_gather_pci_data - Copy assorted PCI config space registers to buff |
138 | * @edev: device to report data for | 148 | * @edev: device to report data for |
@@ -145,73 +155,67 @@ static struct eeh_stats eeh_stats; | |||
145 | static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len) | 155 | static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len) |
146 | { | 156 | { |
147 | struct device_node *dn = eeh_dev_to_of_node(edev); | 157 | struct device_node *dn = eeh_dev_to_of_node(edev); |
148 | struct pci_dev *dev = eeh_dev_to_pci_dev(edev); | ||
149 | u32 cfg; | 158 | u32 cfg; |
150 | int cap, i; | 159 | int cap, i; |
151 | int n = 0; | 160 | int n = 0; |
152 | 161 | ||
153 | n += scnprintf(buf+n, len-n, "%s\n", dn->full_name); | 162 | n += scnprintf(buf+n, len-n, "%s\n", dn->full_name); |
154 | printk(KERN_WARNING "EEH: of node=%s\n", dn->full_name); | 163 | pr_warn("EEH: of node=%s\n", dn->full_name); |
155 | 164 | ||
156 | eeh_ops->read_config(dn, PCI_VENDOR_ID, 4, &cfg); | 165 | eeh_ops->read_config(dn, PCI_VENDOR_ID, 4, &cfg); |
157 | n += scnprintf(buf+n, len-n, "dev/vend:%08x\n", cfg); | 166 | n += scnprintf(buf+n, len-n, "dev/vend:%08x\n", cfg); |
158 | printk(KERN_WARNING "EEH: PCI device/vendor: %08x\n", cfg); | 167 | pr_warn("EEH: PCI device/vendor: %08x\n", cfg); |
159 | 168 | ||
160 | eeh_ops->read_config(dn, PCI_COMMAND, 4, &cfg); | 169 | eeh_ops->read_config(dn, PCI_COMMAND, 4, &cfg); |
161 | n += scnprintf(buf+n, len-n, "cmd/stat:%x\n", cfg); | 170 | n += scnprintf(buf+n, len-n, "cmd/stat:%x\n", cfg); |
162 | printk(KERN_WARNING "EEH: PCI cmd/status register: %08x\n", cfg); | 171 | pr_warn("EEH: PCI cmd/status register: %08x\n", cfg); |
163 | |||
164 | if (!dev) { | ||
165 | printk(KERN_WARNING "EEH: no PCI device for this of node\n"); | ||
166 | return n; | ||
167 | } | ||
168 | 172 | ||
169 | /* Gather bridge-specific registers */ | 173 | /* Gather bridge-specific registers */ |
170 | if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) { | 174 | if (edev->mode & EEH_DEV_BRIDGE) { |
171 | eeh_ops->read_config(dn, PCI_SEC_STATUS, 2, &cfg); | 175 | eeh_ops->read_config(dn, PCI_SEC_STATUS, 2, &cfg); |
172 | n += scnprintf(buf+n, len-n, "sec stat:%x\n", cfg); | 176 | n += scnprintf(buf+n, len-n, "sec stat:%x\n", cfg); |
173 | printk(KERN_WARNING "EEH: Bridge secondary status: %04x\n", cfg); | 177 | pr_warn("EEH: Bridge secondary status: %04x\n", cfg); |
174 | 178 | ||
175 | eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &cfg); | 179 | eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &cfg); |
176 | n += scnprintf(buf+n, len-n, "brdg ctl:%x\n", cfg); | 180 | n += scnprintf(buf+n, len-n, "brdg ctl:%x\n", cfg); |
177 | printk(KERN_WARNING "EEH: Bridge control: %04x\n", cfg); | 181 | pr_warn("EEH: Bridge control: %04x\n", cfg); |
178 | } | 182 | } |
179 | 183 | ||
180 | /* Dump out the PCI-X command and status regs */ | 184 | /* Dump out the PCI-X command and status regs */ |
181 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); | 185 | cap = edev->pcix_cap; |
182 | if (cap) { | 186 | if (cap) { |
183 | eeh_ops->read_config(dn, cap, 4, &cfg); | 187 | eeh_ops->read_config(dn, cap, 4, &cfg); |
184 | n += scnprintf(buf+n, len-n, "pcix-cmd:%x\n", cfg); | 188 | n += scnprintf(buf+n, len-n, "pcix-cmd:%x\n", cfg); |
185 | printk(KERN_WARNING "EEH: PCI-X cmd: %08x\n", cfg); | 189 | pr_warn("EEH: PCI-X cmd: %08x\n", cfg); |
186 | 190 | ||
187 | eeh_ops->read_config(dn, cap+4, 4, &cfg); | 191 | eeh_ops->read_config(dn, cap+4, 4, &cfg); |
188 | n += scnprintf(buf+n, len-n, "pcix-stat:%x\n", cfg); | 192 | n += scnprintf(buf+n, len-n, "pcix-stat:%x\n", cfg); |
189 | printk(KERN_WARNING "EEH: PCI-X status: %08x\n", cfg); | 193 | pr_warn("EEH: PCI-X status: %08x\n", cfg); |
190 | } | 194 | } |
191 | 195 | ||
192 | /* If PCI-E capable, dump PCI-E cap 10, and the AER */ | 196 | /* If PCI-E capable, dump PCI-E cap 10 */ |
193 | if (pci_is_pcie(dev)) { | 197 | cap = edev->pcie_cap; |
198 | if (cap) { | ||
194 | n += scnprintf(buf+n, len-n, "pci-e cap10:\n"); | 199 | n += scnprintf(buf+n, len-n, "pci-e cap10:\n"); |
195 | printk(KERN_WARNING | 200 | pr_warn("EEH: PCI-E capabilities and status follow:\n"); |
196 | "EEH: PCI-E capabilities and status follow:\n"); | ||
197 | 201 | ||
198 | for (i=0; i<=8; i++) { | 202 | for (i=0; i<=8; i++) { |
199 | eeh_ops->read_config(dn, dev->pcie_cap+4*i, 4, &cfg); | 203 | eeh_ops->read_config(dn, cap+4*i, 4, &cfg); |
200 | n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg); | 204 | n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg); |
201 | printk(KERN_WARNING "EEH: PCI-E %02x: %08x\n", i, cfg); | 205 | pr_warn("EEH: PCI-E %02x: %08x\n", i, cfg); |
202 | } | 206 | } |
207 | } | ||
203 | 208 | ||
204 | cap = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 209 | /* If AER capable, dump it */ |
205 | if (cap) { | 210 | cap = edev->aer_cap; |
206 | n += scnprintf(buf+n, len-n, "pci-e AER:\n"); | 211 | if (cap) { |
207 | printk(KERN_WARNING | 212 | n += scnprintf(buf+n, len-n, "pci-e AER:\n"); |
208 | "EEH: PCI-E AER capability register set follows:\n"); | 213 | pr_warn("EEH: PCI-E AER capability register set follows:\n"); |
209 | 214 | ||
210 | for (i=0; i<14; i++) { | 215 | for (i=0; i<14; i++) { |
211 | eeh_ops->read_config(dn, cap+4*i, 4, &cfg); | 216 | eeh_ops->read_config(dn, cap+4*i, 4, &cfg); |
212 | n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg); | 217 | n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg); |
213 | printk(KERN_WARNING "EEH: PCI-E AER %02x: %08x\n", i, cfg); | 218 | pr_warn("EEH: PCI-E AER %02x: %08x\n", i, cfg); |
214 | } | ||
215 | } | 219 | } |
216 | } | 220 | } |
217 | 221 | ||
@@ -232,21 +236,19 @@ void eeh_slot_error_detail(struct eeh_pe *pe, int severity) | |||
232 | { | 236 | { |
233 | size_t loglen = 0; | 237 | size_t loglen = 0; |
234 | struct eeh_dev *edev, *tmp; | 238 | struct eeh_dev *edev, *tmp; |
235 | bool valid_cfg_log = true; | ||
236 | 239 | ||
237 | /* | 240 | /* |
238 | * When the PHB is fenced or dead, it's pointless to collect | 241 | * When the PHB is fenced or dead, it's pointless to collect |
239 | * the data from PCI config space because it should return | 242 | * the data from PCI config space because it should return |
240 | * 0xFF's. For ER, we still retrieve the data from the PCI | 243 | * 0xFF's. For ER, we still retrieve the data from the PCI |
241 | * config space. | 244 | * config space. |
245 | * | ||
246 | * For pHyp, we have to enable IO for log retrieval. Otherwise, | ||
247 | * 0xFF's is always returned from PCI config space. | ||
242 | */ | 248 | */ |
243 | if (eeh_probe_mode_dev() && | 249 | if (!(pe->type & EEH_PE_PHB)) { |
244 | (pe->type & EEH_PE_PHB) && | 250 | if (eeh_probe_mode_devtree()) |
245 | (pe->state & (EEH_PE_ISOLATED | EEH_PE_PHB_DEAD))) | 251 | eeh_pci_enable(pe, EEH_OPT_THAW_MMIO); |
246 | valid_cfg_log = false; | ||
247 | |||
248 | if (valid_cfg_log) { | ||
249 | eeh_pci_enable(pe, EEH_OPT_THAW_MMIO); | ||
250 | eeh_ops->configure_bridge(pe); | 252 | eeh_ops->configure_bridge(pe); |
251 | eeh_pe_restore_bars(pe); | 253 | eeh_pe_restore_bars(pe); |
252 | 254 | ||
@@ -309,7 +311,7 @@ static int eeh_phb_check_failure(struct eeh_pe *pe) | |||
309 | 311 | ||
310 | /* If the PHB has been in problematic state */ | 312 | /* If the PHB has been in problematic state */ |
311 | eeh_serialize_lock(&flags); | 313 | eeh_serialize_lock(&flags); |
312 | if (phb_pe->state & (EEH_PE_ISOLATED | EEH_PE_PHB_DEAD)) { | 314 | if (phb_pe->state & EEH_PE_ISOLATED) { |
313 | ret = 0; | 315 | ret = 0; |
314 | goto out; | 316 | goto out; |
315 | } | 317 | } |
@@ -515,16 +517,42 @@ EXPORT_SYMBOL(eeh_check_failure); | |||
515 | */ | 517 | */ |
516 | int eeh_pci_enable(struct eeh_pe *pe, int function) | 518 | int eeh_pci_enable(struct eeh_pe *pe, int function) |
517 | { | 519 | { |
518 | int rc; | 520 | int rc, flags = (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE); |
521 | |||
522 | /* | ||
523 | * pHyp doesn't allow to enable IO or DMA on unfrozen PE. | ||
524 | * Also, it's pointless to enable them on unfrozen PE. So | ||
525 | * we have the check here. | ||
526 | */ | ||
527 | if (function == EEH_OPT_THAW_MMIO || | ||
528 | function == EEH_OPT_THAW_DMA) { | ||
529 | rc = eeh_ops->get_state(pe, NULL); | ||
530 | if (rc < 0) | ||
531 | return rc; | ||
532 | |||
533 | /* Needn't to enable or already enabled */ | ||
534 | if ((rc == EEH_STATE_NOT_SUPPORT) || | ||
535 | ((rc & flags) == flags)) | ||
536 | return 0; | ||
537 | } | ||
519 | 538 | ||
520 | rc = eeh_ops->set_option(pe, function); | 539 | rc = eeh_ops->set_option(pe, function); |
521 | if (rc) | 540 | if (rc) |
522 | pr_warning("%s: Unexpected state change %d on PHB#%d-PE#%x, err=%d\n", | 541 | pr_warn("%s: Unexpected state change %d on " |
523 | __func__, function, pe->phb->global_number, pe->addr, rc); | 542 | "PHB#%d-PE#%x, err=%d\n", |
543 | __func__, function, pe->phb->global_number, | ||
544 | pe->addr, rc); | ||
524 | 545 | ||
525 | rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC); | 546 | rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC); |
526 | if (rc > 0 && (rc & EEH_STATE_MMIO_ENABLED) && | 547 | if (rc <= 0) |
527 | (function == EEH_OPT_THAW_MMIO)) | 548 | return rc; |
549 | |||
550 | if ((function == EEH_OPT_THAW_MMIO) && | ||
551 | (rc & EEH_STATE_MMIO_ENABLED)) | ||
552 | return 0; | ||
553 | |||
554 | if ((function == EEH_OPT_THAW_DMA) && | ||
555 | (rc & EEH_STATE_DMA_ENABLED)) | ||
528 | return 0; | 556 | return 0; |
529 | 557 | ||
530 | return rc; | 558 | return rc; |
@@ -612,26 +640,7 @@ static void eeh_reset_pe_once(struct eeh_pe *pe) | |||
612 | else | 640 | else |
613 | eeh_ops->reset(pe, EEH_RESET_HOT); | 641 | eeh_ops->reset(pe, EEH_RESET_HOT); |
614 | 642 | ||
615 | /* The PCI bus requires that the reset be held high for at least | ||
616 | * a 100 milliseconds. We wait a bit longer 'just in case'. | ||
617 | */ | ||
618 | #define PCI_BUS_RST_HOLD_TIME_MSEC 250 | ||
619 | msleep(PCI_BUS_RST_HOLD_TIME_MSEC); | ||
620 | |||
621 | /* We might get hit with another EEH freeze as soon as the | ||
622 | * pci slot reset line is dropped. Make sure we don't miss | ||
623 | * these, and clear the flag now. | ||
624 | */ | ||
625 | eeh_pe_state_clear(pe, EEH_PE_ISOLATED); | ||
626 | |||
627 | eeh_ops->reset(pe, EEH_RESET_DEACTIVATE); | 643 | eeh_ops->reset(pe, EEH_RESET_DEACTIVATE); |
628 | |||
629 | /* After a PCI slot has been reset, the PCI Express spec requires | ||
630 | * a 1.5 second idle time for the bus to stabilize, before starting | ||
631 | * up traffic. | ||
632 | */ | ||
633 | #define PCI_BUS_SETTLE_TIME_MSEC 1800 | ||
634 | msleep(PCI_BUS_SETTLE_TIME_MSEC); | ||
635 | } | 644 | } |
636 | 645 | ||
637 | /** | 646 | /** |
@@ -651,6 +660,10 @@ int eeh_reset_pe(struct eeh_pe *pe) | |||
651 | for (i=0; i<3; i++) { | 660 | for (i=0; i<3; i++) { |
652 | eeh_reset_pe_once(pe); | 661 | eeh_reset_pe_once(pe); |
653 | 662 | ||
663 | /* | ||
664 | * EEH_PE_ISOLATED is expected to be removed after | ||
665 | * BAR restore. | ||
666 | */ | ||
654 | rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC); | 667 | rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC); |
655 | if ((rc & flags) == flags) | 668 | if ((rc & flags) == flags) |
656 | return 0; | 669 | return 0; |
@@ -826,8 +839,8 @@ int eeh_init(void) | |||
826 | &hose_list, list_node) | 839 | &hose_list, list_node) |
827 | pci_walk_bus(hose->bus, eeh_ops->dev_probe, NULL); | 840 | pci_walk_bus(hose->bus, eeh_ops->dev_probe, NULL); |
828 | } else { | 841 | } else { |
829 | pr_warning("%s: Invalid probe mode %d\n", | 842 | pr_warn("%s: Invalid probe mode %x", |
830 | __func__, eeh_probe_mode); | 843 | __func__, eeh_subsystem_flags); |
831 | return -EINVAL; | 844 | return -EINVAL; |
832 | } | 845 | } |
833 | 846 | ||
@@ -1102,10 +1115,45 @@ static const struct file_operations proc_eeh_operations = { | |||
1102 | .release = single_release, | 1115 | .release = single_release, |
1103 | }; | 1116 | }; |
1104 | 1117 | ||
1118 | #ifdef CONFIG_DEBUG_FS | ||
1119 | static int eeh_enable_dbgfs_set(void *data, u64 val) | ||
1120 | { | ||
1121 | if (val) | ||
1122 | eeh_subsystem_flags &= ~EEH_FORCE_DISABLED; | ||
1123 | else | ||
1124 | eeh_subsystem_flags |= EEH_FORCE_DISABLED; | ||
1125 | |||
1126 | /* Notify the backend */ | ||
1127 | if (eeh_ops->post_init) | ||
1128 | eeh_ops->post_init(); | ||
1129 | |||
1130 | return 0; | ||
1131 | } | ||
1132 | |||
1133 | static int eeh_enable_dbgfs_get(void *data, u64 *val) | ||
1134 | { | ||
1135 | if (eeh_enabled()) | ||
1136 | *val = 0x1ul; | ||
1137 | else | ||
1138 | *val = 0x0ul; | ||
1139 | return 0; | ||
1140 | } | ||
1141 | |||
1142 | DEFINE_SIMPLE_ATTRIBUTE(eeh_enable_dbgfs_ops, eeh_enable_dbgfs_get, | ||
1143 | eeh_enable_dbgfs_set, "0x%llx\n"); | ||
1144 | #endif | ||
1145 | |||
1105 | static int __init eeh_init_proc(void) | 1146 | static int __init eeh_init_proc(void) |
1106 | { | 1147 | { |
1107 | if (machine_is(pseries) || machine_is(powernv)) | 1148 | if (machine_is(pseries) || machine_is(powernv)) { |
1108 | proc_create("powerpc/eeh", 0, NULL, &proc_eeh_operations); | 1149 | proc_create("powerpc/eeh", 0, NULL, &proc_eeh_operations); |
1150 | #ifdef CONFIG_DEBUG_FS | ||
1151 | debugfs_create_file("eeh_enable", 0600, | ||
1152 | powerpc_debugfs_root, NULL, | ||
1153 | &eeh_enable_dbgfs_ops); | ||
1154 | #endif | ||
1155 | } | ||
1156 | |||
1109 | return 0; | 1157 | return 0; |
1110 | } | 1158 | } |
1111 | __initcall(eeh_init_proc); | 1159 | __initcall(eeh_init_proc); |
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index bb61ca58ca6d..7100a5b96e70 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c | |||
@@ -171,6 +171,15 @@ static void eeh_enable_irq(struct pci_dev *dev) | |||
171 | } | 171 | } |
172 | } | 172 | } |
173 | 173 | ||
174 | static bool eeh_dev_removed(struct eeh_dev *edev) | ||
175 | { | ||
176 | /* EEH device removed ? */ | ||
177 | if (!edev || (edev->mode & EEH_DEV_REMOVED)) | ||
178 | return true; | ||
179 | |||
180 | return false; | ||
181 | } | ||
182 | |||
174 | /** | 183 | /** |
175 | * eeh_report_error - Report pci error to each device driver | 184 | * eeh_report_error - Report pci error to each device driver |
176 | * @data: eeh device | 185 | * @data: eeh device |
@@ -187,10 +196,8 @@ static void *eeh_report_error(void *data, void *userdata) | |||
187 | enum pci_ers_result rc, *res = userdata; | 196 | enum pci_ers_result rc, *res = userdata; |
188 | struct pci_driver *driver; | 197 | struct pci_driver *driver; |
189 | 198 | ||
190 | /* We might not have the associated PCI device, | 199 | if (!dev || eeh_dev_removed(edev)) |
191 | * then we should continue for next one. | 200 | return NULL; |
192 | */ | ||
193 | if (!dev) return NULL; | ||
194 | dev->error_state = pci_channel_io_frozen; | 201 | dev->error_state = pci_channel_io_frozen; |
195 | 202 | ||
196 | driver = eeh_pcid_get(dev); | 203 | driver = eeh_pcid_get(dev); |
@@ -230,6 +237,9 @@ static void *eeh_report_mmio_enabled(void *data, void *userdata) | |||
230 | enum pci_ers_result rc, *res = userdata; | 237 | enum pci_ers_result rc, *res = userdata; |
231 | struct pci_driver *driver; | 238 | struct pci_driver *driver; |
232 | 239 | ||
240 | if (!dev || eeh_dev_removed(edev)) | ||
241 | return NULL; | ||
242 | |||
233 | driver = eeh_pcid_get(dev); | 243 | driver = eeh_pcid_get(dev); |
234 | if (!driver) return NULL; | 244 | if (!driver) return NULL; |
235 | 245 | ||
@@ -267,7 +277,8 @@ static void *eeh_report_reset(void *data, void *userdata) | |||
267 | enum pci_ers_result rc, *res = userdata; | 277 | enum pci_ers_result rc, *res = userdata; |
268 | struct pci_driver *driver; | 278 | struct pci_driver *driver; |
269 | 279 | ||
270 | if (!dev) return NULL; | 280 | if (!dev || eeh_dev_removed(edev)) |
281 | return NULL; | ||
271 | dev->error_state = pci_channel_io_normal; | 282 | dev->error_state = pci_channel_io_normal; |
272 | 283 | ||
273 | driver = eeh_pcid_get(dev); | 284 | driver = eeh_pcid_get(dev); |
@@ -307,7 +318,8 @@ static void *eeh_report_resume(void *data, void *userdata) | |||
307 | struct pci_dev *dev = eeh_dev_to_pci_dev(edev); | 318 | struct pci_dev *dev = eeh_dev_to_pci_dev(edev); |
308 | struct pci_driver *driver; | 319 | struct pci_driver *driver; |
309 | 320 | ||
310 | if (!dev) return NULL; | 321 | if (!dev || eeh_dev_removed(edev)) |
322 | return NULL; | ||
311 | dev->error_state = pci_channel_io_normal; | 323 | dev->error_state = pci_channel_io_normal; |
312 | 324 | ||
313 | driver = eeh_pcid_get(dev); | 325 | driver = eeh_pcid_get(dev); |
@@ -343,7 +355,8 @@ static void *eeh_report_failure(void *data, void *userdata) | |||
343 | struct pci_dev *dev = eeh_dev_to_pci_dev(edev); | 355 | struct pci_dev *dev = eeh_dev_to_pci_dev(edev); |
344 | struct pci_driver *driver; | 356 | struct pci_driver *driver; |
345 | 357 | ||
346 | if (!dev) return NULL; | 358 | if (!dev || eeh_dev_removed(edev)) |
359 | return NULL; | ||
347 | dev->error_state = pci_channel_io_perm_failure; | 360 | dev->error_state = pci_channel_io_perm_failure; |
348 | 361 | ||
349 | driver = eeh_pcid_get(dev); | 362 | driver = eeh_pcid_get(dev); |
@@ -380,6 +393,16 @@ static void *eeh_rmv_device(void *data, void *userdata) | |||
380 | if (!dev || (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE)) | 393 | if (!dev || (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE)) |
381 | return NULL; | 394 | return NULL; |
382 | 395 | ||
396 | /* | ||
397 | * We rely on count-based pcibios_release_device() to | ||
398 | * detach permanently offlined PEs. Unfortunately, that's | ||
399 | * not reliable enough. We might have the permanently | ||
400 | * offlined PEs attached, but we needn't take care of | ||
401 | * them and their child devices. | ||
402 | */ | ||
403 | if (eeh_dev_removed(edev)) | ||
404 | return NULL; | ||
405 | |||
383 | driver = eeh_pcid_get(dev); | 406 | driver = eeh_pcid_get(dev); |
384 | if (driver) { | 407 | if (driver) { |
385 | eeh_pcid_put(dev); | 408 | eeh_pcid_put(dev); |
@@ -417,6 +440,36 @@ static void *eeh_pe_detach_dev(void *data, void *userdata) | |||
417 | return NULL; | 440 | return NULL; |
418 | } | 441 | } |
419 | 442 | ||
443 | /* | ||
444 | * Explicitly clear PE's frozen state for PowerNV where | ||
445 | * we have frozen PE until BAR restore is completed. It's | ||
446 | * harmless to clear it for pSeries. To be consistent with | ||
447 | * PE reset (for 3 times), we try to clear the frozen state | ||
448 | * for 3 times as well. | ||
449 | */ | ||
450 | static int eeh_clear_pe_frozen_state(struct eeh_pe *pe) | ||
451 | { | ||
452 | int i, rc; | ||
453 | |||
454 | for (i = 0; i < 3; i++) { | ||
455 | rc = eeh_pci_enable(pe, EEH_OPT_THAW_MMIO); | ||
456 | if (rc) | ||
457 | continue; | ||
458 | rc = eeh_pci_enable(pe, EEH_OPT_THAW_DMA); | ||
459 | if (!rc) | ||
460 | break; | ||
461 | } | ||
462 | |||
463 | /* The PE has been isolated, clear it */ | ||
464 | if (rc) | ||
465 | pr_warn("%s: Can't clear frozen PHB#%x-PE#%x (%d)\n", | ||
466 | __func__, pe->phb->global_number, pe->addr, rc); | ||
467 | else | ||
468 | eeh_pe_state_clear(pe, EEH_PE_ISOLATED); | ||
469 | |||
470 | return rc; | ||
471 | } | ||
472 | |||
420 | /** | 473 | /** |
421 | * eeh_reset_device - Perform actual reset of a pci slot | 474 | * eeh_reset_device - Perform actual reset of a pci slot |
422 | * @pe: EEH PE | 475 | * @pe: EEH PE |
@@ -451,19 +504,33 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) | |||
451 | eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed); | 504 | eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed); |
452 | } | 505 | } |
453 | 506 | ||
454 | /* Reset the pci controller. (Asserts RST#; resets config space). | 507 | /* |
508 | * Reset the pci controller. (Asserts RST#; resets config space). | ||
455 | * Reconfigure bridges and devices. Don't try to bring the system | 509 | * Reconfigure bridges and devices. Don't try to bring the system |
456 | * up if the reset failed for some reason. | 510 | * up if the reset failed for some reason. |
511 | * | ||
512 | * During the reset, it's very dangerous to have uncontrolled PCI | ||
513 | * config accesses. So we prefer to block them. However, controlled | ||
514 | * PCI config accesses initiated from EEH itself are allowed. | ||
457 | */ | 515 | */ |
516 | eeh_pe_state_mark(pe, EEH_PE_RESET); | ||
458 | rc = eeh_reset_pe(pe); | 517 | rc = eeh_reset_pe(pe); |
459 | if (rc) | 518 | if (rc) { |
519 | eeh_pe_state_clear(pe, EEH_PE_RESET); | ||
460 | return rc; | 520 | return rc; |
521 | } | ||
461 | 522 | ||
462 | pci_lock_rescan_remove(); | 523 | pci_lock_rescan_remove(); |
463 | 524 | ||
464 | /* Restore PE */ | 525 | /* Restore PE */ |
465 | eeh_ops->configure_bridge(pe); | 526 | eeh_ops->configure_bridge(pe); |
466 | eeh_pe_restore_bars(pe); | 527 | eeh_pe_restore_bars(pe); |
528 | eeh_pe_state_clear(pe, EEH_PE_RESET); | ||
529 | |||
530 | /* Clear frozen state */ | ||
531 | rc = eeh_clear_pe_frozen_state(pe); | ||
532 | if (rc) | ||
533 | return rc; | ||
467 | 534 | ||
468 | /* Give the system 5 seconds to finish running the user-space | 535 | /* Give the system 5 seconds to finish running the user-space |
469 | * hotplug shutdown scripts, e.g. ifdown for ethernet. Yes, | 536 | * hotplug shutdown scripts, e.g. ifdown for ethernet. Yes, |
@@ -573,7 +640,6 @@ static void eeh_handle_normal_event(struct eeh_pe *pe) | |||
573 | result = PCI_ERS_RESULT_NEED_RESET; | 640 | result = PCI_ERS_RESULT_NEED_RESET; |
574 | } else { | 641 | } else { |
575 | pr_info("EEH: Notify device drivers to resume I/O\n"); | 642 | pr_info("EEH: Notify device drivers to resume I/O\n"); |
576 | result = PCI_ERS_RESULT_NONE; | ||
577 | eeh_pe_dev_traverse(pe, eeh_report_mmio_enabled, &result); | 643 | eeh_pe_dev_traverse(pe, eeh_report_mmio_enabled, &result); |
578 | } | 644 | } |
579 | } | 645 | } |
@@ -585,10 +651,17 @@ static void eeh_handle_normal_event(struct eeh_pe *pe) | |||
585 | 651 | ||
586 | if (rc < 0) | 652 | if (rc < 0) |
587 | goto hard_fail; | 653 | goto hard_fail; |
588 | if (rc) | 654 | if (rc) { |
589 | result = PCI_ERS_RESULT_NEED_RESET; | 655 | result = PCI_ERS_RESULT_NEED_RESET; |
590 | else | 656 | } else { |
657 | /* | ||
658 | * We didn't do PE reset for the case. The PE | ||
659 | * is still in frozen state. Clear it before | ||
660 | * resuming the PE. | ||
661 | */ | ||
662 | eeh_pe_state_clear(pe, EEH_PE_ISOLATED); | ||
591 | result = PCI_ERS_RESULT_RECOVERED; | 663 | result = PCI_ERS_RESULT_RECOVERED; |
664 | } | ||
592 | } | 665 | } |
593 | 666 | ||
594 | /* If any device has a hard failure, then shut off everything. */ | 667 | /* If any device has a hard failure, then shut off everything. */ |
@@ -650,8 +723,17 @@ perm_error: | |||
650 | /* Notify all devices that they're about to go down. */ | 723 | /* Notify all devices that they're about to go down. */ |
651 | eeh_pe_dev_traverse(pe, eeh_report_failure, NULL); | 724 | eeh_pe_dev_traverse(pe, eeh_report_failure, NULL); |
652 | 725 | ||
653 | /* Shut down the device drivers for good. */ | 726 | /* Mark the PE to be removed permanently */ |
727 | pe->freeze_count = EEH_MAX_ALLOWED_FREEZES + 1; | ||
728 | |||
729 | /* | ||
730 | * Shut down the device drivers for good. We mark | ||
731 | * all removed devices correctly to avoid access | ||
732 | * the their PCI config any more. | ||
733 | */ | ||
654 | if (frozen_bus) { | 734 | if (frozen_bus) { |
735 | eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); | ||
736 | |||
655 | pci_lock_rescan_remove(); | 737 | pci_lock_rescan_remove(); |
656 | pcibios_remove_pci_devices(frozen_bus); | 738 | pcibios_remove_pci_devices(frozen_bus); |
657 | pci_unlock_rescan_remove(); | 739 | pci_unlock_rescan_remove(); |
@@ -682,8 +764,7 @@ static void eeh_handle_special_event(void) | |||
682 | phb_pe = eeh_phb_pe_get(hose); | 764 | phb_pe = eeh_phb_pe_get(hose); |
683 | if (!phb_pe) continue; | 765 | if (!phb_pe) continue; |
684 | 766 | ||
685 | eeh_pe_state_mark(phb_pe, | 767 | eeh_pe_state_mark(phb_pe, EEH_PE_ISOLATED); |
686 | EEH_PE_ISOLATED | EEH_PE_PHB_DEAD); | ||
687 | } | 768 | } |
688 | 769 | ||
689 | eeh_serialize_unlock(flags); | 770 | eeh_serialize_unlock(flags); |
@@ -699,8 +780,7 @@ static void eeh_handle_special_event(void) | |||
699 | eeh_remove_event(pe); | 780 | eeh_remove_event(pe); |
700 | 781 | ||
701 | if (rc == EEH_NEXT_ERR_DEAD_PHB) | 782 | if (rc == EEH_NEXT_ERR_DEAD_PHB) |
702 | eeh_pe_state_mark(pe, | 783 | eeh_pe_state_mark(pe, EEH_PE_ISOLATED); |
703 | EEH_PE_ISOLATED | EEH_PE_PHB_DEAD); | ||
704 | else | 784 | else |
705 | eeh_pe_state_mark(pe, | 785 | eeh_pe_state_mark(pe, |
706 | EEH_PE_ISOLATED | EEH_PE_RECOVERING); | 786 | EEH_PE_ISOLATED | EEH_PE_RECOVERING); |
@@ -724,12 +804,14 @@ static void eeh_handle_special_event(void) | |||
724 | if (rc == EEH_NEXT_ERR_FROZEN_PE || | 804 | if (rc == EEH_NEXT_ERR_FROZEN_PE || |
725 | rc == EEH_NEXT_ERR_FENCED_PHB) { | 805 | rc == EEH_NEXT_ERR_FENCED_PHB) { |
726 | eeh_handle_normal_event(pe); | 806 | eeh_handle_normal_event(pe); |
807 | eeh_pe_state_clear(pe, EEH_PE_RECOVERING); | ||
727 | } else { | 808 | } else { |
728 | pci_lock_rescan_remove(); | 809 | pci_lock_rescan_remove(); |
729 | list_for_each_entry(hose, &hose_list, list_node) { | 810 | list_for_each_entry(hose, &hose_list, list_node) { |
730 | phb_pe = eeh_phb_pe_get(hose); | 811 | phb_pe = eeh_phb_pe_get(hose); |
731 | if (!phb_pe || | 812 | if (!phb_pe || |
732 | !(phb_pe->state & EEH_PE_PHB_DEAD)) | 813 | !(phb_pe->state & EEH_PE_ISOLATED) || |
814 | (phb_pe->state & EEH_PE_RECOVERING)) | ||
733 | continue; | 815 | continue; |
734 | 816 | ||
735 | /* Notify all devices to be down */ | 817 | /* Notify all devices to be down */ |
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c index f0c353fa655a..995c2a284630 100644 --- a/arch/powerpc/kernel/eeh_pe.c +++ b/arch/powerpc/kernel/eeh_pe.c | |||
@@ -503,13 +503,17 @@ static void *__eeh_pe_state_mark(void *data, void *flag) | |||
503 | struct eeh_dev *edev, *tmp; | 503 | struct eeh_dev *edev, *tmp; |
504 | struct pci_dev *pdev; | 504 | struct pci_dev *pdev; |
505 | 505 | ||
506 | /* | 506 | /* Keep the state of permanently removed PE intact */ |
507 | * Mark the PE with the indicated state. Also, | 507 | if ((pe->freeze_count > EEH_MAX_ALLOWED_FREEZES) && |
508 | * the associated PCI device will be put into | 508 | (state & (EEH_PE_ISOLATED | EEH_PE_RECOVERING))) |
509 | * I/O frozen state to avoid I/O accesses from | 509 | return NULL; |
510 | * the PCI device driver. | 510 | |
511 | */ | ||
512 | pe->state |= state; | 511 | pe->state |= state; |
512 | |||
513 | /* Offline PCI devices if applicable */ | ||
514 | if (state != EEH_PE_ISOLATED) | ||
515 | return NULL; | ||
516 | |||
513 | eeh_pe_for_each_dev(pe, edev, tmp) { | 517 | eeh_pe_for_each_dev(pe, edev, tmp) { |
514 | pdev = eeh_dev_to_pci_dev(edev); | 518 | pdev = eeh_dev_to_pci_dev(edev); |
515 | if (pdev) | 519 | if (pdev) |
@@ -532,6 +536,27 @@ void eeh_pe_state_mark(struct eeh_pe *pe, int state) | |||
532 | eeh_pe_traverse(pe, __eeh_pe_state_mark, &state); | 536 | eeh_pe_traverse(pe, __eeh_pe_state_mark, &state); |
533 | } | 537 | } |
534 | 538 | ||
539 | static void *__eeh_pe_dev_mode_mark(void *data, void *flag) | ||
540 | { | ||
541 | struct eeh_dev *edev = data; | ||
542 | int mode = *((int *)flag); | ||
543 | |||
544 | edev->mode |= mode; | ||
545 | |||
546 | return NULL; | ||
547 | } | ||
548 | |||
549 | /** | ||
550 | * eeh_pe_dev_state_mark - Mark state for all device under the PE | ||
551 | * @pe: EEH PE | ||
552 | * | ||
553 | * Mark specific state for all child devices of the PE. | ||
554 | */ | ||
555 | void eeh_pe_dev_mode_mark(struct eeh_pe *pe, int mode) | ||
556 | { | ||
557 | eeh_pe_dev_traverse(pe, __eeh_pe_dev_mode_mark, &mode); | ||
558 | } | ||
559 | |||
535 | /** | 560 | /** |
536 | * __eeh_pe_state_clear - Clear state for the PE | 561 | * __eeh_pe_state_clear - Clear state for the PE |
537 | * @data: EEH PE | 562 | * @data: EEH PE |
@@ -546,8 +571,16 @@ static void *__eeh_pe_state_clear(void *data, void *flag) | |||
546 | struct eeh_pe *pe = (struct eeh_pe *)data; | 571 | struct eeh_pe *pe = (struct eeh_pe *)data; |
547 | int state = *((int *)flag); | 572 | int state = *((int *)flag); |
548 | 573 | ||
574 | /* Keep the state of permanently removed PE intact */ | ||
575 | if ((pe->freeze_count > EEH_MAX_ALLOWED_FREEZES) && | ||
576 | (state & EEH_PE_ISOLATED)) | ||
577 | return NULL; | ||
578 | |||
549 | pe->state &= ~state; | 579 | pe->state &= ~state; |
550 | pe->check_count = 0; | 580 | |
581 | /* Clear check count since last isolation */ | ||
582 | if (state & EEH_PE_ISOLATED) | ||
583 | pe->check_count = 0; | ||
551 | 584 | ||
552 | return NULL; | 585 | return NULL; |
553 | } | 586 | } |
diff --git a/arch/powerpc/kernel/eeh_sysfs.c b/arch/powerpc/kernel/eeh_sysfs.c index 5d753d4f2c75..e2595ba4b720 100644 --- a/arch/powerpc/kernel/eeh_sysfs.c +++ b/arch/powerpc/kernel/eeh_sysfs.c | |||
@@ -59,6 +59,9 @@ void eeh_sysfs_add_device(struct pci_dev *pdev) | |||
59 | struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); | 59 | struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); |
60 | int rc=0; | 60 | int rc=0; |
61 | 61 | ||
62 | if (!eeh_enabled()) | ||
63 | return; | ||
64 | |||
62 | if (edev && (edev->mode & EEH_DEV_SYSFS)) | 65 | if (edev && (edev->mode & EEH_DEV_SYSFS)) |
63 | return; | 66 | return; |
64 | 67 | ||
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 662c6dd98072..911d45366f59 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -39,8 +39,8 @@ | |||
39 | * System calls. | 39 | * System calls. |
40 | */ | 40 | */ |
41 | .section ".toc","aw" | 41 | .section ".toc","aw" |
42 | .SYS_CALL_TABLE: | 42 | SYS_CALL_TABLE: |
43 | .tc .sys_call_table[TC],.sys_call_table | 43 | .tc sys_call_table[TC],sys_call_table |
44 | 44 | ||
45 | /* This value is used to mark exception frames on the stack. */ | 45 | /* This value is used to mark exception frames on the stack. */ |
46 | exception_marker: | 46 | exception_marker: |
@@ -106,7 +106,7 @@ BEGIN_FW_FTR_SECTION | |||
106 | LDX_BE r10,0,r10 /* get log write index */ | 106 | LDX_BE r10,0,r10 /* get log write index */ |
107 | cmpd cr1,r11,r10 | 107 | cmpd cr1,r11,r10 |
108 | beq+ cr1,33f | 108 | beq+ cr1,33f |
109 | bl .accumulate_stolen_time | 109 | bl accumulate_stolen_time |
110 | REST_GPR(0,r1) | 110 | REST_GPR(0,r1) |
111 | REST_4GPRS(3,r1) | 111 | REST_4GPRS(3,r1) |
112 | REST_2GPRS(7,r1) | 112 | REST_2GPRS(7,r1) |
@@ -143,7 +143,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) | |||
143 | std r10,SOFTE(r1) | 143 | std r10,SOFTE(r1) |
144 | 144 | ||
145 | #ifdef SHOW_SYSCALLS | 145 | #ifdef SHOW_SYSCALLS |
146 | bl .do_show_syscall | 146 | bl do_show_syscall |
147 | REST_GPR(0,r1) | 147 | REST_GPR(0,r1) |
148 | REST_4GPRS(3,r1) | 148 | REST_4GPRS(3,r1) |
149 | REST_2GPRS(7,r1) | 149 | REST_2GPRS(7,r1) |
@@ -162,7 +162,7 @@ system_call: /* label this so stack traces look sane */ | |||
162 | * Need to vector to 32 Bit or default sys_call_table here, | 162 | * Need to vector to 32 Bit or default sys_call_table here, |
163 | * based on caller's run-mode / personality. | 163 | * based on caller's run-mode / personality. |
164 | */ | 164 | */ |
165 | ld r11,.SYS_CALL_TABLE@toc(2) | 165 | ld r11,SYS_CALL_TABLE@toc(2) |
166 | andi. r10,r10,_TIF_32BIT | 166 | andi. r10,r10,_TIF_32BIT |
167 | beq 15f | 167 | beq 15f |
168 | addi r11,r11,8 /* use 32-bit syscall entries */ | 168 | addi r11,r11,8 /* use 32-bit syscall entries */ |
@@ -174,14 +174,14 @@ system_call: /* label this so stack traces look sane */ | |||
174 | clrldi r8,r8,32 | 174 | clrldi r8,r8,32 |
175 | 15: | 175 | 15: |
176 | slwi r0,r0,4 | 176 | slwi r0,r0,4 |
177 | ldx r10,r11,r0 /* Fetch system call handler [ptr] */ | 177 | ldx r12,r11,r0 /* Fetch system call handler [ptr] */ |
178 | mtctr r10 | 178 | mtctr r12 |
179 | bctrl /* Call handler */ | 179 | bctrl /* Call handler */ |
180 | 180 | ||
181 | syscall_exit: | 181 | syscall_exit: |
182 | std r3,RESULT(r1) | 182 | std r3,RESULT(r1) |
183 | #ifdef SHOW_SYSCALLS | 183 | #ifdef SHOW_SYSCALLS |
184 | bl .do_show_syscall_exit | 184 | bl do_show_syscall_exit |
185 | ld r3,RESULT(r1) | 185 | ld r3,RESULT(r1) |
186 | #endif | 186 | #endif |
187 | CURRENT_THREAD_INFO(r12, r1) | 187 | CURRENT_THREAD_INFO(r12, r1) |
@@ -248,9 +248,9 @@ syscall_error: | |||
248 | 248 | ||
249 | /* Traced system call support */ | 249 | /* Traced system call support */ |
250 | syscall_dotrace: | 250 | syscall_dotrace: |
251 | bl .save_nvgprs | 251 | bl save_nvgprs |
252 | addi r3,r1,STACK_FRAME_OVERHEAD | 252 | addi r3,r1,STACK_FRAME_OVERHEAD |
253 | bl .do_syscall_trace_enter | 253 | bl do_syscall_trace_enter |
254 | /* | 254 | /* |
255 | * Restore argument registers possibly just changed. | 255 | * Restore argument registers possibly just changed. |
256 | * We use the return value of do_syscall_trace_enter | 256 | * We use the return value of do_syscall_trace_enter |
@@ -308,7 +308,7 @@ syscall_exit_work: | |||
308 | 4: /* Anything else left to do? */ | 308 | 4: /* Anything else left to do? */ |
309 | SET_DEFAULT_THREAD_PPR(r3, r10) /* Set thread.ppr = 3 */ | 309 | SET_DEFAULT_THREAD_PPR(r3, r10) /* Set thread.ppr = 3 */ |
310 | andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) | 310 | andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) |
311 | beq .ret_from_except_lite | 311 | beq ret_from_except_lite |
312 | 312 | ||
313 | /* Re-enable interrupts */ | 313 | /* Re-enable interrupts */ |
314 | #ifdef CONFIG_PPC_BOOK3E | 314 | #ifdef CONFIG_PPC_BOOK3E |
@@ -319,10 +319,10 @@ syscall_exit_work: | |||
319 | mtmsrd r10,1 | 319 | mtmsrd r10,1 |
320 | #endif /* CONFIG_PPC_BOOK3E */ | 320 | #endif /* CONFIG_PPC_BOOK3E */ |
321 | 321 | ||
322 | bl .save_nvgprs | 322 | bl save_nvgprs |
323 | addi r3,r1,STACK_FRAME_OVERHEAD | 323 | addi r3,r1,STACK_FRAME_OVERHEAD |
324 | bl .do_syscall_trace_leave | 324 | bl do_syscall_trace_leave |
325 | b .ret_from_except | 325 | b ret_from_except |
326 | 326 | ||
327 | /* Save non-volatile GPRs, if not already saved. */ | 327 | /* Save non-volatile GPRs, if not already saved. */ |
328 | _GLOBAL(save_nvgprs) | 328 | _GLOBAL(save_nvgprs) |
@@ -345,52 +345,48 @@ _GLOBAL(save_nvgprs) | |||
345 | */ | 345 | */ |
346 | 346 | ||
347 | _GLOBAL(ppc_fork) | 347 | _GLOBAL(ppc_fork) |
348 | bl .save_nvgprs | 348 | bl save_nvgprs |
349 | bl .sys_fork | 349 | bl sys_fork |
350 | b syscall_exit | 350 | b syscall_exit |
351 | 351 | ||
352 | _GLOBAL(ppc_vfork) | 352 | _GLOBAL(ppc_vfork) |
353 | bl .save_nvgprs | 353 | bl save_nvgprs |
354 | bl .sys_vfork | 354 | bl sys_vfork |
355 | b syscall_exit | 355 | b syscall_exit |
356 | 356 | ||
357 | _GLOBAL(ppc_clone) | 357 | _GLOBAL(ppc_clone) |
358 | bl .save_nvgprs | 358 | bl save_nvgprs |
359 | bl .sys_clone | 359 | bl sys_clone |
360 | b syscall_exit | 360 | b syscall_exit |
361 | 361 | ||
362 | _GLOBAL(ppc32_swapcontext) | 362 | _GLOBAL(ppc32_swapcontext) |
363 | bl .save_nvgprs | 363 | bl save_nvgprs |
364 | bl .compat_sys_swapcontext | 364 | bl compat_sys_swapcontext |
365 | b syscall_exit | 365 | b syscall_exit |
366 | 366 | ||
367 | _GLOBAL(ppc64_swapcontext) | 367 | _GLOBAL(ppc64_swapcontext) |
368 | bl .save_nvgprs | 368 | bl save_nvgprs |
369 | bl .sys_swapcontext | 369 | bl sys_swapcontext |
370 | b syscall_exit | 370 | b syscall_exit |
371 | 371 | ||
372 | _GLOBAL(ret_from_fork) | 372 | _GLOBAL(ret_from_fork) |
373 | bl .schedule_tail | 373 | bl schedule_tail |
374 | REST_NVGPRS(r1) | 374 | REST_NVGPRS(r1) |
375 | li r3,0 | 375 | li r3,0 |
376 | b syscall_exit | 376 | b syscall_exit |
377 | 377 | ||
378 | _GLOBAL(ret_from_kernel_thread) | 378 | _GLOBAL(ret_from_kernel_thread) |
379 | bl .schedule_tail | 379 | bl schedule_tail |
380 | REST_NVGPRS(r1) | 380 | REST_NVGPRS(r1) |
381 | ld r14, 0(r14) | ||
382 | mtlr r14 | 381 | mtlr r14 |
383 | mr r3,r15 | 382 | mr r3,r15 |
383 | #if defined(_CALL_ELF) && _CALL_ELF == 2 | ||
384 | mr r12,r14 | ||
385 | #endif | ||
384 | blrl | 386 | blrl |
385 | li r3,0 | 387 | li r3,0 |
386 | b syscall_exit | 388 | b syscall_exit |
387 | 389 | ||
388 | .section ".toc","aw" | ||
389 | DSCR_DEFAULT: | ||
390 | .tc dscr_default[TC],dscr_default | ||
391 | |||
392 | .section ".text" | ||
393 | |||
394 | /* | 390 | /* |
395 | * This routine switches between two different tasks. The process | 391 | * This routine switches between two different tasks. The process |
396 | * state of one is saved on its kernel stack. Then the state | 392 | * state of one is saved on its kernel stack. Then the state |
@@ -575,11 +571,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
575 | #ifdef CONFIG_PPC64 | 571 | #ifdef CONFIG_PPC64 |
576 | BEGIN_FTR_SECTION | 572 | BEGIN_FTR_SECTION |
577 | lwz r6,THREAD_DSCR_INHERIT(r4) | 573 | lwz r6,THREAD_DSCR_INHERIT(r4) |
578 | ld r7,DSCR_DEFAULT@toc(2) | ||
579 | ld r0,THREAD_DSCR(r4) | 574 | ld r0,THREAD_DSCR(r4) |
580 | cmpwi r6,0 | 575 | cmpwi r6,0 |
581 | bne 1f | 576 | bne 1f |
582 | ld r0,0(r7) | 577 | ld r0,PACA_DSCR(r13) |
583 | 1: | 578 | 1: |
584 | BEGIN_FTR_SECTION_NESTED(70) | 579 | BEGIN_FTR_SECTION_NESTED(70) |
585 | mfspr r8, SPRN_FSCR | 580 | mfspr r8, SPRN_FSCR |
@@ -611,7 +606,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_DSCR) | |||
611 | _GLOBAL(ret_from_except) | 606 | _GLOBAL(ret_from_except) |
612 | ld r11,_TRAP(r1) | 607 | ld r11,_TRAP(r1) |
613 | andi. r0,r11,1 | 608 | andi. r0,r11,1 |
614 | bne .ret_from_except_lite | 609 | bne ret_from_except_lite |
615 | REST_NVGPRS(r1) | 610 | REST_NVGPRS(r1) |
616 | 611 | ||
617 | _GLOBAL(ret_from_except_lite) | 612 | _GLOBAL(ret_from_except_lite) |
@@ -661,23 +656,23 @@ _GLOBAL(ret_from_except_lite) | |||
661 | #endif | 656 | #endif |
662 | 1: andi. r0,r4,_TIF_NEED_RESCHED | 657 | 1: andi. r0,r4,_TIF_NEED_RESCHED |
663 | beq 2f | 658 | beq 2f |
664 | bl .restore_interrupts | 659 | bl restore_interrupts |
665 | SCHEDULE_USER | 660 | SCHEDULE_USER |
666 | b .ret_from_except_lite | 661 | b ret_from_except_lite |
667 | 2: | 662 | 2: |
668 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 663 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
669 | andi. r0,r4,_TIF_USER_WORK_MASK & ~_TIF_RESTORE_TM | 664 | andi. r0,r4,_TIF_USER_WORK_MASK & ~_TIF_RESTORE_TM |
670 | bne 3f /* only restore TM if nothing else to do */ | 665 | bne 3f /* only restore TM if nothing else to do */ |
671 | addi r3,r1,STACK_FRAME_OVERHEAD | 666 | addi r3,r1,STACK_FRAME_OVERHEAD |
672 | bl .restore_tm_state | 667 | bl restore_tm_state |
673 | b restore | 668 | b restore |
674 | 3: | 669 | 3: |
675 | #endif | 670 | #endif |
676 | bl .save_nvgprs | 671 | bl save_nvgprs |
677 | bl .restore_interrupts | 672 | bl restore_interrupts |
678 | addi r3,r1,STACK_FRAME_OVERHEAD | 673 | addi r3,r1,STACK_FRAME_OVERHEAD |
679 | bl .do_notify_resume | 674 | bl do_notify_resume |
680 | b .ret_from_except | 675 | b ret_from_except |
681 | 676 | ||
682 | resume_kernel: | 677 | resume_kernel: |
683 | /* check current_thread_info, _TIF_EMULATE_STACK_STORE */ | 678 | /* check current_thread_info, _TIF_EMULATE_STACK_STORE */ |
@@ -730,7 +725,7 @@ resume_kernel: | |||
730 | * sure we are soft-disabled first and reconcile irq state. | 725 | * sure we are soft-disabled first and reconcile irq state. |
731 | */ | 726 | */ |
732 | RECONCILE_IRQ_STATE(r3,r4) | 727 | RECONCILE_IRQ_STATE(r3,r4) |
733 | 1: bl .preempt_schedule_irq | 728 | 1: bl preempt_schedule_irq |
734 | 729 | ||
735 | /* Re-test flags and eventually loop */ | 730 | /* Re-test flags and eventually loop */ |
736 | CURRENT_THREAD_INFO(r9, r1) | 731 | CURRENT_THREAD_INFO(r9, r1) |
@@ -792,7 +787,7 @@ restore_no_replay: | |||
792 | */ | 787 | */ |
793 | do_restore: | 788 | do_restore: |
794 | #ifdef CONFIG_PPC_BOOK3E | 789 | #ifdef CONFIG_PPC_BOOK3E |
795 | b .exception_return_book3e | 790 | b exception_return_book3e |
796 | #else | 791 | #else |
797 | /* | 792 | /* |
798 | * Clear the reservation. If we know the CPU tracks the address of | 793 | * Clear the reservation. If we know the CPU tracks the address of |
@@ -907,7 +902,7 @@ restore_check_irq_replay: | |||
907 | * | 902 | * |
908 | * Still, this might be useful for things like hash_page | 903 | * Still, this might be useful for things like hash_page |
909 | */ | 904 | */ |
910 | bl .__check_irq_replay | 905 | bl __check_irq_replay |
911 | cmpwi cr0,r3,0 | 906 | cmpwi cr0,r3,0 |
912 | beq restore_no_replay | 907 | beq restore_no_replay |
913 | 908 | ||
@@ -928,13 +923,13 @@ restore_check_irq_replay: | |||
928 | cmpwi cr0,r3,0x500 | 923 | cmpwi cr0,r3,0x500 |
929 | bne 1f | 924 | bne 1f |
930 | addi r3,r1,STACK_FRAME_OVERHEAD; | 925 | addi r3,r1,STACK_FRAME_OVERHEAD; |
931 | bl .do_IRQ | 926 | bl do_IRQ |
932 | b .ret_from_except | 927 | b ret_from_except |
933 | 1: cmpwi cr0,r3,0x900 | 928 | 1: cmpwi cr0,r3,0x900 |
934 | bne 1f | 929 | bne 1f |
935 | addi r3,r1,STACK_FRAME_OVERHEAD; | 930 | addi r3,r1,STACK_FRAME_OVERHEAD; |
936 | bl .timer_interrupt | 931 | bl timer_interrupt |
937 | b .ret_from_except | 932 | b ret_from_except |
938 | #ifdef CONFIG_PPC_DOORBELL | 933 | #ifdef CONFIG_PPC_DOORBELL |
939 | 1: | 934 | 1: |
940 | #ifdef CONFIG_PPC_BOOK3E | 935 | #ifdef CONFIG_PPC_BOOK3E |
@@ -948,14 +943,14 @@ restore_check_irq_replay: | |||
948 | #endif /* CONFIG_PPC_BOOK3E */ | 943 | #endif /* CONFIG_PPC_BOOK3E */ |
949 | bne 1f | 944 | bne 1f |
950 | addi r3,r1,STACK_FRAME_OVERHEAD; | 945 | addi r3,r1,STACK_FRAME_OVERHEAD; |
951 | bl .doorbell_exception | 946 | bl doorbell_exception |
952 | b .ret_from_except | 947 | b ret_from_except |
953 | #endif /* CONFIG_PPC_DOORBELL */ | 948 | #endif /* CONFIG_PPC_DOORBELL */ |
954 | 1: b .ret_from_except /* What else to do here ? */ | 949 | 1: b ret_from_except /* What else to do here ? */ |
955 | 950 | ||
956 | unrecov_restore: | 951 | unrecov_restore: |
957 | addi r3,r1,STACK_FRAME_OVERHEAD | 952 | addi r3,r1,STACK_FRAME_OVERHEAD |
958 | bl .unrecoverable_exception | 953 | bl unrecoverable_exception |
959 | b unrecov_restore | 954 | b unrecov_restore |
960 | 955 | ||
961 | #ifdef CONFIG_PPC_RTAS | 956 | #ifdef CONFIG_PPC_RTAS |
@@ -1021,7 +1016,7 @@ _GLOBAL(enter_rtas) | |||
1021 | std r6,PACASAVEDMSR(r13) | 1016 | std r6,PACASAVEDMSR(r13) |
1022 | 1017 | ||
1023 | /* Setup our real return addr */ | 1018 | /* Setup our real return addr */ |
1024 | LOAD_REG_ADDR(r4,.rtas_return_loc) | 1019 | LOAD_REG_ADDR(r4,rtas_return_loc) |
1025 | clrldi r4,r4,2 /* convert to realmode address */ | 1020 | clrldi r4,r4,2 /* convert to realmode address */ |
1026 | mtlr r4 | 1021 | mtlr r4 |
1027 | 1022 | ||
@@ -1045,7 +1040,7 @@ _GLOBAL(enter_rtas) | |||
1045 | rfid | 1040 | rfid |
1046 | b . /* prevent speculative execution */ | 1041 | b . /* prevent speculative execution */ |
1047 | 1042 | ||
1048 | _STATIC(rtas_return_loc) | 1043 | rtas_return_loc: |
1049 | FIXUP_ENDIAN | 1044 | FIXUP_ENDIAN |
1050 | 1045 | ||
1051 | /* relocation is off at this point */ | 1046 | /* relocation is off at this point */ |
@@ -1054,7 +1049,7 @@ _STATIC(rtas_return_loc) | |||
1054 | 1049 | ||
1055 | bcl 20,31,$+4 | 1050 | bcl 20,31,$+4 |
1056 | 0: mflr r3 | 1051 | 0: mflr r3 |
1057 | ld r3,(1f-0b)(r3) /* get &.rtas_restore_regs */ | 1052 | ld r3,(1f-0b)(r3) /* get &rtas_restore_regs */ |
1058 | 1053 | ||
1059 | mfmsr r6 | 1054 | mfmsr r6 |
1060 | li r0,MSR_RI | 1055 | li r0,MSR_RI |
@@ -1071,9 +1066,9 @@ _STATIC(rtas_return_loc) | |||
1071 | b . /* prevent speculative execution */ | 1066 | b . /* prevent speculative execution */ |
1072 | 1067 | ||
1073 | .align 3 | 1068 | .align 3 |
1074 | 1: .llong .rtas_restore_regs | 1069 | 1: .llong rtas_restore_regs |
1075 | 1070 | ||
1076 | _STATIC(rtas_restore_regs) | 1071 | rtas_restore_regs: |
1077 | /* relocation is on at this point */ | 1072 | /* relocation is on at this point */ |
1078 | REST_GPR(2, r1) /* Restore the TOC */ | 1073 | REST_GPR(2, r1) /* Restore the TOC */ |
1079 | REST_GPR(13, r1) /* Restore paca */ | 1074 | REST_GPR(13, r1) /* Restore paca */ |
@@ -1173,7 +1168,7 @@ _GLOBAL(mcount) | |||
1173 | _GLOBAL(_mcount) | 1168 | _GLOBAL(_mcount) |
1174 | blr | 1169 | blr |
1175 | 1170 | ||
1176 | _GLOBAL(ftrace_caller) | 1171 | _GLOBAL_TOC(ftrace_caller) |
1177 | /* Taken from output of objdump from lib64/glibc */ | 1172 | /* Taken from output of objdump from lib64/glibc */ |
1178 | mflr r3 | 1173 | mflr r3 |
1179 | ld r11, 0(r1) | 1174 | ld r11, 0(r1) |
@@ -1197,10 +1192,7 @@ _GLOBAL(ftrace_graph_stub) | |||
1197 | _GLOBAL(ftrace_stub) | 1192 | _GLOBAL(ftrace_stub) |
1198 | blr | 1193 | blr |
1199 | #else | 1194 | #else |
1200 | _GLOBAL(mcount) | 1195 | _GLOBAL_TOC(_mcount) |
1201 | blr | ||
1202 | |||
1203 | _GLOBAL(_mcount) | ||
1204 | /* Taken from output of objdump from lib64/glibc */ | 1196 | /* Taken from output of objdump from lib64/glibc */ |
1205 | mflr r3 | 1197 | mflr r3 |
1206 | ld r11, 0(r1) | 1198 | ld r11, 0(r1) |
@@ -1238,7 +1230,7 @@ _GLOBAL(ftrace_graph_caller) | |||
1238 | ld r11, 112(r1) | 1230 | ld r11, 112(r1) |
1239 | addi r3, r11, 16 | 1231 | addi r3, r11, 16 |
1240 | 1232 | ||
1241 | bl .prepare_ftrace_return | 1233 | bl prepare_ftrace_return |
1242 | nop | 1234 | nop |
1243 | 1235 | ||
1244 | ld r0, 128(r1) | 1236 | ld r0, 128(r1) |
@@ -1254,7 +1246,7 @@ _GLOBAL(return_to_handler) | |||
1254 | mr r31, r1 | 1246 | mr r31, r1 |
1255 | stdu r1, -112(r1) | 1247 | stdu r1, -112(r1) |
1256 | 1248 | ||
1257 | bl .ftrace_return_to_handler | 1249 | bl ftrace_return_to_handler |
1258 | nop | 1250 | nop |
1259 | 1251 | ||
1260 | /* return value has real return address */ | 1252 | /* return value has real return address */ |
@@ -1284,7 +1276,7 @@ _GLOBAL(mod_return_to_handler) | |||
1284 | */ | 1276 | */ |
1285 | ld r2, PACATOC(r13) | 1277 | ld r2, PACATOC(r13) |
1286 | 1278 | ||
1287 | bl .ftrace_return_to_handler | 1279 | bl ftrace_return_to_handler |
1288 | nop | 1280 | nop |
1289 | 1281 | ||
1290 | /* return value has real return address */ | 1282 | /* return value has real return address */ |
diff --git a/arch/powerpc/kernel/epapr_paravirt.c b/arch/powerpc/kernel/epapr_paravirt.c index 60d1a2259dbe..59e4ba74975d 100644 --- a/arch/powerpc/kernel/epapr_paravirt.c +++ b/arch/powerpc/kernel/epapr_paravirt.c | |||
@@ -30,6 +30,7 @@ extern u32 epapr_ev_idle_start[]; | |||
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | bool epapr_paravirt_enabled; | 32 | bool epapr_paravirt_enabled; |
33 | static bool __maybe_unused epapr_has_idle; | ||
33 | 34 | ||
34 | static int __init early_init_dt_scan_epapr(unsigned long node, | 35 | static int __init early_init_dt_scan_epapr(unsigned long node, |
35 | const char *uname, | 36 | const char *uname, |
@@ -56,7 +57,7 @@ static int __init early_init_dt_scan_epapr(unsigned long node, | |||
56 | 57 | ||
57 | #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64) | 58 | #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64) |
58 | if (of_get_flat_dt_prop(node, "has-idle", NULL)) | 59 | if (of_get_flat_dt_prop(node, "has-idle", NULL)) |
59 | ppc_md.power_save = epapr_ev_idle; | 60 | epapr_has_idle = true; |
60 | #endif | 61 | #endif |
61 | 62 | ||
62 | epapr_paravirt_enabled = true; | 63 | epapr_paravirt_enabled = true; |
@@ -71,3 +72,14 @@ int __init epapr_paravirt_early_init(void) | |||
71 | return 0; | 72 | return 0; |
72 | } | 73 | } |
73 | 74 | ||
75 | static int __init epapr_idle_init(void) | ||
76 | { | ||
77 | #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64) | ||
78 | if (epapr_has_idle) | ||
79 | ppc_md.power_save = epapr_ev_idle; | ||
80 | #endif | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | postcore_initcall(epapr_idle_init); | ||
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index c1bee3ce9d1f..771b4e92e5d9 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S | |||
@@ -499,7 +499,7 @@ exc_##n##_bad_stack: \ | |||
499 | CHECK_NAPPING(); \ | 499 | CHECK_NAPPING(); \ |
500 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | 500 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
501 | bl hdlr; \ | 501 | bl hdlr; \ |
502 | b .ret_from_except_lite; | 502 | b ret_from_except_lite; |
503 | 503 | ||
504 | /* This value is used to mark exception frames on the stack. */ | 504 | /* This value is used to mark exception frames on the stack. */ |
505 | .section ".toc","aw" | 505 | .section ".toc","aw" |
@@ -550,11 +550,11 @@ interrupt_end_book3e: | |||
550 | CRIT_EXCEPTION_PROLOG(0x100, BOOKE_INTERRUPT_CRITICAL, | 550 | CRIT_EXCEPTION_PROLOG(0x100, BOOKE_INTERRUPT_CRITICAL, |
551 | PROLOG_ADDITION_NONE) | 551 | PROLOG_ADDITION_NONE) |
552 | EXCEPTION_COMMON_CRIT(0x100) | 552 | EXCEPTION_COMMON_CRIT(0x100) |
553 | bl .save_nvgprs | 553 | bl save_nvgprs |
554 | bl special_reg_save | 554 | bl special_reg_save |
555 | CHECK_NAPPING(); | 555 | CHECK_NAPPING(); |
556 | addi r3,r1,STACK_FRAME_OVERHEAD | 556 | addi r3,r1,STACK_FRAME_OVERHEAD |
557 | bl .unknown_exception | 557 | bl unknown_exception |
558 | b ret_from_crit_except | 558 | b ret_from_crit_except |
559 | 559 | ||
560 | /* Machine Check Interrupt */ | 560 | /* Machine Check Interrupt */ |
@@ -562,11 +562,11 @@ interrupt_end_book3e: | |||
562 | MC_EXCEPTION_PROLOG(0x000, BOOKE_INTERRUPT_MACHINE_CHECK, | 562 | MC_EXCEPTION_PROLOG(0x000, BOOKE_INTERRUPT_MACHINE_CHECK, |
563 | PROLOG_ADDITION_NONE) | 563 | PROLOG_ADDITION_NONE) |
564 | EXCEPTION_COMMON_MC(0x000) | 564 | EXCEPTION_COMMON_MC(0x000) |
565 | bl .save_nvgprs | 565 | bl save_nvgprs |
566 | bl special_reg_save | 566 | bl special_reg_save |
567 | CHECK_NAPPING(); | 567 | CHECK_NAPPING(); |
568 | addi r3,r1,STACK_FRAME_OVERHEAD | 568 | addi r3,r1,STACK_FRAME_OVERHEAD |
569 | bl .machine_check_exception | 569 | bl machine_check_exception |
570 | b ret_from_mc_except | 570 | b ret_from_mc_except |
571 | 571 | ||
572 | /* Data Storage Interrupt */ | 572 | /* Data Storage Interrupt */ |
@@ -591,7 +591,7 @@ interrupt_end_book3e: | |||
591 | 591 | ||
592 | /* External Input Interrupt */ | 592 | /* External Input Interrupt */ |
593 | MASKABLE_EXCEPTION(0x500, BOOKE_INTERRUPT_EXTERNAL, | 593 | MASKABLE_EXCEPTION(0x500, BOOKE_INTERRUPT_EXTERNAL, |
594 | external_input, .do_IRQ, ACK_NONE) | 594 | external_input, do_IRQ, ACK_NONE) |
595 | 595 | ||
596 | /* Alignment */ | 596 | /* Alignment */ |
597 | START_EXCEPTION(alignment); | 597 | START_EXCEPTION(alignment); |
@@ -612,9 +612,9 @@ interrupt_end_book3e: | |||
612 | std r14,_DSISR(r1) | 612 | std r14,_DSISR(r1) |
613 | addi r3,r1,STACK_FRAME_OVERHEAD | 613 | addi r3,r1,STACK_FRAME_OVERHEAD |
614 | ld r14,PACA_EXGEN+EX_R14(r13) | 614 | ld r14,PACA_EXGEN+EX_R14(r13) |
615 | bl .save_nvgprs | 615 | bl save_nvgprs |
616 | bl .program_check_exception | 616 | bl program_check_exception |
617 | b .ret_from_except | 617 | b ret_from_except |
618 | 618 | ||
619 | /* Floating Point Unavailable Interrupt */ | 619 | /* Floating Point Unavailable Interrupt */ |
620 | START_EXCEPTION(fp_unavailable); | 620 | START_EXCEPTION(fp_unavailable); |
@@ -625,13 +625,13 @@ interrupt_end_book3e: | |||
625 | ld r12,_MSR(r1) | 625 | ld r12,_MSR(r1) |
626 | andi. r0,r12,MSR_PR; | 626 | andi. r0,r12,MSR_PR; |
627 | beq- 1f | 627 | beq- 1f |
628 | bl .load_up_fpu | 628 | bl load_up_fpu |
629 | b fast_exception_return | 629 | b fast_exception_return |
630 | 1: INTS_DISABLE | 630 | 1: INTS_DISABLE |
631 | bl .save_nvgprs | 631 | bl save_nvgprs |
632 | addi r3,r1,STACK_FRAME_OVERHEAD | 632 | addi r3,r1,STACK_FRAME_OVERHEAD |
633 | bl .kernel_fp_unavailable_exception | 633 | bl kernel_fp_unavailable_exception |
634 | b .ret_from_except | 634 | b ret_from_except |
635 | 635 | ||
636 | /* Altivec Unavailable Interrupt */ | 636 | /* Altivec Unavailable Interrupt */ |
637 | START_EXCEPTION(altivec_unavailable); | 637 | START_EXCEPTION(altivec_unavailable); |
@@ -644,16 +644,16 @@ BEGIN_FTR_SECTION | |||
644 | ld r12,_MSR(r1) | 644 | ld r12,_MSR(r1) |
645 | andi. r0,r12,MSR_PR; | 645 | andi. r0,r12,MSR_PR; |
646 | beq- 1f | 646 | beq- 1f |
647 | bl .load_up_altivec | 647 | bl load_up_altivec |
648 | b fast_exception_return | 648 | b fast_exception_return |
649 | 1: | 649 | 1: |
650 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 650 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
651 | #endif | 651 | #endif |
652 | INTS_DISABLE | 652 | INTS_DISABLE |
653 | bl .save_nvgprs | 653 | bl save_nvgprs |
654 | addi r3,r1,STACK_FRAME_OVERHEAD | 654 | addi r3,r1,STACK_FRAME_OVERHEAD |
655 | bl .altivec_unavailable_exception | 655 | bl altivec_unavailable_exception |
656 | b .ret_from_except | 656 | b ret_from_except |
657 | 657 | ||
658 | /* AltiVec Assist */ | 658 | /* AltiVec Assist */ |
659 | START_EXCEPTION(altivec_assist); | 659 | START_EXCEPTION(altivec_assist); |
@@ -662,39 +662,39 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
662 | PROLOG_ADDITION_NONE) | 662 | PROLOG_ADDITION_NONE) |
663 | EXCEPTION_COMMON(0x220) | 663 | EXCEPTION_COMMON(0x220) |
664 | INTS_DISABLE | 664 | INTS_DISABLE |
665 | bl .save_nvgprs | 665 | bl save_nvgprs |
666 | addi r3,r1,STACK_FRAME_OVERHEAD | 666 | addi r3,r1,STACK_FRAME_OVERHEAD |
667 | #ifdef CONFIG_ALTIVEC | 667 | #ifdef CONFIG_ALTIVEC |
668 | BEGIN_FTR_SECTION | 668 | BEGIN_FTR_SECTION |
669 | bl .altivec_assist_exception | 669 | bl altivec_assist_exception |
670 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 670 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
671 | #else | 671 | #else |
672 | bl .unknown_exception | 672 | bl unknown_exception |
673 | #endif | 673 | #endif |
674 | b .ret_from_except | 674 | b ret_from_except |
675 | 675 | ||
676 | 676 | ||
677 | /* Decrementer Interrupt */ | 677 | /* Decrementer Interrupt */ |
678 | MASKABLE_EXCEPTION(0x900, BOOKE_INTERRUPT_DECREMENTER, | 678 | MASKABLE_EXCEPTION(0x900, BOOKE_INTERRUPT_DECREMENTER, |
679 | decrementer, .timer_interrupt, ACK_DEC) | 679 | decrementer, timer_interrupt, ACK_DEC) |
680 | 680 | ||
681 | /* Fixed Interval Timer Interrupt */ | 681 | /* Fixed Interval Timer Interrupt */ |
682 | MASKABLE_EXCEPTION(0x980, BOOKE_INTERRUPT_FIT, | 682 | MASKABLE_EXCEPTION(0x980, BOOKE_INTERRUPT_FIT, |
683 | fixed_interval, .unknown_exception, ACK_FIT) | 683 | fixed_interval, unknown_exception, ACK_FIT) |
684 | 684 | ||
685 | /* Watchdog Timer Interrupt */ | 685 | /* Watchdog Timer Interrupt */ |
686 | START_EXCEPTION(watchdog); | 686 | START_EXCEPTION(watchdog); |
687 | CRIT_EXCEPTION_PROLOG(0x9f0, BOOKE_INTERRUPT_WATCHDOG, | 687 | CRIT_EXCEPTION_PROLOG(0x9f0, BOOKE_INTERRUPT_WATCHDOG, |
688 | PROLOG_ADDITION_NONE) | 688 | PROLOG_ADDITION_NONE) |
689 | EXCEPTION_COMMON_CRIT(0x9f0) | 689 | EXCEPTION_COMMON_CRIT(0x9f0) |
690 | bl .save_nvgprs | 690 | bl save_nvgprs |
691 | bl special_reg_save | 691 | bl special_reg_save |
692 | CHECK_NAPPING(); | 692 | CHECK_NAPPING(); |
693 | addi r3,r1,STACK_FRAME_OVERHEAD | 693 | addi r3,r1,STACK_FRAME_OVERHEAD |
694 | #ifdef CONFIG_BOOKE_WDT | 694 | #ifdef CONFIG_BOOKE_WDT |
695 | bl .WatchdogException | 695 | bl WatchdogException |
696 | #else | 696 | #else |
697 | bl .unknown_exception | 697 | bl unknown_exception |
698 | #endif | 698 | #endif |
699 | b ret_from_crit_except | 699 | b ret_from_crit_except |
700 | 700 | ||
@@ -712,10 +712,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
712 | PROLOG_ADDITION_NONE) | 712 | PROLOG_ADDITION_NONE) |
713 | EXCEPTION_COMMON(0xf20) | 713 | EXCEPTION_COMMON(0xf20) |
714 | INTS_DISABLE | 714 | INTS_DISABLE |
715 | bl .save_nvgprs | 715 | bl save_nvgprs |
716 | addi r3,r1,STACK_FRAME_OVERHEAD | 716 | addi r3,r1,STACK_FRAME_OVERHEAD |
717 | bl .unknown_exception | 717 | bl unknown_exception |
718 | b .ret_from_except | 718 | b ret_from_except |
719 | 719 | ||
720 | /* Debug exception as a critical interrupt*/ | 720 | /* Debug exception as a critical interrupt*/ |
721 | START_EXCEPTION(debug_crit); | 721 | START_EXCEPTION(debug_crit); |
@@ -774,9 +774,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
774 | mr r4,r14 | 774 | mr r4,r14 |
775 | ld r14,PACA_EXCRIT+EX_R14(r13) | 775 | ld r14,PACA_EXCRIT+EX_R14(r13) |
776 | ld r15,PACA_EXCRIT+EX_R15(r13) | 776 | ld r15,PACA_EXCRIT+EX_R15(r13) |
777 | bl .save_nvgprs | 777 | bl save_nvgprs |
778 | bl .DebugException | 778 | bl DebugException |
779 | b .ret_from_except | 779 | b ret_from_except |
780 | 780 | ||
781 | kernel_dbg_exc: | 781 | kernel_dbg_exc: |
782 | b . /* NYI */ | 782 | b . /* NYI */ |
@@ -839,9 +839,9 @@ kernel_dbg_exc: | |||
839 | mr r4,r14 | 839 | mr r4,r14 |
840 | ld r14,PACA_EXDBG+EX_R14(r13) | 840 | ld r14,PACA_EXDBG+EX_R14(r13) |
841 | ld r15,PACA_EXDBG+EX_R15(r13) | 841 | ld r15,PACA_EXDBG+EX_R15(r13) |
842 | bl .save_nvgprs | 842 | bl save_nvgprs |
843 | bl .DebugException | 843 | bl DebugException |
844 | b .ret_from_except | 844 | b ret_from_except |
845 | 845 | ||
846 | START_EXCEPTION(perfmon); | 846 | START_EXCEPTION(perfmon); |
847 | NORMAL_EXCEPTION_PROLOG(0x260, BOOKE_INTERRUPT_PERFORMANCE_MONITOR, | 847 | NORMAL_EXCEPTION_PROLOG(0x260, BOOKE_INTERRUPT_PERFORMANCE_MONITOR, |
@@ -850,23 +850,23 @@ kernel_dbg_exc: | |||
850 | INTS_DISABLE | 850 | INTS_DISABLE |
851 | CHECK_NAPPING() | 851 | CHECK_NAPPING() |
852 | addi r3,r1,STACK_FRAME_OVERHEAD | 852 | addi r3,r1,STACK_FRAME_OVERHEAD |
853 | bl .performance_monitor_exception | 853 | bl performance_monitor_exception |
854 | b .ret_from_except_lite | 854 | b ret_from_except_lite |
855 | 855 | ||
856 | /* Doorbell interrupt */ | 856 | /* Doorbell interrupt */ |
857 | MASKABLE_EXCEPTION(0x280, BOOKE_INTERRUPT_DOORBELL, | 857 | MASKABLE_EXCEPTION(0x280, BOOKE_INTERRUPT_DOORBELL, |
858 | doorbell, .doorbell_exception, ACK_NONE) | 858 | doorbell, doorbell_exception, ACK_NONE) |
859 | 859 | ||
860 | /* Doorbell critical Interrupt */ | 860 | /* Doorbell critical Interrupt */ |
861 | START_EXCEPTION(doorbell_crit); | 861 | START_EXCEPTION(doorbell_crit); |
862 | CRIT_EXCEPTION_PROLOG(0x2a0, BOOKE_INTERRUPT_DOORBELL_CRITICAL, | 862 | CRIT_EXCEPTION_PROLOG(0x2a0, BOOKE_INTERRUPT_DOORBELL_CRITICAL, |
863 | PROLOG_ADDITION_NONE) | 863 | PROLOG_ADDITION_NONE) |
864 | EXCEPTION_COMMON_CRIT(0x2a0) | 864 | EXCEPTION_COMMON_CRIT(0x2a0) |
865 | bl .save_nvgprs | 865 | bl save_nvgprs |
866 | bl special_reg_save | 866 | bl special_reg_save |
867 | CHECK_NAPPING(); | 867 | CHECK_NAPPING(); |
868 | addi r3,r1,STACK_FRAME_OVERHEAD | 868 | addi r3,r1,STACK_FRAME_OVERHEAD |
869 | bl .unknown_exception | 869 | bl unknown_exception |
870 | b ret_from_crit_except | 870 | b ret_from_crit_except |
871 | 871 | ||
872 | /* | 872 | /* |
@@ -878,21 +878,21 @@ kernel_dbg_exc: | |||
878 | PROLOG_ADDITION_NONE) | 878 | PROLOG_ADDITION_NONE) |
879 | EXCEPTION_COMMON(0x2c0) | 879 | EXCEPTION_COMMON(0x2c0) |
880 | addi r3,r1,STACK_FRAME_OVERHEAD | 880 | addi r3,r1,STACK_FRAME_OVERHEAD |
881 | bl .save_nvgprs | 881 | bl save_nvgprs |
882 | INTS_RESTORE_HARD | 882 | INTS_RESTORE_HARD |
883 | bl .unknown_exception | 883 | bl unknown_exception |
884 | b .ret_from_except | 884 | b ret_from_except |
885 | 885 | ||
886 | /* Guest Doorbell critical Interrupt */ | 886 | /* Guest Doorbell critical Interrupt */ |
887 | START_EXCEPTION(guest_doorbell_crit); | 887 | START_EXCEPTION(guest_doorbell_crit); |
888 | CRIT_EXCEPTION_PROLOG(0x2e0, BOOKE_INTERRUPT_GUEST_DBELL_CRIT, | 888 | CRIT_EXCEPTION_PROLOG(0x2e0, BOOKE_INTERRUPT_GUEST_DBELL_CRIT, |
889 | PROLOG_ADDITION_NONE) | 889 | PROLOG_ADDITION_NONE) |
890 | EXCEPTION_COMMON_CRIT(0x2e0) | 890 | EXCEPTION_COMMON_CRIT(0x2e0) |
891 | bl .save_nvgprs | 891 | bl save_nvgprs |
892 | bl special_reg_save | 892 | bl special_reg_save |
893 | CHECK_NAPPING(); | 893 | CHECK_NAPPING(); |
894 | addi r3,r1,STACK_FRAME_OVERHEAD | 894 | addi r3,r1,STACK_FRAME_OVERHEAD |
895 | bl .unknown_exception | 895 | bl unknown_exception |
896 | b ret_from_crit_except | 896 | b ret_from_crit_except |
897 | 897 | ||
898 | /* Hypervisor call */ | 898 | /* Hypervisor call */ |
@@ -901,10 +901,10 @@ kernel_dbg_exc: | |||
901 | PROLOG_ADDITION_NONE) | 901 | PROLOG_ADDITION_NONE) |
902 | EXCEPTION_COMMON(0x310) | 902 | EXCEPTION_COMMON(0x310) |
903 | addi r3,r1,STACK_FRAME_OVERHEAD | 903 | addi r3,r1,STACK_FRAME_OVERHEAD |
904 | bl .save_nvgprs | 904 | bl save_nvgprs |
905 | INTS_RESTORE_HARD | 905 | INTS_RESTORE_HARD |
906 | bl .unknown_exception | 906 | bl unknown_exception |
907 | b .ret_from_except | 907 | b ret_from_except |
908 | 908 | ||
909 | /* Embedded Hypervisor priviledged */ | 909 | /* Embedded Hypervisor priviledged */ |
910 | START_EXCEPTION(ehpriv); | 910 | START_EXCEPTION(ehpriv); |
@@ -912,10 +912,10 @@ kernel_dbg_exc: | |||
912 | PROLOG_ADDITION_NONE) | 912 | PROLOG_ADDITION_NONE) |
913 | EXCEPTION_COMMON(0x320) | 913 | EXCEPTION_COMMON(0x320) |
914 | addi r3,r1,STACK_FRAME_OVERHEAD | 914 | addi r3,r1,STACK_FRAME_OVERHEAD |
915 | bl .save_nvgprs | 915 | bl save_nvgprs |
916 | INTS_RESTORE_HARD | 916 | INTS_RESTORE_HARD |
917 | bl .unknown_exception | 917 | bl unknown_exception |
918 | b .ret_from_except | 918 | b ret_from_except |
919 | 919 | ||
920 | /* LRAT Error interrupt */ | 920 | /* LRAT Error interrupt */ |
921 | START_EXCEPTION(lrat_error); | 921 | START_EXCEPTION(lrat_error); |
@@ -1014,16 +1014,16 @@ storage_fault_common: | |||
1014 | mr r5,r15 | 1014 | mr r5,r15 |
1015 | ld r14,PACA_EXGEN+EX_R14(r13) | 1015 | ld r14,PACA_EXGEN+EX_R14(r13) |
1016 | ld r15,PACA_EXGEN+EX_R15(r13) | 1016 | ld r15,PACA_EXGEN+EX_R15(r13) |
1017 | bl .do_page_fault | 1017 | bl do_page_fault |
1018 | cmpdi r3,0 | 1018 | cmpdi r3,0 |
1019 | bne- 1f | 1019 | bne- 1f |
1020 | b .ret_from_except_lite | 1020 | b ret_from_except_lite |
1021 | 1: bl .save_nvgprs | 1021 | 1: bl save_nvgprs |
1022 | mr r5,r3 | 1022 | mr r5,r3 |
1023 | addi r3,r1,STACK_FRAME_OVERHEAD | 1023 | addi r3,r1,STACK_FRAME_OVERHEAD |
1024 | ld r4,_DAR(r1) | 1024 | ld r4,_DAR(r1) |
1025 | bl .bad_page_fault | 1025 | bl bad_page_fault |
1026 | b .ret_from_except | 1026 | b ret_from_except |
1027 | 1027 | ||
1028 | /* | 1028 | /* |
1029 | * Alignment exception doesn't fit entirely in the 0x100 bytes so it | 1029 | * Alignment exception doesn't fit entirely in the 0x100 bytes so it |
@@ -1035,10 +1035,10 @@ alignment_more: | |||
1035 | addi r3,r1,STACK_FRAME_OVERHEAD | 1035 | addi r3,r1,STACK_FRAME_OVERHEAD |
1036 | ld r14,PACA_EXGEN+EX_R14(r13) | 1036 | ld r14,PACA_EXGEN+EX_R14(r13) |
1037 | ld r15,PACA_EXGEN+EX_R15(r13) | 1037 | ld r15,PACA_EXGEN+EX_R15(r13) |
1038 | bl .save_nvgprs | 1038 | bl save_nvgprs |
1039 | INTS_RESTORE_HARD | 1039 | INTS_RESTORE_HARD |
1040 | bl .alignment_exception | 1040 | bl alignment_exception |
1041 | b .ret_from_except | 1041 | b ret_from_except |
1042 | 1042 | ||
1043 | /* | 1043 | /* |
1044 | * We branch here from entry_64.S for the last stage of the exception | 1044 | * We branch here from entry_64.S for the last stage of the exception |
@@ -1172,7 +1172,7 @@ bad_stack_book3e: | |||
1172 | std r12,0(r11) | 1172 | std r12,0(r11) |
1173 | ld r2,PACATOC(r13) | 1173 | ld r2,PACATOC(r13) |
1174 | 1: addi r3,r1,STACK_FRAME_OVERHEAD | 1174 | 1: addi r3,r1,STACK_FRAME_OVERHEAD |
1175 | bl .kernel_bad_stack | 1175 | bl kernel_bad_stack |
1176 | b 1b | 1176 | b 1b |
1177 | 1177 | ||
1178 | /* | 1178 | /* |
@@ -1521,13 +1521,13 @@ _GLOBAL(start_initialization_book3e) | |||
1521 | * and always use AS 0, so we just set it up to match our link | 1521 | * and always use AS 0, so we just set it up to match our link |
1522 | * address and never use 0 based addresses. | 1522 | * address and never use 0 based addresses. |
1523 | */ | 1523 | */ |
1524 | bl .initial_tlb_book3e | 1524 | bl initial_tlb_book3e |
1525 | 1525 | ||
1526 | /* Init global core bits */ | 1526 | /* Init global core bits */ |
1527 | bl .init_core_book3e | 1527 | bl init_core_book3e |
1528 | 1528 | ||
1529 | /* Init per-thread bits */ | 1529 | /* Init per-thread bits */ |
1530 | bl .init_thread_book3e | 1530 | bl init_thread_book3e |
1531 | 1531 | ||
1532 | /* Return to common init code */ | 1532 | /* Return to common init code */ |
1533 | tovirt(r28,r28) | 1533 | tovirt(r28,r28) |
@@ -1548,7 +1548,7 @@ _GLOBAL(start_initialization_book3e) | |||
1548 | */ | 1548 | */ |
1549 | _GLOBAL(book3e_secondary_core_init_tlb_set) | 1549 | _GLOBAL(book3e_secondary_core_init_tlb_set) |
1550 | li r4,1 | 1550 | li r4,1 |
1551 | b .generic_secondary_smp_init | 1551 | b generic_secondary_smp_init |
1552 | 1552 | ||
1553 | _GLOBAL(book3e_secondary_core_init) | 1553 | _GLOBAL(book3e_secondary_core_init) |
1554 | mflr r28 | 1554 | mflr r28 |
@@ -1558,18 +1558,18 @@ _GLOBAL(book3e_secondary_core_init) | |||
1558 | bne 2f | 1558 | bne 2f |
1559 | 1559 | ||
1560 | /* Setup TLB for this core */ | 1560 | /* Setup TLB for this core */ |
1561 | bl .initial_tlb_book3e | 1561 | bl initial_tlb_book3e |
1562 | 1562 | ||
1563 | /* We can return from the above running at a different | 1563 | /* We can return from the above running at a different |
1564 | * address, so recalculate r2 (TOC) | 1564 | * address, so recalculate r2 (TOC) |
1565 | */ | 1565 | */ |
1566 | bl .relative_toc | 1566 | bl relative_toc |
1567 | 1567 | ||
1568 | /* Init global core bits */ | 1568 | /* Init global core bits */ |
1569 | 2: bl .init_core_book3e | 1569 | 2: bl init_core_book3e |
1570 | 1570 | ||
1571 | /* Init per-thread bits */ | 1571 | /* Init per-thread bits */ |
1572 | 3: bl .init_thread_book3e | 1572 | 3: bl init_thread_book3e |
1573 | 1573 | ||
1574 | /* Return to common init code at proper virtual address. | 1574 | /* Return to common init code at proper virtual address. |
1575 | * | 1575 | * |
@@ -1596,14 +1596,14 @@ _GLOBAL(book3e_secondary_thread_init) | |||
1596 | mflr r28 | 1596 | mflr r28 |
1597 | b 3b | 1597 | b 3b |
1598 | 1598 | ||
1599 | _STATIC(init_core_book3e) | 1599 | init_core_book3e: |
1600 | /* Establish the interrupt vector base */ | 1600 | /* Establish the interrupt vector base */ |
1601 | LOAD_REG_IMMEDIATE(r3, interrupt_base_book3e) | 1601 | LOAD_REG_IMMEDIATE(r3, interrupt_base_book3e) |
1602 | mtspr SPRN_IVPR,r3 | 1602 | mtspr SPRN_IVPR,r3 |
1603 | sync | 1603 | sync |
1604 | blr | 1604 | blr |
1605 | 1605 | ||
1606 | _STATIC(init_thread_book3e) | 1606 | init_thread_book3e: |
1607 | lis r3,(SPRN_EPCR_ICM | SPRN_EPCR_GICM)@h | 1607 | lis r3,(SPRN_EPCR_ICM | SPRN_EPCR_GICM)@h |
1608 | mtspr SPRN_EPCR,r3 | 1608 | mtspr SPRN_EPCR,r3 |
1609 | 1609 | ||
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 3afd3915921a..20f11eb4dff7 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -132,12 +132,12 @@ BEGIN_FTR_SECTION | |||
132 | #endif | 132 | #endif |
133 | 133 | ||
134 | beq cr1,2f | 134 | beq cr1,2f |
135 | b .power7_wakeup_noloss | 135 | b power7_wakeup_noloss |
136 | 2: b .power7_wakeup_loss | 136 | 2: b power7_wakeup_loss |
137 | 137 | ||
138 | /* Fast Sleep wakeup on PowerNV */ | 138 | /* Fast Sleep wakeup on PowerNV */ |
139 | 8: GET_PACA(r13) | 139 | 8: GET_PACA(r13) |
140 | b .power7_wakeup_tb_loss | 140 | b power7_wakeup_tb_loss |
141 | 141 | ||
142 | 9: | 142 | 9: |
143 | END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) | 143 | END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) |
@@ -211,16 +211,16 @@ data_access_slb_pSeries: | |||
211 | #endif /* __DISABLED__ */ | 211 | #endif /* __DISABLED__ */ |
212 | mfspr r12,SPRN_SRR1 | 212 | mfspr r12,SPRN_SRR1 |
213 | #ifndef CONFIG_RELOCATABLE | 213 | #ifndef CONFIG_RELOCATABLE |
214 | b .slb_miss_realmode | 214 | b slb_miss_realmode |
215 | #else | 215 | #else |
216 | /* | 216 | /* |
217 | * We can't just use a direct branch to .slb_miss_realmode | 217 | * We can't just use a direct branch to slb_miss_realmode |
218 | * because the distance from here to there depends on where | 218 | * because the distance from here to there depends on where |
219 | * the kernel ends up being put. | 219 | * the kernel ends up being put. |
220 | */ | 220 | */ |
221 | mfctr r11 | 221 | mfctr r11 |
222 | ld r10,PACAKBASE(r13) | 222 | ld r10,PACAKBASE(r13) |
223 | LOAD_HANDLER(r10, .slb_miss_realmode) | 223 | LOAD_HANDLER(r10, slb_miss_realmode) |
224 | mtctr r10 | 224 | mtctr r10 |
225 | bctr | 225 | bctr |
226 | #endif | 226 | #endif |
@@ -243,11 +243,11 @@ instruction_access_slb_pSeries: | |||
243 | #endif /* __DISABLED__ */ | 243 | #endif /* __DISABLED__ */ |
244 | mfspr r12,SPRN_SRR1 | 244 | mfspr r12,SPRN_SRR1 |
245 | #ifndef CONFIG_RELOCATABLE | 245 | #ifndef CONFIG_RELOCATABLE |
246 | b .slb_miss_realmode | 246 | b slb_miss_realmode |
247 | #else | 247 | #else |
248 | mfctr r11 | 248 | mfctr r11 |
249 | ld r10,PACAKBASE(r13) | 249 | ld r10,PACAKBASE(r13) |
250 | LOAD_HANDLER(r10, .slb_miss_realmode) | 250 | LOAD_HANDLER(r10, slb_miss_realmode) |
251 | mtctr r10 | 251 | mtctr r10 |
252 | bctr | 252 | bctr |
253 | #endif | 253 | #endif |
@@ -524,7 +524,7 @@ do_stab_bolted_pSeries: | |||
524 | std r12,PACA_EXSLB+EX_R12(r13) | 524 | std r12,PACA_EXSLB+EX_R12(r13) |
525 | GET_SCRATCH0(r10) | 525 | GET_SCRATCH0(r10) |
526 | std r10,PACA_EXSLB+EX_R13(r13) | 526 | std r10,PACA_EXSLB+EX_R13(r13) |
527 | EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted, EXC_STD) | 527 | EXCEPTION_PROLOG_PSERIES_1(do_stab_bolted, EXC_STD) |
528 | 528 | ||
529 | KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x300) | 529 | KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x300) |
530 | KVM_HANDLER_SKIP(PACA_EXSLB, EXC_STD, 0x380) | 530 | KVM_HANDLER_SKIP(PACA_EXSLB, EXC_STD, 0x380) |
@@ -769,38 +769,38 @@ kvmppc_skip_Hinterrupt: | |||
769 | 769 | ||
770 | /*** Common interrupt handlers ***/ | 770 | /*** Common interrupt handlers ***/ |
771 | 771 | ||
772 | STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception) | 772 | STD_EXCEPTION_COMMON(0x100, system_reset, system_reset_exception) |
773 | 773 | ||
774 | STD_EXCEPTION_COMMON_ASYNC(0x500, hardware_interrupt, do_IRQ) | 774 | STD_EXCEPTION_COMMON_ASYNC(0x500, hardware_interrupt, do_IRQ) |
775 | STD_EXCEPTION_COMMON_ASYNC(0x900, decrementer, .timer_interrupt) | 775 | STD_EXCEPTION_COMMON_ASYNC(0x900, decrementer, timer_interrupt) |
776 | STD_EXCEPTION_COMMON(0x980, hdecrementer, .hdec_interrupt) | 776 | STD_EXCEPTION_COMMON(0x980, hdecrementer, hdec_interrupt) |
777 | #ifdef CONFIG_PPC_DOORBELL | 777 | #ifdef CONFIG_PPC_DOORBELL |
778 | STD_EXCEPTION_COMMON_ASYNC(0xa00, doorbell_super, .doorbell_exception) | 778 | STD_EXCEPTION_COMMON_ASYNC(0xa00, doorbell_super, doorbell_exception) |
779 | #else | 779 | #else |
780 | STD_EXCEPTION_COMMON_ASYNC(0xa00, doorbell_super, .unknown_exception) | 780 | STD_EXCEPTION_COMMON_ASYNC(0xa00, doorbell_super, unknown_exception) |
781 | #endif | 781 | #endif |
782 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) | 782 | STD_EXCEPTION_COMMON(0xb00, trap_0b, unknown_exception) |
783 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) | 783 | STD_EXCEPTION_COMMON(0xd00, single_step, single_step_exception) |
784 | STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) | 784 | STD_EXCEPTION_COMMON(0xe00, trap_0e, unknown_exception) |
785 | STD_EXCEPTION_COMMON(0xe40, emulation_assist, .emulation_assist_interrupt) | 785 | STD_EXCEPTION_COMMON(0xe40, emulation_assist, emulation_assist_interrupt) |
786 | STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception) | 786 | STD_EXCEPTION_COMMON(0xe60, hmi_exception, unknown_exception) |
787 | #ifdef CONFIG_PPC_DOORBELL | 787 | #ifdef CONFIG_PPC_DOORBELL |
788 | STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, .doorbell_exception) | 788 | STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, doorbell_exception) |
789 | #else | 789 | #else |
790 | STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, .unknown_exception) | 790 | STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, unknown_exception) |
791 | #endif | 791 | #endif |
792 | STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, .performance_monitor_exception) | 792 | STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, performance_monitor_exception) |
793 | STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception) | 793 | STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, instruction_breakpoint_exception) |
794 | STD_EXCEPTION_COMMON(0x1502, denorm, .unknown_exception) | 794 | STD_EXCEPTION_COMMON(0x1502, denorm, unknown_exception) |
795 | #ifdef CONFIG_ALTIVEC | 795 | #ifdef CONFIG_ALTIVEC |
796 | STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception) | 796 | STD_EXCEPTION_COMMON(0x1700, altivec_assist, altivec_assist_exception) |
797 | #else | 797 | #else |
798 | STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception) | 798 | STD_EXCEPTION_COMMON(0x1700, altivec_assist, unknown_exception) |
799 | #endif | 799 | #endif |
800 | #ifdef CONFIG_CBE_RAS | 800 | #ifdef CONFIG_CBE_RAS |
801 | STD_EXCEPTION_COMMON(0x1200, cbe_system_error, .cbe_system_error_exception) | 801 | STD_EXCEPTION_COMMON(0x1200, cbe_system_error, cbe_system_error_exception) |
802 | STD_EXCEPTION_COMMON(0x1600, cbe_maintenance, .cbe_maintenance_exception) | 802 | STD_EXCEPTION_COMMON(0x1600, cbe_maintenance, cbe_maintenance_exception) |
803 | STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception) | 803 | STD_EXCEPTION_COMMON(0x1800, cbe_thermal, cbe_thermal_exception) |
804 | #endif /* CONFIG_CBE_RAS */ | 804 | #endif /* CONFIG_CBE_RAS */ |
805 | 805 | ||
806 | /* | 806 | /* |
@@ -829,16 +829,16 @@ data_access_slb_relon_pSeries: | |||
829 | mfspr r3,SPRN_DAR | 829 | mfspr r3,SPRN_DAR |
830 | mfspr r12,SPRN_SRR1 | 830 | mfspr r12,SPRN_SRR1 |
831 | #ifndef CONFIG_RELOCATABLE | 831 | #ifndef CONFIG_RELOCATABLE |
832 | b .slb_miss_realmode | 832 | b slb_miss_realmode |
833 | #else | 833 | #else |
834 | /* | 834 | /* |
835 | * We can't just use a direct branch to .slb_miss_realmode | 835 | * We can't just use a direct branch to slb_miss_realmode |
836 | * because the distance from here to there depends on where | 836 | * because the distance from here to there depends on where |
837 | * the kernel ends up being put. | 837 | * the kernel ends up being put. |
838 | */ | 838 | */ |
839 | mfctr r11 | 839 | mfctr r11 |
840 | ld r10,PACAKBASE(r13) | 840 | ld r10,PACAKBASE(r13) |
841 | LOAD_HANDLER(r10, .slb_miss_realmode) | 841 | LOAD_HANDLER(r10, slb_miss_realmode) |
842 | mtctr r10 | 842 | mtctr r10 |
843 | bctr | 843 | bctr |
844 | #endif | 844 | #endif |
@@ -854,11 +854,11 @@ instruction_access_slb_relon_pSeries: | |||
854 | mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */ | 854 | mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */ |
855 | mfspr r12,SPRN_SRR1 | 855 | mfspr r12,SPRN_SRR1 |
856 | #ifndef CONFIG_RELOCATABLE | 856 | #ifndef CONFIG_RELOCATABLE |
857 | b .slb_miss_realmode | 857 | b slb_miss_realmode |
858 | #else | 858 | #else |
859 | mfctr r11 | 859 | mfctr r11 |
860 | ld r10,PACAKBASE(r13) | 860 | ld r10,PACAKBASE(r13) |
861 | LOAD_HANDLER(r10, .slb_miss_realmode) | 861 | LOAD_HANDLER(r10, slb_miss_realmode) |
862 | mtctr r10 | 862 | mtctr r10 |
863 | bctr | 863 | bctr |
864 | #endif | 864 | #endif |
@@ -966,7 +966,7 @@ system_call_entry: | |||
966 | b system_call_common | 966 | b system_call_common |
967 | 967 | ||
968 | ppc64_runlatch_on_trampoline: | 968 | ppc64_runlatch_on_trampoline: |
969 | b .__ppc64_runlatch_on | 969 | b __ppc64_runlatch_on |
970 | 970 | ||
971 | /* | 971 | /* |
972 | * Here we have detected that the kernel stack pointer is bad. | 972 | * Here we have detected that the kernel stack pointer is bad. |
@@ -1025,7 +1025,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR) | |||
1025 | std r12,RESULT(r1) | 1025 | std r12,RESULT(r1) |
1026 | std r11,STACK_FRAME_OVERHEAD-16(r1) | 1026 | std r11,STACK_FRAME_OVERHEAD-16(r1) |
1027 | 1: addi r3,r1,STACK_FRAME_OVERHEAD | 1027 | 1: addi r3,r1,STACK_FRAME_OVERHEAD |
1028 | bl .kernel_bad_stack | 1028 | bl kernel_bad_stack |
1029 | b 1b | 1029 | b 1b |
1030 | 1030 | ||
1031 | /* | 1031 | /* |
@@ -1046,7 +1046,7 @@ data_access_common: | |||
1046 | ld r3,PACA_EXGEN+EX_DAR(r13) | 1046 | ld r3,PACA_EXGEN+EX_DAR(r13) |
1047 | lwz r4,PACA_EXGEN+EX_DSISR(r13) | 1047 | lwz r4,PACA_EXGEN+EX_DSISR(r13) |
1048 | li r5,0x300 | 1048 | li r5,0x300 |
1049 | b .do_hash_page /* Try to handle as hpte fault */ | 1049 | b do_hash_page /* Try to handle as hpte fault */ |
1050 | 1050 | ||
1051 | .align 7 | 1051 | .align 7 |
1052 | .globl h_data_storage_common | 1052 | .globl h_data_storage_common |
@@ -1056,11 +1056,11 @@ h_data_storage_common: | |||
1056 | mfspr r10,SPRN_HDSISR | 1056 | mfspr r10,SPRN_HDSISR |
1057 | stw r10,PACA_EXGEN+EX_DSISR(r13) | 1057 | stw r10,PACA_EXGEN+EX_DSISR(r13) |
1058 | EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN) | 1058 | EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN) |
1059 | bl .save_nvgprs | 1059 | bl save_nvgprs |
1060 | DISABLE_INTS | 1060 | DISABLE_INTS |
1061 | addi r3,r1,STACK_FRAME_OVERHEAD | 1061 | addi r3,r1,STACK_FRAME_OVERHEAD |
1062 | bl .unknown_exception | 1062 | bl unknown_exception |
1063 | b .ret_from_except | 1063 | b ret_from_except |
1064 | 1064 | ||
1065 | .align 7 | 1065 | .align 7 |
1066 | .globl instruction_access_common | 1066 | .globl instruction_access_common |
@@ -1071,9 +1071,9 @@ instruction_access_common: | |||
1071 | ld r3,_NIP(r1) | 1071 | ld r3,_NIP(r1) |
1072 | andis. r4,r12,0x5820 | 1072 | andis. r4,r12,0x5820 |
1073 | li r5,0x400 | 1073 | li r5,0x400 |
1074 | b .do_hash_page /* Try to handle as hpte fault */ | 1074 | b do_hash_page /* Try to handle as hpte fault */ |
1075 | 1075 | ||
1076 | STD_EXCEPTION_COMMON(0xe20, h_instr_storage, .unknown_exception) | 1076 | STD_EXCEPTION_COMMON(0xe20, h_instr_storage, unknown_exception) |
1077 | 1077 | ||
1078 | /* | 1078 | /* |
1079 | * Here is the common SLB miss user that is used when going to virtual | 1079 | * Here is the common SLB miss user that is used when going to virtual |
@@ -1088,7 +1088,7 @@ slb_miss_user_common: | |||
1088 | stw r9,PACA_EXGEN+EX_CCR(r13) | 1088 | stw r9,PACA_EXGEN+EX_CCR(r13) |
1089 | std r10,PACA_EXGEN+EX_LR(r13) | 1089 | std r10,PACA_EXGEN+EX_LR(r13) |
1090 | std r11,PACA_EXGEN+EX_SRR0(r13) | 1090 | std r11,PACA_EXGEN+EX_SRR0(r13) |
1091 | bl .slb_allocate_user | 1091 | bl slb_allocate_user |
1092 | 1092 | ||
1093 | ld r10,PACA_EXGEN+EX_LR(r13) | 1093 | ld r10,PACA_EXGEN+EX_LR(r13) |
1094 | ld r3,PACA_EXGEN+EX_R3(r13) | 1094 | ld r3,PACA_EXGEN+EX_R3(r13) |
@@ -1131,9 +1131,9 @@ slb_miss_fault: | |||
1131 | unrecov_user_slb: | 1131 | unrecov_user_slb: |
1132 | EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN) | 1132 | EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN) |
1133 | DISABLE_INTS | 1133 | DISABLE_INTS |
1134 | bl .save_nvgprs | 1134 | bl save_nvgprs |
1135 | 1: addi r3,r1,STACK_FRAME_OVERHEAD | 1135 | 1: addi r3,r1,STACK_FRAME_OVERHEAD |
1136 | bl .unrecoverable_exception | 1136 | bl unrecoverable_exception |
1137 | b 1b | 1137 | b 1b |
1138 | 1138 | ||
1139 | #endif /* __DISABLED__ */ | 1139 | #endif /* __DISABLED__ */ |
@@ -1158,10 +1158,10 @@ machine_check_common: | |||
1158 | lwz r4,PACA_EXGEN+EX_DSISR(r13) | 1158 | lwz r4,PACA_EXGEN+EX_DSISR(r13) |
1159 | std r3,_DAR(r1) | 1159 | std r3,_DAR(r1) |
1160 | std r4,_DSISR(r1) | 1160 | std r4,_DSISR(r1) |
1161 | bl .save_nvgprs | 1161 | bl save_nvgprs |
1162 | addi r3,r1,STACK_FRAME_OVERHEAD | 1162 | addi r3,r1,STACK_FRAME_OVERHEAD |
1163 | bl .machine_check_exception | 1163 | bl machine_check_exception |
1164 | b .ret_from_except | 1164 | b ret_from_except |
1165 | 1165 | ||
1166 | .align 7 | 1166 | .align 7 |
1167 | .globl alignment_common | 1167 | .globl alignment_common |
@@ -1175,31 +1175,31 @@ alignment_common: | |||
1175 | lwz r4,PACA_EXGEN+EX_DSISR(r13) | 1175 | lwz r4,PACA_EXGEN+EX_DSISR(r13) |
1176 | std r3,_DAR(r1) | 1176 | std r3,_DAR(r1) |
1177 | std r4,_DSISR(r1) | 1177 | std r4,_DSISR(r1) |
1178 | bl .save_nvgprs | 1178 | bl save_nvgprs |
1179 | DISABLE_INTS | 1179 | DISABLE_INTS |
1180 | addi r3,r1,STACK_FRAME_OVERHEAD | 1180 | addi r3,r1,STACK_FRAME_OVERHEAD |
1181 | bl .alignment_exception | 1181 | bl alignment_exception |
1182 | b .ret_from_except | 1182 | b ret_from_except |
1183 | 1183 | ||
1184 | .align 7 | 1184 | .align 7 |
1185 | .globl program_check_common | 1185 | .globl program_check_common |
1186 | program_check_common: | 1186 | program_check_common: |
1187 | EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN) | 1187 | EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN) |
1188 | bl .save_nvgprs | 1188 | bl save_nvgprs |
1189 | DISABLE_INTS | 1189 | DISABLE_INTS |
1190 | addi r3,r1,STACK_FRAME_OVERHEAD | 1190 | addi r3,r1,STACK_FRAME_OVERHEAD |
1191 | bl .program_check_exception | 1191 | bl program_check_exception |
1192 | b .ret_from_except | 1192 | b ret_from_except |
1193 | 1193 | ||
1194 | .align 7 | 1194 | .align 7 |
1195 | .globl fp_unavailable_common | 1195 | .globl fp_unavailable_common |
1196 | fp_unavailable_common: | 1196 | fp_unavailable_common: |
1197 | EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN) | 1197 | EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN) |
1198 | bne 1f /* if from user, just load it up */ | 1198 | bne 1f /* if from user, just load it up */ |
1199 | bl .save_nvgprs | 1199 | bl save_nvgprs |
1200 | DISABLE_INTS | 1200 | DISABLE_INTS |
1201 | addi r3,r1,STACK_FRAME_OVERHEAD | 1201 | addi r3,r1,STACK_FRAME_OVERHEAD |
1202 | bl .kernel_fp_unavailable_exception | 1202 | bl kernel_fp_unavailable_exception |
1203 | BUG_OPCODE | 1203 | BUG_OPCODE |
1204 | 1: | 1204 | 1: |
1205 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 1205 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
@@ -1211,15 +1211,15 @@ BEGIN_FTR_SECTION | |||
1211 | bne- 2f | 1211 | bne- 2f |
1212 | END_FTR_SECTION_IFSET(CPU_FTR_TM) | 1212 | END_FTR_SECTION_IFSET(CPU_FTR_TM) |
1213 | #endif | 1213 | #endif |
1214 | bl .load_up_fpu | 1214 | bl load_up_fpu |
1215 | b fast_exception_return | 1215 | b fast_exception_return |
1216 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 1216 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
1217 | 2: /* User process was in a transaction */ | 1217 | 2: /* User process was in a transaction */ |
1218 | bl .save_nvgprs | 1218 | bl save_nvgprs |
1219 | DISABLE_INTS | 1219 | DISABLE_INTS |
1220 | addi r3,r1,STACK_FRAME_OVERHEAD | 1220 | addi r3,r1,STACK_FRAME_OVERHEAD |
1221 | bl .fp_unavailable_tm | 1221 | bl fp_unavailable_tm |
1222 | b .ret_from_except | 1222 | b ret_from_except |
1223 | #endif | 1223 | #endif |
1224 | .align 7 | 1224 | .align 7 |
1225 | .globl altivec_unavailable_common | 1225 | .globl altivec_unavailable_common |
@@ -1237,24 +1237,24 @@ BEGIN_FTR_SECTION | |||
1237 | bne- 2f | 1237 | bne- 2f |
1238 | END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69) | 1238 | END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69) |
1239 | #endif | 1239 | #endif |
1240 | bl .load_up_altivec | 1240 | bl load_up_altivec |
1241 | b fast_exception_return | 1241 | b fast_exception_return |
1242 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 1242 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
1243 | 2: /* User process was in a transaction */ | 1243 | 2: /* User process was in a transaction */ |
1244 | bl .save_nvgprs | 1244 | bl save_nvgprs |
1245 | DISABLE_INTS | 1245 | DISABLE_INTS |
1246 | addi r3,r1,STACK_FRAME_OVERHEAD | 1246 | addi r3,r1,STACK_FRAME_OVERHEAD |
1247 | bl .altivec_unavailable_tm | 1247 | bl altivec_unavailable_tm |
1248 | b .ret_from_except | 1248 | b ret_from_except |
1249 | #endif | 1249 | #endif |
1250 | 1: | 1250 | 1: |
1251 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 1251 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
1252 | #endif | 1252 | #endif |
1253 | bl .save_nvgprs | 1253 | bl save_nvgprs |
1254 | DISABLE_INTS | 1254 | DISABLE_INTS |
1255 | addi r3,r1,STACK_FRAME_OVERHEAD | 1255 | addi r3,r1,STACK_FRAME_OVERHEAD |
1256 | bl .altivec_unavailable_exception | 1256 | bl altivec_unavailable_exception |
1257 | b .ret_from_except | 1257 | b ret_from_except |
1258 | 1258 | ||
1259 | .align 7 | 1259 | .align 7 |
1260 | .globl vsx_unavailable_common | 1260 | .globl vsx_unavailable_common |
@@ -1272,26 +1272,26 @@ BEGIN_FTR_SECTION | |||
1272 | bne- 2f | 1272 | bne- 2f |
1273 | END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69) | 1273 | END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69) |
1274 | #endif | 1274 | #endif |
1275 | b .load_up_vsx | 1275 | b load_up_vsx |
1276 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 1276 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
1277 | 2: /* User process was in a transaction */ | 1277 | 2: /* User process was in a transaction */ |
1278 | bl .save_nvgprs | 1278 | bl save_nvgprs |
1279 | DISABLE_INTS | 1279 | DISABLE_INTS |
1280 | addi r3,r1,STACK_FRAME_OVERHEAD | 1280 | addi r3,r1,STACK_FRAME_OVERHEAD |
1281 | bl .vsx_unavailable_tm | 1281 | bl vsx_unavailable_tm |
1282 | b .ret_from_except | 1282 | b ret_from_except |
1283 | #endif | 1283 | #endif |
1284 | 1: | 1284 | 1: |
1285 | END_FTR_SECTION_IFSET(CPU_FTR_VSX) | 1285 | END_FTR_SECTION_IFSET(CPU_FTR_VSX) |
1286 | #endif | 1286 | #endif |
1287 | bl .save_nvgprs | 1287 | bl save_nvgprs |
1288 | DISABLE_INTS | 1288 | DISABLE_INTS |
1289 | addi r3,r1,STACK_FRAME_OVERHEAD | 1289 | addi r3,r1,STACK_FRAME_OVERHEAD |
1290 | bl .vsx_unavailable_exception | 1290 | bl vsx_unavailable_exception |
1291 | b .ret_from_except | 1291 | b ret_from_except |
1292 | 1292 | ||
1293 | STD_EXCEPTION_COMMON(0xf60, facility_unavailable, .facility_unavailable_exception) | 1293 | STD_EXCEPTION_COMMON(0xf60, facility_unavailable, facility_unavailable_exception) |
1294 | STD_EXCEPTION_COMMON(0xf80, hv_facility_unavailable, .facility_unavailable_exception) | 1294 | STD_EXCEPTION_COMMON(0xf80, hv_facility_unavailable, facility_unavailable_exception) |
1295 | 1295 | ||
1296 | .align 7 | 1296 | .align 7 |
1297 | .globl __end_handlers | 1297 | .globl __end_handlers |
@@ -1386,9 +1386,9 @@ _GLOBAL(opal_mc_secondary_handler) | |||
1386 | machine_check_handle_early: | 1386 | machine_check_handle_early: |
1387 | std r0,GPR0(r1) /* Save r0 */ | 1387 | std r0,GPR0(r1) /* Save r0 */ |
1388 | EXCEPTION_PROLOG_COMMON_3(0x200) | 1388 | EXCEPTION_PROLOG_COMMON_3(0x200) |
1389 | bl .save_nvgprs | 1389 | bl save_nvgprs |
1390 | addi r3,r1,STACK_FRAME_OVERHEAD | 1390 | addi r3,r1,STACK_FRAME_OVERHEAD |
1391 | bl .machine_check_early | 1391 | bl machine_check_early |
1392 | ld r12,_MSR(r1) | 1392 | ld r12,_MSR(r1) |
1393 | #ifdef CONFIG_PPC_P7_NAP | 1393 | #ifdef CONFIG_PPC_P7_NAP |
1394 | /* | 1394 | /* |
@@ -1408,11 +1408,11 @@ machine_check_handle_early: | |||
1408 | /* Supervisor state loss */ | 1408 | /* Supervisor state loss */ |
1409 | li r0,1 | 1409 | li r0,1 |
1410 | stb r0,PACA_NAPSTATELOST(r13) | 1410 | stb r0,PACA_NAPSTATELOST(r13) |
1411 | 3: bl .machine_check_queue_event | 1411 | 3: bl machine_check_queue_event |
1412 | MACHINE_CHECK_HANDLER_WINDUP | 1412 | MACHINE_CHECK_HANDLER_WINDUP |
1413 | GET_PACA(r13) | 1413 | GET_PACA(r13) |
1414 | ld r1,PACAR1(r13) | 1414 | ld r1,PACAR1(r13) |
1415 | b .power7_enter_nap_mode | 1415 | b power7_enter_nap_mode |
1416 | 4: | 1416 | 4: |
1417 | #endif | 1417 | #endif |
1418 | /* | 1418 | /* |
@@ -1444,7 +1444,7 @@ machine_check_handle_early: | |||
1444 | andi. r11,r12,MSR_RI | 1444 | andi. r11,r12,MSR_RI |
1445 | bne 2f | 1445 | bne 2f |
1446 | 1: addi r3,r1,STACK_FRAME_OVERHEAD | 1446 | 1: addi r3,r1,STACK_FRAME_OVERHEAD |
1447 | bl .unrecoverable_exception | 1447 | bl unrecoverable_exception |
1448 | b 1b | 1448 | b 1b |
1449 | 2: | 1449 | 2: |
1450 | /* | 1450 | /* |
@@ -1452,7 +1452,7 @@ machine_check_handle_early: | |||
1452 | * Queue up the MCE event so that we can log it later, while | 1452 | * Queue up the MCE event so that we can log it later, while |
1453 | * returning from kernel or opal call. | 1453 | * returning from kernel or opal call. |
1454 | */ | 1454 | */ |
1455 | bl .machine_check_queue_event | 1455 | bl machine_check_queue_event |
1456 | MACHINE_CHECK_HANDLER_WINDUP | 1456 | MACHINE_CHECK_HANDLER_WINDUP |
1457 | rfid | 1457 | rfid |
1458 | 9: | 1458 | 9: |
@@ -1468,7 +1468,7 @@ machine_check_handle_early: | |||
1468 | * r3 is saved in paca->slb_r3 | 1468 | * r3 is saved in paca->slb_r3 |
1469 | * We assume we aren't going to take any exceptions during this procedure. | 1469 | * We assume we aren't going to take any exceptions during this procedure. |
1470 | */ | 1470 | */ |
1471 | _GLOBAL(slb_miss_realmode) | 1471 | slb_miss_realmode: |
1472 | mflr r10 | 1472 | mflr r10 |
1473 | #ifdef CONFIG_RELOCATABLE | 1473 | #ifdef CONFIG_RELOCATABLE |
1474 | mtctr r11 | 1474 | mtctr r11 |
@@ -1477,7 +1477,7 @@ _GLOBAL(slb_miss_realmode) | |||
1477 | stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ | 1477 | stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ |
1478 | std r10,PACA_EXSLB+EX_LR(r13) /* save LR */ | 1478 | std r10,PACA_EXSLB+EX_LR(r13) /* save LR */ |
1479 | 1479 | ||
1480 | bl .slb_allocate_realmode | 1480 | bl slb_allocate_realmode |
1481 | 1481 | ||
1482 | /* All done -- return from exception. */ | 1482 | /* All done -- return from exception. */ |
1483 | 1483 | ||
@@ -1517,9 +1517,9 @@ _GLOBAL(slb_miss_realmode) | |||
1517 | unrecov_slb: | 1517 | unrecov_slb: |
1518 | EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB) | 1518 | EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB) |
1519 | DISABLE_INTS | 1519 | DISABLE_INTS |
1520 | bl .save_nvgprs | 1520 | bl save_nvgprs |
1521 | 1: addi r3,r1,STACK_FRAME_OVERHEAD | 1521 | 1: addi r3,r1,STACK_FRAME_OVERHEAD |
1522 | bl .unrecoverable_exception | 1522 | bl unrecoverable_exception |
1523 | b 1b | 1523 | b 1b |
1524 | 1524 | ||
1525 | 1525 | ||
@@ -1536,7 +1536,7 @@ power4_fixup_nap: | |||
1536 | * Hash table stuff | 1536 | * Hash table stuff |
1537 | */ | 1537 | */ |
1538 | .align 7 | 1538 | .align 7 |
1539 | _STATIC(do_hash_page) | 1539 | do_hash_page: |
1540 | std r3,_DAR(r1) | 1540 | std r3,_DAR(r1) |
1541 | std r4,_DSISR(r1) | 1541 | std r4,_DSISR(r1) |
1542 | 1542 | ||
@@ -1573,7 +1573,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB) | |||
1573 | * | 1573 | * |
1574 | * at return r3 = 0 for success, 1 for page fault, negative for error | 1574 | * at return r3 = 0 for success, 1 for page fault, negative for error |
1575 | */ | 1575 | */ |
1576 | bl .hash_page /* build HPTE if possible */ | 1576 | bl hash_page /* build HPTE if possible */ |
1577 | cmpdi r3,0 /* see if hash_page succeeded */ | 1577 | cmpdi r3,0 /* see if hash_page succeeded */ |
1578 | 1578 | ||
1579 | /* Success */ | 1579 | /* Success */ |
@@ -1587,35 +1587,35 @@ handle_page_fault: | |||
1587 | 11: ld r4,_DAR(r1) | 1587 | 11: ld r4,_DAR(r1) |
1588 | ld r5,_DSISR(r1) | 1588 | ld r5,_DSISR(r1) |
1589 | addi r3,r1,STACK_FRAME_OVERHEAD | 1589 | addi r3,r1,STACK_FRAME_OVERHEAD |
1590 | bl .do_page_fault | 1590 | bl do_page_fault |
1591 | cmpdi r3,0 | 1591 | cmpdi r3,0 |
1592 | beq+ 12f | 1592 | beq+ 12f |
1593 | bl .save_nvgprs | 1593 | bl save_nvgprs |
1594 | mr r5,r3 | 1594 | mr r5,r3 |
1595 | addi r3,r1,STACK_FRAME_OVERHEAD | 1595 | addi r3,r1,STACK_FRAME_OVERHEAD |
1596 | lwz r4,_DAR(r1) | 1596 | lwz r4,_DAR(r1) |
1597 | bl .bad_page_fault | 1597 | bl bad_page_fault |
1598 | b .ret_from_except | 1598 | b ret_from_except |
1599 | 1599 | ||
1600 | /* We have a data breakpoint exception - handle it */ | 1600 | /* We have a data breakpoint exception - handle it */ |
1601 | handle_dabr_fault: | 1601 | handle_dabr_fault: |
1602 | bl .save_nvgprs | 1602 | bl save_nvgprs |
1603 | ld r4,_DAR(r1) | 1603 | ld r4,_DAR(r1) |
1604 | ld r5,_DSISR(r1) | 1604 | ld r5,_DSISR(r1) |
1605 | addi r3,r1,STACK_FRAME_OVERHEAD | 1605 | addi r3,r1,STACK_FRAME_OVERHEAD |
1606 | bl .do_break | 1606 | bl do_break |
1607 | 12: b .ret_from_except_lite | 1607 | 12: b ret_from_except_lite |
1608 | 1608 | ||
1609 | 1609 | ||
1610 | /* We have a page fault that hash_page could handle but HV refused | 1610 | /* We have a page fault that hash_page could handle but HV refused |
1611 | * the PTE insertion | 1611 | * the PTE insertion |
1612 | */ | 1612 | */ |
1613 | 13: bl .save_nvgprs | 1613 | 13: bl save_nvgprs |
1614 | mr r5,r3 | 1614 | mr r5,r3 |
1615 | addi r3,r1,STACK_FRAME_OVERHEAD | 1615 | addi r3,r1,STACK_FRAME_OVERHEAD |
1616 | ld r4,_DAR(r1) | 1616 | ld r4,_DAR(r1) |
1617 | bl .low_hash_fault | 1617 | bl low_hash_fault |
1618 | b .ret_from_except | 1618 | b ret_from_except |
1619 | 1619 | ||
1620 | /* | 1620 | /* |
1621 | * We come here as a result of a DSI at a point where we don't want | 1621 | * We come here as a result of a DSI at a point where we don't want |
@@ -1624,16 +1624,16 @@ handle_dabr_fault: | |||
1624 | * were soft-disabled. We want to invoke the exception handler for | 1624 | * were soft-disabled. We want to invoke the exception handler for |
1625 | * the access, or panic if there isn't a handler. | 1625 | * the access, or panic if there isn't a handler. |
1626 | */ | 1626 | */ |
1627 | 77: bl .save_nvgprs | 1627 | 77: bl save_nvgprs |
1628 | mr r4,r3 | 1628 | mr r4,r3 |
1629 | addi r3,r1,STACK_FRAME_OVERHEAD | 1629 | addi r3,r1,STACK_FRAME_OVERHEAD |
1630 | li r5,SIGSEGV | 1630 | li r5,SIGSEGV |
1631 | bl .bad_page_fault | 1631 | bl bad_page_fault |
1632 | b .ret_from_except | 1632 | b ret_from_except |
1633 | 1633 | ||
1634 | /* here we have a segment miss */ | 1634 | /* here we have a segment miss */ |
1635 | do_ste_alloc: | 1635 | do_ste_alloc: |
1636 | bl .ste_allocate /* try to insert stab entry */ | 1636 | bl ste_allocate /* try to insert stab entry */ |
1637 | cmpdi r3,0 | 1637 | cmpdi r3,0 |
1638 | bne- handle_page_fault | 1638 | bne- handle_page_fault |
1639 | b fast_exception_return | 1639 | b fast_exception_return |
@@ -1646,7 +1646,7 @@ do_ste_alloc: | |||
1646 | * We assume (DAR >> 60) == 0xc. | 1646 | * We assume (DAR >> 60) == 0xc. |
1647 | */ | 1647 | */ |
1648 | .align 7 | 1648 | .align 7 |
1649 | _GLOBAL(do_stab_bolted) | 1649 | do_stab_bolted: |
1650 | stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ | 1650 | stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ |
1651 | std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */ | 1651 | std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */ |
1652 | mfspr r11,SPRN_DAR /* ea */ | 1652 | mfspr r11,SPRN_DAR /* ea */ |
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c index 7213d930918d..742694c1d852 100644 --- a/arch/powerpc/kernel/fadump.c +++ b/arch/powerpc/kernel/fadump.c | |||
@@ -69,7 +69,7 @@ int __init early_init_dt_scan_fw_dump(unsigned long node, | |||
69 | */ | 69 | */ |
70 | token = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump", NULL); | 70 | token = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump", NULL); |
71 | if (!token) | 71 | if (!token) |
72 | return 0; | 72 | return 1; |
73 | 73 | ||
74 | fw_dump.fadump_supported = 1; | 74 | fw_dump.fadump_supported = 1; |
75 | fw_dump.ibm_configure_kernel_dump = *token; | 75 | fw_dump.ibm_configure_kernel_dump = *token; |
@@ -92,7 +92,7 @@ int __init early_init_dt_scan_fw_dump(unsigned long node, | |||
92 | &size); | 92 | &size); |
93 | 93 | ||
94 | if (!sections) | 94 | if (!sections) |
95 | return 0; | 95 | return 1; |
96 | 96 | ||
97 | num_sections = size / (3 * sizeof(u32)); | 97 | num_sections = size / (3 * sizeof(u32)); |
98 | 98 | ||
@@ -110,6 +110,7 @@ int __init early_init_dt_scan_fw_dump(unsigned long node, | |||
110 | break; | 110 | break; |
111 | } | 111 | } |
112 | } | 112 | } |
113 | |||
113 | return 1; | 114 | return 1; |
114 | } | 115 | } |
115 | 116 | ||
@@ -645,7 +646,7 @@ static int __init fadump_build_cpu_notes(const struct fadump_mem_struct *fdm) | |||
645 | } | 646 | } |
646 | /* Lower 4 bytes of reg_value contains logical cpu id */ | 647 | /* Lower 4 bytes of reg_value contains logical cpu id */ |
647 | cpu = reg_entry->reg_value & FADUMP_CPU_ID_MASK; | 648 | cpu = reg_entry->reg_value & FADUMP_CPU_ID_MASK; |
648 | if (!cpumask_test_cpu(cpu, &fdh->cpu_online_mask)) { | 649 | if (fdh && !cpumask_test_cpu(cpu, &fdh->cpu_online_mask)) { |
649 | SKIP_TO_NEXT_CPU(reg_entry); | 650 | SKIP_TO_NEXT_CPU(reg_entry); |
650 | continue; | 651 | continue; |
651 | } | 652 | } |
@@ -662,9 +663,11 @@ static int __init fadump_build_cpu_notes(const struct fadump_mem_struct *fdm) | |||
662 | } | 663 | } |
663 | fadump_final_note(note_buf); | 664 | fadump_final_note(note_buf); |
664 | 665 | ||
665 | pr_debug("Updating elfcore header (%llx) with cpu notes\n", | 666 | if (fdh) { |
667 | pr_debug("Updating elfcore header (%llx) with cpu notes\n", | ||
666 | fdh->elfcorehdr_addr); | 668 | fdh->elfcorehdr_addr); |
667 | fadump_update_elfcore_header((char *)__va(fdh->elfcorehdr_addr)); | 669 | fadump_update_elfcore_header((char *)__va(fdh->elfcorehdr_addr)); |
670 | } | ||
668 | return 0; | 671 | return 0; |
669 | 672 | ||
670 | error_out: | 673 | error_out: |
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index 6a014c763cc7..f202d0731b06 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c | |||
@@ -105,11 +105,9 @@ __ftrace_make_nop(struct module *mod, | |||
105 | struct dyn_ftrace *rec, unsigned long addr) | 105 | struct dyn_ftrace *rec, unsigned long addr) |
106 | { | 106 | { |
107 | unsigned int op; | 107 | unsigned int op; |
108 | unsigned int jmp[5]; | ||
109 | unsigned long ptr; | 108 | unsigned long ptr; |
110 | unsigned long ip = rec->ip; | 109 | unsigned long ip = rec->ip; |
111 | unsigned long tramp; | 110 | void *tramp; |
112 | int offset; | ||
113 | 111 | ||
114 | /* read where this goes */ | 112 | /* read where this goes */ |
115 | if (probe_kernel_read(&op, (void *)ip, sizeof(int))) | 113 | if (probe_kernel_read(&op, (void *)ip, sizeof(int))) |
@@ -122,96 +120,41 @@ __ftrace_make_nop(struct module *mod, | |||
122 | } | 120 | } |
123 | 121 | ||
124 | /* lets find where the pointer goes */ | 122 | /* lets find where the pointer goes */ |
125 | tramp = find_bl_target(ip, op); | 123 | tramp = (void *)find_bl_target(ip, op); |
126 | |||
127 | /* | ||
128 | * On PPC64 the trampoline looks like: | ||
129 | * 0x3d, 0x82, 0x00, 0x00, addis r12,r2, <high> | ||
130 | * 0x39, 0x8c, 0x00, 0x00, addi r12,r12, <low> | ||
131 | * Where the bytes 2,3,6 and 7 make up the 32bit offset | ||
132 | * to the TOC that holds the pointer. | ||
133 | * to jump to. | ||
134 | * 0xf8, 0x41, 0x00, 0x28, std r2,40(r1) | ||
135 | * 0xe9, 0x6c, 0x00, 0x20, ld r11,32(r12) | ||
136 | * The actually address is 32 bytes from the offset | ||
137 | * into the TOC. | ||
138 | * 0xe8, 0x4c, 0x00, 0x28, ld r2,40(r12) | ||
139 | */ | ||
140 | |||
141 | pr_devel("ip:%lx jumps to %lx r2: %lx", ip, tramp, mod->arch.toc); | ||
142 | |||
143 | /* Find where the trampoline jumps to */ | ||
144 | if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) { | ||
145 | printk(KERN_ERR "Failed to read %lx\n", tramp); | ||
146 | return -EFAULT; | ||
147 | } | ||
148 | 124 | ||
149 | pr_devel(" %08x %08x", jmp[0], jmp[1]); | 125 | pr_devel("ip:%lx jumps to %p", ip, tramp); |
150 | 126 | ||
151 | /* verify that this is what we expect it to be */ | 127 | if (!is_module_trampoline(tramp)) { |
152 | if (((jmp[0] & 0xffff0000) != 0x3d820000) || | ||
153 | ((jmp[1] & 0xffff0000) != 0x398c0000) || | ||
154 | (jmp[2] != 0xf8410028) || | ||
155 | (jmp[3] != 0xe96c0020) || | ||
156 | (jmp[4] != 0xe84c0028)) { | ||
157 | printk(KERN_ERR "Not a trampoline\n"); | 128 | printk(KERN_ERR "Not a trampoline\n"); |
158 | return -EINVAL; | 129 | return -EINVAL; |
159 | } | 130 | } |
160 | 131 | ||
161 | /* The bottom half is signed extended */ | 132 | if (module_trampoline_target(mod, tramp, &ptr)) { |
162 | offset = ((unsigned)((unsigned short)jmp[0]) << 16) + | 133 | printk(KERN_ERR "Failed to get trampoline target\n"); |
163 | (int)((short)jmp[1]); | ||
164 | |||
165 | pr_devel(" %x ", offset); | ||
166 | |||
167 | /* get the address this jumps too */ | ||
168 | tramp = mod->arch.toc + offset + 32; | ||
169 | pr_devel("toc: %lx", tramp); | ||
170 | |||
171 | if (probe_kernel_read(jmp, (void *)tramp, 8)) { | ||
172 | printk(KERN_ERR "Failed to read %lx\n", tramp); | ||
173 | return -EFAULT; | 134 | return -EFAULT; |
174 | } | 135 | } |
175 | 136 | ||
176 | pr_devel(" %08x %08x\n", jmp[0], jmp[1]); | 137 | pr_devel("trampoline target %lx", ptr); |
177 | |||
178 | #ifdef __LITTLE_ENDIAN__ | ||
179 | ptr = ((unsigned long)jmp[1] << 32) + jmp[0]; | ||
180 | #else | ||
181 | ptr = ((unsigned long)jmp[0] << 32) + jmp[1]; | ||
182 | #endif | ||
183 | 138 | ||
184 | /* This should match what was called */ | 139 | /* This should match what was called */ |
185 | if (ptr != ppc_function_entry((void *)addr)) { | 140 | if (ptr != ppc_function_entry((void *)addr)) { |
186 | printk(KERN_ERR "addr does not match %lx\n", ptr); | 141 | printk(KERN_ERR "addr %lx does not match expected %lx\n", |
142 | ptr, ppc_function_entry((void *)addr)); | ||
187 | return -EINVAL; | 143 | return -EINVAL; |
188 | } | 144 | } |
189 | 145 | ||
190 | /* | 146 | /* |
191 | * We want to nop the line, but the next line is | 147 | * Our original call site looks like: |
192 | * 0xe8, 0x41, 0x00, 0x28 ld r2,40(r1) | 148 | * |
193 | * This needs to be turned to a nop too. | 149 | * bl <tramp> |
194 | */ | 150 | * ld r2,XX(r1) |
195 | if (probe_kernel_read(&op, (void *)(ip+4), MCOUNT_INSN_SIZE)) | 151 | * |
196 | return -EFAULT; | 152 | * Milton Miller pointed out that we can not simply nop the branch. |
197 | 153 | * If a task was preempted when calling a trace function, the nops | |
198 | if (op != 0xe8410028) { | 154 | * will remove the way to restore the TOC in r2 and the r2 TOC will |
199 | printk(KERN_ERR "Next line is not ld! (%08x)\n", op); | 155 | * get corrupted. |
200 | return -EINVAL; | 156 | * |
201 | } | 157 | * Use a b +8 to jump over the load. |
202 | |||
203 | /* | ||
204 | * Milton Miller pointed out that we can not blindly do nops. | ||
205 | * If a task was preempted when calling a trace function, | ||
206 | * the nops will remove the way to restore the TOC in r2 | ||
207 | * and the r2 TOC will get corrupted. | ||
208 | */ | ||
209 | |||
210 | /* | ||
211 | * Replace: | ||
212 | * bl <tramp> <==== will be replaced with "b 1f" | ||
213 | * ld r2,40(r1) | ||
214 | * 1: | ||
215 | */ | 158 | */ |
216 | op = 0x48000008; /* b +8 */ | 159 | op = 0x48000008; /* b +8 */ |
217 | 160 | ||
@@ -349,19 +292,24 @@ static int | |||
349 | __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | 292 | __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) |
350 | { | 293 | { |
351 | unsigned int op[2]; | 294 | unsigned int op[2]; |
352 | unsigned long ip = rec->ip; | 295 | void *ip = (void *)rec->ip; |
353 | 296 | ||
354 | /* read where this goes */ | 297 | /* read where this goes */ |
355 | if (probe_kernel_read(op, (void *)ip, MCOUNT_INSN_SIZE * 2)) | 298 | if (probe_kernel_read(op, ip, sizeof(op))) |
356 | return -EFAULT; | 299 | return -EFAULT; |
357 | 300 | ||
358 | /* | 301 | /* |
359 | * It should be pointing to two nops or | 302 | * We expect to see: |
360 | * b +8; ld r2,40(r1) | 303 | * |
304 | * b +8 | ||
305 | * ld r2,XX(r1) | ||
306 | * | ||
307 | * The load offset is different depending on the ABI. For simplicity | ||
308 | * just mask it out when doing the compare. | ||
361 | */ | 309 | */ |
362 | if (((op[0] != 0x48000008) || (op[1] != 0xe8410028)) && | 310 | if ((op[0] != 0x48000008) || ((op[1] & 0xffff00000) != 0xe8410000)) { |
363 | ((op[0] != PPC_INST_NOP) || (op[1] != PPC_INST_NOP))) { | 311 | printk(KERN_ERR "Unexpected call sequence: %x %x\n", |
364 | printk(KERN_ERR "Expected NOPs but have %x %x\n", op[0], op[1]); | 312 | op[0], op[1]); |
365 | return -EINVAL; | 313 | return -EINVAL; |
366 | } | 314 | } |
367 | 315 | ||
@@ -371,23 +319,16 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | |||
371 | return -EINVAL; | 319 | return -EINVAL; |
372 | } | 320 | } |
373 | 321 | ||
374 | /* create the branch to the trampoline */ | 322 | /* Ensure branch is within 24 bits */ |
375 | op[0] = create_branch((unsigned int *)ip, | 323 | if (create_branch(ip, rec->arch.mod->arch.tramp, BRANCH_SET_LINK)) { |
376 | rec->arch.mod->arch.tramp, BRANCH_SET_LINK); | 324 | printk(KERN_ERR "Branch out of range"); |
377 | if (!op[0]) { | ||
378 | printk(KERN_ERR "REL24 out of range!\n"); | ||
379 | return -EINVAL; | 325 | return -EINVAL; |
380 | } | 326 | } |
381 | 327 | ||
382 | /* ld r2,40(r1) */ | 328 | if (patch_branch(ip, rec->arch.mod->arch.tramp, BRANCH_SET_LINK)) { |
383 | op[1] = 0xe8410028; | 329 | printk(KERN_ERR "REL24 out of range!\n"); |
384 | 330 | return -EINVAL; | |
385 | pr_devel("write to %lx\n", rec->ip); | 331 | } |
386 | |||
387 | if (probe_kernel_write((void *)ip, op, MCOUNT_INSN_SIZE * 2)) | ||
388 | return -EPERM; | ||
389 | |||
390 | flush_icache_range(ip, ip + 8); | ||
391 | 332 | ||
392 | return 0; | 333 | return 0; |
393 | } | 334 | } |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index b7363bd42452..a95145d7f61b 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -70,16 +70,15 @@ _GLOBAL(__start) | |||
70 | /* NOP this out unconditionally */ | 70 | /* NOP this out unconditionally */ |
71 | BEGIN_FTR_SECTION | 71 | BEGIN_FTR_SECTION |
72 | FIXUP_ENDIAN | 72 | FIXUP_ENDIAN |
73 | b .__start_initialization_multiplatform | 73 | b __start_initialization_multiplatform |
74 | END_FTR_SECTION(0, 1) | 74 | END_FTR_SECTION(0, 1) |
75 | 75 | ||
76 | /* Catch branch to 0 in real mode */ | 76 | /* Catch branch to 0 in real mode */ |
77 | trap | 77 | trap |
78 | 78 | ||
79 | /* Secondary processors spin on this value until it becomes nonzero. | 79 | /* Secondary processors spin on this value until it becomes non-zero. |
80 | * When it does it contains the real address of the descriptor | 80 | * When non-zero, it contains the real address of the function the cpu |
81 | * of the function that the cpu should jump to to continue | 81 | * should jump to. |
82 | * initialization. | ||
83 | */ | 82 | */ |
84 | .balign 8 | 83 | .balign 8 |
85 | .globl __secondary_hold_spinloop | 84 | .globl __secondary_hold_spinloop |
@@ -140,16 +139,15 @@ __secondary_hold: | |||
140 | tovirt(r26,r26) | 139 | tovirt(r26,r26) |
141 | #endif | 140 | #endif |
142 | /* All secondary cpus wait here until told to start. */ | 141 | /* All secondary cpus wait here until told to start. */ |
143 | 100: ld r4,__secondary_hold_spinloop-_stext(r26) | 142 | 100: ld r12,__secondary_hold_spinloop-_stext(r26) |
144 | cmpdi 0,r4,0 | 143 | cmpdi 0,r12,0 |
145 | beq 100b | 144 | beq 100b |
146 | 145 | ||
147 | #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) | 146 | #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) |
148 | #ifdef CONFIG_PPC_BOOK3E | 147 | #ifdef CONFIG_PPC_BOOK3E |
149 | tovirt(r4,r4) | 148 | tovirt(r12,r12) |
150 | #endif | 149 | #endif |
151 | ld r4,0(r4) /* deref function descriptor */ | 150 | mtctr r12 |
152 | mtctr r4 | ||
153 | mr r3,r24 | 151 | mr r3,r24 |
154 | /* | 152 | /* |
155 | * it may be the case that other platforms have r4 right to | 153 | * it may be the case that other platforms have r4 right to |
@@ -186,16 +184,16 @@ _GLOBAL(generic_secondary_thread_init) | |||
186 | mr r24,r3 | 184 | mr r24,r3 |
187 | 185 | ||
188 | /* turn on 64-bit mode */ | 186 | /* turn on 64-bit mode */ |
189 | bl .enable_64b_mode | 187 | bl enable_64b_mode |
190 | 188 | ||
191 | /* get a valid TOC pointer, wherever we're mapped at */ | 189 | /* get a valid TOC pointer, wherever we're mapped at */ |
192 | bl .relative_toc | 190 | bl relative_toc |
193 | tovirt(r2,r2) | 191 | tovirt(r2,r2) |
194 | 192 | ||
195 | #ifdef CONFIG_PPC_BOOK3E | 193 | #ifdef CONFIG_PPC_BOOK3E |
196 | /* Book3E initialization */ | 194 | /* Book3E initialization */ |
197 | mr r3,r24 | 195 | mr r3,r24 |
198 | bl .book3e_secondary_thread_init | 196 | bl book3e_secondary_thread_init |
199 | #endif | 197 | #endif |
200 | b generic_secondary_common_init | 198 | b generic_secondary_common_init |
201 | 199 | ||
@@ -214,17 +212,17 @@ _GLOBAL(generic_secondary_smp_init) | |||
214 | mr r25,r4 | 212 | mr r25,r4 |
215 | 213 | ||
216 | /* turn on 64-bit mode */ | 214 | /* turn on 64-bit mode */ |
217 | bl .enable_64b_mode | 215 | bl enable_64b_mode |
218 | 216 | ||
219 | /* get a valid TOC pointer, wherever we're mapped at */ | 217 | /* get a valid TOC pointer, wherever we're mapped at */ |
220 | bl .relative_toc | 218 | bl relative_toc |
221 | tovirt(r2,r2) | 219 | tovirt(r2,r2) |
222 | 220 | ||
223 | #ifdef CONFIG_PPC_BOOK3E | 221 | #ifdef CONFIG_PPC_BOOK3E |
224 | /* Book3E initialization */ | 222 | /* Book3E initialization */ |
225 | mr r3,r24 | 223 | mr r3,r24 |
226 | mr r4,r25 | 224 | mr r4,r25 |
227 | bl .book3e_secondary_core_init | 225 | bl book3e_secondary_core_init |
228 | #endif | 226 | #endif |
229 | 227 | ||
230 | generic_secondary_common_init: | 228 | generic_secondary_common_init: |
@@ -236,7 +234,7 @@ generic_secondary_common_init: | |||
236 | ld r13,0(r13) /* Get base vaddr of paca array */ | 234 | ld r13,0(r13) /* Get base vaddr of paca array */ |
237 | #ifndef CONFIG_SMP | 235 | #ifndef CONFIG_SMP |
238 | addi r13,r13,PACA_SIZE /* know r13 if used accidentally */ | 236 | addi r13,r13,PACA_SIZE /* know r13 if used accidentally */ |
239 | b .kexec_wait /* wait for next kernel if !SMP */ | 237 | b kexec_wait /* wait for next kernel if !SMP */ |
240 | #else | 238 | #else |
241 | LOAD_REG_ADDR(r7, nr_cpu_ids) /* Load nr_cpu_ids address */ | 239 | LOAD_REG_ADDR(r7, nr_cpu_ids) /* Load nr_cpu_ids address */ |
242 | lwz r7,0(r7) /* also the max paca allocated */ | 240 | lwz r7,0(r7) /* also the max paca allocated */ |
@@ -250,7 +248,7 @@ generic_secondary_common_init: | |||
250 | blt 1b | 248 | blt 1b |
251 | 249 | ||
252 | mr r3,r24 /* not found, copy phys to r3 */ | 250 | mr r3,r24 /* not found, copy phys to r3 */ |
253 | b .kexec_wait /* next kernel might do better */ | 251 | b kexec_wait /* next kernel might do better */ |
254 | 252 | ||
255 | 2: SET_PACA(r13) | 253 | 2: SET_PACA(r13) |
256 | #ifdef CONFIG_PPC_BOOK3E | 254 | #ifdef CONFIG_PPC_BOOK3E |
@@ -264,11 +262,13 @@ generic_secondary_common_init: | |||
264 | /* See if we need to call a cpu state restore handler */ | 262 | /* See if we need to call a cpu state restore handler */ |
265 | LOAD_REG_ADDR(r23, cur_cpu_spec) | 263 | LOAD_REG_ADDR(r23, cur_cpu_spec) |
266 | ld r23,0(r23) | 264 | ld r23,0(r23) |
267 | ld r23,CPU_SPEC_RESTORE(r23) | 265 | ld r12,CPU_SPEC_RESTORE(r23) |
268 | cmpdi 0,r23,0 | 266 | cmpdi 0,r12,0 |
269 | beq 3f | 267 | beq 3f |
270 | ld r23,0(r23) | 268 | #if !defined(_CALL_ELF) || _CALL_ELF != 2 |
271 | mtctr r23 | 269 | ld r12,0(r12) |
270 | #endif | ||
271 | mtctr r12 | ||
272 | bctrl | 272 | bctrl |
273 | 273 | ||
274 | 3: LOAD_REG_ADDR(r3, spinning_secondaries) /* Decrement spinning_secondaries */ | 274 | 3: LOAD_REG_ADDR(r3, spinning_secondaries) /* Decrement spinning_secondaries */ |
@@ -299,7 +299,7 @@ generic_secondary_common_init: | |||
299 | * Assumes we're mapped EA == RA if the MMU is on. | 299 | * Assumes we're mapped EA == RA if the MMU is on. |
300 | */ | 300 | */ |
301 | #ifdef CONFIG_PPC_BOOK3S | 301 | #ifdef CONFIG_PPC_BOOK3S |
302 | _STATIC(__mmu_off) | 302 | __mmu_off: |
303 | mfmsr r3 | 303 | mfmsr r3 |
304 | andi. r0,r3,MSR_IR|MSR_DR | 304 | andi. r0,r3,MSR_IR|MSR_DR |
305 | beqlr | 305 | beqlr |
@@ -324,12 +324,12 @@ _STATIC(__mmu_off) | |||
324 | * DT block, r4 is a physical pointer to the kernel itself | 324 | * DT block, r4 is a physical pointer to the kernel itself |
325 | * | 325 | * |
326 | */ | 326 | */ |
327 | _GLOBAL(__start_initialization_multiplatform) | 327 | __start_initialization_multiplatform: |
328 | /* Make sure we are running in 64 bits mode */ | 328 | /* Make sure we are running in 64 bits mode */ |
329 | bl .enable_64b_mode | 329 | bl enable_64b_mode |
330 | 330 | ||
331 | /* Get TOC pointer (current runtime address) */ | 331 | /* Get TOC pointer (current runtime address) */ |
332 | bl .relative_toc | 332 | bl relative_toc |
333 | 333 | ||
334 | /* find out where we are now */ | 334 | /* find out where we are now */ |
335 | bcl 20,31,$+4 | 335 | bcl 20,31,$+4 |
@@ -342,7 +342,7 @@ _GLOBAL(__start_initialization_multiplatform) | |||
342 | */ | 342 | */ |
343 | cmpldi cr0,r5,0 | 343 | cmpldi cr0,r5,0 |
344 | beq 1f | 344 | beq 1f |
345 | b .__boot_from_prom /* yes -> prom */ | 345 | b __boot_from_prom /* yes -> prom */ |
346 | 1: | 346 | 1: |
347 | /* Save parameters */ | 347 | /* Save parameters */ |
348 | mr r31,r3 | 348 | mr r31,r3 |
@@ -354,8 +354,8 @@ _GLOBAL(__start_initialization_multiplatform) | |||
354 | #endif | 354 | #endif |
355 | 355 | ||
356 | #ifdef CONFIG_PPC_BOOK3E | 356 | #ifdef CONFIG_PPC_BOOK3E |
357 | bl .start_initialization_book3e | 357 | bl start_initialization_book3e |
358 | b .__after_prom_start | 358 | b __after_prom_start |
359 | #else | 359 | #else |
360 | /* Setup some critical 970 SPRs before switching MMU off */ | 360 | /* Setup some critical 970 SPRs before switching MMU off */ |
361 | mfspr r0,SPRN_PVR | 361 | mfspr r0,SPRN_PVR |
@@ -368,15 +368,15 @@ _GLOBAL(__start_initialization_multiplatform) | |||
368 | beq 1f | 368 | beq 1f |
369 | cmpwi r0,0x45 /* 970GX */ | 369 | cmpwi r0,0x45 /* 970GX */ |
370 | bne 2f | 370 | bne 2f |
371 | 1: bl .__cpu_preinit_ppc970 | 371 | 1: bl __cpu_preinit_ppc970 |
372 | 2: | 372 | 2: |
373 | 373 | ||
374 | /* Switch off MMU if not already off */ | 374 | /* Switch off MMU if not already off */ |
375 | bl .__mmu_off | 375 | bl __mmu_off |
376 | b .__after_prom_start | 376 | b __after_prom_start |
377 | #endif /* CONFIG_PPC_BOOK3E */ | 377 | #endif /* CONFIG_PPC_BOOK3E */ |
378 | 378 | ||
379 | _INIT_STATIC(__boot_from_prom) | 379 | __boot_from_prom: |
380 | #ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE | 380 | #ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE |
381 | /* Save parameters */ | 381 | /* Save parameters */ |
382 | mr r31,r3 | 382 | mr r31,r3 |
@@ -395,7 +395,7 @@ _INIT_STATIC(__boot_from_prom) | |||
395 | #ifdef CONFIG_RELOCATABLE | 395 | #ifdef CONFIG_RELOCATABLE |
396 | /* Relocate code for where we are now */ | 396 | /* Relocate code for where we are now */ |
397 | mr r3,r26 | 397 | mr r3,r26 |
398 | bl .relocate | 398 | bl relocate |
399 | #endif | 399 | #endif |
400 | 400 | ||
401 | /* Restore parameters */ | 401 | /* Restore parameters */ |
@@ -407,14 +407,14 @@ _INIT_STATIC(__boot_from_prom) | |||
407 | 407 | ||
408 | /* Do all of the interaction with OF client interface */ | 408 | /* Do all of the interaction with OF client interface */ |
409 | mr r8,r26 | 409 | mr r8,r26 |
410 | bl .prom_init | 410 | bl prom_init |
411 | #endif /* #CONFIG_PPC_OF_BOOT_TRAMPOLINE */ | 411 | #endif /* #CONFIG_PPC_OF_BOOT_TRAMPOLINE */ |
412 | 412 | ||
413 | /* We never return. We also hit that trap if trying to boot | 413 | /* We never return. We also hit that trap if trying to boot |
414 | * from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */ | 414 | * from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */ |
415 | trap | 415 | trap |
416 | 416 | ||
417 | _STATIC(__after_prom_start) | 417 | __after_prom_start: |
418 | #ifdef CONFIG_RELOCATABLE | 418 | #ifdef CONFIG_RELOCATABLE |
419 | /* process relocations for the final address of the kernel */ | 419 | /* process relocations for the final address of the kernel */ |
420 | lis r25,PAGE_OFFSET@highest /* compute virtual base of kernel */ | 420 | lis r25,PAGE_OFFSET@highest /* compute virtual base of kernel */ |
@@ -424,7 +424,7 @@ _STATIC(__after_prom_start) | |||
424 | bne 1f | 424 | bne 1f |
425 | add r25,r25,r26 | 425 | add r25,r25,r26 |
426 | 1: mr r3,r25 | 426 | 1: mr r3,r25 |
427 | bl .relocate | 427 | bl relocate |
428 | #endif | 428 | #endif |
429 | 429 | ||
430 | /* | 430 | /* |
@@ -464,12 +464,12 @@ _STATIC(__after_prom_start) | |||
464 | lis r5,(copy_to_here - _stext)@ha | 464 | lis r5,(copy_to_here - _stext)@ha |
465 | addi r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */ | 465 | addi r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */ |
466 | 466 | ||
467 | bl .copy_and_flush /* copy the first n bytes */ | 467 | bl copy_and_flush /* copy the first n bytes */ |
468 | /* this includes the code being */ | 468 | /* this includes the code being */ |
469 | /* executed here. */ | 469 | /* executed here. */ |
470 | addis r8,r3,(4f - _stext)@ha /* Jump to the copy of this code */ | 470 | addis r8,r3,(4f - _stext)@ha /* Jump to the copy of this code */ |
471 | addi r8,r8,(4f - _stext)@l /* that we just made */ | 471 | addi r12,r8,(4f - _stext)@l /* that we just made */ |
472 | mtctr r8 | 472 | mtctr r12 |
473 | bctr | 473 | bctr |
474 | 474 | ||
475 | .balign 8 | 475 | .balign 8 |
@@ -478,9 +478,9 @@ p_end: .llong _end - _stext | |||
478 | 4: /* Now copy the rest of the kernel up to _end */ | 478 | 4: /* Now copy the rest of the kernel up to _end */ |
479 | addis r5,r26,(p_end - _stext)@ha | 479 | addis r5,r26,(p_end - _stext)@ha |
480 | ld r5,(p_end - _stext)@l(r5) /* get _end */ | 480 | ld r5,(p_end - _stext)@l(r5) /* get _end */ |
481 | 5: bl .copy_and_flush /* copy the rest */ | 481 | 5: bl copy_and_flush /* copy the rest */ |
482 | 482 | ||
483 | 9: b .start_here_multiplatform | 483 | 9: b start_here_multiplatform |
484 | 484 | ||
485 | /* | 485 | /* |
486 | * Copy routine used to copy the kernel to start at physical address 0 | 486 | * Copy routine used to copy the kernel to start at physical address 0 |
@@ -544,7 +544,7 @@ __secondary_start_pmac_0: | |||
544 | 544 | ||
545 | _GLOBAL(pmac_secondary_start) | 545 | _GLOBAL(pmac_secondary_start) |
546 | /* turn on 64-bit mode */ | 546 | /* turn on 64-bit mode */ |
547 | bl .enable_64b_mode | 547 | bl enable_64b_mode |
548 | 548 | ||
549 | li r0,0 | 549 | li r0,0 |
550 | mfspr r3,SPRN_HID4 | 550 | mfspr r3,SPRN_HID4 |
@@ -556,11 +556,11 @@ _GLOBAL(pmac_secondary_start) | |||
556 | slbia | 556 | slbia |
557 | 557 | ||
558 | /* get TOC pointer (real address) */ | 558 | /* get TOC pointer (real address) */ |
559 | bl .relative_toc | 559 | bl relative_toc |
560 | tovirt(r2,r2) | 560 | tovirt(r2,r2) |
561 | 561 | ||
562 | /* Copy some CPU settings from CPU 0 */ | 562 | /* Copy some CPU settings from CPU 0 */ |
563 | bl .__restore_cpu_ppc970 | 563 | bl __restore_cpu_ppc970 |
564 | 564 | ||
565 | /* pSeries do that early though I don't think we really need it */ | 565 | /* pSeries do that early though I don't think we really need it */ |
566 | mfmsr r3 | 566 | mfmsr r3 |
@@ -619,7 +619,7 @@ __secondary_start: | |||
619 | std r14,PACAKSAVE(r13) | 619 | std r14,PACAKSAVE(r13) |
620 | 620 | ||
621 | /* Do early setup for that CPU (stab, slb, hash table pointer) */ | 621 | /* Do early setup for that CPU (stab, slb, hash table pointer) */ |
622 | bl .early_setup_secondary | 622 | bl early_setup_secondary |
623 | 623 | ||
624 | /* | 624 | /* |
625 | * setup the new stack pointer, but *don't* use this until | 625 | * setup the new stack pointer, but *don't* use this until |
@@ -639,7 +639,7 @@ __secondary_start: | |||
639 | stb r0,PACAIRQHAPPENED(r13) | 639 | stb r0,PACAIRQHAPPENED(r13) |
640 | 640 | ||
641 | /* enable MMU and jump to start_secondary */ | 641 | /* enable MMU and jump to start_secondary */ |
642 | LOAD_REG_ADDR(r3, .start_secondary_prolog) | 642 | LOAD_REG_ADDR(r3, start_secondary_prolog) |
643 | LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) | 643 | LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) |
644 | 644 | ||
645 | mtspr SPRN_SRR0,r3 | 645 | mtspr SPRN_SRR0,r3 |
@@ -652,11 +652,11 @@ __secondary_start: | |||
652 | * zero the stack back-chain pointer and get the TOC virtual address | 652 | * zero the stack back-chain pointer and get the TOC virtual address |
653 | * before going into C code. | 653 | * before going into C code. |
654 | */ | 654 | */ |
655 | _GLOBAL(start_secondary_prolog) | 655 | start_secondary_prolog: |
656 | ld r2,PACATOC(r13) | 656 | ld r2,PACATOC(r13) |
657 | li r3,0 | 657 | li r3,0 |
658 | std r3,0(r1) /* Zero the stack frame pointer */ | 658 | std r3,0(r1) /* Zero the stack frame pointer */ |
659 | bl .start_secondary | 659 | bl start_secondary |
660 | b . | 660 | b . |
661 | /* | 661 | /* |
662 | * Reset stack pointer and call start_secondary | 662 | * Reset stack pointer and call start_secondary |
@@ -667,14 +667,14 @@ _GLOBAL(start_secondary_resume) | |||
667 | ld r1,PACAKSAVE(r13) /* Reload kernel stack pointer */ | 667 | ld r1,PACAKSAVE(r13) /* Reload kernel stack pointer */ |
668 | li r3,0 | 668 | li r3,0 |
669 | std r3,0(r1) /* Zero the stack frame pointer */ | 669 | std r3,0(r1) /* Zero the stack frame pointer */ |
670 | bl .start_secondary | 670 | bl start_secondary |
671 | b . | 671 | b . |
672 | #endif | 672 | #endif |
673 | 673 | ||
674 | /* | 674 | /* |
675 | * This subroutine clobbers r11 and r12 | 675 | * This subroutine clobbers r11 and r12 |
676 | */ | 676 | */ |
677 | _GLOBAL(enable_64b_mode) | 677 | enable_64b_mode: |
678 | mfmsr r11 /* grab the current MSR */ | 678 | mfmsr r11 /* grab the current MSR */ |
679 | #ifdef CONFIG_PPC_BOOK3E | 679 | #ifdef CONFIG_PPC_BOOK3E |
680 | oris r11,r11,0x8000 /* CM bit set, we'll set ICM later */ | 680 | oris r11,r11,0x8000 /* CM bit set, we'll set ICM later */ |
@@ -715,9 +715,9 @@ p_toc: .llong __toc_start + 0x8000 - 0b | |||
715 | /* | 715 | /* |
716 | * This is where the main kernel code starts. | 716 | * This is where the main kernel code starts. |
717 | */ | 717 | */ |
718 | _INIT_STATIC(start_here_multiplatform) | 718 | start_here_multiplatform: |
719 | /* set up the TOC */ | 719 | /* set up the TOC */ |
720 | bl .relative_toc | 720 | bl relative_toc |
721 | tovirt(r2,r2) | 721 | tovirt(r2,r2) |
722 | 722 | ||
723 | /* Clear out the BSS. It may have been done in prom_init, | 723 | /* Clear out the BSS. It may have been done in prom_init, |
@@ -776,9 +776,9 @@ _INIT_STATIC(start_here_multiplatform) | |||
776 | 776 | ||
777 | /* Restore parameters passed from prom_init/kexec */ | 777 | /* Restore parameters passed from prom_init/kexec */ |
778 | mr r3,r31 | 778 | mr r3,r31 |
779 | bl .early_setup /* also sets r13 and SPRG_PACA */ | 779 | bl early_setup /* also sets r13 and SPRG_PACA */ |
780 | 780 | ||
781 | LOAD_REG_ADDR(r3, .start_here_common) | 781 | LOAD_REG_ADDR(r3, start_here_common) |
782 | ld r4,PACAKMSR(r13) | 782 | ld r4,PACAKMSR(r13) |
783 | mtspr SPRN_SRR0,r3 | 783 | mtspr SPRN_SRR0,r3 |
784 | mtspr SPRN_SRR1,r4 | 784 | mtspr SPRN_SRR1,r4 |
@@ -786,7 +786,8 @@ _INIT_STATIC(start_here_multiplatform) | |||
786 | b . /* prevent speculative execution */ | 786 | b . /* prevent speculative execution */ |
787 | 787 | ||
788 | /* This is where all platforms converge execution */ | 788 | /* This is where all platforms converge execution */ |
789 | _INIT_GLOBAL(start_here_common) | 789 | |
790 | start_here_common: | ||
790 | /* relocation is on at this point */ | 791 | /* relocation is on at this point */ |
791 | std r1,PACAKSAVE(r13) | 792 | std r1,PACAKSAVE(r13) |
792 | 793 | ||
@@ -794,7 +795,7 @@ _INIT_GLOBAL(start_here_common) | |||
794 | ld r2,PACATOC(r13) | 795 | ld r2,PACATOC(r13) |
795 | 796 | ||
796 | /* Do more system initializations in virtual mode */ | 797 | /* Do more system initializations in virtual mode */ |
797 | bl .setup_system | 798 | bl setup_system |
798 | 799 | ||
799 | /* Mark interrupts soft and hard disabled (they might be enabled | 800 | /* Mark interrupts soft and hard disabled (they might be enabled |
800 | * in the PACA when doing hotplug) | 801 | * in the PACA when doing hotplug) |
@@ -805,7 +806,7 @@ _INIT_GLOBAL(start_here_common) | |||
805 | stb r0,PACAIRQHAPPENED(r13) | 806 | stb r0,PACAIRQHAPPENED(r13) |
806 | 807 | ||
807 | /* Generic kernel entry */ | 808 | /* Generic kernel entry */ |
808 | bl .start_kernel | 809 | bl start_kernel |
809 | 810 | ||
810 | /* Not reached */ | 811 | /* Not reached */ |
811 | BUG_OPCODE | 812 | BUG_OPCODE |
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index b0a1792279bb..0bb5918faaaf 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c | |||
@@ -72,7 +72,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp) | |||
72 | * If so, DABR will be populated in single_step_dabr_instruction(). | 72 | * If so, DABR will be populated in single_step_dabr_instruction(). |
73 | */ | 73 | */ |
74 | if (current->thread.last_hit_ubp != bp) | 74 | if (current->thread.last_hit_ubp != bp) |
75 | set_breakpoint(info); | 75 | __set_breakpoint(info); |
76 | 76 | ||
77 | return 0; | 77 | return 0; |
78 | } | 78 | } |
@@ -198,7 +198,7 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs) | |||
198 | 198 | ||
199 | info = counter_arch_bp(tsk->thread.last_hit_ubp); | 199 | info = counter_arch_bp(tsk->thread.last_hit_ubp); |
200 | regs->msr &= ~MSR_SE; | 200 | regs->msr &= ~MSR_SE; |
201 | set_breakpoint(info); | 201 | __set_breakpoint(info); |
202 | tsk->thread.last_hit_ubp = NULL; | 202 | tsk->thread.last_hit_ubp = NULL; |
203 | } | 203 | } |
204 | 204 | ||
@@ -284,7 +284,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args) | |||
284 | if (!(info->type & HW_BRK_TYPE_EXTRANEOUS_IRQ)) | 284 | if (!(info->type & HW_BRK_TYPE_EXTRANEOUS_IRQ)) |
285 | perf_bp_event(bp, regs); | 285 | perf_bp_event(bp, regs); |
286 | 286 | ||
287 | set_breakpoint(info); | 287 | __set_breakpoint(info); |
288 | out: | 288 | out: |
289 | rcu_read_unlock(); | 289 | rcu_read_unlock(); |
290 | return rc; | 290 | return rc; |
@@ -316,7 +316,7 @@ int __kprobes single_step_dabr_instruction(struct die_args *args) | |||
316 | if (!(info->type & HW_BRK_TYPE_EXTRANEOUS_IRQ)) | 316 | if (!(info->type & HW_BRK_TYPE_EXTRANEOUS_IRQ)) |
317 | perf_bp_event(bp, regs); | 317 | perf_bp_event(bp, regs); |
318 | 318 | ||
319 | set_breakpoint(info); | 319 | __set_breakpoint(info); |
320 | current->thread.last_hit_ubp = NULL; | 320 | current->thread.last_hit_ubp = NULL; |
321 | 321 | ||
322 | /* | 322 | /* |
diff --git a/arch/powerpc/kernel/idle_book3e.S b/arch/powerpc/kernel/idle_book3e.S index bfb73cc209ce..48c21acef915 100644 --- a/arch/powerpc/kernel/idle_book3e.S +++ b/arch/powerpc/kernel/idle_book3e.S | |||
@@ -43,7 +43,7 @@ _GLOBAL(\name) | |||
43 | */ | 43 | */ |
44 | #ifdef CONFIG_TRACE_IRQFLAGS | 44 | #ifdef CONFIG_TRACE_IRQFLAGS |
45 | stdu r1,-128(r1) | 45 | stdu r1,-128(r1) |
46 | bl .trace_hardirqs_on | 46 | bl trace_hardirqs_on |
47 | addi r1,r1,128 | 47 | addi r1,r1,128 |
48 | #endif | 48 | #endif |
49 | li r0,1 | 49 | li r0,1 |
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S index e3edaa189911..f57a19348bdd 100644 --- a/arch/powerpc/kernel/idle_power4.S +++ b/arch/powerpc/kernel/idle_power4.S | |||
@@ -46,7 +46,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP) | |||
46 | mflr r0 | 46 | mflr r0 |
47 | std r0,16(r1) | 47 | std r0,16(r1) |
48 | stdu r1,-128(r1) | 48 | stdu r1,-128(r1) |
49 | bl .trace_hardirqs_on | 49 | bl trace_hardirqs_on |
50 | addi r1,r1,128 | 50 | addi r1,r1,128 |
51 | ld r0,16(r1) | 51 | ld r0,16(r1) |
52 | mtlr r0 | 52 | mtlr r0 |
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S index c3ab86975614..2480256272d4 100644 --- a/arch/powerpc/kernel/idle_power7.S +++ b/arch/powerpc/kernel/idle_power7.S | |||
@@ -39,6 +39,10 @@ | |||
39 | * Pass requested state in r3: | 39 | * Pass requested state in r3: |
40 | * 0 - nap | 40 | * 0 - nap |
41 | * 1 - sleep | 41 | * 1 - sleep |
42 | * | ||
43 | * To check IRQ_HAPPENED in r4 | ||
44 | * 0 - don't check | ||
45 | * 1 - check | ||
42 | */ | 46 | */ |
43 | _GLOBAL(power7_powersave_common) | 47 | _GLOBAL(power7_powersave_common) |
44 | /* Use r3 to pass state nap/sleep/winkle */ | 48 | /* Use r3 to pass state nap/sleep/winkle */ |
@@ -58,7 +62,7 @@ _GLOBAL(power7_powersave_common) | |||
58 | /* Make sure FPU, VSX etc... are flushed as we may lose | 62 | /* Make sure FPU, VSX etc... are flushed as we may lose |
59 | * state when going to nap mode | 63 | * state when going to nap mode |
60 | */ | 64 | */ |
61 | bl .discard_lazy_cpu_state | 65 | bl discard_lazy_cpu_state |
62 | #endif /* CONFIG_SMP */ | 66 | #endif /* CONFIG_SMP */ |
63 | 67 | ||
64 | /* Hard disable interrupts */ | 68 | /* Hard disable interrupts */ |
@@ -71,6 +75,8 @@ _GLOBAL(power7_powersave_common) | |||
71 | lbz r0,PACAIRQHAPPENED(r13) | 75 | lbz r0,PACAIRQHAPPENED(r13) |
72 | cmpwi cr0,r0,0 | 76 | cmpwi cr0,r0,0 |
73 | beq 1f | 77 | beq 1f |
78 | cmpwi cr0,r4,0 | ||
79 | beq 1f | ||
74 | addi r1,r1,INT_FRAME_SIZE | 80 | addi r1,r1,INT_FRAME_SIZE |
75 | ld r0,16(r1) | 81 | ld r0,16(r1) |
76 | mtlr r0 | 82 | mtlr r0 |
@@ -114,15 +120,18 @@ _GLOBAL(power7_idle) | |||
114 | lwz r4,ADDROFF(powersave_nap)(r3) | 120 | lwz r4,ADDROFF(powersave_nap)(r3) |
115 | cmpwi 0,r4,0 | 121 | cmpwi 0,r4,0 |
116 | beqlr | 122 | beqlr |
123 | li r3, 1 | ||
117 | /* fall through */ | 124 | /* fall through */ |
118 | 125 | ||
119 | _GLOBAL(power7_nap) | 126 | _GLOBAL(power7_nap) |
127 | mr r4,r3 | ||
120 | li r3,0 | 128 | li r3,0 |
121 | b power7_powersave_common | 129 | b power7_powersave_common |
122 | /* No return */ | 130 | /* No return */ |
123 | 131 | ||
124 | _GLOBAL(power7_sleep) | 132 | _GLOBAL(power7_sleep) |
125 | li r3,1 | 133 | li r3,1 |
134 | li r4,0 | ||
126 | b power7_powersave_common | 135 | b power7_powersave_common |
127 | /* No return */ | 136 | /* No return */ |
128 | 137 | ||
@@ -168,7 +177,7 @@ _GLOBAL(power7_wakeup_loss) | |||
168 | _GLOBAL(power7_wakeup_noloss) | 177 | _GLOBAL(power7_wakeup_noloss) |
169 | lbz r0,PACA_NAPSTATELOST(r13) | 178 | lbz r0,PACA_NAPSTATELOST(r13) |
170 | cmpwi r0,0 | 179 | cmpwi r0,0 |
171 | bne .power7_wakeup_loss | 180 | bne power7_wakeup_loss |
172 | ld r1,PACAR1(r13) | 181 | ld r1,PACAR1(r13) |
173 | ld r4,_MSR(r1) | 182 | ld r4,_MSR(r1) |
174 | ld r5,_NIP(r1) | 183 | ld r5,_NIP(r1) |
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 40bd7bd4e19a..936258881c98 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c | |||
@@ -48,6 +48,9 @@ static struct of_device_id legacy_serial_parents[] __initdata = { | |||
48 | static unsigned int legacy_serial_count; | 48 | static unsigned int legacy_serial_count; |
49 | static int legacy_serial_console = -1; | 49 | static int legacy_serial_console = -1; |
50 | 50 | ||
51 | static const upf_t legacy_port_flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | | ||
52 | UPF_SHARE_IRQ | UPF_FIXED_PORT; | ||
53 | |||
51 | static unsigned int tsi_serial_in(struct uart_port *p, int offset) | 54 | static unsigned int tsi_serial_in(struct uart_port *p, int offset) |
52 | { | 55 | { |
53 | unsigned int tmp; | 56 | unsigned int tmp; |
@@ -71,8 +74,9 @@ static int __init add_legacy_port(struct device_node *np, int want_index, | |||
71 | phys_addr_t taddr, unsigned long irq, | 74 | phys_addr_t taddr, unsigned long irq, |
72 | upf_t flags, int irq_check_parent) | 75 | upf_t flags, int irq_check_parent) |
73 | { | 76 | { |
74 | const __be32 *clk, *spd; | 77 | const __be32 *clk, *spd, *rs; |
75 | u32 clock = BASE_BAUD * 16; | 78 | u32 clock = BASE_BAUD * 16; |
79 | u32 shift = 0; | ||
76 | int index; | 80 | int index; |
77 | 81 | ||
78 | /* get clock freq. if present */ | 82 | /* get clock freq. if present */ |
@@ -83,6 +87,11 @@ static int __init add_legacy_port(struct device_node *np, int want_index, | |||
83 | /* get default speed if present */ | 87 | /* get default speed if present */ |
84 | spd = of_get_property(np, "current-speed", NULL); | 88 | spd = of_get_property(np, "current-speed", NULL); |
85 | 89 | ||
90 | /* get register shift if present */ | ||
91 | rs = of_get_property(np, "reg-shift", NULL); | ||
92 | if (rs && *rs) | ||
93 | shift = be32_to_cpup(rs); | ||
94 | |||
86 | /* If we have a location index, then try to use it */ | 95 | /* If we have a location index, then try to use it */ |
87 | if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS) | 96 | if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS) |
88 | index = want_index; | 97 | index = want_index; |
@@ -126,6 +135,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index, | |||
126 | legacy_serial_ports[index].uartclk = clock; | 135 | legacy_serial_ports[index].uartclk = clock; |
127 | legacy_serial_ports[index].irq = irq; | 136 | legacy_serial_ports[index].irq = irq; |
128 | legacy_serial_ports[index].flags = flags; | 137 | legacy_serial_ports[index].flags = flags; |
138 | legacy_serial_ports[index].regshift = shift; | ||
129 | legacy_serial_infos[index].taddr = taddr; | 139 | legacy_serial_infos[index].taddr = taddr; |
130 | legacy_serial_infos[index].np = of_node_get(np); | 140 | legacy_serial_infos[index].np = of_node_get(np); |
131 | legacy_serial_infos[index].clock = clock; | 141 | legacy_serial_infos[index].clock = clock; |
@@ -153,8 +163,6 @@ static int __init add_legacy_soc_port(struct device_node *np, | |||
153 | { | 163 | { |
154 | u64 addr; | 164 | u64 addr; |
155 | const __be32 *addrp; | 165 | const __be32 *addrp; |
156 | upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ | ||
157 | | UPF_FIXED_PORT; | ||
158 | struct device_node *tsi = of_get_parent(np); | 166 | struct device_node *tsi = of_get_parent(np); |
159 | 167 | ||
160 | /* We only support ports that have a clock frequency properly | 168 | /* We only support ports that have a clock frequency properly |
@@ -163,9 +171,8 @@ static int __init add_legacy_soc_port(struct device_node *np, | |||
163 | if (of_get_property(np, "clock-frequency", NULL) == NULL) | 171 | if (of_get_property(np, "clock-frequency", NULL) == NULL) |
164 | return -1; | 172 | return -1; |
165 | 173 | ||
166 | /* if reg-shift or offset, don't try to use it */ | 174 | /* if reg-offset don't try to use it */ |
167 | if ((of_get_property(np, "reg-shift", NULL) != NULL) || | 175 | if ((of_get_property(np, "reg-offset", NULL) != NULL)) |
168 | (of_get_property(np, "reg-offset", NULL) != NULL)) | ||
169 | return -1; | 176 | return -1; |
170 | 177 | ||
171 | /* if rtas uses this device, don't try to use it as well */ | 178 | /* if rtas uses this device, don't try to use it as well */ |
@@ -185,9 +192,11 @@ static int __init add_legacy_soc_port(struct device_node *np, | |||
185 | * IO port value. It will be fixed up later along with the irq | 192 | * IO port value. It will be fixed up later along with the irq |
186 | */ | 193 | */ |
187 | if (tsi && !strcmp(tsi->type, "tsi-bridge")) | 194 | if (tsi && !strcmp(tsi->type, "tsi-bridge")) |
188 | return add_legacy_port(np, -1, UPIO_TSI, addr, addr, NO_IRQ, flags, 0); | 195 | return add_legacy_port(np, -1, UPIO_TSI, addr, addr, |
196 | NO_IRQ, legacy_port_flags, 0); | ||
189 | else | 197 | else |
190 | return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0); | 198 | return add_legacy_port(np, -1, UPIO_MEM, addr, addr, |
199 | NO_IRQ, legacy_port_flags, 0); | ||
191 | } | 200 | } |
192 | 201 | ||
193 | static int __init add_legacy_isa_port(struct device_node *np, | 202 | static int __init add_legacy_isa_port(struct device_node *np, |
@@ -233,7 +242,7 @@ static int __init add_legacy_isa_port(struct device_node *np, | |||
233 | 242 | ||
234 | /* Add port, irq will be dealt with later */ | 243 | /* Add port, irq will be dealt with later */ |
235 | return add_legacy_port(np, index, UPIO_PORT, be32_to_cpu(reg[1]), | 244 | return add_legacy_port(np, index, UPIO_PORT, be32_to_cpu(reg[1]), |
236 | taddr, NO_IRQ, UPF_BOOT_AUTOCONF, 0); | 245 | taddr, NO_IRQ, legacy_port_flags, 0); |
237 | 246 | ||
238 | } | 247 | } |
239 | 248 | ||
@@ -306,7 +315,7 @@ static int __init add_legacy_pci_port(struct device_node *np, | |||
306 | * IO port value. It will be fixed up later along with the irq | 315 | * IO port value. It will be fixed up later along with the irq |
307 | */ | 316 | */ |
308 | return add_legacy_port(np, index, iotype, base, addr, NO_IRQ, | 317 | return add_legacy_port(np, index, iotype, base, addr, NO_IRQ, |
309 | UPF_BOOT_AUTOCONF, np != pci_dev); | 318 | legacy_port_flags, np != pci_dev); |
310 | } | 319 | } |
311 | #endif | 320 | #endif |
312 | 321 | ||
@@ -315,17 +324,20 @@ static void __init setup_legacy_serial_console(int console) | |||
315 | struct legacy_serial_info *info = &legacy_serial_infos[console]; | 324 | struct legacy_serial_info *info = &legacy_serial_infos[console]; |
316 | struct plat_serial8250_port *port = &legacy_serial_ports[console]; | 325 | struct plat_serial8250_port *port = &legacy_serial_ports[console]; |
317 | void __iomem *addr; | 326 | void __iomem *addr; |
327 | unsigned int stride; | ||
328 | |||
329 | stride = 1 << port->regshift; | ||
318 | 330 | ||
319 | /* Check if a translated MMIO address has been found */ | 331 | /* Check if a translated MMIO address has been found */ |
320 | if (info->taddr) { | 332 | if (info->taddr) { |
321 | addr = ioremap(info->taddr, 0x1000); | 333 | addr = ioremap(info->taddr, 0x1000); |
322 | if (addr == NULL) | 334 | if (addr == NULL) |
323 | return; | 335 | return; |
324 | udbg_uart_init_mmio(addr, 1); | 336 | udbg_uart_init_mmio(addr, stride); |
325 | } else { | 337 | } else { |
326 | /* Check if it's PIO and we support untranslated PIO */ | 338 | /* Check if it's PIO and we support untranslated PIO */ |
327 | if (port->iotype == UPIO_PORT && isa_io_special) | 339 | if (port->iotype == UPIO_PORT && isa_io_special) |
328 | udbg_uart_init_pio(port->iobase, 1); | 340 | udbg_uart_init_pio(port->iobase, stride); |
329 | else | 341 | else |
330 | return; | 342 | return; |
331 | } | 343 | } |
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index 3d0249599d52..4e314b90c75d 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S | |||
@@ -34,7 +34,7 @@ _GLOBAL(call_do_softirq) | |||
34 | std r0,16(r1) | 34 | std r0,16(r1) |
35 | stdu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r3) | 35 | stdu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r3) |
36 | mr r1,r3 | 36 | mr r1,r3 |
37 | bl .__do_softirq | 37 | bl __do_softirq |
38 | ld r1,0(r1) | 38 | ld r1,0(r1) |
39 | ld r0,16(r1) | 39 | ld r0,16(r1) |
40 | mtlr r0 | 40 | mtlr r0 |
@@ -45,7 +45,7 @@ _GLOBAL(call_do_irq) | |||
45 | std r0,16(r1) | 45 | std r0,16(r1) |
46 | stdu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r4) | 46 | stdu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r4) |
47 | mr r1,r4 | 47 | mr r1,r4 |
48 | bl .__do_irq | 48 | bl __do_irq |
49 | ld r1,0(r1) | 49 | ld r1,0(r1) |
50 | ld r0,16(r1) | 50 | ld r0,16(r1) |
51 | mtlr r0 | 51 | mtlr r0 |
@@ -506,7 +506,7 @@ _GLOBAL(kexec_smp_wait) | |||
506 | stb r4,PACAKEXECSTATE(r13) | 506 | stb r4,PACAKEXECSTATE(r13) |
507 | SYNC | 507 | SYNC |
508 | 508 | ||
509 | b .kexec_wait | 509 | b kexec_wait |
510 | 510 | ||
511 | /* | 511 | /* |
512 | * switch to real mode (turn mmu off) | 512 | * switch to real mode (turn mmu off) |
@@ -576,7 +576,7 @@ _GLOBAL(kexec_sequence) | |||
576 | 576 | ||
577 | /* copy dest pages, flush whole dest image */ | 577 | /* copy dest pages, flush whole dest image */ |
578 | mr r3,r29 | 578 | mr r3,r29 |
579 | bl .kexec_copy_flush /* (image) */ | 579 | bl kexec_copy_flush /* (image) */ |
580 | 580 | ||
581 | /* turn off mmu */ | 581 | /* turn off mmu */ |
582 | bl real_mode | 582 | bl real_mode |
@@ -586,7 +586,7 @@ _GLOBAL(kexec_sequence) | |||
586 | mr r4,r30 /* start, aka phys mem offset */ | 586 | mr r4,r30 /* start, aka phys mem offset */ |
587 | li r5,0x100 | 587 | li r5,0x100 |
588 | li r6,0 | 588 | li r6,0 |
589 | bl .copy_and_flush /* (dest, src, copy limit, start offset) */ | 589 | bl copy_and_flush /* (dest, src, copy limit, start offset) */ |
590 | 1: /* assume normal blr return */ | 590 | 1: /* assume normal blr return */ |
591 | 591 | ||
592 | /* release other cpus to the new kernel secondary start at 0x60 */ | 592 | /* release other cpus to the new kernel secondary start at 0x60 */ |
@@ -595,8 +595,12 @@ _GLOBAL(kexec_sequence) | |||
595 | stw r6,kexec_flag-1b(5) | 595 | stw r6,kexec_flag-1b(5) |
596 | 596 | ||
597 | /* clear out hardware hash page table and tlb */ | 597 | /* clear out hardware hash page table and tlb */ |
598 | ld r5,0(r27) /* deref function descriptor */ | 598 | #if !defined(_CALL_ELF) || _CALL_ELF != 2 |
599 | mtctr r5 | 599 | ld r12,0(r27) /* deref function descriptor */ |
600 | #else | ||
601 | mr r12,r27 | ||
602 | #endif | ||
603 | mtctr r12 | ||
600 | bctrl /* ppc_md.hpte_clear_all(void); */ | 604 | bctrl /* ppc_md.hpte_clear_all(void); */ |
601 | 605 | ||
602 | /* | 606 | /* |
@@ -630,3 +634,31 @@ _GLOBAL(kexec_sequence) | |||
630 | li r5,0 | 634 | li r5,0 |
631 | blr /* image->start(physid, image->start, 0); */ | 635 | blr /* image->start(physid, image->start, 0); */ |
632 | #endif /* CONFIG_KEXEC */ | 636 | #endif /* CONFIG_KEXEC */ |
637 | |||
638 | #ifdef CONFIG_MODULES | ||
639 | #if defined(_CALL_ELF) && _CALL_ELF == 2 | ||
640 | |||
641 | #ifdef CONFIG_MODVERSIONS | ||
642 | .weak __crc_TOC. | ||
643 | .section "___kcrctab+TOC.","a" | ||
644 | .globl __kcrctab_TOC. | ||
645 | __kcrctab_TOC.: | ||
646 | .llong __crc_TOC. | ||
647 | #endif | ||
648 | |||
649 | /* | ||
650 | * Export a fake .TOC. since both modpost and depmod will complain otherwise. | ||
651 | * Both modpost and depmod strip the leading . so we do the same here. | ||
652 | */ | ||
653 | .section "__ksymtab_strings","a" | ||
654 | __kstrtab_TOC.: | ||
655 | .asciz "TOC." | ||
656 | |||
657 | .section "___ksymtab+TOC.","a" | ||
658 | /* This symbol name is important: it's used by modpost to find exported syms */ | ||
659 | .globl __ksymtab_TOC. | ||
660 | __ksymtab_TOC.: | ||
661 | .llong 0 /* .value */ | ||
662 | .llong __kstrtab_TOC. | ||
663 | #endif /* ELFv2 */ | ||
664 | #endif /* MODULES */ | ||
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index 12664c130d73..077d2ce6c5a7 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/vmalloc.h> | 22 | #include <linux/vmalloc.h> |
23 | #include <linux/ftrace.h> | 23 | #include <linux/ftrace.h> |
24 | #include <linux/bug.h> | 24 | #include <linux/bug.h> |
25 | #include <linux/uaccess.h> | ||
25 | #include <asm/module.h> | 26 | #include <asm/module.h> |
26 | #include <asm/firmware.h> | 27 | #include <asm/firmware.h> |
27 | #include <asm/code-patching.h> | 28 | #include <asm/code-patching.h> |
@@ -41,46 +42,170 @@ | |||
41 | #define DEBUGP(fmt , ...) | 42 | #define DEBUGP(fmt , ...) |
42 | #endif | 43 | #endif |
43 | 44 | ||
45 | #if defined(_CALL_ELF) && _CALL_ELF == 2 | ||
46 | #define R2_STACK_OFFSET 24 | ||
47 | |||
48 | /* An address is simply the address of the function. */ | ||
49 | typedef unsigned long func_desc_t; | ||
50 | |||
51 | static func_desc_t func_desc(unsigned long addr) | ||
52 | { | ||
53 | return addr; | ||
54 | } | ||
55 | static unsigned long func_addr(unsigned long addr) | ||
56 | { | ||
57 | return addr; | ||
58 | } | ||
59 | static unsigned long stub_func_addr(func_desc_t func) | ||
60 | { | ||
61 | return func; | ||
62 | } | ||
63 | |||
64 | /* PowerPC64 specific values for the Elf64_Sym st_other field. */ | ||
65 | #define STO_PPC64_LOCAL_BIT 5 | ||
66 | #define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT) | ||
67 | #define PPC64_LOCAL_ENTRY_OFFSET(other) \ | ||
68 | (((1 << (((other) & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT)) >> 2) << 2) | ||
69 | |||
70 | static unsigned int local_entry_offset(const Elf64_Sym *sym) | ||
71 | { | ||
72 | /* sym->st_other indicates offset to local entry point | ||
73 | * (otherwise it will assume r12 is the address of the start | ||
74 | * of function and try to derive r2 from it). */ | ||
75 | return PPC64_LOCAL_ENTRY_OFFSET(sym->st_other); | ||
76 | } | ||
77 | #else | ||
78 | #define R2_STACK_OFFSET 40 | ||
79 | |||
80 | /* An address is address of the OPD entry, which contains address of fn. */ | ||
81 | typedef struct ppc64_opd_entry func_desc_t; | ||
82 | |||
83 | static func_desc_t func_desc(unsigned long addr) | ||
84 | { | ||
85 | return *(struct ppc64_opd_entry *)addr; | ||
86 | } | ||
87 | static unsigned long func_addr(unsigned long addr) | ||
88 | { | ||
89 | return func_desc(addr).funcaddr; | ||
90 | } | ||
91 | static unsigned long stub_func_addr(func_desc_t func) | ||
92 | { | ||
93 | return func.funcaddr; | ||
94 | } | ||
95 | static unsigned int local_entry_offset(const Elf64_Sym *sym) | ||
96 | { | ||
97 | return 0; | ||
98 | } | ||
99 | #endif | ||
100 | |||
44 | /* Like PPC32, we need little trampolines to do > 24-bit jumps (into | 101 | /* Like PPC32, we need little trampolines to do > 24-bit jumps (into |
45 | the kernel itself). But on PPC64, these need to be used for every | 102 | the kernel itself). But on PPC64, these need to be used for every |
46 | jump, actually, to reset r2 (TOC+0x8000). */ | 103 | jump, actually, to reset r2 (TOC+0x8000). */ |
47 | struct ppc64_stub_entry | 104 | struct ppc64_stub_entry |
48 | { | 105 | { |
49 | /* 28 byte jump instruction sequence (7 instructions) */ | 106 | /* 28 byte jump instruction sequence (7 instructions). We only |
50 | unsigned char jump[28]; | 107 | * need 6 instructions on ABIv2 but we always allocate 7 so |
51 | unsigned char unused[4]; | 108 | * so we don't have to modify the trampoline load instruction. */ |
109 | u32 jump[7]; | ||
110 | u32 unused; | ||
52 | /* Data for the above code */ | 111 | /* Data for the above code */ |
53 | struct ppc64_opd_entry opd; | 112 | func_desc_t funcdata; |
54 | }; | 113 | }; |
55 | 114 | ||
56 | /* We use a stub to fix up r2 (TOC ptr) and to jump to the (external) | 115 | /* |
57 | function which may be more than 24-bits away. We could simply | 116 | * PPC64 uses 24 bit jumps, but we need to jump into other modules or |
58 | patch the new r2 value and function pointer into the stub, but it's | 117 | * the kernel which may be further. So we jump to a stub. |
59 | significantly shorter to put these values at the end of the stub | 118 | * |
60 | code, and patch the stub address (32-bits relative to the TOC ptr, | 119 | * For ELFv1 we need to use this to set up the new r2 value (aka TOC |
61 | r2) into the stub. */ | 120 | * pointer). For ELFv2 it's the callee's responsibility to set up the |
62 | static struct ppc64_stub_entry ppc64_stub = | 121 | * new r2, but for both we need to save the old r2. |
63 | { .jump = { | 122 | * |
64 | #ifdef __LITTLE_ENDIAN__ | 123 | * We could simply patch the new r2 value and function pointer into |
65 | 0x00, 0x00, 0x82, 0x3d, /* addis r12,r2, <high> */ | 124 | * the stub, but it's significantly shorter to put these values at the |
66 | 0x00, 0x00, 0x8c, 0x39, /* addi r12,r12, <low> */ | 125 | * end of the stub code, and patch the stub address (32-bits relative |
67 | /* Save current r2 value in magic place on the stack. */ | 126 | * to the TOC ptr, r2) into the stub. |
68 | 0x28, 0x00, 0x41, 0xf8, /* std r2,40(r1) */ | 127 | */ |
69 | 0x20, 0x00, 0x6c, 0xe9, /* ld r11,32(r12) */ | 128 | |
70 | 0x28, 0x00, 0x4c, 0xe8, /* ld r2,40(r12) */ | 129 | static u32 ppc64_stub_insns[] = { |
71 | 0xa6, 0x03, 0x69, 0x7d, /* mtctr r11 */ | 130 | 0x3d620000, /* addis r11,r2, <high> */ |
72 | 0x20, 0x04, 0x80, 0x4e /* bctr */ | 131 | 0x396b0000, /* addi r11,r11, <low> */ |
73 | #else | ||
74 | 0x3d, 0x82, 0x00, 0x00, /* addis r12,r2, <high> */ | ||
75 | 0x39, 0x8c, 0x00, 0x00, /* addi r12,r12, <low> */ | ||
76 | /* Save current r2 value in magic place on the stack. */ | 132 | /* Save current r2 value in magic place on the stack. */ |
77 | 0xf8, 0x41, 0x00, 0x28, /* std r2,40(r1) */ | 133 | 0xf8410000|R2_STACK_OFFSET, /* std r2,R2_STACK_OFFSET(r1) */ |
78 | 0xe9, 0x6c, 0x00, 0x20, /* ld r11,32(r12) */ | 134 | 0xe98b0020, /* ld r12,32(r11) */ |
79 | 0xe8, 0x4c, 0x00, 0x28, /* ld r2,40(r12) */ | 135 | #if !defined(_CALL_ELF) || _CALL_ELF != 2 |
80 | 0x7d, 0x69, 0x03, 0xa6, /* mtctr r11 */ | 136 | /* Set up new r2 from function descriptor */ |
81 | 0x4e, 0x80, 0x04, 0x20 /* bctr */ | 137 | 0xe84b0028, /* ld r2,40(r11) */ |
138 | #endif | ||
139 | 0x7d8903a6, /* mtctr r12 */ | ||
140 | 0x4e800420 /* bctr */ | ||
141 | }; | ||
142 | |||
143 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
144 | |||
145 | static u32 ppc64_stub_mask[] = { | ||
146 | 0xffff0000, | ||
147 | 0xffff0000, | ||
148 | 0xffffffff, | ||
149 | 0xffffffff, | ||
150 | #if !defined(_CALL_ELF) || _CALL_ELF != 2 | ||
151 | 0xffffffff, | ||
152 | #endif | ||
153 | 0xffffffff, | ||
154 | 0xffffffff | ||
155 | }; | ||
156 | |||
157 | bool is_module_trampoline(u32 *p) | ||
158 | { | ||
159 | unsigned int i; | ||
160 | u32 insns[ARRAY_SIZE(ppc64_stub_insns)]; | ||
161 | |||
162 | BUILD_BUG_ON(sizeof(ppc64_stub_insns) != sizeof(ppc64_stub_mask)); | ||
163 | |||
164 | if (probe_kernel_read(insns, p, sizeof(insns))) | ||
165 | return -EFAULT; | ||
166 | |||
167 | for (i = 0; i < ARRAY_SIZE(ppc64_stub_insns); i++) { | ||
168 | u32 insna = insns[i]; | ||
169 | u32 insnb = ppc64_stub_insns[i]; | ||
170 | u32 mask = ppc64_stub_mask[i]; | ||
171 | |||
172 | if ((insna & mask) != (insnb & mask)) | ||
173 | return false; | ||
174 | } | ||
175 | |||
176 | return true; | ||
177 | } | ||
178 | |||
179 | int module_trampoline_target(struct module *mod, u32 *trampoline, | ||
180 | unsigned long *target) | ||
181 | { | ||
182 | u32 buf[2]; | ||
183 | u16 upper, lower; | ||
184 | long offset; | ||
185 | void *toc_entry; | ||
186 | |||
187 | if (probe_kernel_read(buf, trampoline, sizeof(buf))) | ||
188 | return -EFAULT; | ||
189 | |||
190 | upper = buf[0] & 0xffff; | ||
191 | lower = buf[1] & 0xffff; | ||
192 | |||
193 | /* perform the addis/addi, both signed */ | ||
194 | offset = ((short)upper << 16) + (short)lower; | ||
195 | |||
196 | /* | ||
197 | * Now get the address this trampoline jumps to. This | ||
198 | * is always 32 bytes into our trampoline stub. | ||
199 | */ | ||
200 | toc_entry = (void *)mod->arch.toc + offset + 32; | ||
201 | |||
202 | if (probe_kernel_read(target, toc_entry, sizeof(*target))) | ||
203 | return -EFAULT; | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | |||
82 | #endif | 208 | #endif |
83 | } }; | ||
84 | 209 | ||
85 | /* Count how many different 24-bit relocations (different symbol, | 210 | /* Count how many different 24-bit relocations (different symbol, |
86 | different addend) */ | 211 | different addend) */ |
@@ -183,6 +308,7 @@ static unsigned long get_stubs_size(const Elf64_Ehdr *hdr, | |||
183 | return relocs * sizeof(struct ppc64_stub_entry); | 308 | return relocs * sizeof(struct ppc64_stub_entry); |
184 | } | 309 | } |
185 | 310 | ||
311 | /* Still needed for ELFv2, for .TOC. */ | ||
186 | static void dedotify_versions(struct modversion_info *vers, | 312 | static void dedotify_versions(struct modversion_info *vers, |
187 | unsigned long size) | 313 | unsigned long size) |
188 | { | 314 | { |
@@ -193,7 +319,7 @@ static void dedotify_versions(struct modversion_info *vers, | |||
193 | memmove(vers->name, vers->name+1, strlen(vers->name)); | 319 | memmove(vers->name, vers->name+1, strlen(vers->name)); |
194 | } | 320 | } |
195 | 321 | ||
196 | /* Undefined symbols which refer to .funcname, hack to funcname */ | 322 | /* Undefined symbols which refer to .funcname, hack to funcname (or .TOC.) */ |
197 | static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab) | 323 | static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab) |
198 | { | 324 | { |
199 | unsigned int i; | 325 | unsigned int i; |
@@ -207,6 +333,24 @@ static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab) | |||
207 | } | 333 | } |
208 | } | 334 | } |
209 | 335 | ||
336 | static Elf64_Sym *find_dot_toc(Elf64_Shdr *sechdrs, | ||
337 | const char *strtab, | ||
338 | unsigned int symindex) | ||
339 | { | ||
340 | unsigned int i, numsyms; | ||
341 | Elf64_Sym *syms; | ||
342 | |||
343 | syms = (Elf64_Sym *)sechdrs[symindex].sh_addr; | ||
344 | numsyms = sechdrs[symindex].sh_size / sizeof(Elf64_Sym); | ||
345 | |||
346 | for (i = 1; i < numsyms; i++) { | ||
347 | if (syms[i].st_shndx == SHN_UNDEF | ||
348 | && strcmp(strtab + syms[i].st_name, "TOC.") == 0) | ||
349 | return &syms[i]; | ||
350 | } | ||
351 | return NULL; | ||
352 | } | ||
353 | |||
210 | int module_frob_arch_sections(Elf64_Ehdr *hdr, | 354 | int module_frob_arch_sections(Elf64_Ehdr *hdr, |
211 | Elf64_Shdr *sechdrs, | 355 | Elf64_Shdr *sechdrs, |
212 | char *secstrings, | 356 | char *secstrings, |
@@ -271,21 +415,12 @@ static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me) | |||
271 | /* Patch stub to reference function and correct r2 value. */ | 415 | /* Patch stub to reference function and correct r2 value. */ |
272 | static inline int create_stub(Elf64_Shdr *sechdrs, | 416 | static inline int create_stub(Elf64_Shdr *sechdrs, |
273 | struct ppc64_stub_entry *entry, | 417 | struct ppc64_stub_entry *entry, |
274 | struct ppc64_opd_entry *opd, | 418 | unsigned long addr, |
275 | struct module *me) | 419 | struct module *me) |
276 | { | 420 | { |
277 | Elf64_Half *loc1, *loc2; | ||
278 | long reladdr; | 421 | long reladdr; |
279 | 422 | ||
280 | *entry = ppc64_stub; | 423 | memcpy(entry->jump, ppc64_stub_insns, sizeof(ppc64_stub_insns)); |
281 | |||
282 | #ifdef __LITTLE_ENDIAN__ | ||
283 | loc1 = (Elf64_Half *)&entry->jump[0]; | ||
284 | loc2 = (Elf64_Half *)&entry->jump[4]; | ||
285 | #else | ||
286 | loc1 = (Elf64_Half *)&entry->jump[2]; | ||
287 | loc2 = (Elf64_Half *)&entry->jump[6]; | ||
288 | #endif | ||
289 | 424 | ||
290 | /* Stub uses address relative to r2. */ | 425 | /* Stub uses address relative to r2. */ |
291 | reladdr = (unsigned long)entry - my_r2(sechdrs, me); | 426 | reladdr = (unsigned long)entry - my_r2(sechdrs, me); |
@@ -296,35 +431,33 @@ static inline int create_stub(Elf64_Shdr *sechdrs, | |||
296 | } | 431 | } |
297 | DEBUGP("Stub %p get data from reladdr %li\n", entry, reladdr); | 432 | DEBUGP("Stub %p get data from reladdr %li\n", entry, reladdr); |
298 | 433 | ||
299 | *loc1 = PPC_HA(reladdr); | 434 | entry->jump[0] |= PPC_HA(reladdr); |
300 | *loc2 = PPC_LO(reladdr); | 435 | entry->jump[1] |= PPC_LO(reladdr); |
301 | entry->opd.funcaddr = opd->funcaddr; | 436 | entry->funcdata = func_desc(addr); |
302 | entry->opd.r2 = opd->r2; | ||
303 | return 1; | 437 | return 1; |
304 | } | 438 | } |
305 | 439 | ||
306 | /* Create stub to jump to function described in this OPD: we need the | 440 | /* Create stub to jump to function described in this OPD/ptr: we need the |
307 | stub to set up the TOC ptr (r2) for the function. */ | 441 | stub to set up the TOC ptr (r2) for the function. */ |
308 | static unsigned long stub_for_addr(Elf64_Shdr *sechdrs, | 442 | static unsigned long stub_for_addr(Elf64_Shdr *sechdrs, |
309 | unsigned long opdaddr, | 443 | unsigned long addr, |
310 | struct module *me) | 444 | struct module *me) |
311 | { | 445 | { |
312 | struct ppc64_stub_entry *stubs; | 446 | struct ppc64_stub_entry *stubs; |
313 | struct ppc64_opd_entry *opd = (void *)opdaddr; | ||
314 | unsigned int i, num_stubs; | 447 | unsigned int i, num_stubs; |
315 | 448 | ||
316 | num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*stubs); | 449 | num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*stubs); |
317 | 450 | ||
318 | /* Find this stub, or if that fails, the next avail. entry */ | 451 | /* Find this stub, or if that fails, the next avail. entry */ |
319 | stubs = (void *)sechdrs[me->arch.stubs_section].sh_addr; | 452 | stubs = (void *)sechdrs[me->arch.stubs_section].sh_addr; |
320 | for (i = 0; stubs[i].opd.funcaddr; i++) { | 453 | for (i = 0; stub_func_addr(stubs[i].funcdata); i++) { |
321 | BUG_ON(i >= num_stubs); | 454 | BUG_ON(i >= num_stubs); |
322 | 455 | ||
323 | if (stubs[i].opd.funcaddr == opd->funcaddr) | 456 | if (stub_func_addr(stubs[i].funcdata) == func_addr(addr)) |
324 | return (unsigned long)&stubs[i]; | 457 | return (unsigned long)&stubs[i]; |
325 | } | 458 | } |
326 | 459 | ||
327 | if (!create_stub(sechdrs, &stubs[i], opd, me)) | 460 | if (!create_stub(sechdrs, &stubs[i], addr, me)) |
328 | return 0; | 461 | return 0; |
329 | 462 | ||
330 | return (unsigned long)&stubs[i]; | 463 | return (unsigned long)&stubs[i]; |
@@ -339,7 +472,8 @@ static int restore_r2(u32 *instruction, struct module *me) | |||
339 | me->name, *instruction); | 472 | me->name, *instruction); |
340 | return 0; | 473 | return 0; |
341 | } | 474 | } |
342 | *instruction = 0xe8410028; /* ld r2,40(r1) */ | 475 | /* ld r2,R2_STACK_OFFSET(r1) */ |
476 | *instruction = 0xe8410000 | R2_STACK_OFFSET; | ||
343 | return 1; | 477 | return 1; |
344 | } | 478 | } |
345 | 479 | ||
@@ -357,6 +491,17 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
357 | 491 | ||
358 | DEBUGP("Applying ADD relocate section %u to %u\n", relsec, | 492 | DEBUGP("Applying ADD relocate section %u to %u\n", relsec, |
359 | sechdrs[relsec].sh_info); | 493 | sechdrs[relsec].sh_info); |
494 | |||
495 | /* First time we're called, we can fix up .TOC. */ | ||
496 | if (!me->arch.toc_fixed) { | ||
497 | sym = find_dot_toc(sechdrs, strtab, symindex); | ||
498 | /* It's theoretically possible that a module doesn't want a | ||
499 | * .TOC. so don't fail it just for that. */ | ||
500 | if (sym) | ||
501 | sym->st_value = my_r2(sechdrs, me); | ||
502 | me->arch.toc_fixed = true; | ||
503 | } | ||
504 | |||
360 | for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) { | 505 | for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) { |
361 | /* This is where to make the change */ | 506 | /* This is where to make the change */ |
362 | location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr | 507 | location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr |
@@ -453,7 +598,8 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
453 | return -ENOENT; | 598 | return -ENOENT; |
454 | if (!restore_r2((u32 *)location + 1, me)) | 599 | if (!restore_r2((u32 *)location + 1, me)) |
455 | return -ENOEXEC; | 600 | return -ENOEXEC; |
456 | } | 601 | } else |
602 | value += local_entry_offset(sym); | ||
457 | 603 | ||
458 | /* Convert value to relative */ | 604 | /* Convert value to relative */ |
459 | value -= (unsigned long)location; | 605 | value -= (unsigned long)location; |
@@ -474,6 +620,31 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
474 | *location = value - (unsigned long)location; | 620 | *location = value - (unsigned long)location; |
475 | break; | 621 | break; |
476 | 622 | ||
623 | case R_PPC64_TOCSAVE: | ||
624 | /* | ||
625 | * Marker reloc indicates we don't have to save r2. | ||
626 | * That would only save us one instruction, so ignore | ||
627 | * it. | ||
628 | */ | ||
629 | break; | ||
630 | |||
631 | case R_PPC64_REL16_HA: | ||
632 | /* Subtract location pointer */ | ||
633 | value -= (unsigned long)location; | ||
634 | value = ((value + 0x8000) >> 16); | ||
635 | *((uint16_t *) location) | ||
636 | = (*((uint16_t *) location) & ~0xffff) | ||
637 | | (value & 0xffff); | ||
638 | break; | ||
639 | |||
640 | case R_PPC64_REL16_LO: | ||
641 | /* Subtract location pointer */ | ||
642 | value -= (unsigned long)location; | ||
643 | *((uint16_t *) location) | ||
644 | = (*((uint16_t *) location) & ~0xffff) | ||
645 | | (value & 0xffff); | ||
646 | break; | ||
647 | |||
477 | default: | 648 | default: |
478 | printk("%s: Unknown ADD relocation: %lu\n", | 649 | printk("%s: Unknown ADD relocation: %lu\n", |
479 | me->name, | 650 | me->name, |
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 24d342e91790..b49c72fd7f16 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/string.h> | 21 | #include <linux/string.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/bootmem.h> | 23 | #include <linux/bootmem.h> |
24 | #include <linux/delay.h> | ||
24 | #include <linux/export.h> | 25 | #include <linux/export.h> |
25 | #include <linux/of_address.h> | 26 | #include <linux/of_address.h> |
26 | #include <linux/of_pci.h> | 27 | #include <linux/of_pci.h> |
@@ -120,6 +121,25 @@ resource_size_t pcibios_window_alignment(struct pci_bus *bus, | |||
120 | return 1; | 121 | return 1; |
121 | } | 122 | } |
122 | 123 | ||
124 | void pcibios_reset_secondary_bus(struct pci_dev *dev) | ||
125 | { | ||
126 | u16 ctrl; | ||
127 | |||
128 | if (ppc_md.pcibios_reset_secondary_bus) { | ||
129 | ppc_md.pcibios_reset_secondary_bus(dev); | ||
130 | return; | ||
131 | } | ||
132 | |||
133 | pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &ctrl); | ||
134 | ctrl |= PCI_BRIDGE_CTL_BUS_RESET; | ||
135 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl); | ||
136 | msleep(2); | ||
137 | |||
138 | ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET; | ||
139 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl); | ||
140 | ssleep(1); | ||
141 | } | ||
142 | |||
123 | static resource_size_t pcibios_io_size(const struct pci_controller *hose) | 143 | static resource_size_t pcibios_io_size(const struct pci_controller *hose) |
124 | { | 144 | { |
125 | #ifdef CONFIG_PPC64 | 145 | #ifdef CONFIG_PPC64 |
@@ -646,60 +666,36 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
646 | void pci_process_bridge_OF_ranges(struct pci_controller *hose, | 666 | void pci_process_bridge_OF_ranges(struct pci_controller *hose, |
647 | struct device_node *dev, int primary) | 667 | struct device_node *dev, int primary) |
648 | { | 668 | { |
649 | const __be32 *ranges; | ||
650 | int rlen; | ||
651 | int pna = of_n_addr_cells(dev); | ||
652 | int np = pna + 5; | ||
653 | int memno = 0; | 669 | int memno = 0; |
654 | u32 pci_space; | ||
655 | unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size; | ||
656 | struct resource *res; | 670 | struct resource *res; |
671 | struct of_pci_range range; | ||
672 | struct of_pci_range_parser parser; | ||
657 | 673 | ||
658 | printk(KERN_INFO "PCI host bridge %s %s ranges:\n", | 674 | printk(KERN_INFO "PCI host bridge %s %s ranges:\n", |
659 | dev->full_name, primary ? "(primary)" : ""); | 675 | dev->full_name, primary ? "(primary)" : ""); |
660 | 676 | ||
661 | /* Get ranges property */ | 677 | /* Check for ranges property */ |
662 | ranges = of_get_property(dev, "ranges", &rlen); | 678 | if (of_pci_range_parser_init(&parser, dev)) |
663 | if (ranges == NULL) | ||
664 | return; | 679 | return; |
665 | 680 | ||
666 | /* Parse it */ | 681 | /* Parse it */ |
667 | while ((rlen -= np * 4) >= 0) { | 682 | for_each_of_pci_range(&parser, &range) { |
668 | /* Read next ranges element */ | ||
669 | pci_space = of_read_number(ranges, 1); | ||
670 | pci_addr = of_read_number(ranges + 1, 2); | ||
671 | cpu_addr = of_translate_address(dev, ranges + 3); | ||
672 | size = of_read_number(ranges + pna + 3, 2); | ||
673 | ranges += np; | ||
674 | |||
675 | /* If we failed translation or got a zero-sized region | 683 | /* If we failed translation or got a zero-sized region |
676 | * (some FW try to feed us with non sensical zero sized regions | 684 | * (some FW try to feed us with non sensical zero sized regions |
677 | * such as power3 which look like some kind of attempt at exposing | 685 | * such as power3 which look like some kind of attempt at exposing |
678 | * the VGA memory hole) | 686 | * the VGA memory hole) |
679 | */ | 687 | */ |
680 | if (cpu_addr == OF_BAD_ADDR || size == 0) | 688 | if (range.cpu_addr == OF_BAD_ADDR || range.size == 0) |
681 | continue; | 689 | continue; |
682 | 690 | ||
683 | /* Now consume following elements while they are contiguous */ | ||
684 | for (; rlen >= np * sizeof(u32); | ||
685 | ranges += np, rlen -= np * 4) { | ||
686 | if (of_read_number(ranges, 1) != pci_space) | ||
687 | break; | ||
688 | pci_next = of_read_number(ranges + 1, 2); | ||
689 | cpu_next = of_translate_address(dev, ranges + 3); | ||
690 | if (pci_next != pci_addr + size || | ||
691 | cpu_next != cpu_addr + size) | ||
692 | break; | ||
693 | size += of_read_number(ranges + pna + 3, 2); | ||
694 | } | ||
695 | |||
696 | /* Act based on address space type */ | 691 | /* Act based on address space type */ |
697 | res = NULL; | 692 | res = NULL; |
698 | switch ((pci_space >> 24) & 0x3) { | 693 | switch (range.flags & IORESOURCE_TYPE_BITS) { |
699 | case 1: /* PCI IO space */ | 694 | case IORESOURCE_IO: |
700 | printk(KERN_INFO | 695 | printk(KERN_INFO |
701 | " IO 0x%016llx..0x%016llx -> 0x%016llx\n", | 696 | " IO 0x%016llx..0x%016llx -> 0x%016llx\n", |
702 | cpu_addr, cpu_addr + size - 1, pci_addr); | 697 | range.cpu_addr, range.cpu_addr + range.size - 1, |
698 | range.pci_addr); | ||
703 | 699 | ||
704 | /* We support only one IO range */ | 700 | /* We support only one IO range */ |
705 | if (hose->pci_io_size) { | 701 | if (hose->pci_io_size) { |
@@ -709,11 +705,12 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
709 | } | 705 | } |
710 | #ifdef CONFIG_PPC32 | 706 | #ifdef CONFIG_PPC32 |
711 | /* On 32 bits, limit I/O space to 16MB */ | 707 | /* On 32 bits, limit I/O space to 16MB */ |
712 | if (size > 0x01000000) | 708 | if (range.size > 0x01000000) |
713 | size = 0x01000000; | 709 | range.size = 0x01000000; |
714 | 710 | ||
715 | /* 32 bits needs to map IOs here */ | 711 | /* 32 bits needs to map IOs here */ |
716 | hose->io_base_virt = ioremap(cpu_addr, size); | 712 | hose->io_base_virt = ioremap(range.cpu_addr, |
713 | range.size); | ||
717 | 714 | ||
718 | /* Expect trouble if pci_addr is not 0 */ | 715 | /* Expect trouble if pci_addr is not 0 */ |
719 | if (primary) | 716 | if (primary) |
@@ -723,20 +720,20 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
723 | /* pci_io_size and io_base_phys always represent IO | 720 | /* pci_io_size and io_base_phys always represent IO |
724 | * space starting at 0 so we factor in pci_addr | 721 | * space starting at 0 so we factor in pci_addr |
725 | */ | 722 | */ |
726 | hose->pci_io_size = pci_addr + size; | 723 | hose->pci_io_size = range.pci_addr + range.size; |
727 | hose->io_base_phys = cpu_addr - pci_addr; | 724 | hose->io_base_phys = range.cpu_addr - range.pci_addr; |
728 | 725 | ||
729 | /* Build resource */ | 726 | /* Build resource */ |
730 | res = &hose->io_resource; | 727 | res = &hose->io_resource; |
731 | res->flags = IORESOURCE_IO; | 728 | range.cpu_addr = range.pci_addr; |
732 | res->start = pci_addr; | ||
733 | break; | 729 | break; |
734 | case 2: /* PCI Memory space */ | 730 | case IORESOURCE_MEM: |
735 | case 3: /* PCI 64 bits Memory space */ | ||
736 | printk(KERN_INFO | 731 | printk(KERN_INFO |
737 | " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n", | 732 | " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n", |
738 | cpu_addr, cpu_addr + size - 1, pci_addr, | 733 | range.cpu_addr, range.cpu_addr + range.size - 1, |
739 | (pci_space & 0x40000000) ? "Prefetch" : ""); | 734 | range.pci_addr, |
735 | (range.pci_space & 0x40000000) ? | ||
736 | "Prefetch" : ""); | ||
740 | 737 | ||
741 | /* We support only 3 memory ranges */ | 738 | /* We support only 3 memory ranges */ |
742 | if (memno >= 3) { | 739 | if (memno >= 3) { |
@@ -745,28 +742,21 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
745 | continue; | 742 | continue; |
746 | } | 743 | } |
747 | /* Handles ISA memory hole space here */ | 744 | /* Handles ISA memory hole space here */ |
748 | if (pci_addr == 0) { | 745 | if (range.pci_addr == 0) { |
749 | if (primary || isa_mem_base == 0) | 746 | if (primary || isa_mem_base == 0) |
750 | isa_mem_base = cpu_addr; | 747 | isa_mem_base = range.cpu_addr; |
751 | hose->isa_mem_phys = cpu_addr; | 748 | hose->isa_mem_phys = range.cpu_addr; |
752 | hose->isa_mem_size = size; | 749 | hose->isa_mem_size = range.size; |
753 | } | 750 | } |
754 | 751 | ||
755 | /* Build resource */ | 752 | /* Build resource */ |
756 | hose->mem_offset[memno] = cpu_addr - pci_addr; | 753 | hose->mem_offset[memno] = range.cpu_addr - |
754 | range.pci_addr; | ||
757 | res = &hose->mem_resources[memno++]; | 755 | res = &hose->mem_resources[memno++]; |
758 | res->flags = IORESOURCE_MEM; | ||
759 | if (pci_space & 0x40000000) | ||
760 | res->flags |= IORESOURCE_PREFETCH; | ||
761 | res->start = cpu_addr; | ||
762 | break; | 756 | break; |
763 | } | 757 | } |
764 | if (res != NULL) { | 758 | if (res != NULL) { |
765 | res->name = dev->full_name; | 759 | of_pci_range_to_resource(&range, dev, res); |
766 | res->end = res->start + size - 1; | ||
767 | res->parent = NULL; | ||
768 | res->sibling = NULL; | ||
769 | res->child = NULL; | ||
770 | } | 760 | } |
771 | } | 761 | } |
772 | } | 762 | } |
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 059e244484fe..44562aa97f16 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c | |||
@@ -304,6 +304,9 @@ static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus, | |||
304 | struct pci_dev *dev = NULL; | 304 | struct pci_dev *dev = NULL; |
305 | const __be32 *reg; | 305 | const __be32 *reg; |
306 | int reglen, devfn; | 306 | int reglen, devfn; |
307 | #ifdef CONFIG_EEH | ||
308 | struct eeh_dev *edev = of_node_to_eeh_dev(dn); | ||
309 | #endif | ||
307 | 310 | ||
308 | pr_debug(" * %s\n", dn->full_name); | 311 | pr_debug(" * %s\n", dn->full_name); |
309 | if (!of_device_is_available(dn)) | 312 | if (!of_device_is_available(dn)) |
@@ -321,6 +324,12 @@ static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus, | |||
321 | return dev; | 324 | return dev; |
322 | } | 325 | } |
323 | 326 | ||
327 | /* Device removed permanently ? */ | ||
328 | #ifdef CONFIG_EEH | ||
329 | if (edev && (edev->mode & EEH_DEV_REMOVED)) | ||
330 | return NULL; | ||
331 | #endif | ||
332 | |||
324 | /* create a new pci_dev for this device */ | 333 | /* create a new pci_dev for this device */ |
325 | dev = of_create_pci_dev(dn, bus, devfn); | 334 | dev = of_create_pci_dev(dn, bus, devfn); |
326 | if (!dev) | 335 | if (!dev) |
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 450850a49dce..48d17d6fca5b 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -155,9 +155,7 @@ EXPORT_SYMBOL(__cmpdi2); | |||
155 | #endif | 155 | #endif |
156 | long long __bswapdi2(long long); | 156 | long long __bswapdi2(long long); |
157 | EXPORT_SYMBOL(__bswapdi2); | 157 | EXPORT_SYMBOL(__bswapdi2); |
158 | #ifdef __BIG_ENDIAN__ | ||
159 | EXPORT_SYMBOL(memcpy); | 158 | EXPORT_SYMBOL(memcpy); |
160 | #endif | ||
161 | EXPORT_SYMBOL(memset); | 159 | EXPORT_SYMBOL(memset); |
162 | EXPORT_SYMBOL(memmove); | 160 | EXPORT_SYMBOL(memmove); |
163 | EXPORT_SYMBOL(memcmp); | 161 | EXPORT_SYMBOL(memcmp); |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 31d021506d21..8a1edbe26b8f 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #ifdef CONFIG_PPC64 | 54 | #ifdef CONFIG_PPC64 |
55 | #include <asm/firmware.h> | 55 | #include <asm/firmware.h> |
56 | #endif | 56 | #endif |
57 | #include <asm/code-patching.h> | ||
57 | #include <linux/kprobes.h> | 58 | #include <linux/kprobes.h> |
58 | #include <linux/kdebug.h> | 59 | #include <linux/kdebug.h> |
59 | 60 | ||
@@ -495,14 +496,21 @@ static inline int set_dawr(struct arch_hw_breakpoint *brk) | |||
495 | return 0; | 496 | return 0; |
496 | } | 497 | } |
497 | 498 | ||
498 | int set_breakpoint(struct arch_hw_breakpoint *brk) | 499 | void __set_breakpoint(struct arch_hw_breakpoint *brk) |
499 | { | 500 | { |
500 | __get_cpu_var(current_brk) = *brk; | 501 | __get_cpu_var(current_brk) = *brk; |
501 | 502 | ||
502 | if (cpu_has_feature(CPU_FTR_DAWR)) | 503 | if (cpu_has_feature(CPU_FTR_DAWR)) |
503 | return set_dawr(brk); | 504 | set_dawr(brk); |
505 | else | ||
506 | set_dabr(brk); | ||
507 | } | ||
504 | 508 | ||
505 | return set_dabr(brk); | 509 | void set_breakpoint(struct arch_hw_breakpoint *brk) |
510 | { | ||
511 | preempt_disable(); | ||
512 | __set_breakpoint(brk); | ||
513 | preempt_enable(); | ||
506 | } | 514 | } |
507 | 515 | ||
508 | #ifdef CONFIG_PPC64 | 516 | #ifdef CONFIG_PPC64 |
@@ -834,7 +842,7 @@ struct task_struct *__switch_to(struct task_struct *prev, | |||
834 | */ | 842 | */ |
835 | #ifndef CONFIG_HAVE_HW_BREAKPOINT | 843 | #ifndef CONFIG_HAVE_HW_BREAKPOINT |
836 | if (unlikely(!hw_brk_match(&__get_cpu_var(current_brk), &new->thread.hw_brk))) | 844 | if (unlikely(!hw_brk_match(&__get_cpu_var(current_brk), &new->thread.hw_brk))) |
837 | set_breakpoint(&new->thread.hw_brk); | 845 | __set_breakpoint(&new->thread.hw_brk); |
838 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | 846 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ |
839 | #endif | 847 | #endif |
840 | 848 | ||
@@ -1108,7 +1116,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
1108 | struct thread_info *ti = (void *)task_stack_page(p); | 1116 | struct thread_info *ti = (void *)task_stack_page(p); |
1109 | memset(childregs, 0, sizeof(struct pt_regs)); | 1117 | memset(childregs, 0, sizeof(struct pt_regs)); |
1110 | childregs->gpr[1] = sp + sizeof(struct pt_regs); | 1118 | childregs->gpr[1] = sp + sizeof(struct pt_regs); |
1111 | childregs->gpr[14] = usp; /* function */ | 1119 | /* function */ |
1120 | if (usp) | ||
1121 | childregs->gpr[14] = ppc_function_entry((void *)usp); | ||
1112 | #ifdef CONFIG_PPC64 | 1122 | #ifdef CONFIG_PPC64 |
1113 | clear_tsk_thread_flag(p, TIF_32BIT); | 1123 | clear_tsk_thread_flag(p, TIF_32BIT); |
1114 | childregs->softe = 1; | 1124 | childregs->softe = 1; |
@@ -1187,17 +1197,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
1187 | if (cpu_has_feature(CPU_FTR_HAS_PPR)) | 1197 | if (cpu_has_feature(CPU_FTR_HAS_PPR)) |
1188 | p->thread.ppr = INIT_PPR; | 1198 | p->thread.ppr = INIT_PPR; |
1189 | #endif | 1199 | #endif |
1190 | /* | 1200 | kregs->nip = ppc_function_entry(f); |
1191 | * The PPC64 ABI makes use of a TOC to contain function | ||
1192 | * pointers. The function (ret_from_except) is actually a pointer | ||
1193 | * to the TOC entry. The first entry is a pointer to the actual | ||
1194 | * function. | ||
1195 | */ | ||
1196 | #ifdef CONFIG_PPC64 | ||
1197 | kregs->nip = *((unsigned long *)f); | ||
1198 | #else | ||
1199 | kregs->nip = (unsigned long)f; | ||
1200 | #endif | ||
1201 | return 0; | 1201 | return 0; |
1202 | } | 1202 | } |
1203 | 1203 | ||
diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh index b0c263da219a..77aa1e95e904 100644 --- a/arch/powerpc/kernel/prom_init_check.sh +++ b/arch/powerpc/kernel/prom_init_check.sh | |||
@@ -23,7 +23,7 @@ strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224 | |||
23 | reloc_got2 kernstart_addr memstart_addr linux_banner _stext | 23 | reloc_got2 kernstart_addr memstart_addr linux_banner _stext |
24 | opal_query_takeover opal_do_takeover opal_enter_rtas opal_secondary_entry | 24 | opal_query_takeover opal_do_takeover opal_enter_rtas opal_secondary_entry |
25 | boot_command_line __prom_init_toc_start __prom_init_toc_end | 25 | boot_command_line __prom_init_toc_start __prom_init_toc_end |
26 | btext_setup_display" | 26 | btext_setup_display TOC." |
27 | 27 | ||
28 | NM="$1" | 28 | NM="$1" |
29 | OBJ="$2" | 29 | OBJ="$2" |
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 7d4c7172f38e..c168337aef9d 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c | |||
@@ -80,10 +80,6 @@ int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val) | |||
80 | if (ret) | 80 | if (ret) |
81 | return PCIBIOS_DEVICE_NOT_FOUND; | 81 | return PCIBIOS_DEVICE_NOT_FOUND; |
82 | 82 | ||
83 | if (returnval == EEH_IO_ERROR_VALUE(size) && | ||
84 | eeh_dev_check_failure(of_node_to_eeh_dev(pdn->node))) | ||
85 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
86 | |||
87 | return PCIBIOS_SUCCESSFUL; | 83 | return PCIBIOS_SUCCESSFUL; |
88 | } | 84 | } |
89 | 85 | ||
@@ -92,18 +88,39 @@ static int rtas_pci_read_config(struct pci_bus *bus, | |||
92 | int where, int size, u32 *val) | 88 | int where, int size, u32 *val) |
93 | { | 89 | { |
94 | struct device_node *busdn, *dn; | 90 | struct device_node *busdn, *dn; |
95 | 91 | struct pci_dn *pdn; | |
96 | busdn = pci_bus_to_OF_node(bus); | 92 | bool found = false; |
93 | #ifdef CONFIG_EEH | ||
94 | struct eeh_dev *edev; | ||
95 | #endif | ||
96 | int ret; | ||
97 | 97 | ||
98 | /* Search only direct children of the bus */ | 98 | /* Search only direct children of the bus */ |
99 | *val = 0xFFFFFFFF; | ||
100 | busdn = pci_bus_to_OF_node(bus); | ||
99 | for (dn = busdn->child; dn; dn = dn->sibling) { | 101 | for (dn = busdn->child; dn; dn = dn->sibling) { |
100 | struct pci_dn *pdn = PCI_DN(dn); | 102 | pdn = PCI_DN(dn); |
101 | if (pdn && pdn->devfn == devfn | 103 | if (pdn && pdn->devfn == devfn |
102 | && of_device_is_available(dn)) | 104 | && of_device_is_available(dn)) { |
103 | return rtas_read_config(pdn, where, size, val); | 105 | found = true; |
106 | break; | ||
107 | } | ||
104 | } | 108 | } |
105 | 109 | ||
106 | return PCIBIOS_DEVICE_NOT_FOUND; | 110 | if (!found) |
111 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
112 | #ifdef CONFIG_EEH | ||
113 | edev = of_node_to_eeh_dev(dn); | ||
114 | if (edev && edev->pe && edev->pe->state & EEH_PE_RESET) | ||
115 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
116 | #endif | ||
117 | |||
118 | ret = rtas_read_config(pdn, where, size, val); | ||
119 | if (*val == EEH_IO_ERROR_VALUE(size) && | ||
120 | eeh_dev_check_failure(of_node_to_eeh_dev(dn))) | ||
121 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
122 | |||
123 | return ret; | ||
107 | } | 124 | } |
108 | 125 | ||
109 | int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val) | 126 | int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val) |
@@ -136,17 +153,34 @@ static int rtas_pci_write_config(struct pci_bus *bus, | |||
136 | int where, int size, u32 val) | 153 | int where, int size, u32 val) |
137 | { | 154 | { |
138 | struct device_node *busdn, *dn; | 155 | struct device_node *busdn, *dn; |
139 | 156 | struct pci_dn *pdn; | |
140 | busdn = pci_bus_to_OF_node(bus); | 157 | bool found = false; |
158 | #ifdef CONFIG_EEH | ||
159 | struct eeh_dev *edev; | ||
160 | #endif | ||
161 | int ret; | ||
141 | 162 | ||
142 | /* Search only direct children of the bus */ | 163 | /* Search only direct children of the bus */ |
164 | busdn = pci_bus_to_OF_node(bus); | ||
143 | for (dn = busdn->child; dn; dn = dn->sibling) { | 165 | for (dn = busdn->child; dn; dn = dn->sibling) { |
144 | struct pci_dn *pdn = PCI_DN(dn); | 166 | pdn = PCI_DN(dn); |
145 | if (pdn && pdn->devfn == devfn | 167 | if (pdn && pdn->devfn == devfn |
146 | && of_device_is_available(dn)) | 168 | && of_device_is_available(dn)) { |
147 | return rtas_write_config(pdn, where, size, val); | 169 | found = true; |
170 | break; | ||
171 | } | ||
148 | } | 172 | } |
149 | return PCIBIOS_DEVICE_NOT_FOUND; | 173 | |
174 | if (!found) | ||
175 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
176 | #ifdef CONFIG_EEH | ||
177 | edev = of_node_to_eeh_dev(dn); | ||
178 | if (edev && edev->pe && (edev->pe->state & EEH_PE_RESET)) | ||
179 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
180 | #endif | ||
181 | ret = rtas_write_config(pdn, where, size, val); | ||
182 | |||
183 | return ret; | ||
150 | } | 184 | } |
151 | 185 | ||
152 | static struct pci_ops rtas_pci_ops = { | 186 | static struct pci_ops rtas_pci_ops = { |
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 79b7612ac6fa..aa0f5edd8570 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c | |||
@@ -212,6 +212,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
212 | { | 212 | { |
213 | unsigned long cpu_id = (unsigned long)v - 1; | 213 | unsigned long cpu_id = (unsigned long)v - 1; |
214 | unsigned int pvr; | 214 | unsigned int pvr; |
215 | unsigned long proc_freq; | ||
215 | unsigned short maj; | 216 | unsigned short maj; |
216 | unsigned short min; | 217 | unsigned short min; |
217 | 218 | ||
@@ -263,12 +264,19 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
263 | #endif /* CONFIG_TAU */ | 264 | #endif /* CONFIG_TAU */ |
264 | 265 | ||
265 | /* | 266 | /* |
266 | * Assume here that all clock rates are the same in a | 267 | * Platforms that have variable clock rates, should implement |
267 | * smp system. -- Cort | 268 | * the method ppc_md.get_proc_freq() that reports the clock |
269 | * rate of a given cpu. The rest can use ppc_proc_freq to | ||
270 | * report the clock rate that is same across all cpus. | ||
268 | */ | 271 | */ |
269 | if (ppc_proc_freq) | 272 | if (ppc_md.get_proc_freq) |
273 | proc_freq = ppc_md.get_proc_freq(cpu_id); | ||
274 | else | ||
275 | proc_freq = ppc_proc_freq; | ||
276 | |||
277 | if (proc_freq) | ||
270 | seq_printf(m, "clock\t\t: %lu.%06luMHz\n", | 278 | seq_printf(m, "clock\t\t: %lu.%06luMHz\n", |
271 | ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); | 279 | proc_freq / 1000000, proc_freq % 1000000); |
272 | 280 | ||
273 | if (ppc_md.show_percpuinfo != NULL) | 281 | if (ppc_md.show_percpuinfo != NULL) |
274 | ppc_md.show_percpuinfo(m, cpu_id); | 282 | ppc_md.show_percpuinfo(m, cpu_id); |
@@ -382,9 +390,10 @@ void __init check_for_initrd(void) | |||
382 | 390 | ||
383 | #ifdef CONFIG_SMP | 391 | #ifdef CONFIG_SMP |
384 | 392 | ||
385 | int threads_per_core, threads_shift; | 393 | int threads_per_core, threads_per_subcore, threads_shift; |
386 | cpumask_t threads_core_mask; | 394 | cpumask_t threads_core_mask; |
387 | EXPORT_SYMBOL_GPL(threads_per_core); | 395 | EXPORT_SYMBOL_GPL(threads_per_core); |
396 | EXPORT_SYMBOL_GPL(threads_per_subcore); | ||
388 | EXPORT_SYMBOL_GPL(threads_shift); | 397 | EXPORT_SYMBOL_GPL(threads_shift); |
389 | EXPORT_SYMBOL_GPL(threads_core_mask); | 398 | EXPORT_SYMBOL_GPL(threads_core_mask); |
390 | 399 | ||
@@ -393,6 +402,7 @@ static void __init cpu_init_thread_core_maps(int tpc) | |||
393 | int i; | 402 | int i; |
394 | 403 | ||
395 | threads_per_core = tpc; | 404 | threads_per_core = tpc; |
405 | threads_per_subcore = tpc; | ||
396 | cpumask_clear(&threads_core_mask); | 406 | cpumask_clear(&threads_core_mask); |
397 | 407 | ||
398 | /* This implementation only supports power of 2 number of threads | 408 | /* This implementation only supports power of 2 number of threads |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index fbe24377eda3..ee082d771178 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/lockdep.h> | 36 | #include <linux/lockdep.h> |
37 | #include <linux/memblock.h> | 37 | #include <linux/memblock.h> |
38 | #include <linux/hugetlb.h> | 38 | #include <linux/hugetlb.h> |
39 | #include <linux/memory.h> | ||
39 | 40 | ||
40 | #include <asm/io.h> | 41 | #include <asm/io.h> |
41 | #include <asm/kdump.h> | 42 | #include <asm/kdump.h> |
@@ -341,7 +342,7 @@ void smp_release_cpus(void) | |||
341 | 342 | ||
342 | ptr = (unsigned long *)((unsigned long)&__secondary_hold_spinloop | 343 | ptr = (unsigned long *)((unsigned long)&__secondary_hold_spinloop |
343 | - PHYSICAL_START); | 344 | - PHYSICAL_START); |
344 | *ptr = __pa(generic_secondary_smp_init); | 345 | *ptr = ppc_function_entry(generic_secondary_smp_init); |
345 | 346 | ||
346 | /* And wait a bit for them to catch up */ | 347 | /* And wait a bit for them to catch up */ |
347 | for (i = 0; i < 100000; i++) { | 348 | for (i = 0; i < 100000; i++) { |
@@ -780,6 +781,15 @@ void __init setup_per_cpu_areas(void) | |||
780 | } | 781 | } |
781 | #endif | 782 | #endif |
782 | 783 | ||
784 | #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE | ||
785 | unsigned long memory_block_size_bytes(void) | ||
786 | { | ||
787 | if (ppc_md.memory_block_size) | ||
788 | return ppc_md.memory_block_size(); | ||
789 | |||
790 | return MIN_MEMORY_BLOCK_SIZE; | ||
791 | } | ||
792 | #endif | ||
783 | 793 | ||
784 | #if defined(CONFIG_PPC_INDIRECT_PIO) || defined(CONFIG_PPC_INDIRECT_MMIO) | 794 | #if defined(CONFIG_PPC_INDIRECT_PIO) || defined(CONFIG_PPC_INDIRECT_MMIO) |
785 | struct ppc_pci_io ppc_pci_io; | 795 | struct ppc_pci_io ppc_pci_io; |
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index 8fc4177ed65a..1c794cef2883 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c | |||
@@ -134,7 +134,7 @@ static int do_signal(struct pt_regs *regs) | |||
134 | */ | 134 | */ |
135 | if (current->thread.hw_brk.address && | 135 | if (current->thread.hw_brk.address && |
136 | current->thread.hw_brk.type) | 136 | current->thread.hw_brk.type) |
137 | set_breakpoint(¤t->thread.hw_brk); | 137 | __set_breakpoint(¤t->thread.hw_brk); |
138 | #endif | 138 | #endif |
139 | /* Re-enable the breakpoints for the signal stack */ | 139 | /* Re-enable the breakpoints for the signal stack */ |
140 | thread_change_pc(current, regs); | 140 | thread_change_pc(current, regs); |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 10ffffef0414..7753af2d2613 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/atomic.h> | 36 | #include <linux/atomic.h> |
37 | #include <asm/irq.h> | 37 | #include <asm/irq.h> |
38 | #include <asm/hw_irq.h> | 38 | #include <asm/hw_irq.h> |
39 | #include <asm/kvm_ppc.h> | ||
39 | #include <asm/page.h> | 40 | #include <asm/page.h> |
40 | #include <asm/pgtable.h> | 41 | #include <asm/pgtable.h> |
41 | #include <asm/prom.h> | 42 | #include <asm/prom.h> |
@@ -390,6 +391,7 @@ void smp_prepare_boot_cpu(void) | |||
390 | #ifdef CONFIG_PPC64 | 391 | #ifdef CONFIG_PPC64 |
391 | paca[boot_cpuid].__current = current; | 392 | paca[boot_cpuid].__current = current; |
392 | #endif | 393 | #endif |
394 | set_numa_node(numa_cpu_lookup_table[boot_cpuid]); | ||
393 | current_set[boot_cpuid] = task_thread_info(current); | 395 | current_set[boot_cpuid] = task_thread_info(current); |
394 | } | 396 | } |
395 | 397 | ||
@@ -457,38 +459,9 @@ int generic_check_cpu_restart(unsigned int cpu) | |||
457 | return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE; | 459 | return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE; |
458 | } | 460 | } |
459 | 461 | ||
460 | static atomic_t secondary_inhibit_count; | 462 | static bool secondaries_inhibited(void) |
461 | |||
462 | /* | ||
463 | * Don't allow secondary CPU threads to come online | ||
464 | */ | ||
465 | void inhibit_secondary_onlining(void) | ||
466 | { | 463 | { |
467 | /* | 464 | return kvm_hv_mode_active(); |
468 | * This makes secondary_inhibit_count stable during cpu | ||
469 | * online/offline operations. | ||
470 | */ | ||
471 | get_online_cpus(); | ||
472 | |||
473 | atomic_inc(&secondary_inhibit_count); | ||
474 | put_online_cpus(); | ||
475 | } | ||
476 | EXPORT_SYMBOL_GPL(inhibit_secondary_onlining); | ||
477 | |||
478 | /* | ||
479 | * Allow secondary CPU threads to come online again | ||
480 | */ | ||
481 | void uninhibit_secondary_onlining(void) | ||
482 | { | ||
483 | get_online_cpus(); | ||
484 | atomic_dec(&secondary_inhibit_count); | ||
485 | put_online_cpus(); | ||
486 | } | ||
487 | EXPORT_SYMBOL_GPL(uninhibit_secondary_onlining); | ||
488 | |||
489 | static int secondaries_inhibited(void) | ||
490 | { | ||
491 | return atomic_read(&secondary_inhibit_count); | ||
492 | } | 465 | } |
493 | 466 | ||
494 | #else /* HOTPLUG_CPU */ | 467 | #else /* HOTPLUG_CPU */ |
@@ -517,7 +490,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle) | |||
517 | * Don't allow secondary threads to come online if inhibited | 490 | * Don't allow secondary threads to come online if inhibited |
518 | */ | 491 | */ |
519 | if (threads_per_core > 1 && secondaries_inhibited() && | 492 | if (threads_per_core > 1 && secondaries_inhibited() && |
520 | cpu % threads_per_core != 0) | 493 | cpu_thread_in_subcore(cpu)) |
521 | return -EBUSY; | 494 | return -EBUSY; |
522 | 495 | ||
523 | if (smp_ops == NULL || | 496 | if (smp_ops == NULL || |
@@ -750,6 +723,12 @@ void start_secondary(void *unused) | |||
750 | } | 723 | } |
751 | traverse_core_siblings(cpu, true); | 724 | traverse_core_siblings(cpu, true); |
752 | 725 | ||
726 | /* | ||
727 | * numa_node_id() works after this. | ||
728 | */ | ||
729 | set_numa_node(numa_cpu_lookup_table[cpu]); | ||
730 | set_numa_mem(local_memory_node(numa_cpu_lookup_table[cpu])); | ||
731 | |||
753 | smp_wmb(); | 732 | smp_wmb(); |
754 | notify_cpu_starting(cpu); | 733 | notify_cpu_starting(cpu); |
755 | set_cpu_online(cpu, true); | 734 | set_cpu_online(cpu, true); |
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index d90d4b7810d6..67fd2fd2620a 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c | |||
@@ -404,7 +404,7 @@ void ppc_enable_pmcs(void) | |||
404 | } | 404 | } |
405 | EXPORT_SYMBOL(ppc_enable_pmcs); | 405 | EXPORT_SYMBOL(ppc_enable_pmcs); |
406 | 406 | ||
407 | #define __SYSFS_SPRSETUP(NAME, ADDRESS, EXTRA) \ | 407 | #define __SYSFS_SPRSETUP_READ_WRITE(NAME, ADDRESS, EXTRA) \ |
408 | static void read_##NAME(void *val) \ | 408 | static void read_##NAME(void *val) \ |
409 | { \ | 409 | { \ |
410 | *(unsigned long *)val = mfspr(ADDRESS); \ | 410 | *(unsigned long *)val = mfspr(ADDRESS); \ |
@@ -413,7 +413,9 @@ static void write_##NAME(void *val) \ | |||
413 | { \ | 413 | { \ |
414 | EXTRA; \ | 414 | EXTRA; \ |
415 | mtspr(ADDRESS, *(unsigned long *)val); \ | 415 | mtspr(ADDRESS, *(unsigned long *)val); \ |
416 | } \ | 416 | } |
417 | |||
418 | #define __SYSFS_SPRSETUP_SHOW_STORE(NAME) \ | ||
417 | static ssize_t show_##NAME(struct device *dev, \ | 419 | static ssize_t show_##NAME(struct device *dev, \ |
418 | struct device_attribute *attr, \ | 420 | struct device_attribute *attr, \ |
419 | char *buf) \ | 421 | char *buf) \ |
@@ -436,10 +438,15 @@ static ssize_t __used \ | |||
436 | return count; \ | 438 | return count; \ |
437 | } | 439 | } |
438 | 440 | ||
439 | #define SYSFS_PMCSETUP(NAME, ADDRESS) \ | 441 | #define SYSFS_PMCSETUP(NAME, ADDRESS) \ |
440 | __SYSFS_SPRSETUP(NAME, ADDRESS, ppc_enable_pmcs()) | 442 | __SYSFS_SPRSETUP_READ_WRITE(NAME, ADDRESS, ppc_enable_pmcs()) \ |
441 | #define SYSFS_SPRSETUP(NAME, ADDRESS) \ | 443 | __SYSFS_SPRSETUP_SHOW_STORE(NAME) |
442 | __SYSFS_SPRSETUP(NAME, ADDRESS, ) | 444 | #define SYSFS_SPRSETUP(NAME, ADDRESS) \ |
445 | __SYSFS_SPRSETUP_READ_WRITE(NAME, ADDRESS, ) \ | ||
446 | __SYSFS_SPRSETUP_SHOW_STORE(NAME) | ||
447 | |||
448 | #define SYSFS_SPRSETUP_SHOW_STORE(NAME) \ | ||
449 | __SYSFS_SPRSETUP_SHOW_STORE(NAME) | ||
443 | 450 | ||
444 | /* Let's define all possible registers, we'll only hook up the ones | 451 | /* Let's define all possible registers, we'll only hook up the ones |
445 | * that are implemented on the current processor | 452 | * that are implemented on the current processor |
@@ -477,7 +484,6 @@ SYSFS_PMCSETUP(pmc8, SPRN_PMC8); | |||
477 | SYSFS_PMCSETUP(mmcra, SPRN_MMCRA); | 484 | SYSFS_PMCSETUP(mmcra, SPRN_MMCRA); |
478 | SYSFS_SPRSETUP(purr, SPRN_PURR); | 485 | SYSFS_SPRSETUP(purr, SPRN_PURR); |
479 | SYSFS_SPRSETUP(spurr, SPRN_SPURR); | 486 | SYSFS_SPRSETUP(spurr, SPRN_SPURR); |
480 | SYSFS_SPRSETUP(dscr, SPRN_DSCR); | ||
481 | SYSFS_SPRSETUP(pir, SPRN_PIR); | 487 | SYSFS_SPRSETUP(pir, SPRN_PIR); |
482 | 488 | ||
483 | /* | 489 | /* |
@@ -487,12 +493,27 @@ SYSFS_SPRSETUP(pir, SPRN_PIR); | |||
487 | */ | 493 | */ |
488 | static DEVICE_ATTR(mmcra, 0600, show_mmcra, store_mmcra); | 494 | static DEVICE_ATTR(mmcra, 0600, show_mmcra, store_mmcra); |
489 | static DEVICE_ATTR(spurr, 0400, show_spurr, NULL); | 495 | static DEVICE_ATTR(spurr, 0400, show_spurr, NULL); |
490 | static DEVICE_ATTR(dscr, 0600, show_dscr, store_dscr); | ||
491 | static DEVICE_ATTR(purr, 0400, show_purr, store_purr); | 496 | static DEVICE_ATTR(purr, 0400, show_purr, store_purr); |
492 | static DEVICE_ATTR(pir, 0400, show_pir, NULL); | 497 | static DEVICE_ATTR(pir, 0400, show_pir, NULL); |
493 | 498 | ||
494 | unsigned long dscr_default = 0; | 499 | static unsigned long dscr_default; |
495 | EXPORT_SYMBOL(dscr_default); | 500 | |
501 | static void read_dscr(void *val) | ||
502 | { | ||
503 | *(unsigned long *)val = get_paca()->dscr_default; | ||
504 | } | ||
505 | |||
506 | static void write_dscr(void *val) | ||
507 | { | ||
508 | get_paca()->dscr_default = *(unsigned long *)val; | ||
509 | if (!current->thread.dscr_inherit) { | ||
510 | current->thread.dscr = *(unsigned long *)val; | ||
511 | mtspr(SPRN_DSCR, *(unsigned long *)val); | ||
512 | } | ||
513 | } | ||
514 | |||
515 | SYSFS_SPRSETUP_SHOW_STORE(dscr); | ||
516 | static DEVICE_ATTR(dscr, 0600, show_dscr, store_dscr); | ||
496 | 517 | ||
497 | static void add_write_permission_dev_attr(struct device_attribute *attr) | 518 | static void add_write_permission_dev_attr(struct device_attribute *attr) |
498 | { | 519 | { |
@@ -505,14 +526,6 @@ static ssize_t show_dscr_default(struct device *dev, | |||
505 | return sprintf(buf, "%lx\n", dscr_default); | 526 | return sprintf(buf, "%lx\n", dscr_default); |
506 | } | 527 | } |
507 | 528 | ||
508 | static void update_dscr(void *dummy) | ||
509 | { | ||
510 | if (!current->thread.dscr_inherit) { | ||
511 | current->thread.dscr = dscr_default; | ||
512 | mtspr(SPRN_DSCR, dscr_default); | ||
513 | } | ||
514 | } | ||
515 | |||
516 | static ssize_t __used store_dscr_default(struct device *dev, | 529 | static ssize_t __used store_dscr_default(struct device *dev, |
517 | struct device_attribute *attr, const char *buf, | 530 | struct device_attribute *attr, const char *buf, |
518 | size_t count) | 531 | size_t count) |
@@ -525,7 +538,7 @@ static ssize_t __used store_dscr_default(struct device *dev, | |||
525 | return -EINVAL; | 538 | return -EINVAL; |
526 | dscr_default = val; | 539 | dscr_default = val; |
527 | 540 | ||
528 | on_each_cpu(update_dscr, NULL, 1); | 541 | on_each_cpu(write_dscr, &val, 1); |
529 | 542 | ||
530 | return count; | 543 | return count; |
531 | } | 544 | } |
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S index 93219c34af32..895c50ca943c 100644 --- a/arch/powerpc/kernel/systbl.S +++ b/arch/powerpc/kernel/systbl.S | |||
@@ -17,12 +17,12 @@ | |||
17 | #include <asm/ppc_asm.h> | 17 | #include <asm/ppc_asm.h> |
18 | 18 | ||
19 | #ifdef CONFIG_PPC64 | 19 | #ifdef CONFIG_PPC64 |
20 | #define SYSCALL(func) .llong .sys_##func,.sys_##func | 20 | #define SYSCALL(func) .llong DOTSYM(sys_##func),DOTSYM(sys_##func) |
21 | #define COMPAT_SYS(func) .llong .sys_##func,.compat_sys_##func | 21 | #define COMPAT_SYS(func) .llong DOTSYM(sys_##func),DOTSYM(compat_sys_##func) |
22 | #define PPC_SYS(func) .llong .ppc_##func,.ppc_##func | 22 | #define PPC_SYS(func) .llong DOTSYM(ppc_##func),DOTSYM(ppc_##func) |
23 | #define OLDSYS(func) .llong .sys_ni_syscall,.sys_ni_syscall | 23 | #define OLDSYS(func) .llong DOTSYM(sys_ni_syscall),DOTSYM(sys_ni_syscall) |
24 | #define SYS32ONLY(func) .llong .sys_ni_syscall,.compat_sys_##func | 24 | #define SYS32ONLY(func) .llong DOTSYM(sys_ni_syscall),DOTSYM(compat_sys_##func) |
25 | #define SYSX(f, f3264, f32) .llong .f,.f3264 | 25 | #define SYSX(f, f3264, f32) .llong DOTSYM(f),DOTSYM(f3264) |
26 | #else | 26 | #else |
27 | #define SYSCALL(func) .long sys_##func | 27 | #define SYSCALL(func) .long sys_##func |
28 | #define COMPAT_SYS(func) .long sys_##func | 28 | #define COMPAT_SYS(func) .long sys_##func |
@@ -36,6 +36,8 @@ | |||
36 | #define PPC_SYS_SPU(func) PPC_SYS(func) | 36 | #define PPC_SYS_SPU(func) PPC_SYS(func) |
37 | #define SYSX_SPU(f, f3264, f32) SYSX(f, f3264, f32) | 37 | #define SYSX_SPU(f, f3264, f32) SYSX(f, f3264, f32) |
38 | 38 | ||
39 | .section .rodata,"a" | ||
40 | |||
39 | #ifdef CONFIG_PPC64 | 41 | #ifdef CONFIG_PPC64 |
40 | #define sys_sigpending sys_ni_syscall | 42 | #define sys_sigpending sys_ni_syscall |
41 | #define sys_old_getrlimit sys_ni_syscall | 43 | #define sys_old_getrlimit sys_ni_syscall |
@@ -43,5 +45,7 @@ | |||
43 | .p2align 3 | 45 | .p2align 3 |
44 | #endif | 46 | #endif |
45 | 47 | ||
46 | _GLOBAL(sys_call_table) | 48 | .globl sys_call_table |
49 | sys_call_table: | ||
50 | |||
47 | #include <asm/systbl.h> | 51 | #include <asm/systbl.h> |
diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S index 03567c05950a..2a324f4cb1b9 100644 --- a/arch/powerpc/kernel/tm.S +++ b/arch/powerpc/kernel/tm.S | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <asm/ppc-opcode.h> | 10 | #include <asm/ppc-opcode.h> |
11 | #include <asm/ptrace.h> | 11 | #include <asm/ptrace.h> |
12 | #include <asm/reg.h> | 12 | #include <asm/reg.h> |
13 | #include <asm/bug.h> | ||
13 | 14 | ||
14 | #ifdef CONFIG_VSX | 15 | #ifdef CONFIG_VSX |
15 | /* See fpu.S, this is borrowed from there */ | 16 | /* See fpu.S, this is borrowed from there */ |
@@ -41,7 +42,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ | |||
41 | /* Stack frame offsets for local variables. */ | 42 | /* Stack frame offsets for local variables. */ |
42 | #define TM_FRAME_L0 TM_FRAME_SIZE-16 | 43 | #define TM_FRAME_L0 TM_FRAME_SIZE-16 |
43 | #define TM_FRAME_L1 TM_FRAME_SIZE-8 | 44 | #define TM_FRAME_L1 TM_FRAME_SIZE-8 |
44 | #define STACK_PARAM(x) (48+((x)*8)) | ||
45 | 45 | ||
46 | 46 | ||
47 | /* In order to access the TM SPRs, TM must be enabled. So, do so: */ | 47 | /* In order to access the TM SPRs, TM must be enabled. So, do so: */ |
@@ -78,12 +78,6 @@ _GLOBAL(tm_abort) | |||
78 | TABORT(R3) | 78 | TABORT(R3) |
79 | blr | 79 | blr |
80 | 80 | ||
81 | .section ".toc","aw" | ||
82 | DSCR_DEFAULT: | ||
83 | .tc dscr_default[TC],dscr_default | ||
84 | |||
85 | .section ".text" | ||
86 | |||
87 | /* void tm_reclaim(struct thread_struct *thread, | 81 | /* void tm_reclaim(struct thread_struct *thread, |
88 | * unsigned long orig_msr, | 82 | * unsigned long orig_msr, |
89 | * uint8_t cause) | 83 | * uint8_t cause) |
@@ -108,12 +102,12 @@ _GLOBAL(tm_reclaim) | |||
108 | mflr r0 | 102 | mflr r0 |
109 | stw r6, 8(r1) | 103 | stw r6, 8(r1) |
110 | std r0, 16(r1) | 104 | std r0, 16(r1) |
111 | std r2, 40(r1) | 105 | std r2, STK_GOT(r1) |
112 | stdu r1, -TM_FRAME_SIZE(r1) | 106 | stdu r1, -TM_FRAME_SIZE(r1) |
113 | 107 | ||
114 | /* We've a struct pt_regs at [r1+STACK_FRAME_OVERHEAD]. */ | 108 | /* We've a struct pt_regs at [r1+STACK_FRAME_OVERHEAD]. */ |
115 | 109 | ||
116 | std r3, STACK_PARAM(0)(r1) | 110 | std r3, STK_PARAM(R3)(r1) |
117 | SAVE_NVGPRS(r1) | 111 | SAVE_NVGPRS(r1) |
118 | 112 | ||
119 | /* We need to setup MSR for VSX register save instructions. Here we | 113 | /* We need to setup MSR for VSX register save instructions. Here we |
@@ -175,6 +169,13 @@ dont_backup_vec: | |||
175 | stfd fr0,FPSTATE_FPSCR(r7) | 169 | stfd fr0,FPSTATE_FPSCR(r7) |
176 | 170 | ||
177 | dont_backup_fp: | 171 | dont_backup_fp: |
172 | /* Do sanity check on MSR to make sure we are suspended */ | ||
173 | li r7, (MSR_TS_S)@higher | ||
174 | srdi r6, r14, 32 | ||
175 | and r6, r6, r7 | ||
176 | 1: tdeqi r6, 0 | ||
177 | EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0 | ||
178 | |||
178 | /* The moment we treclaim, ALL of our GPRs will switch | 179 | /* The moment we treclaim, ALL of our GPRs will switch |
179 | * to user register state. (FPRs, CCR etc. also!) | 180 | * to user register state. (FPRs, CCR etc. also!) |
180 | * Use an sprg and a tm_scratch in the PACA to shuffle. | 181 | * Use an sprg and a tm_scratch in the PACA to shuffle. |
@@ -202,7 +203,7 @@ dont_backup_fp: | |||
202 | /* Now get some more GPRS free */ | 203 | /* Now get some more GPRS free */ |
203 | std r7, GPR7(r1) /* Temporary stash */ | 204 | std r7, GPR7(r1) /* Temporary stash */ |
204 | std r12, GPR12(r1) /* '' '' '' */ | 205 | std r12, GPR12(r1) /* '' '' '' */ |
205 | ld r12, STACK_PARAM(0)(r1) /* Param 0, thread_struct * */ | 206 | ld r12, STK_PARAM(R3)(r1) /* Param 0, thread_struct * */ |
206 | 207 | ||
207 | std r11, THREAD_TM_PPR(r12) /* Store PPR and free r11 */ | 208 | std r11, THREAD_TM_PPR(r12) /* Store PPR and free r11 */ |
208 | 209 | ||
@@ -289,11 +290,10 @@ dont_backup_fp: | |||
289 | ld r0, 16(r1) | 290 | ld r0, 16(r1) |
290 | mtcr r4 | 291 | mtcr r4 |
291 | mtlr r0 | 292 | mtlr r0 |
292 | ld r2, 40(r1) | 293 | ld r2, STK_GOT(r1) |
293 | 294 | ||
294 | /* Load system default DSCR */ | 295 | /* Load CPU's default DSCR */ |
295 | ld r4, DSCR_DEFAULT@toc(r2) | 296 | ld r0, PACA_DSCR(r13) |
296 | ld r0, 0(r4) | ||
297 | mtspr SPRN_DSCR, r0 | 297 | mtspr SPRN_DSCR, r0 |
298 | 298 | ||
299 | blr | 299 | blr |
@@ -312,7 +312,7 @@ _GLOBAL(__tm_recheckpoint) | |||
312 | mflr r0 | 312 | mflr r0 |
313 | stw r5, 8(r1) | 313 | stw r5, 8(r1) |
314 | std r0, 16(r1) | 314 | std r0, 16(r1) |
315 | std r2, 40(r1) | 315 | std r2, STK_GOT(r1) |
316 | stdu r1, -TM_FRAME_SIZE(r1) | 316 | stdu r1, -TM_FRAME_SIZE(r1) |
317 | 317 | ||
318 | /* We've a struct pt_regs at [r1+STACK_FRAME_OVERHEAD]. | 318 | /* We've a struct pt_regs at [r1+STACK_FRAME_OVERHEAD]. |
@@ -320,8 +320,6 @@ _GLOBAL(__tm_recheckpoint) | |||
320 | */ | 320 | */ |
321 | SAVE_NVGPRS(r1) | 321 | SAVE_NVGPRS(r1) |
322 | 322 | ||
323 | std r1, PACAR1(r13) | ||
324 | |||
325 | /* Load complete register state from ts_ckpt* registers */ | 323 | /* Load complete register state from ts_ckpt* registers */ |
326 | 324 | ||
327 | addi r7, r3, PT_CKPT_REGS /* Thread's ckpt_regs */ | 325 | addi r7, r3, PT_CKPT_REGS /* Thread's ckpt_regs */ |
@@ -385,12 +383,10 @@ restore_gprs: | |||
385 | /* ******************** CR,LR,CCR,MSR ********** */ | 383 | /* ******************** CR,LR,CCR,MSR ********** */ |
386 | ld r4, _CTR(r7) | 384 | ld r4, _CTR(r7) |
387 | ld r5, _LINK(r7) | 385 | ld r5, _LINK(r7) |
388 | ld r6, _CCR(r7) | ||
389 | ld r8, _XER(r7) | 386 | ld r8, _XER(r7) |
390 | 387 | ||
391 | mtctr r4 | 388 | mtctr r4 |
392 | mtlr r5 | 389 | mtlr r5 |
393 | mtcr r6 | ||
394 | mtxer r8 | 390 | mtxer r8 |
395 | 391 | ||
396 | /* ******************** TAR ******************** */ | 392 | /* ******************** TAR ******************** */ |
@@ -406,7 +402,8 @@ restore_gprs: | |||
406 | li r4, 0 | 402 | li r4, 0 |
407 | mtmsrd r4, 1 | 403 | mtmsrd r4, 1 |
408 | 404 | ||
409 | REST_4GPRS(0, r7) /* GPR0-3 */ | 405 | REST_GPR(0, r7) /* GPR0 */ |
406 | REST_2GPRS(2, r7) /* GPR2-3 */ | ||
410 | REST_GPR(4, r7) /* GPR4 */ | 407 | REST_GPR(4, r7) /* GPR4 */ |
411 | REST_4GPRS(8, r7) /* GPR8-11 */ | 408 | REST_4GPRS(8, r7) /* GPR8-11 */ |
412 | REST_2GPRS(12, r7) /* GPR12-13 */ | 409 | REST_2GPRS(12, r7) /* GPR12-13 */ |
@@ -418,6 +415,31 @@ restore_gprs: | |||
418 | mtspr SPRN_DSCR, r5 | 415 | mtspr SPRN_DSCR, r5 |
419 | mtspr SPRN_PPR, r6 | 416 | mtspr SPRN_PPR, r6 |
420 | 417 | ||
418 | /* Do final sanity check on TEXASR to make sure FS is set. Do this | ||
419 | * here before we load up the userspace r1 so any bugs we hit will get | ||
420 | * a call chain */ | ||
421 | mfspr r5, SPRN_TEXASR | ||
422 | srdi r5, r5, 16 | ||
423 | li r6, (TEXASR_FS)@h | ||
424 | and r6, r6, r5 | ||
425 | 1: tdeqi r6, 0 | ||
426 | EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0 | ||
427 | |||
428 | /* Do final sanity check on MSR to make sure we are not transactional | ||
429 | * or suspended | ||
430 | */ | ||
431 | mfmsr r6 | ||
432 | li r5, (MSR_TS_MASK)@higher | ||
433 | srdi r6, r6, 32 | ||
434 | and r6, r6, r5 | ||
435 | 1: tdnei r6, 0 | ||
436 | EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0 | ||
437 | |||
438 | /* Restore CR */ | ||
439 | ld r6, _CCR(r7) | ||
440 | mtcr r6 | ||
441 | |||
442 | REST_GPR(1, r7) /* GPR1 */ | ||
421 | REST_GPR(5, r7) /* GPR5-7 */ | 443 | REST_GPR(5, r7) /* GPR5-7 */ |
422 | REST_GPR(6, r7) | 444 | REST_GPR(6, r7) |
423 | ld r7, GPR7(r7) | 445 | ld r7, GPR7(r7) |
@@ -448,11 +470,10 @@ restore_gprs: | |||
448 | ld r0, 16(r1) | 470 | ld r0, 16(r1) |
449 | mtcr r4 | 471 | mtcr r4 |
450 | mtlr r0 | 472 | mtlr r0 |
451 | ld r2, 40(r1) | 473 | ld r2, STK_GOT(r1) |
452 | 474 | ||
453 | /* Load system default DSCR */ | 475 | /* Load CPU's default DSCR */ |
454 | ld r4, DSCR_DEFAULT@toc(r2) | 476 | ld r0, PACA_DSCR(r13) |
455 | ld r0, 0(r4) | ||
456 | mtspr SPRN_DSCR, r0 | 477 | mtspr SPRN_DSCR, r0 |
457 | 478 | ||
458 | blr | 479 | blr |
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index aba05bbb3e74..7a12edbb61e7 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c | |||
@@ -1236,7 +1236,7 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_hv(struct kvm *kvm, | |||
1236 | int core; | 1236 | int core; |
1237 | struct kvmppc_vcore *vcore; | 1237 | struct kvmppc_vcore *vcore; |
1238 | 1238 | ||
1239 | core = id / threads_per_core; | 1239 | core = id / threads_per_subcore; |
1240 | if (core >= KVM_MAX_VCORES) | 1240 | if (core >= KVM_MAX_VCORES) |
1241 | goto out; | 1241 | goto out; |
1242 | 1242 | ||
@@ -1286,7 +1286,7 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_hv(struct kvm *kvm, | |||
1286 | init_waitqueue_head(&vcore->wq); | 1286 | init_waitqueue_head(&vcore->wq); |
1287 | vcore->preempt_tb = TB_NIL; | 1287 | vcore->preempt_tb = TB_NIL; |
1288 | vcore->lpcr = kvm->arch.lpcr; | 1288 | vcore->lpcr = kvm->arch.lpcr; |
1289 | vcore->first_vcpuid = core * threads_per_core; | 1289 | vcore->first_vcpuid = core * threads_per_subcore; |
1290 | vcore->kvm = kvm; | 1290 | vcore->kvm = kvm; |
1291 | } | 1291 | } |
1292 | kvm->arch.vcores[core] = vcore; | 1292 | kvm->arch.vcores[core] = vcore; |
@@ -1476,16 +1476,19 @@ static void kvmppc_wait_for_nap(struct kvmppc_vcore *vc) | |||
1476 | static int on_primary_thread(void) | 1476 | static int on_primary_thread(void) |
1477 | { | 1477 | { |
1478 | int cpu = smp_processor_id(); | 1478 | int cpu = smp_processor_id(); |
1479 | int thr = cpu_thread_in_core(cpu); | 1479 | int thr; |
1480 | 1480 | ||
1481 | if (thr) | 1481 | /* Are we on a primary subcore? */ |
1482 | if (cpu_thread_in_subcore(cpu)) | ||
1482 | return 0; | 1483 | return 0; |
1483 | while (++thr < threads_per_core) | 1484 | |
1485 | thr = 0; | ||
1486 | while (++thr < threads_per_subcore) | ||
1484 | if (cpu_online(cpu + thr)) | 1487 | if (cpu_online(cpu + thr)) |
1485 | return 0; | 1488 | return 0; |
1486 | 1489 | ||
1487 | /* Grab all hw threads so they can't go into the kernel */ | 1490 | /* Grab all hw threads so they can't go into the kernel */ |
1488 | for (thr = 1; thr < threads_per_core; ++thr) { | 1491 | for (thr = 1; thr < threads_per_subcore; ++thr) { |
1489 | if (kvmppc_grab_hwthread(cpu + thr)) { | 1492 | if (kvmppc_grab_hwthread(cpu + thr)) { |
1490 | /* Couldn't grab one; let the others go */ | 1493 | /* Couldn't grab one; let the others go */ |
1491 | do { | 1494 | do { |
@@ -1544,15 +1547,18 @@ static void kvmppc_run_core(struct kvmppc_vcore *vc) | |||
1544 | } | 1547 | } |
1545 | 1548 | ||
1546 | /* | 1549 | /* |
1547 | * Make sure we are running on thread 0, and that | 1550 | * Make sure we are running on primary threads, and that secondary |
1548 | * secondary threads are offline. | 1551 | * threads are offline. Also check if the number of threads in this |
1552 | * guest are greater than the current system threads per guest. | ||
1549 | */ | 1553 | */ |
1550 | if (threads_per_core > 1 && !on_primary_thread()) { | 1554 | if ((threads_per_core > 1) && |
1555 | ((vc->num_threads > threads_per_subcore) || !on_primary_thread())) { | ||
1551 | list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) | 1556 | list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) |
1552 | vcpu->arch.ret = -EBUSY; | 1557 | vcpu->arch.ret = -EBUSY; |
1553 | goto out; | 1558 | goto out; |
1554 | } | 1559 | } |
1555 | 1560 | ||
1561 | |||
1556 | vc->pcpu = smp_processor_id(); | 1562 | vc->pcpu = smp_processor_id(); |
1557 | list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) { | 1563 | list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) { |
1558 | kvmppc_start_thread(vcpu); | 1564 | kvmppc_start_thread(vcpu); |
@@ -1580,7 +1586,7 @@ static void kvmppc_run_core(struct kvmppc_vcore *vc) | |||
1580 | /* wait for secondary threads to finish writing their state to memory */ | 1586 | /* wait for secondary threads to finish writing their state to memory */ |
1581 | if (vc->nap_count < vc->n_woken) | 1587 | if (vc->nap_count < vc->n_woken) |
1582 | kvmppc_wait_for_nap(vc); | 1588 | kvmppc_wait_for_nap(vc); |
1583 | for (i = 0; i < threads_per_core; ++i) | 1589 | for (i = 0; i < threads_per_subcore; ++i) |
1584 | kvmppc_release_hwthread(vc->pcpu + i); | 1590 | kvmppc_release_hwthread(vc->pcpu + i); |
1585 | /* prevent other vcpu threads from doing kvmppc_start_thread() now */ | 1591 | /* prevent other vcpu threads from doing kvmppc_start_thread() now */ |
1586 | vc->vcore_state = VCORE_EXITING; | 1592 | vc->vcore_state = VCORE_EXITING; |
@@ -2305,10 +2311,10 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm) | |||
2305 | spin_lock_init(&kvm->arch.slot_phys_lock); | 2311 | spin_lock_init(&kvm->arch.slot_phys_lock); |
2306 | 2312 | ||
2307 | /* | 2313 | /* |
2308 | * Don't allow secondary CPU threads to come online | 2314 | * Track that we now have a HV mode VM active. This blocks secondary |
2309 | * while any KVM VMs exist. | 2315 | * CPU threads from coming online. |
2310 | */ | 2316 | */ |
2311 | inhibit_secondary_onlining(); | 2317 | kvm_hv_vm_activated(); |
2312 | 2318 | ||
2313 | return 0; | 2319 | return 0; |
2314 | } | 2320 | } |
@@ -2324,7 +2330,7 @@ static void kvmppc_free_vcores(struct kvm *kvm) | |||
2324 | 2330 | ||
2325 | static void kvmppc_core_destroy_vm_hv(struct kvm *kvm) | 2331 | static void kvmppc_core_destroy_vm_hv(struct kvm *kvm) |
2326 | { | 2332 | { |
2327 | uninhibit_secondary_onlining(); | 2333 | kvm_hv_vm_deactivated(); |
2328 | 2334 | ||
2329 | kvmppc_free_vcores(kvm); | 2335 | kvmppc_free_vcores(kvm); |
2330 | if (kvm->arch.rma) { | 2336 | if (kvm->arch.rma) { |
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index 8cd0daebb82d..7cde8a665205 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * published by the Free Software Foundation. | 6 | * published by the Free Software Foundation. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/cpu.h> | ||
9 | #include <linux/kvm_host.h> | 10 | #include <linux/kvm_host.h> |
10 | #include <linux/preempt.h> | 11 | #include <linux/preempt.h> |
11 | #include <linux/export.h> | 12 | #include <linux/export.h> |
@@ -181,3 +182,33 @@ void __init kvm_cma_reserve(void) | |||
181 | kvm_cma_declare_contiguous(selected_size, align_size); | 182 | kvm_cma_declare_contiguous(selected_size, align_size); |
182 | } | 183 | } |
183 | } | 184 | } |
185 | |||
186 | /* | ||
187 | * When running HV mode KVM we need to block certain operations while KVM VMs | ||
188 | * exist in the system. We use a counter of VMs to track this. | ||
189 | * | ||
190 | * One of the operations we need to block is onlining of secondaries, so we | ||
191 | * protect hv_vm_count with get/put_online_cpus(). | ||
192 | */ | ||
193 | static atomic_t hv_vm_count; | ||
194 | |||
195 | void kvm_hv_vm_activated(void) | ||
196 | { | ||
197 | get_online_cpus(); | ||
198 | atomic_inc(&hv_vm_count); | ||
199 | put_online_cpus(); | ||
200 | } | ||
201 | EXPORT_SYMBOL_GPL(kvm_hv_vm_activated); | ||
202 | |||
203 | void kvm_hv_vm_deactivated(void) | ||
204 | { | ||
205 | get_online_cpus(); | ||
206 | atomic_dec(&hv_vm_count); | ||
207 | put_online_cpus(); | ||
208 | } | ||
209 | EXPORT_SYMBOL_GPL(kvm_hv_vm_deactivated); | ||
210 | |||
211 | bool kvm_hv_mode_active(void) | ||
212 | { | ||
213 | return atomic_read(&hv_vm_count) != 0; | ||
214 | } | ||
diff --git a/arch/powerpc/kvm/book3s_hv_interrupts.S b/arch/powerpc/kvm/book3s_hv_interrupts.S index e18e3cfc32de..8c86422a1e37 100644 --- a/arch/powerpc/kvm/book3s_hv_interrupts.S +++ b/arch/powerpc/kvm/book3s_hv_interrupts.S | |||
@@ -171,7 +171,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) | |||
171 | #endif /* CONFIG_SMP */ | 171 | #endif /* CONFIG_SMP */ |
172 | 172 | ||
173 | /* Jump to partition switch code */ | 173 | /* Jump to partition switch code */ |
174 | bl .kvmppc_hv_entry_trampoline | 174 | bl kvmppc_hv_entry_trampoline |
175 | nop | 175 | nop |
176 | 176 | ||
177 | /* | 177 | /* |
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 974793435a2e..77356fd25ccc 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S | |||
@@ -292,8 +292,7 @@ kvm_start_guest: | |||
292 | beq kvm_no_guest | 292 | beq kvm_no_guest |
293 | 293 | ||
294 | /* Set HSTATE_DSCR(r13) to something sensible */ | 294 | /* Set HSTATE_DSCR(r13) to something sensible */ |
295 | LOAD_REG_ADDR(r6, dscr_default) | 295 | ld r6, PACA_DSCR(r13) |
296 | ld r6, 0(r6) | ||
297 | std r6, HSTATE_DSCR(r13) | 296 | std r6, HSTATE_DSCR(r13) |
298 | 297 | ||
299 | bl kvmppc_hv_entry | 298 | bl kvmppc_hv_entry |
@@ -1799,7 +1798,7 @@ kvmppc_hdsi: | |||
1799 | /* Search the hash table. */ | 1798 | /* Search the hash table. */ |
1800 | mr r3, r9 /* vcpu pointer */ | 1799 | mr r3, r9 /* vcpu pointer */ |
1801 | li r7, 1 /* data fault */ | 1800 | li r7, 1 /* data fault */ |
1802 | bl .kvmppc_hpte_hv_fault | 1801 | bl kvmppc_hpte_hv_fault |
1803 | ld r9, HSTATE_KVM_VCPU(r13) | 1802 | ld r9, HSTATE_KVM_VCPU(r13) |
1804 | ld r10, VCPU_PC(r9) | 1803 | ld r10, VCPU_PC(r9) |
1805 | ld r11, VCPU_MSR(r9) | 1804 | ld r11, VCPU_MSR(r9) |
@@ -1873,7 +1872,7 @@ kvmppc_hisi: | |||
1873 | mr r4, r10 | 1872 | mr r4, r10 |
1874 | mr r6, r11 | 1873 | mr r6, r11 |
1875 | li r7, 0 /* instruction fault */ | 1874 | li r7, 0 /* instruction fault */ |
1876 | bl .kvmppc_hpte_hv_fault | 1875 | bl kvmppc_hpte_hv_fault |
1877 | ld r9, HSTATE_KVM_VCPU(r13) | 1876 | ld r9, HSTATE_KVM_VCPU(r13) |
1878 | ld r10, VCPU_PC(r9) | 1877 | ld r10, VCPU_PC(r9) |
1879 | ld r11, VCPU_MSR(r9) | 1878 | ld r11, VCPU_MSR(r9) |
@@ -1947,16 +1946,16 @@ hcall_real_fallback: | |||
1947 | .globl hcall_real_table | 1946 | .globl hcall_real_table |
1948 | hcall_real_table: | 1947 | hcall_real_table: |
1949 | .long 0 /* 0 - unused */ | 1948 | .long 0 /* 0 - unused */ |
1950 | .long .kvmppc_h_remove - hcall_real_table | 1949 | .long DOTSYM(kvmppc_h_remove) - hcall_real_table |
1951 | .long .kvmppc_h_enter - hcall_real_table | 1950 | .long DOTSYM(kvmppc_h_enter) - hcall_real_table |
1952 | .long .kvmppc_h_read - hcall_real_table | 1951 | .long DOTSYM(kvmppc_h_read) - hcall_real_table |
1953 | .long 0 /* 0x10 - H_CLEAR_MOD */ | 1952 | .long 0 /* 0x10 - H_CLEAR_MOD */ |
1954 | .long 0 /* 0x14 - H_CLEAR_REF */ | 1953 | .long 0 /* 0x14 - H_CLEAR_REF */ |
1955 | .long .kvmppc_h_protect - hcall_real_table | 1954 | .long DOTSYM(kvmppc_h_protect) - hcall_real_table |
1956 | .long .kvmppc_h_get_tce - hcall_real_table | 1955 | .long DOTSYM(kvmppc_h_get_tce) - hcall_real_table |
1957 | .long .kvmppc_h_put_tce - hcall_real_table | 1956 | .long DOTSYM(kvmppc_h_put_tce) - hcall_real_table |
1958 | .long 0 /* 0x24 - H_SET_SPRG0 */ | 1957 | .long 0 /* 0x24 - H_SET_SPRG0 */ |
1959 | .long .kvmppc_h_set_dabr - hcall_real_table | 1958 | .long DOTSYM(kvmppc_h_set_dabr) - hcall_real_table |
1960 | .long 0 /* 0x2c */ | 1959 | .long 0 /* 0x2c */ |
1961 | .long 0 /* 0x30 */ | 1960 | .long 0 /* 0x30 */ |
1962 | .long 0 /* 0x34 */ | 1961 | .long 0 /* 0x34 */ |
@@ -1972,11 +1971,11 @@ hcall_real_table: | |||
1972 | .long 0 /* 0x5c */ | 1971 | .long 0 /* 0x5c */ |
1973 | .long 0 /* 0x60 */ | 1972 | .long 0 /* 0x60 */ |
1974 | #ifdef CONFIG_KVM_XICS | 1973 | #ifdef CONFIG_KVM_XICS |
1975 | .long .kvmppc_rm_h_eoi - hcall_real_table | 1974 | .long DOTSYM(kvmppc_rm_h_eoi) - hcall_real_table |
1976 | .long .kvmppc_rm_h_cppr - hcall_real_table | 1975 | .long DOTSYM(kvmppc_rm_h_cppr) - hcall_real_table |
1977 | .long .kvmppc_rm_h_ipi - hcall_real_table | 1976 | .long DOTSYM(kvmppc_rm_h_ipi) - hcall_real_table |
1978 | .long 0 /* 0x70 - H_IPOLL */ | 1977 | .long 0 /* 0x70 - H_IPOLL */ |
1979 | .long .kvmppc_rm_h_xirr - hcall_real_table | 1978 | .long DOTSYM(kvmppc_rm_h_xirr) - hcall_real_table |
1980 | #else | 1979 | #else |
1981 | .long 0 /* 0x64 - H_EOI */ | 1980 | .long 0 /* 0x64 - H_EOI */ |
1982 | .long 0 /* 0x68 - H_CPPR */ | 1981 | .long 0 /* 0x68 - H_CPPR */ |
@@ -2010,7 +2009,7 @@ hcall_real_table: | |||
2010 | .long 0 /* 0xd4 */ | 2009 | .long 0 /* 0xd4 */ |
2011 | .long 0 /* 0xd8 */ | 2010 | .long 0 /* 0xd8 */ |
2012 | .long 0 /* 0xdc */ | 2011 | .long 0 /* 0xdc */ |
2013 | .long .kvmppc_h_cede - hcall_real_table | 2012 | .long DOTSYM(kvmppc_h_cede) - hcall_real_table |
2014 | .long 0 /* 0xe4 */ | 2013 | .long 0 /* 0xe4 */ |
2015 | .long 0 /* 0xe8 */ | 2014 | .long 0 /* 0xe8 */ |
2016 | .long 0 /* 0xec */ | 2015 | .long 0 /* 0xec */ |
@@ -2027,11 +2026,11 @@ hcall_real_table: | |||
2027 | .long 0 /* 0x118 */ | 2026 | .long 0 /* 0x118 */ |
2028 | .long 0 /* 0x11c */ | 2027 | .long 0 /* 0x11c */ |
2029 | .long 0 /* 0x120 */ | 2028 | .long 0 /* 0x120 */ |
2030 | .long .kvmppc_h_bulk_remove - hcall_real_table | 2029 | .long DOTSYM(kvmppc_h_bulk_remove) - hcall_real_table |
2031 | .long 0 /* 0x128 */ | 2030 | .long 0 /* 0x128 */ |
2032 | .long 0 /* 0x12c */ | 2031 | .long 0 /* 0x12c */ |
2033 | .long 0 /* 0x130 */ | 2032 | .long 0 /* 0x130 */ |
2034 | .long .kvmppc_h_set_xdabr - hcall_real_table | 2033 | .long DOTSYM(kvmppc_h_set_xdabr) - hcall_real_table |
2035 | hcall_real_table_end: | 2034 | hcall_real_table_end: |
2036 | 2035 | ||
2037 | ignore_hdec: | 2036 | ignore_hdec: |
@@ -2256,7 +2255,7 @@ kvm_cede_exit: | |||
2256 | /* Try to handle a machine check in real mode */ | 2255 | /* Try to handle a machine check in real mode */ |
2257 | machine_check_realmode: | 2256 | machine_check_realmode: |
2258 | mr r3, r9 /* get vcpu pointer */ | 2257 | mr r3, r9 /* get vcpu pointer */ |
2259 | bl .kvmppc_realmode_machine_check | 2258 | bl kvmppc_realmode_machine_check |
2260 | nop | 2259 | nop |
2261 | cmpdi r3, 0 /* continue exiting from guest? */ | 2260 | cmpdi r3, 0 /* continue exiting from guest? */ |
2262 | ld r9, HSTATE_KVM_VCPU(r13) | 2261 | ld r9, HSTATE_KVM_VCPU(r13) |
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index bab20f410443..61c738ab1283 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -426,7 +426,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
426 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE | 426 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE |
427 | case KVM_CAP_PPC_SMT: | 427 | case KVM_CAP_PPC_SMT: |
428 | if (hv_enabled) | 428 | if (hv_enabled) |
429 | r = threads_per_core; | 429 | r = threads_per_subcore; |
430 | else | 430 | else |
431 | r = 0; | 431 | r = 0; |
432 | break; | 432 | break; |
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 95a20e17dbff..59fa2de9546d 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile | |||
@@ -23,9 +23,7 @@ obj-y += checksum_$(CONFIG_WORD_SIZE).o | |||
23 | obj-$(CONFIG_PPC64) += checksum_wrappers_64.o | 23 | obj-$(CONFIG_PPC64) += checksum_wrappers_64.o |
24 | endif | 24 | endif |
25 | 25 | ||
26 | ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),) | ||
27 | obj-$(CONFIG_PPC64) += memcpy_power7.o memcpy_64.o | 26 | obj-$(CONFIG_PPC64) += memcpy_power7.o memcpy_64.o |
28 | endif | ||
29 | 27 | ||
30 | obj-$(CONFIG_PPC_EMULATE_SSTEP) += sstep.o ldstfp.o | 28 | obj-$(CONFIG_PPC_EMULATE_SSTEP) += sstep.o ldstfp.o |
31 | 29 | ||
diff --git a/arch/powerpc/lib/copypage_64.S b/arch/powerpc/lib/copypage_64.S index 9f9434a85264..a3c4dc4defdd 100644 --- a/arch/powerpc/lib/copypage_64.S +++ b/arch/powerpc/lib/copypage_64.S | |||
@@ -16,11 +16,11 @@ PPC64_CACHES: | |||
16 | .tc ppc64_caches[TC],ppc64_caches | 16 | .tc ppc64_caches[TC],ppc64_caches |
17 | .section ".text" | 17 | .section ".text" |
18 | 18 | ||
19 | _GLOBAL(copy_page) | 19 | _GLOBAL_TOC(copy_page) |
20 | BEGIN_FTR_SECTION | 20 | BEGIN_FTR_SECTION |
21 | lis r5,PAGE_SIZE@h | 21 | lis r5,PAGE_SIZE@h |
22 | FTR_SECTION_ELSE | 22 | FTR_SECTION_ELSE |
23 | b .copypage_power7 | 23 | b copypage_power7 |
24 | ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY) | 24 | ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY) |
25 | ori r5,r5,PAGE_SIZE@l | 25 | ori r5,r5,PAGE_SIZE@l |
26 | BEGIN_FTR_SECTION | 26 | BEGIN_FTR_SECTION |
diff --git a/arch/powerpc/lib/copypage_power7.S b/arch/powerpc/lib/copypage_power7.S index 395c594722a2..d7dafb3777ac 100644 --- a/arch/powerpc/lib/copypage_power7.S +++ b/arch/powerpc/lib/copypage_power7.S | |||
@@ -56,15 +56,15 @@ _GLOBAL(copypage_power7) | |||
56 | 56 | ||
57 | #ifdef CONFIG_ALTIVEC | 57 | #ifdef CONFIG_ALTIVEC |
58 | mflr r0 | 58 | mflr r0 |
59 | std r3,48(r1) | 59 | std r3,-STACKFRAMESIZE+STK_REG(R31)(r1) |
60 | std r4,56(r1) | 60 | std r4,-STACKFRAMESIZE+STK_REG(R30)(r1) |
61 | std r0,16(r1) | 61 | std r0,16(r1) |
62 | stdu r1,-STACKFRAMESIZE(r1) | 62 | stdu r1,-STACKFRAMESIZE(r1) |
63 | bl .enter_vmx_copy | 63 | bl enter_vmx_copy |
64 | cmpwi r3,0 | 64 | cmpwi r3,0 |
65 | ld r0,STACKFRAMESIZE+16(r1) | 65 | ld r0,STACKFRAMESIZE+16(r1) |
66 | ld r3,STACKFRAMESIZE+48(r1) | 66 | ld r3,STK_REG(R31)(r1) |
67 | ld r4,STACKFRAMESIZE+56(r1) | 67 | ld r4,STK_REG(R30)(r1) |
68 | mtlr r0 | 68 | mtlr r0 |
69 | 69 | ||
70 | li r0,(PAGE_SIZE/128) | 70 | li r0,(PAGE_SIZE/128) |
@@ -103,7 +103,7 @@ _GLOBAL(copypage_power7) | |||
103 | addi r3,r3,128 | 103 | addi r3,r3,128 |
104 | bdnz 1b | 104 | bdnz 1b |
105 | 105 | ||
106 | b .exit_vmx_copy /* tail call optimise */ | 106 | b exit_vmx_copy /* tail call optimise */ |
107 | 107 | ||
108 | #else | 108 | #else |
109 | li r0,(PAGE_SIZE/128) | 109 | li r0,(PAGE_SIZE/128) |
diff --git a/arch/powerpc/lib/copyuser_64.S b/arch/powerpc/lib/copyuser_64.S index 596a285c0755..0860ee46013c 100644 --- a/arch/powerpc/lib/copyuser_64.S +++ b/arch/powerpc/lib/copyuser_64.S | |||
@@ -18,7 +18,7 @@ | |||
18 | #endif | 18 | #endif |
19 | 19 | ||
20 | .align 7 | 20 | .align 7 |
21 | _GLOBAL(__copy_tofrom_user) | 21 | _GLOBAL_TOC(__copy_tofrom_user) |
22 | BEGIN_FTR_SECTION | 22 | BEGIN_FTR_SECTION |
23 | nop | 23 | nop |
24 | FTR_SECTION_ELSE | 24 | FTR_SECTION_ELSE |
diff --git a/arch/powerpc/lib/copyuser_power7.S b/arch/powerpc/lib/copyuser_power7.S index e8e9c36dc784..c46c876ac96a 100644 --- a/arch/powerpc/lib/copyuser_power7.S +++ b/arch/powerpc/lib/copyuser_power7.S | |||
@@ -66,7 +66,7 @@ | |||
66 | ld r15,STK_REG(R15)(r1) | 66 | ld r15,STK_REG(R15)(r1) |
67 | ld r14,STK_REG(R14)(r1) | 67 | ld r14,STK_REG(R14)(r1) |
68 | .Ldo_err3: | 68 | .Ldo_err3: |
69 | bl .exit_vmx_usercopy | 69 | bl exit_vmx_usercopy |
70 | ld r0,STACKFRAMESIZE+16(r1) | 70 | ld r0,STACKFRAMESIZE+16(r1) |
71 | mtlr r0 | 71 | mtlr r0 |
72 | b .Lexit | 72 | b .Lexit |
@@ -85,9 +85,9 @@ | |||
85 | .Lexit: | 85 | .Lexit: |
86 | addi r1,r1,STACKFRAMESIZE | 86 | addi r1,r1,STACKFRAMESIZE |
87 | .Ldo_err1: | 87 | .Ldo_err1: |
88 | ld r3,48(r1) | 88 | ld r3,-STACKFRAMESIZE+STK_REG(R31)(r1) |
89 | ld r4,56(r1) | 89 | ld r4,-STACKFRAMESIZE+STK_REG(R30)(r1) |
90 | ld r5,64(r1) | 90 | ld r5,-STACKFRAMESIZE+STK_REG(R29)(r1) |
91 | b __copy_tofrom_user_base | 91 | b __copy_tofrom_user_base |
92 | 92 | ||
93 | 93 | ||
@@ -96,18 +96,18 @@ _GLOBAL(__copy_tofrom_user_power7) | |||
96 | cmpldi r5,16 | 96 | cmpldi r5,16 |
97 | cmpldi cr1,r5,4096 | 97 | cmpldi cr1,r5,4096 |
98 | 98 | ||
99 | std r3,48(r1) | 99 | std r3,-STACKFRAMESIZE+STK_REG(R31)(r1) |
100 | std r4,56(r1) | 100 | std r4,-STACKFRAMESIZE+STK_REG(R30)(r1) |
101 | std r5,64(r1) | 101 | std r5,-STACKFRAMESIZE+STK_REG(R29)(r1) |
102 | 102 | ||
103 | blt .Lshort_copy | 103 | blt .Lshort_copy |
104 | bgt cr1,.Lvmx_copy | 104 | bgt cr1,.Lvmx_copy |
105 | #else | 105 | #else |
106 | cmpldi r5,16 | 106 | cmpldi r5,16 |
107 | 107 | ||
108 | std r3,48(r1) | 108 | std r3,-STACKFRAMESIZE+STK_REG(R31)(r1) |
109 | std r4,56(r1) | 109 | std r4,-STACKFRAMESIZE+STK_REG(R30)(r1) |
110 | std r5,64(r1) | 110 | std r5,-STACKFRAMESIZE+STK_REG(R29)(r1) |
111 | 111 | ||
112 | blt .Lshort_copy | 112 | blt .Lshort_copy |
113 | #endif | 113 | #endif |
@@ -295,12 +295,12 @@ err1; stb r0,0(r3) | |||
295 | mflr r0 | 295 | mflr r0 |
296 | std r0,16(r1) | 296 | std r0,16(r1) |
297 | stdu r1,-STACKFRAMESIZE(r1) | 297 | stdu r1,-STACKFRAMESIZE(r1) |
298 | bl .enter_vmx_usercopy | 298 | bl enter_vmx_usercopy |
299 | cmpwi cr1,r3,0 | 299 | cmpwi cr1,r3,0 |
300 | ld r0,STACKFRAMESIZE+16(r1) | 300 | ld r0,STACKFRAMESIZE+16(r1) |
301 | ld r3,STACKFRAMESIZE+48(r1) | 301 | ld r3,STK_REG(R31)(r1) |
302 | ld r4,STACKFRAMESIZE+56(r1) | 302 | ld r4,STK_REG(R30)(r1) |
303 | ld r5,STACKFRAMESIZE+64(r1) | 303 | ld r5,STK_REG(R29)(r1) |
304 | mtlr r0 | 304 | mtlr r0 |
305 | 305 | ||
306 | /* | 306 | /* |
@@ -514,7 +514,7 @@ err3; lbz r0,0(r4) | |||
514 | err3; stb r0,0(r3) | 514 | err3; stb r0,0(r3) |
515 | 515 | ||
516 | 15: addi r1,r1,STACKFRAMESIZE | 516 | 15: addi r1,r1,STACKFRAMESIZE |
517 | b .exit_vmx_usercopy /* tail call optimise */ | 517 | b exit_vmx_usercopy /* tail call optimise */ |
518 | 518 | ||
519 | .Lvmx_unaligned_copy: | 519 | .Lvmx_unaligned_copy: |
520 | /* Get the destination 16B aligned */ | 520 | /* Get the destination 16B aligned */ |
@@ -717,5 +717,5 @@ err3; lbz r0,0(r4) | |||
717 | err3; stb r0,0(r3) | 717 | err3; stb r0,0(r3) |
718 | 718 | ||
719 | 15: addi r1,r1,STACKFRAMESIZE | 719 | 15: addi r1,r1,STACKFRAMESIZE |
720 | b .exit_vmx_usercopy /* tail call optimise */ | 720 | b exit_vmx_usercopy /* tail call optimise */ |
721 | #endif /* CONFiG_ALTIVEC */ | 721 | #endif /* CONFiG_ALTIVEC */ |
diff --git a/arch/powerpc/lib/hweight_64.S b/arch/powerpc/lib/hweight_64.S index 9b96ff2ecd4d..19e66001a4f9 100644 --- a/arch/powerpc/lib/hweight_64.S +++ b/arch/powerpc/lib/hweight_64.S | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | _GLOBAL(__arch_hweight8) | 25 | _GLOBAL(__arch_hweight8) |
26 | BEGIN_FTR_SECTION | 26 | BEGIN_FTR_SECTION |
27 | b .__sw_hweight8 | 27 | b __sw_hweight8 |
28 | nop | 28 | nop |
29 | nop | 29 | nop |
30 | FTR_SECTION_ELSE | 30 | FTR_SECTION_ELSE |
@@ -35,7 +35,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB) | |||
35 | 35 | ||
36 | _GLOBAL(__arch_hweight16) | 36 | _GLOBAL(__arch_hweight16) |
37 | BEGIN_FTR_SECTION | 37 | BEGIN_FTR_SECTION |
38 | b .__sw_hweight16 | 38 | b __sw_hweight16 |
39 | nop | 39 | nop |
40 | nop | 40 | nop |
41 | nop | 41 | nop |
@@ -57,7 +57,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB) | |||
57 | 57 | ||
58 | _GLOBAL(__arch_hweight32) | 58 | _GLOBAL(__arch_hweight32) |
59 | BEGIN_FTR_SECTION | 59 | BEGIN_FTR_SECTION |
60 | b .__sw_hweight32 | 60 | b __sw_hweight32 |
61 | nop | 61 | nop |
62 | nop | 62 | nop |
63 | nop | 63 | nop |
@@ -82,7 +82,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB) | |||
82 | 82 | ||
83 | _GLOBAL(__arch_hweight64) | 83 | _GLOBAL(__arch_hweight64) |
84 | BEGIN_FTR_SECTION | 84 | BEGIN_FTR_SECTION |
85 | b .__sw_hweight64 | 85 | b __sw_hweight64 |
86 | nop | 86 | nop |
87 | nop | 87 | nop |
88 | nop | 88 | nop |
diff --git a/arch/powerpc/lib/mem_64.S b/arch/powerpc/lib/mem_64.S index f4fcb0bc6563..0738f96befbf 100644 --- a/arch/powerpc/lib/mem_64.S +++ b/arch/powerpc/lib/mem_64.S | |||
@@ -79,8 +79,8 @@ _GLOBAL(memset) | |||
79 | 79 | ||
80 | _GLOBAL(memmove) | 80 | _GLOBAL(memmove) |
81 | cmplw 0,r3,r4 | 81 | cmplw 0,r3,r4 |
82 | bgt .backwards_memcpy | 82 | bgt backwards_memcpy |
83 | b .memcpy | 83 | b memcpy |
84 | 84 | ||
85 | _GLOBAL(backwards_memcpy) | 85 | _GLOBAL(backwards_memcpy) |
86 | rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ | 86 | rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ |
diff --git a/arch/powerpc/lib/memcpy_64.S b/arch/powerpc/lib/memcpy_64.S index 72ad055168a3..32a06ec395d2 100644 --- a/arch/powerpc/lib/memcpy_64.S +++ b/arch/powerpc/lib/memcpy_64.S | |||
@@ -10,14 +10,29 @@ | |||
10 | #include <asm/ppc_asm.h> | 10 | #include <asm/ppc_asm.h> |
11 | 11 | ||
12 | .align 7 | 12 | .align 7 |
13 | _GLOBAL(memcpy) | 13 | _GLOBAL_TOC(memcpy) |
14 | BEGIN_FTR_SECTION | 14 | BEGIN_FTR_SECTION |
15 | std r3,48(r1) /* save destination pointer for return value */ | 15 | #ifdef __LITTLE_ENDIAN__ |
16 | cmpdi cr7,r5,0 | ||
17 | #else | ||
18 | std r3,-STACKFRAMESIZE+STK_REG(R31)(r1) /* save destination pointer for return value */ | ||
19 | #endif | ||
16 | FTR_SECTION_ELSE | 20 | FTR_SECTION_ELSE |
17 | #ifndef SELFTEST | 21 | #ifndef SELFTEST |
18 | b memcpy_power7 | 22 | b memcpy_power7 |
19 | #endif | 23 | #endif |
20 | ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY) | 24 | ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY) |
25 | #ifdef __LITTLE_ENDIAN__ | ||
26 | /* dumb little-endian memcpy that will get replaced at runtime */ | ||
27 | addi r9,r3,-1 | ||
28 | addi r4,r4,-1 | ||
29 | beqlr cr7 | ||
30 | mtctr r5 | ||
31 | 1: lbzu r10,1(r4) | ||
32 | stbu r10,1(r9) | ||
33 | bdnz 1b | ||
34 | blr | ||
35 | #else | ||
21 | PPC_MTOCRF(0x01,r5) | 36 | PPC_MTOCRF(0x01,r5) |
22 | cmpldi cr1,r5,16 | 37 | cmpldi cr1,r5,16 |
23 | neg r6,r3 # LS 3 bits = # bytes to 8-byte dest bdry | 38 | neg r6,r3 # LS 3 bits = # bytes to 8-byte dest bdry |
@@ -73,7 +88,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) | |||
73 | 2: bf cr7*4+3,3f | 88 | 2: bf cr7*4+3,3f |
74 | lbz r9,8(r4) | 89 | lbz r9,8(r4) |
75 | stb r9,0(r3) | 90 | stb r9,0(r3) |
76 | 3: ld r3,48(r1) /* return dest pointer */ | 91 | 3: ld r3,-STACKFRAMESIZE+STK_REG(R31)(r1) /* return dest pointer */ |
77 | blr | 92 | blr |
78 | 93 | ||
79 | .Lsrc_unaligned: | 94 | .Lsrc_unaligned: |
@@ -156,7 +171,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) | |||
156 | 2: bf cr7*4+3,3f | 171 | 2: bf cr7*4+3,3f |
157 | rotldi r9,r9,8 | 172 | rotldi r9,r9,8 |
158 | stb r9,0(r3) | 173 | stb r9,0(r3) |
159 | 3: ld r3,48(r1) /* return dest pointer */ | 174 | 3: ld r3,-STACKFRAMESIZE+STK_REG(R31)(r1) /* return dest pointer */ |
160 | blr | 175 | blr |
161 | 176 | ||
162 | .Ldst_unaligned: | 177 | .Ldst_unaligned: |
@@ -201,5 +216,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) | |||
201 | 3: bf cr7*4+3,4f | 216 | 3: bf cr7*4+3,4f |
202 | lbz r0,0(r4) | 217 | lbz r0,0(r4) |
203 | stb r0,0(r3) | 218 | stb r0,0(r3) |
204 | 4: ld r3,48(r1) /* return dest pointer */ | 219 | 4: ld r3,-STACKFRAMESIZE+STK_REG(R31)(r1) /* return dest pointer */ |
205 | blr | 220 | blr |
221 | #endif | ||
diff --git a/arch/powerpc/lib/memcpy_power7.S b/arch/powerpc/lib/memcpy_power7.S index e4177dbea6bd..2ff5c142f87b 100644 --- a/arch/powerpc/lib/memcpy_power7.S +++ b/arch/powerpc/lib/memcpy_power7.S | |||
@@ -33,14 +33,14 @@ _GLOBAL(memcpy_power7) | |||
33 | cmpldi r5,16 | 33 | cmpldi r5,16 |
34 | cmpldi cr1,r5,4096 | 34 | cmpldi cr1,r5,4096 |
35 | 35 | ||
36 | std r3,48(r1) | 36 | std r3,-STACKFRAMESIZE+STK_REG(R31)(r1) |
37 | 37 | ||
38 | blt .Lshort_copy | 38 | blt .Lshort_copy |
39 | bgt cr1,.Lvmx_copy | 39 | bgt cr1,.Lvmx_copy |
40 | #else | 40 | #else |
41 | cmpldi r5,16 | 41 | cmpldi r5,16 |
42 | 42 | ||
43 | std r3,48(r1) | 43 | std r3,-STACKFRAMESIZE+STK_REG(R31)(r1) |
44 | 44 | ||
45 | blt .Lshort_copy | 45 | blt .Lshort_copy |
46 | #endif | 46 | #endif |
@@ -216,7 +216,7 @@ _GLOBAL(memcpy_power7) | |||
216 | lbz r0,0(r4) | 216 | lbz r0,0(r4) |
217 | stb r0,0(r3) | 217 | stb r0,0(r3) |
218 | 218 | ||
219 | 15: ld r3,48(r1) | 219 | 15: ld r3,-STACKFRAMESIZE+STK_REG(R31)(r1) |
220 | blr | 220 | blr |
221 | 221 | ||
222 | .Lunwind_stack_nonvmx_copy: | 222 | .Lunwind_stack_nonvmx_copy: |
@@ -226,16 +226,16 @@ _GLOBAL(memcpy_power7) | |||
226 | #ifdef CONFIG_ALTIVEC | 226 | #ifdef CONFIG_ALTIVEC |
227 | .Lvmx_copy: | 227 | .Lvmx_copy: |
228 | mflr r0 | 228 | mflr r0 |
229 | std r4,56(r1) | 229 | std r4,-STACKFRAMESIZE+STK_REG(R30)(r1) |
230 | std r5,64(r1) | 230 | std r5,-STACKFRAMESIZE+STK_REG(R29)(r1) |
231 | std r0,16(r1) | 231 | std r0,16(r1) |
232 | stdu r1,-STACKFRAMESIZE(r1) | 232 | stdu r1,-STACKFRAMESIZE(r1) |
233 | bl .enter_vmx_copy | 233 | bl enter_vmx_copy |
234 | cmpwi cr1,r3,0 | 234 | cmpwi cr1,r3,0 |
235 | ld r0,STACKFRAMESIZE+16(r1) | 235 | ld r0,STACKFRAMESIZE+16(r1) |
236 | ld r3,STACKFRAMESIZE+48(r1) | 236 | ld r3,STK_REG(R31)(r1) |
237 | ld r4,STACKFRAMESIZE+56(r1) | 237 | ld r4,STK_REG(R30)(r1) |
238 | ld r5,STACKFRAMESIZE+64(r1) | 238 | ld r5,STK_REG(R29)(r1) |
239 | mtlr r0 | 239 | mtlr r0 |
240 | 240 | ||
241 | /* | 241 | /* |
@@ -447,8 +447,8 @@ _GLOBAL(memcpy_power7) | |||
447 | stb r0,0(r3) | 447 | stb r0,0(r3) |
448 | 448 | ||
449 | 15: addi r1,r1,STACKFRAMESIZE | 449 | 15: addi r1,r1,STACKFRAMESIZE |
450 | ld r3,48(r1) | 450 | ld r3,-STACKFRAMESIZE+STK_REG(R31)(r1) |
451 | b .exit_vmx_copy /* tail call optimise */ | 451 | b exit_vmx_copy /* tail call optimise */ |
452 | 452 | ||
453 | .Lvmx_unaligned_copy: | 453 | .Lvmx_unaligned_copy: |
454 | /* Get the destination 16B aligned */ | 454 | /* Get the destination 16B aligned */ |
@@ -651,6 +651,6 @@ _GLOBAL(memcpy_power7) | |||
651 | stb r0,0(r3) | 651 | stb r0,0(r3) |
652 | 652 | ||
653 | 15: addi r1,r1,STACKFRAMESIZE | 653 | 15: addi r1,r1,STACKFRAMESIZE |
654 | ld r3,48(r1) | 654 | ld r3,-STACKFRAMESIZE+STK_REG(R31)(r1) |
655 | b .exit_vmx_copy /* tail call optimise */ | 655 | b exit_vmx_copy /* tail call optimise */ |
656 | #endif /* CONFiG_ALTIVEC */ | 656 | #endif /* CONFiG_ALTIVEC */ |
diff --git a/arch/powerpc/lib/string_64.S b/arch/powerpc/lib/string_64.S index 3b1e48049faf..7bd9549a90a2 100644 --- a/arch/powerpc/lib/string_64.S +++ b/arch/powerpc/lib/string_64.S | |||
@@ -77,7 +77,7 @@ err3; stb r0,0(r3) | |||
77 | mr r3,r4 | 77 | mr r3,r4 |
78 | blr | 78 | blr |
79 | 79 | ||
80 | _GLOBAL(__clear_user) | 80 | _GLOBAL_TOC(__clear_user) |
81 | cmpdi r4,32 | 81 | cmpdi r4,32 |
82 | neg r6,r3 | 82 | neg r6,r3 |
83 | li r0,0 | 83 | li r0,0 |
diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S index 1136d26a95ae..057cbbb4c576 100644 --- a/arch/powerpc/mm/hash_low_64.S +++ b/arch/powerpc/mm/hash_low_64.S | |||
@@ -159,7 +159,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) | |||
159 | BEGIN_FTR_SECTION | 159 | BEGIN_FTR_SECTION |
160 | mr r4,r30 | 160 | mr r4,r30 |
161 | mr r5,r7 | 161 | mr r5,r7 |
162 | bl .hash_page_do_lazy_icache | 162 | bl hash_page_do_lazy_icache |
163 | END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE) | 163 | END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE) |
164 | 164 | ||
165 | /* At this point, r3 contains new PP bits, save them in | 165 | /* At this point, r3 contains new PP bits, save them in |
@@ -201,7 +201,8 @@ htab_insert_pte: | |||
201 | li r8,MMU_PAGE_4K /* page size */ | 201 | li r8,MMU_PAGE_4K /* page size */ |
202 | li r9,MMU_PAGE_4K /* actual page size */ | 202 | li r9,MMU_PAGE_4K /* actual page size */ |
203 | ld r10,STK_PARAM(R9)(r1) /* segment size */ | 203 | ld r10,STK_PARAM(R9)(r1) /* segment size */ |
204 | _GLOBAL(htab_call_hpte_insert1) | 204 | .globl htab_call_hpte_insert1 |
205 | htab_call_hpte_insert1: | ||
205 | bl . /* Patched by htab_finish_init() */ | 206 | bl . /* Patched by htab_finish_init() */ |
206 | cmpdi 0,r3,0 | 207 | cmpdi 0,r3,0 |
207 | bge htab_pte_insert_ok /* Insertion successful */ | 208 | bge htab_pte_insert_ok /* Insertion successful */ |
@@ -225,7 +226,8 @@ _GLOBAL(htab_call_hpte_insert1) | |||
225 | li r8,MMU_PAGE_4K /* page size */ | 226 | li r8,MMU_PAGE_4K /* page size */ |
226 | li r9,MMU_PAGE_4K /* actual page size */ | 227 | li r9,MMU_PAGE_4K /* actual page size */ |
227 | ld r10,STK_PARAM(R9)(r1) /* segment size */ | 228 | ld r10,STK_PARAM(R9)(r1) /* segment size */ |
228 | _GLOBAL(htab_call_hpte_insert2) | 229 | .globl htab_call_hpte_insert2 |
230 | htab_call_hpte_insert2: | ||
229 | bl . /* Patched by htab_finish_init() */ | 231 | bl . /* Patched by htab_finish_init() */ |
230 | cmpdi 0,r3,0 | 232 | cmpdi 0,r3,0 |
231 | bge+ htab_pte_insert_ok /* Insertion successful */ | 233 | bge+ htab_pte_insert_ok /* Insertion successful */ |
@@ -242,7 +244,8 @@ _GLOBAL(htab_call_hpte_insert2) | |||
242 | 2: and r0,r5,r27 | 244 | 2: and r0,r5,r27 |
243 | rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ | 245 | rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ |
244 | /* Call ppc_md.hpte_remove */ | 246 | /* Call ppc_md.hpte_remove */ |
245 | _GLOBAL(htab_call_hpte_remove) | 247 | .globl htab_call_hpte_remove |
248 | htab_call_hpte_remove: | ||
246 | bl . /* Patched by htab_finish_init() */ | 249 | bl . /* Patched by htab_finish_init() */ |
247 | 250 | ||
248 | /* Try all again */ | 251 | /* Try all again */ |
@@ -296,7 +299,8 @@ htab_modify_pte: | |||
296 | li r7,MMU_PAGE_4K /* actual page size */ | 299 | li r7,MMU_PAGE_4K /* actual page size */ |
297 | ld r8,STK_PARAM(R9)(r1) /* segment size */ | 300 | ld r8,STK_PARAM(R9)(r1) /* segment size */ |
298 | ld r9,STK_PARAM(R8)(r1) /* get "local" param */ | 301 | ld r9,STK_PARAM(R8)(r1) /* get "local" param */ |
299 | _GLOBAL(htab_call_hpte_updatepp) | 302 | .globl htab_call_hpte_updatepp |
303 | htab_call_hpte_updatepp: | ||
300 | bl . /* Patched by htab_finish_init() */ | 304 | bl . /* Patched by htab_finish_init() */ |
301 | 305 | ||
302 | /* if we failed because typically the HPTE wasn't really here | 306 | /* if we failed because typically the HPTE wasn't really here |
@@ -471,7 +475,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) | |||
471 | BEGIN_FTR_SECTION | 475 | BEGIN_FTR_SECTION |
472 | mr r4,r30 | 476 | mr r4,r30 |
473 | mr r5,r7 | 477 | mr r5,r7 |
474 | bl .hash_page_do_lazy_icache | 478 | bl hash_page_do_lazy_icache |
475 | END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE) | 479 | END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE) |
476 | 480 | ||
477 | /* At this point, r3 contains new PP bits, save them in | 481 | /* At this point, r3 contains new PP bits, save them in |
@@ -526,7 +530,8 @@ htab_special_pfn: | |||
526 | li r8,MMU_PAGE_4K /* page size */ | 530 | li r8,MMU_PAGE_4K /* page size */ |
527 | li r9,MMU_PAGE_4K /* actual page size */ | 531 | li r9,MMU_PAGE_4K /* actual page size */ |
528 | ld r10,STK_PARAM(R9)(r1) /* segment size */ | 532 | ld r10,STK_PARAM(R9)(r1) /* segment size */ |
529 | _GLOBAL(htab_call_hpte_insert1) | 533 | .globl htab_call_hpte_insert1 |
534 | htab_call_hpte_insert1: | ||
530 | bl . /* patched by htab_finish_init() */ | 535 | bl . /* patched by htab_finish_init() */ |
531 | cmpdi 0,r3,0 | 536 | cmpdi 0,r3,0 |
532 | bge htab_pte_insert_ok /* Insertion successful */ | 537 | bge htab_pte_insert_ok /* Insertion successful */ |
@@ -554,7 +559,8 @@ _GLOBAL(htab_call_hpte_insert1) | |||
554 | li r8,MMU_PAGE_4K /* page size */ | 559 | li r8,MMU_PAGE_4K /* page size */ |
555 | li r9,MMU_PAGE_4K /* actual page size */ | 560 | li r9,MMU_PAGE_4K /* actual page size */ |
556 | ld r10,STK_PARAM(R9)(r1) /* segment size */ | 561 | ld r10,STK_PARAM(R9)(r1) /* segment size */ |
557 | _GLOBAL(htab_call_hpte_insert2) | 562 | .globl htab_call_hpte_insert2 |
563 | htab_call_hpte_insert2: | ||
558 | bl . /* patched by htab_finish_init() */ | 564 | bl . /* patched by htab_finish_init() */ |
559 | cmpdi 0,r3,0 | 565 | cmpdi 0,r3,0 |
560 | bge+ htab_pte_insert_ok /* Insertion successful */ | 566 | bge+ htab_pte_insert_ok /* Insertion successful */ |
@@ -571,7 +577,8 @@ _GLOBAL(htab_call_hpte_insert2) | |||
571 | 2: and r0,r5,r27 | 577 | 2: and r0,r5,r27 |
572 | rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ | 578 | rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ |
573 | /* Call ppc_md.hpte_remove */ | 579 | /* Call ppc_md.hpte_remove */ |
574 | _GLOBAL(htab_call_hpte_remove) | 580 | .globl htab_call_hpte_remove |
581 | htab_call_hpte_remove: | ||
575 | bl . /* patched by htab_finish_init() */ | 582 | bl . /* patched by htab_finish_init() */ |
576 | 583 | ||
577 | /* Try all again */ | 584 | /* Try all again */ |
@@ -588,7 +595,7 @@ htab_inval_old_hpte: | |||
588 | li r6,MMU_PAGE_64K /* psize */ | 595 | li r6,MMU_PAGE_64K /* psize */ |
589 | ld r7,STK_PARAM(R9)(r1) /* ssize */ | 596 | ld r7,STK_PARAM(R9)(r1) /* ssize */ |
590 | ld r8,STK_PARAM(R8)(r1) /* local */ | 597 | ld r8,STK_PARAM(R8)(r1) /* local */ |
591 | bl .flush_hash_page | 598 | bl flush_hash_page |
592 | /* Clear out _PAGE_HPTE_SUB bits in the new linux PTE */ | 599 | /* Clear out _PAGE_HPTE_SUB bits in the new linux PTE */ |
593 | lis r0,_PAGE_HPTE_SUB@h | 600 | lis r0,_PAGE_HPTE_SUB@h |
594 | ori r0,r0,_PAGE_HPTE_SUB@l | 601 | ori r0,r0,_PAGE_HPTE_SUB@l |
@@ -660,7 +667,8 @@ htab_modify_pte: | |||
660 | li r7,MMU_PAGE_4K /* actual page size */ | 667 | li r7,MMU_PAGE_4K /* actual page size */ |
661 | ld r8,STK_PARAM(R9)(r1) /* segment size */ | 668 | ld r8,STK_PARAM(R9)(r1) /* segment size */ |
662 | ld r9,STK_PARAM(R8)(r1) /* get "local" param */ | 669 | ld r9,STK_PARAM(R8)(r1) /* get "local" param */ |
663 | _GLOBAL(htab_call_hpte_updatepp) | 670 | .globl htab_call_hpte_updatepp |
671 | htab_call_hpte_updatepp: | ||
664 | bl . /* patched by htab_finish_init() */ | 672 | bl . /* patched by htab_finish_init() */ |
665 | 673 | ||
666 | /* if we failed because typically the HPTE wasn't really here | 674 | /* if we failed because typically the HPTE wasn't really here |
@@ -812,7 +820,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) | |||
812 | BEGIN_FTR_SECTION | 820 | BEGIN_FTR_SECTION |
813 | mr r4,r30 | 821 | mr r4,r30 |
814 | mr r5,r7 | 822 | mr r5,r7 |
815 | bl .hash_page_do_lazy_icache | 823 | bl hash_page_do_lazy_icache |
816 | END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE) | 824 | END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE) |
817 | 825 | ||
818 | /* At this point, r3 contains new PP bits, save them in | 826 | /* At this point, r3 contains new PP bits, save them in |
@@ -857,7 +865,8 @@ ht64_insert_pte: | |||
857 | li r8,MMU_PAGE_64K | 865 | li r8,MMU_PAGE_64K |
858 | li r9,MMU_PAGE_64K /* actual page size */ | 866 | li r9,MMU_PAGE_64K /* actual page size */ |
859 | ld r10,STK_PARAM(R9)(r1) /* segment size */ | 867 | ld r10,STK_PARAM(R9)(r1) /* segment size */ |
860 | _GLOBAL(ht64_call_hpte_insert1) | 868 | .globl ht64_call_hpte_insert1 |
869 | ht64_call_hpte_insert1: | ||
861 | bl . /* patched by htab_finish_init() */ | 870 | bl . /* patched by htab_finish_init() */ |
862 | cmpdi 0,r3,0 | 871 | cmpdi 0,r3,0 |
863 | bge ht64_pte_insert_ok /* Insertion successful */ | 872 | bge ht64_pte_insert_ok /* Insertion successful */ |
@@ -881,7 +890,8 @@ _GLOBAL(ht64_call_hpte_insert1) | |||
881 | li r8,MMU_PAGE_64K | 890 | li r8,MMU_PAGE_64K |
882 | li r9,MMU_PAGE_64K /* actual page size */ | 891 | li r9,MMU_PAGE_64K /* actual page size */ |
883 | ld r10,STK_PARAM(R9)(r1) /* segment size */ | 892 | ld r10,STK_PARAM(R9)(r1) /* segment size */ |
884 | _GLOBAL(ht64_call_hpte_insert2) | 893 | .globl ht64_call_hpte_insert2 |
894 | ht64_call_hpte_insert2: | ||
885 | bl . /* patched by htab_finish_init() */ | 895 | bl . /* patched by htab_finish_init() */ |
886 | cmpdi 0,r3,0 | 896 | cmpdi 0,r3,0 |
887 | bge+ ht64_pte_insert_ok /* Insertion successful */ | 897 | bge+ ht64_pte_insert_ok /* Insertion successful */ |
@@ -898,7 +908,8 @@ _GLOBAL(ht64_call_hpte_insert2) | |||
898 | 2: and r0,r5,r27 | 908 | 2: and r0,r5,r27 |
899 | rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ | 909 | rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */ |
900 | /* Call ppc_md.hpte_remove */ | 910 | /* Call ppc_md.hpte_remove */ |
901 | _GLOBAL(ht64_call_hpte_remove) | 911 | .globl ht64_call_hpte_remove |
912 | ht64_call_hpte_remove: | ||
902 | bl . /* patched by htab_finish_init() */ | 913 | bl . /* patched by htab_finish_init() */ |
903 | 914 | ||
904 | /* Try all again */ | 915 | /* Try all again */ |
@@ -952,7 +963,8 @@ ht64_modify_pte: | |||
952 | li r7,MMU_PAGE_64K /* actual page size */ | 963 | li r7,MMU_PAGE_64K /* actual page size */ |
953 | ld r8,STK_PARAM(R9)(r1) /* segment size */ | 964 | ld r8,STK_PARAM(R9)(r1) /* segment size */ |
954 | ld r9,STK_PARAM(R8)(r1) /* get "local" param */ | 965 | ld r9,STK_PARAM(R8)(r1) /* get "local" param */ |
955 | _GLOBAL(ht64_call_hpte_updatepp) | 966 | .globl ht64_call_hpte_updatepp |
967 | ht64_call_hpte_updatepp: | ||
956 | bl . /* patched by htab_finish_init() */ | 968 | bl . /* patched by htab_finish_init() */ |
957 | 969 | ||
958 | /* if we failed because typically the HPTE wasn't really here | 970 | /* if we failed because typically the HPTE wasn't really here |
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 350aa58a6f95..88fdd9d25077 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
@@ -449,6 +449,24 @@ static void mmu_psize_set_default_penc(void) | |||
449 | mmu_psize_defs[bpsize].penc[apsize] = -1; | 449 | mmu_psize_defs[bpsize].penc[apsize] = -1; |
450 | } | 450 | } |
451 | 451 | ||
452 | #ifdef CONFIG_PPC_64K_PAGES | ||
453 | |||
454 | static bool might_have_hea(void) | ||
455 | { | ||
456 | /* | ||
457 | * The HEA ethernet adapter requires awareness of the | ||
458 | * GX bus. Without that awareness we can easily assume | ||
459 | * we will never see an HEA ethernet device. | ||
460 | */ | ||
461 | #ifdef CONFIG_IBMEBUS | ||
462 | return !cpu_has_feature(CPU_FTR_ARCH_207S); | ||
463 | #else | ||
464 | return false; | ||
465 | #endif | ||
466 | } | ||
467 | |||
468 | #endif /* #ifdef CONFIG_PPC_64K_PAGES */ | ||
469 | |||
452 | static void __init htab_init_page_sizes(void) | 470 | static void __init htab_init_page_sizes(void) |
453 | { | 471 | { |
454 | int rc; | 472 | int rc; |
@@ -503,10 +521,11 @@ static void __init htab_init_page_sizes(void) | |||
503 | mmu_linear_psize = MMU_PAGE_64K; | 521 | mmu_linear_psize = MMU_PAGE_64K; |
504 | if (mmu_has_feature(MMU_FTR_CI_LARGE_PAGE)) { | 522 | if (mmu_has_feature(MMU_FTR_CI_LARGE_PAGE)) { |
505 | /* | 523 | /* |
506 | * Don't use 64k pages for ioremap on pSeries, since | 524 | * When running on pSeries using 64k pages for ioremap |
507 | * that would stop us accessing the HEA ethernet. | 525 | * would stop us accessing the HEA ethernet. So if we |
526 | * have the chance of ever seeing one, stay at 4k. | ||
508 | */ | 527 | */ |
509 | if (!machine_is(pseries)) | 528 | if (!might_have_hea() || !machine_is(pseries)) |
510 | mmu_io_psize = MMU_PAGE_64K; | 529 | mmu_io_psize = MMU_PAGE_64K; |
511 | } else | 530 | } else |
512 | mmu_ci_restrictions = 1; | 531 | mmu_ci_restrictions = 1; |
@@ -607,47 +626,43 @@ int remove_section_mapping(unsigned long start, unsigned long end) | |||
607 | } | 626 | } |
608 | #endif /* CONFIG_MEMORY_HOTPLUG */ | 627 | #endif /* CONFIG_MEMORY_HOTPLUG */ |
609 | 628 | ||
610 | #define FUNCTION_TEXT(A) ((*(unsigned long *)(A))) | 629 | extern u32 htab_call_hpte_insert1[]; |
630 | extern u32 htab_call_hpte_insert2[]; | ||
631 | extern u32 htab_call_hpte_remove[]; | ||
632 | extern u32 htab_call_hpte_updatepp[]; | ||
633 | extern u32 ht64_call_hpte_insert1[]; | ||
634 | extern u32 ht64_call_hpte_insert2[]; | ||
635 | extern u32 ht64_call_hpte_remove[]; | ||
636 | extern u32 ht64_call_hpte_updatepp[]; | ||
611 | 637 | ||
612 | static void __init htab_finish_init(void) | 638 | static void __init htab_finish_init(void) |
613 | { | 639 | { |
614 | extern unsigned int *htab_call_hpte_insert1; | ||
615 | extern unsigned int *htab_call_hpte_insert2; | ||
616 | extern unsigned int *htab_call_hpte_remove; | ||
617 | extern unsigned int *htab_call_hpte_updatepp; | ||
618 | |||
619 | #ifdef CONFIG_PPC_HAS_HASH_64K | 640 | #ifdef CONFIG_PPC_HAS_HASH_64K |
620 | extern unsigned int *ht64_call_hpte_insert1; | ||
621 | extern unsigned int *ht64_call_hpte_insert2; | ||
622 | extern unsigned int *ht64_call_hpte_remove; | ||
623 | extern unsigned int *ht64_call_hpte_updatepp; | ||
624 | |||
625 | patch_branch(ht64_call_hpte_insert1, | 641 | patch_branch(ht64_call_hpte_insert1, |
626 | FUNCTION_TEXT(ppc_md.hpte_insert), | 642 | ppc_function_entry(ppc_md.hpte_insert), |
627 | BRANCH_SET_LINK); | 643 | BRANCH_SET_LINK); |
628 | patch_branch(ht64_call_hpte_insert2, | 644 | patch_branch(ht64_call_hpte_insert2, |
629 | FUNCTION_TEXT(ppc_md.hpte_insert), | 645 | ppc_function_entry(ppc_md.hpte_insert), |
630 | BRANCH_SET_LINK); | 646 | BRANCH_SET_LINK); |
631 | patch_branch(ht64_call_hpte_remove, | 647 | patch_branch(ht64_call_hpte_remove, |
632 | FUNCTION_TEXT(ppc_md.hpte_remove), | 648 | ppc_function_entry(ppc_md.hpte_remove), |
633 | BRANCH_SET_LINK); | 649 | BRANCH_SET_LINK); |
634 | patch_branch(ht64_call_hpte_updatepp, | 650 | patch_branch(ht64_call_hpte_updatepp, |
635 | FUNCTION_TEXT(ppc_md.hpte_updatepp), | 651 | ppc_function_entry(ppc_md.hpte_updatepp), |
636 | BRANCH_SET_LINK); | 652 | BRANCH_SET_LINK); |
637 | |||
638 | #endif /* CONFIG_PPC_HAS_HASH_64K */ | 653 | #endif /* CONFIG_PPC_HAS_HASH_64K */ |
639 | 654 | ||
640 | patch_branch(htab_call_hpte_insert1, | 655 | patch_branch(htab_call_hpte_insert1, |
641 | FUNCTION_TEXT(ppc_md.hpte_insert), | 656 | ppc_function_entry(ppc_md.hpte_insert), |
642 | BRANCH_SET_LINK); | 657 | BRANCH_SET_LINK); |
643 | patch_branch(htab_call_hpte_insert2, | 658 | patch_branch(htab_call_hpte_insert2, |
644 | FUNCTION_TEXT(ppc_md.hpte_insert), | 659 | ppc_function_entry(ppc_md.hpte_insert), |
645 | BRANCH_SET_LINK); | 660 | BRANCH_SET_LINK); |
646 | patch_branch(htab_call_hpte_remove, | 661 | patch_branch(htab_call_hpte_remove, |
647 | FUNCTION_TEXT(ppc_md.hpte_remove), | 662 | ppc_function_entry(ppc_md.hpte_remove), |
648 | BRANCH_SET_LINK); | 663 | BRANCH_SET_LINK); |
649 | patch_branch(htab_call_hpte_updatepp, | 664 | patch_branch(htab_call_hpte_updatepp, |
650 | FUNCTION_TEXT(ppc_md.hpte_updatepp), | 665 | ppc_function_entry(ppc_md.hpte_updatepp), |
651 | BRANCH_SET_LINK); | 666 | BRANCH_SET_LINK); |
652 | } | 667 | } |
653 | 668 | ||
@@ -964,6 +979,22 @@ void hash_failure_debug(unsigned long ea, unsigned long access, | |||
964 | trap, vsid, ssize, psize, lpsize, pte); | 979 | trap, vsid, ssize, psize, lpsize, pte); |
965 | } | 980 | } |
966 | 981 | ||
982 | static void check_paca_psize(unsigned long ea, struct mm_struct *mm, | ||
983 | int psize, bool user_region) | ||
984 | { | ||
985 | if (user_region) { | ||
986 | if (psize != get_paca_psize(ea)) { | ||
987 | get_paca()->context = mm->context; | ||
988 | slb_flush_and_rebolt(); | ||
989 | } | ||
990 | } else if (get_paca()->vmalloc_sllp != | ||
991 | mmu_psize_defs[mmu_vmalloc_psize].sllp) { | ||
992 | get_paca()->vmalloc_sllp = | ||
993 | mmu_psize_defs[mmu_vmalloc_psize].sllp; | ||
994 | slb_vmalloc_update(); | ||
995 | } | ||
996 | } | ||
997 | |||
967 | /* Result code is: | 998 | /* Result code is: |
968 | * 0 - handled | 999 | * 0 - handled |
969 | * 1 - normal page fault | 1000 | * 1 - normal page fault |
@@ -1085,6 +1116,8 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
1085 | WARN_ON(1); | 1116 | WARN_ON(1); |
1086 | } | 1117 | } |
1087 | #endif | 1118 | #endif |
1119 | check_paca_psize(ea, mm, psize, user_region); | ||
1120 | |||
1088 | goto bail; | 1121 | goto bail; |
1089 | } | 1122 | } |
1090 | 1123 | ||
@@ -1125,17 +1158,8 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
1125 | #endif | 1158 | #endif |
1126 | } | 1159 | } |
1127 | } | 1160 | } |
1128 | if (user_region) { | 1161 | |
1129 | if (psize != get_paca_psize(ea)) { | 1162 | check_paca_psize(ea, mm, psize, user_region); |
1130 | get_paca()->context = mm->context; | ||
1131 | slb_flush_and_rebolt(); | ||
1132 | } | ||
1133 | } else if (get_paca()->vmalloc_sllp != | ||
1134 | mmu_psize_defs[mmu_vmalloc_psize].sllp) { | ||
1135 | get_paca()->vmalloc_sllp = | ||
1136 | mmu_psize_defs[mmu_vmalloc_psize].sllp; | ||
1137 | slb_vmalloc_update(); | ||
1138 | } | ||
1139 | #endif /* CONFIG_PPC_64K_PAGES */ | 1163 | #endif /* CONFIG_PPC_64K_PAGES */ |
1140 | 1164 | ||
1141 | #ifdef CONFIG_PPC_HAS_HASH_64K | 1165 | #ifdef CONFIG_PPC_HAS_HASH_64K |
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index 964a5f61488a..0399a6702958 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c | |||
@@ -256,10 +256,14 @@ static inline void patch_slb_encoding(unsigned int *insn_addr, | |||
256 | patch_instruction(insn_addr, insn); | 256 | patch_instruction(insn_addr, insn); |
257 | } | 257 | } |
258 | 258 | ||
259 | extern u32 slb_compare_rr_to_size[]; | ||
260 | extern u32 slb_miss_kernel_load_linear[]; | ||
261 | extern u32 slb_miss_kernel_load_io[]; | ||
262 | extern u32 slb_compare_rr_to_size[]; | ||
263 | extern u32 slb_miss_kernel_load_vmemmap[]; | ||
264 | |||
259 | void slb_set_size(u16 size) | 265 | void slb_set_size(u16 size) |
260 | { | 266 | { |
261 | extern unsigned int *slb_compare_rr_to_size; | ||
262 | |||
263 | if (mmu_slb_size == size) | 267 | if (mmu_slb_size == size) |
264 | return; | 268 | return; |
265 | 269 | ||
@@ -272,11 +276,7 @@ void slb_initialize(void) | |||
272 | unsigned long linear_llp, vmalloc_llp, io_llp; | 276 | unsigned long linear_llp, vmalloc_llp, io_llp; |
273 | unsigned long lflags, vflags; | 277 | unsigned long lflags, vflags; |
274 | static int slb_encoding_inited; | 278 | static int slb_encoding_inited; |
275 | extern unsigned int *slb_miss_kernel_load_linear; | ||
276 | extern unsigned int *slb_miss_kernel_load_io; | ||
277 | extern unsigned int *slb_compare_rr_to_size; | ||
278 | #ifdef CONFIG_SPARSEMEM_VMEMMAP | 279 | #ifdef CONFIG_SPARSEMEM_VMEMMAP |
279 | extern unsigned int *slb_miss_kernel_load_vmemmap; | ||
280 | unsigned long vmemmap_llp; | 280 | unsigned long vmemmap_llp; |
281 | #endif | 281 | #endif |
282 | 282 | ||
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S index 17aa6dfceb34..736d18b3cefd 100644 --- a/arch/powerpc/mm/slb_low.S +++ b/arch/powerpc/mm/slb_low.S | |||
@@ -35,7 +35,7 @@ _GLOBAL(slb_allocate_realmode) | |||
35 | * check for bad kernel/user address | 35 | * check for bad kernel/user address |
36 | * (ea & ~REGION_MASK) >= PGTABLE_RANGE | 36 | * (ea & ~REGION_MASK) >= PGTABLE_RANGE |
37 | */ | 37 | */ |
38 | rldicr. r9,r3,4,(63 - 46 - 4) | 38 | rldicr. r9,r3,4,(63 - PGTABLE_EADDR_SIZE - 4) |
39 | bne- 8f | 39 | bne- 8f |
40 | 40 | ||
41 | srdi r9,r3,60 /* get region */ | 41 | srdi r9,r3,60 /* get region */ |
@@ -59,7 +59,8 @@ _GLOBAL(slb_allocate_realmode) | |||
59 | /* Linear mapping encoding bits, the "li" instruction below will | 59 | /* Linear mapping encoding bits, the "li" instruction below will |
60 | * be patched by the kernel at boot | 60 | * be patched by the kernel at boot |
61 | */ | 61 | */ |
62 | _GLOBAL(slb_miss_kernel_load_linear) | 62 | .globl slb_miss_kernel_load_linear |
63 | slb_miss_kernel_load_linear: | ||
63 | li r11,0 | 64 | li r11,0 |
64 | /* | 65 | /* |
65 | * context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1 | 66 | * context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1 |
@@ -79,7 +80,8 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT) | |||
79 | /* Check virtual memmap region. To be patches at kernel boot */ | 80 | /* Check virtual memmap region. To be patches at kernel boot */ |
80 | cmpldi cr0,r9,0xf | 81 | cmpldi cr0,r9,0xf |
81 | bne 1f | 82 | bne 1f |
82 | _GLOBAL(slb_miss_kernel_load_vmemmap) | 83 | .globl slb_miss_kernel_load_vmemmap |
84 | slb_miss_kernel_load_vmemmap: | ||
83 | li r11,0 | 85 | li r11,0 |
84 | b 6f | 86 | b 6f |
85 | 1: | 87 | 1: |
@@ -95,7 +97,8 @@ _GLOBAL(slb_miss_kernel_load_vmemmap) | |||
95 | b 6f | 97 | b 6f |
96 | 5: | 98 | 5: |
97 | /* IO mapping */ | 99 | /* IO mapping */ |
98 | _GLOBAL(slb_miss_kernel_load_io) | 100 | .globl slb_miss_kernel_load_io |
101 | slb_miss_kernel_load_io: | ||
99 | li r11,0 | 102 | li r11,0 |
100 | 6: | 103 | 6: |
101 | /* | 104 | /* |
@@ -250,7 +253,8 @@ slb_finish_load: | |||
250 | 7: ld r10,PACASTABRR(r13) | 253 | 7: ld r10,PACASTABRR(r13) |
251 | addi r10,r10,1 | 254 | addi r10,r10,1 |
252 | /* This gets soft patched on boot. */ | 255 | /* This gets soft patched on boot. */ |
253 | _GLOBAL(slb_compare_rr_to_size) | 256 | .globl slb_compare_rr_to_size |
257 | slb_compare_rr_to_size: | ||
254 | cmpldi r10,0 | 258 | cmpldi r10,0 |
255 | 259 | ||
256 | blt+ 4f | 260 | blt+ 4f |
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c index ae3d5b799b90..92cb18d52ea8 100644 --- a/arch/powerpc/mm/tlb_nohash.c +++ b/arch/powerpc/mm/tlb_nohash.c | |||
@@ -596,8 +596,13 @@ static void __early_init_mmu(int boot_cpu) | |||
596 | /* XXX This should be decided at runtime based on supported | 596 | /* XXX This should be decided at runtime based on supported |
597 | * page sizes in the TLB, but for now let's assume 16M is | 597 | * page sizes in the TLB, but for now let's assume 16M is |
598 | * always there and a good fit (which it probably is) | 598 | * always there and a good fit (which it probably is) |
599 | * | ||
600 | * Freescale booke only supports 4K pages in TLB0, so use that. | ||
599 | */ | 601 | */ |
600 | mmu_vmemmap_psize = MMU_PAGE_16M; | 602 | if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) |
603 | mmu_vmemmap_psize = MMU_PAGE_4K; | ||
604 | else | ||
605 | mmu_vmemmap_psize = MMU_PAGE_16M; | ||
601 | 606 | ||
602 | /* XXX This code only checks for TLB 0 capabilities and doesn't | 607 | /* XXX This code only checks for TLB 0 capabilities and doesn't |
603 | * check what page size combos are supported by the HW. It | 608 | * check what page size combos are supported by the HW. It |
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index dc1a264ec6e6..4d88f6a19058 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig | |||
@@ -199,6 +199,34 @@ config CURRITUCK | |||
199 | help | 199 | help |
200 | This option enables support for the IBM Currituck (476fpe) evaluation board | 200 | This option enables support for the IBM Currituck (476fpe) evaluation board |
201 | 201 | ||
202 | config AKEBONO | ||
203 | bool "IBM Akebono (476gtr) Support" | ||
204 | depends on PPC_47x | ||
205 | default n | ||
206 | select SWIOTLB | ||
207 | select 476FPE | ||
208 | select PPC4xx_PCI_EXPRESS | ||
209 | select PCI_MSI | ||
210 | select PPC4xx_HSTA_MSI | ||
211 | select I2C | ||
212 | select I2C_IBM_IIC | ||
213 | select NETDEVICES | ||
214 | select ETHERNET | ||
215 | select NET_VENDOR_IBM | ||
216 | select IBM_EMAC_EMAC4 | ||
217 | select IBM_EMAC_RGMII_WOL | ||
218 | select USB | ||
219 | select USB_OHCI_HCD_PLATFORM | ||
220 | select USB_EHCI_HCD_PLATFORM | ||
221 | select MMC_SDHCI | ||
222 | select MMC_SDHCI_PLTFM | ||
223 | select MMC_SDHCI_OF_476GTR | ||
224 | select ATA | ||
225 | select SATA_AHCI_PLATFORM | ||
226 | help | ||
227 | This option enables support for the IBM Akebono (476gtr) evaluation board | ||
228 | |||
229 | |||
202 | config ICON | 230 | config ICON |
203 | bool "Icon" | 231 | bool "Icon" |
204 | depends on 44x | 232 | depends on 44x |
@@ -323,6 +351,20 @@ config APM821xx | |||
323 | select IBM_EMAC_EMAC4 | 351 | select IBM_EMAC_EMAC4 |
324 | select IBM_EMAC_TAH | 352 | select IBM_EMAC_TAH |
325 | 353 | ||
354 | config 476FPE_ERR46 | ||
355 | depends on 476FPE | ||
356 | bool "Enable linker work around for PPC476FPE errata #46" | ||
357 | help | ||
358 | This option enables a work around for an icache bug on 476 | ||
359 | that can cause execution of stale instructions when falling | ||
360 | through pages (IBM errata #46). It requires a recent version | ||
361 | of binutils which supports the --ppc476-workaround option. | ||
362 | |||
363 | The work around enables the appropriate linker options and | ||
364 | ensures that all module output sections are aligned to 4K | ||
365 | page boundaries. The work around is only required when | ||
366 | building modules. | ||
367 | |||
326 | # 44x errata/workaround config symbols, selected by the CPU models above | 368 | # 44x errata/workaround config symbols, selected by the CPU models above |
327 | config IBM440EP_ERR42 | 369 | config IBM440EP_ERR42 |
328 | bool | 370 | bool |
diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile index d03833abec09..26d35b5941f7 100644 --- a/arch/powerpc/platforms/44x/Makefile +++ b/arch/powerpc/platforms/44x/Makefile | |||
@@ -10,4 +10,5 @@ obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o | |||
10 | obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o | 10 | obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o |
11 | obj-$(CONFIG_ISS4xx) += iss4xx.o | 11 | obj-$(CONFIG_ISS4xx) += iss4xx.o |
12 | obj-$(CONFIG_CANYONLANDS)+= canyonlands.o | 12 | obj-$(CONFIG_CANYONLANDS)+= canyonlands.o |
13 | obj-$(CONFIG_CURRITUCK) += currituck.o | 13 | obj-$(CONFIG_CURRITUCK) += ppc476.o |
14 | obj-$(CONFIG_AKEBONO) += ppc476.o | ||
diff --git a/arch/powerpc/platforms/44x/currituck.c b/arch/powerpc/platforms/44x/ppc476.c index 7f1b71a01c6a..33986c1a05da 100644 --- a/arch/powerpc/platforms/44x/currituck.c +++ b/arch/powerpc/platforms/44x/ppc476.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Currituck board specific routines | 2 | * PowerPC 476FPE board specific routines |
3 | * | 3 | * |
4 | * Copyright © 2011 Tony Breeds IBM Corporation | 4 | * Copyright © 2013 Tony Breeds IBM Corporation |
5 | * Copyright © 2013 Alistair Popple IBM Corporation | ||
5 | * | 6 | * |
6 | * Based on earlier code: | 7 | * Based on earlier code: |
7 | * Matt Porter <mporter@kernel.crashing.org> | 8 | * Matt Porter <mporter@kernel.crashing.org> |
@@ -35,8 +36,9 @@ | |||
35 | #include <asm/mmu.h> | 36 | #include <asm/mmu.h> |
36 | 37 | ||
37 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
39 | #include <linux/i2c.h> | ||
38 | 40 | ||
39 | static __initdata struct of_device_id ppc47x_of_bus[] = { | 41 | static struct of_device_id ppc47x_of_bus[] __initdata = { |
40 | { .compatible = "ibm,plb4", }, | 42 | { .compatible = "ibm,plb4", }, |
41 | { .compatible = "ibm,plb6", }, | 43 | { .compatible = "ibm,plb6", }, |
42 | { .compatible = "ibm,opb", }, | 44 | { .compatible = "ibm,opb", }, |
@@ -55,15 +57,69 @@ static void quirk_ppc_currituck_usb_fixup(struct pci_dev *dev) | |||
55 | } | 57 | } |
56 | DECLARE_PCI_FIXUP_HEADER(0x1033, 0x0035, quirk_ppc_currituck_usb_fixup); | 58 | DECLARE_PCI_FIXUP_HEADER(0x1033, 0x0035, quirk_ppc_currituck_usb_fixup); |
57 | 59 | ||
60 | /* Akebono has an AVR microcontroller attached to the I2C bus | ||
61 | * which is used to power off/reset the system. */ | ||
62 | |||
63 | /* AVR I2C Commands */ | ||
64 | #define AVR_PWRCTL_CMD (0x26) | ||
65 | |||
66 | /* Flags for the power control I2C commands */ | ||
67 | #define AVR_PWRCTL_PWROFF (0x01) | ||
68 | #define AVR_PWRCTL_RESET (0x02) | ||
69 | |||
70 | static struct i2c_client *avr_i2c_client; | ||
71 | static void avr_halt_system(int pwrctl_flags) | ||
72 | { | ||
73 | /* Request the AVR to reset the system */ | ||
74 | i2c_smbus_write_byte_data(avr_i2c_client, | ||
75 | AVR_PWRCTL_CMD, pwrctl_flags); | ||
76 | |||
77 | /* Wait for system to be reset */ | ||
78 | while (1) | ||
79 | ; | ||
80 | } | ||
81 | |||
82 | static void avr_power_off_system(void) | ||
83 | { | ||
84 | avr_halt_system(AVR_PWRCTL_PWROFF); | ||
85 | } | ||
86 | |||
87 | static void avr_reset_system(char *cmd) | ||
88 | { | ||
89 | avr_halt_system(AVR_PWRCTL_RESET); | ||
90 | } | ||
91 | |||
92 | static int avr_probe(struct i2c_client *client, | ||
93 | const struct i2c_device_id *id) | ||
94 | { | ||
95 | avr_i2c_client = client; | ||
96 | ppc_md.restart = avr_reset_system; | ||
97 | ppc_md.power_off = avr_power_off_system; | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static const struct i2c_device_id avr_id[] = { | ||
102 | { "akebono-avr", 0 }, | ||
103 | { } | ||
104 | }; | ||
105 | |||
106 | static struct i2c_driver avr_driver = { | ||
107 | .driver = { | ||
108 | .name = "akebono-avr", | ||
109 | }, | ||
110 | .probe = avr_probe, | ||
111 | .id_table = avr_id, | ||
112 | }; | ||
113 | |||
58 | static int __init ppc47x_device_probe(void) | 114 | static int __init ppc47x_device_probe(void) |
59 | { | 115 | { |
116 | i2c_add_driver(&avr_driver); | ||
60 | of_platform_bus_probe(NULL, ppc47x_of_bus, NULL); | 117 | of_platform_bus_probe(NULL, ppc47x_of_bus, NULL); |
61 | 118 | ||
62 | return 0; | 119 | return 0; |
63 | } | 120 | } |
64 | machine_device_initcall(ppc47x, ppc47x_device_probe); | 121 | machine_device_initcall(ppc47x, ppc47x_device_probe); |
65 | 122 | ||
66 | /* We can have either UICs or MPICs */ | ||
67 | static void __init ppc47x_init_irq(void) | 123 | static void __init ppc47x_init_irq(void) |
68 | { | 124 | { |
69 | struct device_node *np; | 125 | struct device_node *np; |
@@ -157,43 +213,36 @@ static void __init ppc47x_setup_arch(void) | |||
157 | { | 213 | { |
158 | 214 | ||
159 | /* No need to check the DMA config as we /know/ our windows are all of | 215 | /* No need to check the DMA config as we /know/ our windows are all of |
160 | * RAM. Lets hope that doesn't change */ | 216 | * RAM. Lets hope that doesn't change */ |
161 | swiotlb_detect_4g(); | 217 | swiotlb_detect_4g(); |
162 | 218 | ||
163 | ppc47x_smp_init(); | 219 | ppc47x_smp_init(); |
164 | } | 220 | } |
165 | 221 | ||
166 | /* | ||
167 | * Called very early, MMU is off, device-tree isn't unflattened | ||
168 | */ | ||
169 | static int __init ppc47x_probe(void) | ||
170 | { | ||
171 | unsigned long root = of_get_flat_dt_root(); | ||
172 | |||
173 | if (!of_flat_dt_is_compatible(root, "ibm,currituck")) | ||
174 | return 0; | ||
175 | |||
176 | return 1; | ||
177 | } | ||
178 | |||
179 | static int board_rev = -1; | 222 | static int board_rev = -1; |
180 | static int __init ppc47x_get_board_rev(void) | 223 | static int __init ppc47x_get_board_rev(void) |
181 | { | 224 | { |
182 | u8 fpga_reg0; | 225 | int reg; |
183 | void *fpga; | 226 | u8 *fpga; |
184 | struct device_node *np; | 227 | struct device_node *np = NULL; |
228 | |||
229 | if (of_machine_is_compatible("ibm,currituck")) { | ||
230 | np = of_find_compatible_node(NULL, NULL, "ibm,currituck-fpga"); | ||
231 | reg = 0; | ||
232 | } else if (of_machine_is_compatible("ibm,akebono")) { | ||
233 | np = of_find_compatible_node(NULL, NULL, "ibm,akebono-fpga"); | ||
234 | reg = 2; | ||
235 | } | ||
185 | 236 | ||
186 | np = of_find_compatible_node(NULL, NULL, "ibm,currituck-fpga"); | ||
187 | if (!np) | 237 | if (!np) |
188 | goto fail; | 238 | goto fail; |
189 | 239 | ||
190 | fpga = of_iomap(np, 0); | 240 | fpga = (u8 *) of_iomap(np, 0); |
191 | of_node_put(np); | 241 | of_node_put(np); |
192 | if (!fpga) | 242 | if (!fpga) |
193 | goto fail; | 243 | goto fail; |
194 | 244 | ||
195 | fpga_reg0 = ioread8(fpga); | 245 | board_rev = ioread8(fpga + reg) & 0x03; |
196 | board_rev = fpga_reg0 & 0x03; | ||
197 | pr_info("%s: Found board revision %d\n", __func__, board_rev); | 246 | pr_info("%s: Found board revision %d\n", __func__, board_rev); |
198 | iounmap(fpga); | 247 | iounmap(fpga); |
199 | return 0; | 248 | return 0; |
@@ -208,7 +257,7 @@ machine_arch_initcall(ppc47x, ppc47x_get_board_rev); | |||
208 | static void ppc47x_pci_irq_fixup(struct pci_dev *dev) | 257 | static void ppc47x_pci_irq_fixup(struct pci_dev *dev) |
209 | { | 258 | { |
210 | if (dev->vendor == 0x1033 && (dev->device == 0x0035 || | 259 | if (dev->vendor == 0x1033 && (dev->device == 0x0035 || |
211 | dev->device == 0x00e0)) { | 260 | dev->device == 0x00e0)) { |
212 | if (board_rev == 0) { | 261 | if (board_rev == 0) { |
213 | dev->irq = irq_create_mapping(NULL, 47); | 262 | dev->irq = irq_create_mapping(NULL, 47); |
214 | pr_info("%s: Mapping irq %d\n", __func__, dev->irq); | 263 | pr_info("%s: Mapping irq %d\n", __func__, dev->irq); |
@@ -221,13 +270,30 @@ static void ppc47x_pci_irq_fixup(struct pci_dev *dev) | |||
221 | } | 270 | } |
222 | } | 271 | } |
223 | 272 | ||
273 | /* | ||
274 | * Called very early, MMU is off, device-tree isn't unflattened | ||
275 | */ | ||
276 | static int __init ppc47x_probe(void) | ||
277 | { | ||
278 | unsigned long root = of_get_flat_dt_root(); | ||
279 | |||
280 | if (of_flat_dt_is_compatible(root, "ibm,akebono")) | ||
281 | return 1; | ||
282 | |||
283 | if (of_flat_dt_is_compatible(root, "ibm,currituck")) { | ||
284 | ppc_md.pci_irq_fixup = ppc47x_pci_irq_fixup; | ||
285 | return 1; | ||
286 | } | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
224 | define_machine(ppc47x) { | 291 | define_machine(ppc47x) { |
225 | .name = "PowerPC 47x", | 292 | .name = "PowerPC 47x", |
226 | .probe = ppc47x_probe, | 293 | .probe = ppc47x_probe, |
227 | .progress = udbg_progress, | 294 | .progress = udbg_progress, |
228 | .init_IRQ = ppc47x_init_irq, | 295 | .init_IRQ = ppc47x_init_irq, |
229 | .setup_arch = ppc47x_setup_arch, | 296 | .setup_arch = ppc47x_setup_arch, |
230 | .pci_irq_fixup = ppc47x_pci_irq_fixup, | ||
231 | .restart = ppc4xx_reset_system, | 297 | .restart = ppc4xx_reset_system, |
232 | .calibrate_decr = generic_calibrate_decr, | 298 | .calibrate_decr = generic_calibrate_decr, |
233 | }; | 299 | }; |
diff --git a/arch/powerpc/platforms/44x/ppc476_modules.lds b/arch/powerpc/platforms/44x/ppc476_modules.lds new file mode 100644 index 000000000000..9fec5d34ba8e --- /dev/null +++ b/arch/powerpc/platforms/44x/ppc476_modules.lds | |||
@@ -0,0 +1,15 @@ | |||
1 | SECTIONS | ||
2 | { | ||
3 | .text : ALIGN(4096) | ||
4 | { | ||
5 | *(.text .text.* .fixup) | ||
6 | } | ||
7 | .init.text : ALIGN(4096) | ||
8 | { | ||
9 | *(.init.text .init.text.*) | ||
10 | } | ||
11 | .exit.text : ALIGN(4096) | ||
12 | { | ||
13 | *(.exit.text .exit.text.*) | ||
14 | } | ||
15 | } | ||
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index c17aae80e7ff..f442120e0033 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig | |||
@@ -38,6 +38,15 @@ config C293_PCIE | |||
38 | help | 38 | help |
39 | This option enables support for the C293PCIE board | 39 | This option enables support for the C293PCIE board |
40 | 40 | ||
41 | config BSC9132_QDS | ||
42 | bool "Freescale BSC9132QDS" | ||
43 | select DEFAULT_UIMAGE | ||
44 | help | ||
45 | This option enables support for the Freescale BSC9132 QDS board. | ||
46 | BSC9132 is a heterogeneous SoC containing dual e500v2 powerpc cores | ||
47 | and dual StarCore SC3850 DSP cores. | ||
48 | Manufacturer : Freescale Semiconductor, Inc | ||
49 | |||
41 | config MPC8540_ADS | 50 | config MPC8540_ADS |
42 | bool "Freescale MPC8540 ADS" | 51 | bool "Freescale MPC8540 ADS" |
43 | select DEFAULT_UIMAGE | 52 | select DEFAULT_UIMAGE |
@@ -117,11 +126,11 @@ config P1022_RDK | |||
117 | This option enables support for the Freescale / iVeia P1022RDK | 126 | This option enables support for the Freescale / iVeia P1022RDK |
118 | reference board. | 127 | reference board. |
119 | 128 | ||
120 | config P1023_RDS | 129 | config P1023_RDB |
121 | bool "Freescale P1023 RDS/RDB" | 130 | bool "Freescale P1023 RDB" |
122 | select DEFAULT_UIMAGE | 131 | select DEFAULT_UIMAGE |
123 | help | 132 | help |
124 | This option enables support for the P1023 RDS and RDB boards | 133 | This option enables support for the P1023 RDB board. |
125 | 134 | ||
126 | config TWR_P102x | 135 | config TWR_P102x |
127 | bool "Freescale TWR-P102x" | 136 | bool "Freescale TWR-P102x" |
@@ -263,11 +272,11 @@ config CORENET_GENERIC | |||
263 | help | 272 | help |
264 | This option enables support for the FSL CoreNet based boards. | 273 | This option enables support for the FSL CoreNet based boards. |
265 | For 32bit kernel, the following boards are supported: | 274 | For 32bit kernel, the following boards are supported: |
266 | P2041 RDB, P3041 DS and P4080 DS | 275 | P2041 RDB, P3041 DS, P4080 DS, kmcoge4, and OCA4080 |
267 | For 64bit kernel, the following boards are supported: | 276 | For 64bit kernel, the following boards are supported: |
268 | T4240 QDS and B4 QDS | 277 | T4240 QDS and B4 QDS |
269 | The following boards are supported for both 32bit and 64bit kernel: | 278 | The following boards are supported for both 32bit and 64bit kernel: |
270 | P5020 DS and P5040 DS | 279 | P5020 DS, P5040 DS and T104xQDS |
271 | 280 | ||
272 | endif # FSL_SOC_BOOKE | 281 | endif # FSL_SOC_BOOKE |
273 | 282 | ||
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 25cebe74ac46..730326046625 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile | |||
@@ -6,6 +6,7 @@ obj-$(CONFIG_SMP) += smp.o | |||
6 | obj-y += common.o | 6 | obj-y += common.o |
7 | 7 | ||
8 | obj-$(CONFIG_BSC9131_RDB) += bsc913x_rdb.o | 8 | obj-$(CONFIG_BSC9131_RDB) += bsc913x_rdb.o |
9 | obj-$(CONFIG_BSC9132_QDS) += bsc913x_qds.o | ||
9 | obj-$(CONFIG_C293_PCIE) += c293pcie.o | 10 | obj-$(CONFIG_C293_PCIE) += c293pcie.o |
10 | obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o | 11 | obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o |
11 | obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o | 12 | obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o |
@@ -17,7 +18,7 @@ obj-$(CONFIG_MPC85xx_RDB) += mpc85xx_rdb.o | |||
17 | obj-$(CONFIG_P1010_RDB) += p1010rdb.o | 18 | obj-$(CONFIG_P1010_RDB) += p1010rdb.o |
18 | obj-$(CONFIG_P1022_DS) += p1022_ds.o | 19 | obj-$(CONFIG_P1022_DS) += p1022_ds.o |
19 | obj-$(CONFIG_P1022_RDK) += p1022_rdk.o | 20 | obj-$(CONFIG_P1022_RDK) += p1022_rdk.o |
20 | obj-$(CONFIG_P1023_RDS) += p1023_rds.o | 21 | obj-$(CONFIG_P1023_RDB) += p1023_rdb.o |
21 | obj-$(CONFIG_TWR_P102x) += twr_p102x.o | 22 | obj-$(CONFIG_TWR_P102x) += twr_p102x.o |
22 | obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o | 23 | obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o |
23 | obj-$(CONFIG_STX_GP3) += stx_gp3.o | 24 | obj-$(CONFIG_STX_GP3) += stx_gp3.o |
diff --git a/arch/powerpc/platforms/85xx/bsc913x_qds.c b/arch/powerpc/platforms/85xx/bsc913x_qds.c new file mode 100644 index 000000000000..f0927e58af25 --- /dev/null +++ b/arch/powerpc/platforms/85xx/bsc913x_qds.c | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * BSC913xQDS Board Setup | ||
3 | * | ||
4 | * Author: | ||
5 | * Harninder Rai <harninder.rai@freescale.com> | ||
6 | * Priyanka Jain <Priyanka.Jain@freescale.com> | ||
7 | * | ||
8 | * Copyright 2014 Freescale Semiconductor Inc. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/of_platform.h> | ||
17 | #include <linux/pci.h> | ||
18 | #include <asm/mpic.h> | ||
19 | #include <sysdev/fsl_soc.h> | ||
20 | #include <asm/udbg.h> | ||
21 | |||
22 | #include "mpc85xx.h" | ||
23 | #include "smp.h" | ||
24 | |||
25 | void __init bsc913x_qds_pic_init(void) | ||
26 | { | ||
27 | struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | | ||
28 | MPIC_SINGLE_DEST_CPU, | ||
29 | 0, 256, " OpenPIC "); | ||
30 | |||
31 | if (!mpic) | ||
32 | pr_err("bsc913x: Failed to allocate MPIC structure\n"); | ||
33 | else | ||
34 | mpic_init(mpic); | ||
35 | } | ||
36 | |||
37 | /* | ||
38 | * Setup the architecture | ||
39 | */ | ||
40 | static void __init bsc913x_qds_setup_arch(void) | ||
41 | { | ||
42 | if (ppc_md.progress) | ||
43 | ppc_md.progress("bsc913x_qds_setup_arch()", 0); | ||
44 | |||
45 | #if defined(CONFIG_SMP) | ||
46 | mpc85xx_smp_init(); | ||
47 | #endif | ||
48 | |||
49 | pr_info("bsc913x board from Freescale Semiconductor\n"); | ||
50 | } | ||
51 | |||
52 | machine_device_initcall(bsc9132_qds, mpc85xx_common_publish_devices); | ||
53 | |||
54 | /* | ||
55 | * Called very early, device-tree isn't unflattened | ||
56 | */ | ||
57 | |||
58 | static int __init bsc9132_qds_probe(void) | ||
59 | { | ||
60 | unsigned long root = of_get_flat_dt_root(); | ||
61 | |||
62 | return of_flat_dt_is_compatible(root, "fsl,bsc9132qds"); | ||
63 | } | ||
64 | |||
65 | define_machine(bsc9132_qds) { | ||
66 | .name = "BSC9132 QDS", | ||
67 | .probe = bsc9132_qds_probe, | ||
68 | .setup_arch = bsc913x_qds_setup_arch, | ||
69 | .init_IRQ = bsc913x_qds_pic_init, | ||
70 | .get_irq = mpic_get_irq, | ||
71 | .restart = fsl_rstcr_restart, | ||
72 | .calibrate_decr = generic_calibrate_decr, | ||
73 | .progress = udbg_progress, | ||
74 | }; | ||
diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c index 8e4b1e1a4911..5db1e117fdde 100644 --- a/arch/powerpc/platforms/85xx/corenet_generic.c +++ b/arch/powerpc/platforms/85xx/corenet_generic.c | |||
@@ -67,7 +67,7 @@ void __init corenet_gen_setup_arch(void) | |||
67 | 67 | ||
68 | swiotlb_detect_4g(); | 68 | swiotlb_detect_4g(); |
69 | 69 | ||
70 | pr_info("%s board from Freescale Semiconductor\n", ppc_md.name); | 70 | pr_info("%s board\n", ppc_md.name); |
71 | 71 | ||
72 | mpc85xx_qe_init(); | 72 | mpc85xx_qe_init(); |
73 | } | 73 | } |
@@ -115,6 +115,7 @@ int __init corenet_gen_publish_devices(void) | |||
115 | static const char * const boards[] __initconst = { | 115 | static const char * const boards[] __initconst = { |
116 | "fsl,P2041RDB", | 116 | "fsl,P2041RDB", |
117 | "fsl,P3041DS", | 117 | "fsl,P3041DS", |
118 | "fsl,OCA4080", | ||
118 | "fsl,P4080DS", | 119 | "fsl,P4080DS", |
119 | "fsl,P5020DS", | 120 | "fsl,P5020DS", |
120 | "fsl,P5040DS", | 121 | "fsl,P5040DS", |
@@ -122,12 +123,16 @@ static const char * const boards[] __initconst = { | |||
122 | "fsl,B4860QDS", | 123 | "fsl,B4860QDS", |
123 | "fsl,B4420QDS", | 124 | "fsl,B4420QDS", |
124 | "fsl,B4220QDS", | 125 | "fsl,B4220QDS", |
126 | "fsl,T1040QDS", | ||
127 | "fsl,T1042QDS", | ||
128 | "keymile,kmcoge4", | ||
125 | NULL | 129 | NULL |
126 | }; | 130 | }; |
127 | 131 | ||
128 | static const char * const hv_boards[] __initconst = { | 132 | static const char * const hv_boards[] __initconst = { |
129 | "fsl,P2041RDB-hv", | 133 | "fsl,P2041RDB-hv", |
130 | "fsl,P3041DS-hv", | 134 | "fsl,P3041DS-hv", |
135 | "fsl,OCA4080-hv", | ||
131 | "fsl,P4080DS-hv", | 136 | "fsl,P4080DS-hv", |
132 | "fsl,P5020DS-hv", | 137 | "fsl,P5020DS-hv", |
133 | "fsl,P5040DS-hv", | 138 | "fsl,P5040DS-hv", |
@@ -135,6 +140,8 @@ static const char * const hv_boards[] __initconst = { | |||
135 | "fsl,B4860QDS-hv", | 140 | "fsl,B4860QDS-hv", |
136 | "fsl,B4420QDS-hv", | 141 | "fsl,B4420QDS-hv", |
137 | "fsl,B4220QDS-hv", | 142 | "fsl,B4220QDS-hv", |
143 | "fsl,T1040QDS-hv", | ||
144 | "fsl,T1042QDS-hv", | ||
138 | NULL | 145 | NULL |
139 | }; | 146 | }; |
140 | 147 | ||
diff --git a/arch/powerpc/platforms/85xx/p1023_rds.c b/arch/powerpc/platforms/85xx/p1023_rdb.c index 0e614007acfb..d5b7509825de 100644 --- a/arch/powerpc/platforms/85xx/p1023_rds.c +++ b/arch/powerpc/platforms/85xx/p1023_rdb.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Author: Roy Zang <tie-fei.zang@freescale.com> | 4 | * Author: Roy Zang <tie-fei.zang@freescale.com> |
5 | * | 5 | * |
6 | * Description: | 6 | * Description: |
7 | * P1023 RDS Board Setup | 7 | * P1023 RDB Board Setup |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify it | 9 | * This program is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU General Public License as published by the | 10 | * under the terms of the GNU General Public License as published by the |
@@ -41,12 +41,12 @@ | |||
41 | * Setup the architecture | 41 | * Setup the architecture |
42 | * | 42 | * |
43 | */ | 43 | */ |
44 | static void __init mpc85xx_rds_setup_arch(void) | 44 | static void __init mpc85xx_rdb_setup_arch(void) |
45 | { | 45 | { |
46 | struct device_node *np; | 46 | struct device_node *np; |
47 | 47 | ||
48 | if (ppc_md.progress) | 48 | if (ppc_md.progress) |
49 | ppc_md.progress("p1023_rds_setup_arch()", 0); | 49 | ppc_md.progress("p1023_rdb_setup_arch()", 0); |
50 | 50 | ||
51 | /* Map BCSR area */ | 51 | /* Map BCSR area */ |
52 | np = of_find_node_by_name(NULL, "bcsr"); | 52 | np = of_find_node_by_name(NULL, "bcsr"); |
@@ -85,10 +85,9 @@ static void __init mpc85xx_rds_setup_arch(void) | |||
85 | fsl_pci_assign_primary(); | 85 | fsl_pci_assign_primary(); |
86 | } | 86 | } |
87 | 87 | ||
88 | machine_arch_initcall(p1023_rds, mpc85xx_common_publish_devices); | ||
89 | machine_arch_initcall(p1023_rdb, mpc85xx_common_publish_devices); | 88 | machine_arch_initcall(p1023_rdb, mpc85xx_common_publish_devices); |
90 | 89 | ||
91 | static void __init mpc85xx_rds_pic_init(void) | 90 | static void __init mpc85xx_rdb_pic_init(void) |
92 | { | 91 | { |
93 | struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | | 92 | struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | |
94 | MPIC_SINGLE_DEST_CPU, | 93 | MPIC_SINGLE_DEST_CPU, |
@@ -99,14 +98,6 @@ static void __init mpc85xx_rds_pic_init(void) | |||
99 | mpic_init(mpic); | 98 | mpic_init(mpic); |
100 | } | 99 | } |
101 | 100 | ||
102 | static int __init p1023_rds_probe(void) | ||
103 | { | ||
104 | unsigned long root = of_get_flat_dt_root(); | ||
105 | |||
106 | return of_flat_dt_is_compatible(root, "fsl,P1023RDS"); | ||
107 | |||
108 | } | ||
109 | |||
110 | static int __init p1023_rdb_probe(void) | 101 | static int __init p1023_rdb_probe(void) |
111 | { | 102 | { |
112 | unsigned long root = of_get_flat_dt_root(); | 103 | unsigned long root = of_get_flat_dt_root(); |
@@ -115,26 +106,11 @@ static int __init p1023_rdb_probe(void) | |||
115 | 106 | ||
116 | } | 107 | } |
117 | 108 | ||
118 | define_machine(p1023_rds) { | ||
119 | .name = "P1023 RDS", | ||
120 | .probe = p1023_rds_probe, | ||
121 | .setup_arch = mpc85xx_rds_setup_arch, | ||
122 | .init_IRQ = mpc85xx_rds_pic_init, | ||
123 | .get_irq = mpic_get_irq, | ||
124 | .restart = fsl_rstcr_restart, | ||
125 | .calibrate_decr = generic_calibrate_decr, | ||
126 | .progress = udbg_progress, | ||
127 | #ifdef CONFIG_PCI | ||
128 | .pcibios_fixup_bus = fsl_pcibios_fixup_bus, | ||
129 | .pcibios_fixup_phb = fsl_pcibios_fixup_phb, | ||
130 | #endif | ||
131 | }; | ||
132 | |||
133 | define_machine(p1023_rdb) { | 109 | define_machine(p1023_rdb) { |
134 | .name = "P1023 RDB", | 110 | .name = "P1023 RDB", |
135 | .probe = p1023_rdb_probe, | 111 | .probe = p1023_rdb_probe, |
136 | .setup_arch = mpc85xx_rds_setup_arch, | 112 | .setup_arch = mpc85xx_rdb_setup_arch, |
137 | .init_IRQ = mpc85xx_rds_pic_init, | 113 | .init_IRQ = mpc85xx_rdb_pic_init, |
138 | .get_irq = mpic_get_irq, | 114 | .get_irq = mpic_get_irq, |
139 | .restart = fsl_rstcr_restart, | 115 | .restart = fsl_rstcr_restart, |
140 | .calibrate_decr = generic_calibrate_decr, | 116 | .calibrate_decr = generic_calibrate_decr, |
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 6382098d6f8d..ba093f553678 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <asm/cacheflush.h> | 27 | #include <asm/cacheflush.h> |
28 | #include <asm/dbell.h> | 28 | #include <asm/dbell.h> |
29 | #include <asm/fsl_guts.h> | 29 | #include <asm/fsl_guts.h> |
30 | #include <asm/code-patching.h> | ||
30 | 31 | ||
31 | #include <sysdev/fsl_soc.h> | 32 | #include <sysdev/fsl_soc.h> |
32 | #include <sysdev/mpic.h> | 33 | #include <sysdev/mpic.h> |
@@ -267,7 +268,7 @@ out: | |||
267 | flush_spin_table(spin_table); | 268 | flush_spin_table(spin_table); |
268 | out_be32(&spin_table->pir, hw_cpu); | 269 | out_be32(&spin_table->pir, hw_cpu); |
269 | out_be64((u64 *)(&spin_table->addr_h), | 270 | out_be64((u64 *)(&spin_table->addr_h), |
270 | __pa((u64)*((unsigned long long *)generic_secondary_smp_init))); | 271 | __pa(ppc_function_entry(generic_secondary_smp_init))); |
271 | flush_spin_table(spin_table); | 272 | flush_spin_table(spin_table); |
272 | #endif | 273 | #endif |
273 | 274 | ||
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index d9e2b19b7c8d..43b65ad1970a 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype | |||
@@ -422,6 +422,7 @@ config CPU_BIG_ENDIAN | |||
422 | 422 | ||
423 | config CPU_LITTLE_ENDIAN | 423 | config CPU_LITTLE_ENDIAN |
424 | bool "Build little endian kernel" | 424 | bool "Build little endian kernel" |
425 | select PPC64_BOOT_WRAPPER | ||
425 | help | 426 | help |
426 | Build a little endian kernel. | 427 | Build a little endian kernel. |
427 | 428 | ||
@@ -430,3 +431,7 @@ config CPU_LITTLE_ENDIAN | |||
430 | little endian powerpc. | 431 | little endian powerpc. |
431 | 432 | ||
432 | endchoice | 433 | endchoice |
434 | |||
435 | config PPC64_BOOT_WRAPPER | ||
436 | def_bool n | ||
437 | depends on CPU_LITTLE_ENDIAN | ||
diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c index 90745eaa45fe..c8017a7bcabd 100644 --- a/arch/powerpc/platforms/cell/smp.c +++ b/arch/powerpc/platforms/cell/smp.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <asm/firmware.h> | 40 | #include <asm/firmware.h> |
41 | #include <asm/rtas.h> | 41 | #include <asm/rtas.h> |
42 | #include <asm/cputhreads.h> | 42 | #include <asm/cputhreads.h> |
43 | #include <asm/code-patching.h> | ||
43 | 44 | ||
44 | #include "interrupt.h" | 45 | #include "interrupt.h" |
45 | #include <asm/udbg.h> | 46 | #include <asm/udbg.h> |
@@ -70,8 +71,8 @@ static cpumask_t of_spin_map; | |||
70 | static inline int smp_startup_cpu(unsigned int lcpu) | 71 | static inline int smp_startup_cpu(unsigned int lcpu) |
71 | { | 72 | { |
72 | int status; | 73 | int status; |
73 | unsigned long start_here = __pa((u32)*((unsigned long *) | 74 | unsigned long start_here = |
74 | generic_secondary_smp_init)); | 75 | __pa(ppc_function_entry(generic_secondary_smp_init)); |
75 | unsigned int pcpu; | 76 | unsigned int pcpu; |
76 | int start_cpu; | 77 | int start_cpu; |
77 | 78 | ||
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index 2a7024d8d8b1..a25f496c2ef9 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig | |||
@@ -65,6 +65,7 @@ config MVME5100 | |||
65 | select PPC_INDIRECT_PCI | 65 | select PPC_INDIRECT_PCI |
66 | select PPC_I8259 | 66 | select PPC_I8259 |
67 | select PPC_NATIVE | 67 | select PPC_NATIVE |
68 | select PPC_UDBG_16550 | ||
68 | help | 69 | help |
69 | This option enables support for the Motorola (now Emerson) MVME5100 | 70 | This option enables support for the Motorola (now Emerson) MVME5100 |
70 | board. | 71 | board. |
diff --git a/arch/powerpc/platforms/pasemi/powersave.S b/arch/powerpc/platforms/pasemi/powersave.S index 56f45adcd089..81ab555aa491 100644 --- a/arch/powerpc/platforms/pasemi/powersave.S +++ b/arch/powerpc/platforms/pasemi/powersave.S | |||
@@ -66,7 +66,7 @@ sleep_common: | |||
66 | std r3, 48(r1) | 66 | std r3, 48(r1) |
67 | 67 | ||
68 | /* Only do power savings when in astate 0 */ | 68 | /* Only do power savings when in astate 0 */ |
69 | bl .check_astate | 69 | bl check_astate |
70 | cmpwi r3,0 | 70 | cmpwi r3,0 |
71 | bne 1f | 71 | bne 1f |
72 | 72 | ||
diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index 63cebb9b4d45..4ad0d345bc96 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | obj-y += setup.o opal-takeover.o opal-wrappers.o opal.o opal-async.o | 1 | obj-y += setup.o opal-takeover.o opal-wrappers.o opal.o opal-async.o |
2 | obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o | 2 | obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o |
3 | obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o | 3 | obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o |
4 | obj-y += opal-msglog.o | 4 | obj-y += opal-msglog.o subcore.o subcore-asm.o |
5 | 5 | ||
6 | obj-$(CONFIG_SMP) += smp.o | 6 | obj-$(CONFIG_SMP) += smp.o |
7 | obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o | 7 | obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o |
diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index 5b51079f3e3b..753f08e36dfa 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c | |||
@@ -42,11 +42,19 @@ static int ioda_eeh_event(struct notifier_block *nb, | |||
42 | { | 42 | { |
43 | uint64_t changed_evts = (uint64_t)change; | 43 | uint64_t changed_evts = (uint64_t)change; |
44 | 44 | ||
45 | /* We simply send special EEH event */ | 45 | /* |
46 | if ((changed_evts & OPAL_EVENT_PCI_ERROR) && | 46 | * We simply send special EEH event if EEH has |
47 | (events & OPAL_EVENT_PCI_ERROR) && | 47 | * been enabled, or clear pending events in |
48 | eeh_enabled()) | 48 | * case that we enable EEH soon |
49 | */ | ||
50 | if (!(changed_evts & OPAL_EVENT_PCI_ERROR) || | ||
51 | !(events & OPAL_EVENT_PCI_ERROR)) | ||
52 | return 0; | ||
53 | |||
54 | if (eeh_enabled()) | ||
49 | eeh_send_failure_event(NULL); | 55 | eeh_send_failure_event(NULL); |
56 | else | ||
57 | opal_notifier_update_evt(OPAL_EVENT_PCI_ERROR, 0x0ul); | ||
50 | 58 | ||
51 | return 0; | 59 | return 0; |
52 | } | 60 | } |
@@ -141,7 +149,9 @@ static int ioda_eeh_post_init(struct pci_controller *hose) | |||
141 | } | 149 | } |
142 | 150 | ||
143 | #ifdef CONFIG_DEBUG_FS | 151 | #ifdef CONFIG_DEBUG_FS |
144 | if (phb->dbgfs) { | 152 | if (!phb->has_dbgfs && phb->dbgfs) { |
153 | phb->has_dbgfs = 1; | ||
154 | |||
145 | debugfs_create_file("err_injct_outbound", 0600, | 155 | debugfs_create_file("err_injct_outbound", 0600, |
146 | phb->dbgfs, hose, | 156 | phb->dbgfs, hose, |
147 | &ioda_eeh_outb_dbgfs_ops); | 157 | &ioda_eeh_outb_dbgfs_ops); |
@@ -154,7 +164,14 @@ static int ioda_eeh_post_init(struct pci_controller *hose) | |||
154 | } | 164 | } |
155 | #endif | 165 | #endif |
156 | 166 | ||
157 | phb->eeh_state |= PNV_EEH_STATE_ENABLED; | 167 | /* If EEH is enabled, we're going to rely on that. |
168 | * Otherwise, we restore to conventional mechanism | ||
169 | * to clear frozen PE during PCI config access. | ||
170 | */ | ||
171 | if (eeh_enabled()) | ||
172 | phb->flags |= PNV_PHB_FLAG_EEH; | ||
173 | else | ||
174 | phb->flags &= ~PNV_PHB_FLAG_EEH; | ||
158 | 175 | ||
159 | return 0; | 176 | return 0; |
160 | } | 177 | } |
@@ -268,6 +285,21 @@ static int ioda_eeh_get_state(struct eeh_pe *pe) | |||
268 | return EEH_STATE_NOT_SUPPORT; | 285 | return EEH_STATE_NOT_SUPPORT; |
269 | } | 286 | } |
270 | 287 | ||
288 | /* | ||
289 | * If we're in middle of PE reset, return normal | ||
290 | * state to keep EEH core going. For PHB reset, we | ||
291 | * still expect to have fenced PHB cleared with | ||
292 | * PHB reset. | ||
293 | */ | ||
294 | if (!(pe->type & EEH_PE_PHB) && | ||
295 | (pe->state & EEH_PE_RESET)) { | ||
296 | result = (EEH_STATE_MMIO_ACTIVE | | ||
297 | EEH_STATE_DMA_ACTIVE | | ||
298 | EEH_STATE_MMIO_ENABLED | | ||
299 | EEH_STATE_DMA_ENABLED); | ||
300 | return result; | ||
301 | } | ||
302 | |||
271 | /* Retrieve PE status through OPAL */ | 303 | /* Retrieve PE status through OPAL */ |
272 | pe_no = pe->addr; | 304 | pe_no = pe->addr; |
273 | ret = opal_pci_eeh_freeze_status(phb->opal_id, pe_no, | 305 | ret = opal_pci_eeh_freeze_status(phb->opal_id, pe_no, |
@@ -347,52 +379,6 @@ static int ioda_eeh_get_state(struct eeh_pe *pe) | |||
347 | return result; | 379 | return result; |
348 | } | 380 | } |
349 | 381 | ||
350 | static int ioda_eeh_pe_clear(struct eeh_pe *pe) | ||
351 | { | ||
352 | struct pci_controller *hose; | ||
353 | struct pnv_phb *phb; | ||
354 | u32 pe_no; | ||
355 | u8 fstate; | ||
356 | u16 pcierr; | ||
357 | s64 ret; | ||
358 | |||
359 | pe_no = pe->addr; | ||
360 | hose = pe->phb; | ||
361 | phb = pe->phb->private_data; | ||
362 | |||
363 | /* Clear the EEH error on the PE */ | ||
364 | ret = opal_pci_eeh_freeze_clear(phb->opal_id, | ||
365 | pe_no, OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); | ||
366 | if (ret) { | ||
367 | pr_err("%s: Failed to clear EEH error for " | ||
368 | "PHB#%x-PE#%x, err=%lld\n", | ||
369 | __func__, hose->global_number, pe_no, ret); | ||
370 | return -EIO; | ||
371 | } | ||
372 | |||
373 | /* | ||
374 | * Read the PE state back and verify that the frozen | ||
375 | * state has been removed. | ||
376 | */ | ||
377 | ret = opal_pci_eeh_freeze_status(phb->opal_id, pe_no, | ||
378 | &fstate, &pcierr, NULL); | ||
379 | if (ret) { | ||
380 | pr_err("%s: Failed to get EEH status on " | ||
381 | "PHB#%x-PE#%x\n, err=%lld\n", | ||
382 | __func__, hose->global_number, pe_no, ret); | ||
383 | return -EIO; | ||
384 | } | ||
385 | |||
386 | if (fstate != OPAL_EEH_STOPPED_NOT_FROZEN) { | ||
387 | pr_err("%s: Frozen state not cleared on " | ||
388 | "PHB#%x-PE#%x, sts=%x\n", | ||
389 | __func__, hose->global_number, pe_no, fstate); | ||
390 | return -EIO; | ||
391 | } | ||
392 | |||
393 | return 0; | ||
394 | } | ||
395 | |||
396 | static s64 ioda_eeh_phb_poll(struct pnv_phb *phb) | 382 | static s64 ioda_eeh_phb_poll(struct pnv_phb *phb) |
397 | { | 383 | { |
398 | s64 rc = OPAL_HARDWARE; | 384 | s64 rc = OPAL_HARDWARE; |
@@ -402,13 +388,16 @@ static s64 ioda_eeh_phb_poll(struct pnv_phb *phb) | |||
402 | if (rc <= 0) | 388 | if (rc <= 0) |
403 | break; | 389 | break; |
404 | 390 | ||
405 | msleep(rc); | 391 | if (system_state < SYSTEM_RUNNING) |
392 | udelay(1000 * rc); | ||
393 | else | ||
394 | msleep(rc); | ||
406 | } | 395 | } |
407 | 396 | ||
408 | return rc; | 397 | return rc; |
409 | } | 398 | } |
410 | 399 | ||
411 | static int ioda_eeh_phb_reset(struct pci_controller *hose, int option) | 400 | int ioda_eeh_phb_reset(struct pci_controller *hose, int option) |
412 | { | 401 | { |
413 | struct pnv_phb *phb = hose->private_data; | 402 | struct pnv_phb *phb = hose->private_data; |
414 | s64 rc = OPAL_HARDWARE; | 403 | s64 rc = OPAL_HARDWARE; |
@@ -431,9 +420,17 @@ static int ioda_eeh_phb_reset(struct pci_controller *hose, int option) | |||
431 | 420 | ||
432 | /* | 421 | /* |
433 | * Poll state of the PHB until the request is done | 422 | * Poll state of the PHB until the request is done |
434 | * successfully. | 423 | * successfully. The PHB reset is usually PHB complete |
424 | * reset followed by hot reset on root bus. So we also | ||
425 | * need the PCI bus settlement delay. | ||
435 | */ | 426 | */ |
436 | rc = ioda_eeh_phb_poll(phb); | 427 | rc = ioda_eeh_phb_poll(phb); |
428 | if (option == EEH_RESET_DEACTIVATE) { | ||
429 | if (system_state < SYSTEM_RUNNING) | ||
430 | udelay(1000 * EEH_PE_RST_SETTLE_TIME); | ||
431 | else | ||
432 | msleep(EEH_PE_RST_SETTLE_TIME); | ||
433 | } | ||
437 | out: | 434 | out: |
438 | if (rc != OPAL_SUCCESS) | 435 | if (rc != OPAL_SUCCESS) |
439 | return -EIO; | 436 | return -EIO; |
@@ -471,6 +468,8 @@ static int ioda_eeh_root_reset(struct pci_controller *hose, int option) | |||
471 | 468 | ||
472 | /* Poll state of the PHB until the request is done */ | 469 | /* Poll state of the PHB until the request is done */ |
473 | rc = ioda_eeh_phb_poll(phb); | 470 | rc = ioda_eeh_phb_poll(phb); |
471 | if (option == EEH_RESET_DEACTIVATE) | ||
472 | msleep(EEH_PE_RST_SETTLE_TIME); | ||
474 | out: | 473 | out: |
475 | if (rc != OPAL_SUCCESS) | 474 | if (rc != OPAL_SUCCESS) |
476 | return -EIO; | 475 | return -EIO; |
@@ -478,32 +477,71 @@ out: | |||
478 | return 0; | 477 | return 0; |
479 | } | 478 | } |
480 | 479 | ||
481 | static int ioda_eeh_bridge_reset(struct pci_controller *hose, | 480 | static int ioda_eeh_bridge_reset(struct pci_dev *dev, int option) |
482 | struct pci_dev *dev, int option) | 481 | |
483 | { | 482 | { |
484 | u16 ctrl; | 483 | struct device_node *dn = pci_device_to_OF_node(dev); |
484 | struct eeh_dev *edev = of_node_to_eeh_dev(dn); | ||
485 | int aer = edev ? edev->aer_cap : 0; | ||
486 | u32 ctrl; | ||
485 | 487 | ||
486 | pr_debug("%s: Reset device %04x:%02x:%02x.%01x with option %d\n", | 488 | pr_debug("%s: Reset PCI bus %04x:%02x with option %d\n", |
487 | __func__, hose->global_number, dev->bus->number, | 489 | __func__, pci_domain_nr(dev->bus), |
488 | PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), option); | 490 | dev->bus->number, option); |
489 | 491 | ||
490 | switch (option) { | 492 | switch (option) { |
491 | case EEH_RESET_FUNDAMENTAL: | 493 | case EEH_RESET_FUNDAMENTAL: |
492 | case EEH_RESET_HOT: | 494 | case EEH_RESET_HOT: |
493 | pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &ctrl); | 495 | /* Don't report linkDown event */ |
496 | if (aer) { | ||
497 | eeh_ops->read_config(dn, aer + PCI_ERR_UNCOR_MASK, | ||
498 | 4, &ctrl); | ||
499 | ctrl |= PCI_ERR_UNC_SURPDN; | ||
500 | eeh_ops->write_config(dn, aer + PCI_ERR_UNCOR_MASK, | ||
501 | 4, ctrl); | ||
502 | } | ||
503 | |||
504 | eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &ctrl); | ||
494 | ctrl |= PCI_BRIDGE_CTL_BUS_RESET; | 505 | ctrl |= PCI_BRIDGE_CTL_BUS_RESET; |
495 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl); | 506 | eeh_ops->write_config(dn, PCI_BRIDGE_CONTROL, 2, ctrl); |
507 | msleep(EEH_PE_RST_HOLD_TIME); | ||
508 | |||
496 | break; | 509 | break; |
497 | case EEH_RESET_DEACTIVATE: | 510 | case EEH_RESET_DEACTIVATE: |
498 | pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &ctrl); | 511 | eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &ctrl); |
499 | ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET; | 512 | ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET; |
500 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl); | 513 | eeh_ops->write_config(dn, PCI_BRIDGE_CONTROL, 2, ctrl); |
514 | msleep(EEH_PE_RST_SETTLE_TIME); | ||
515 | |||
516 | /* Continue reporting linkDown event */ | ||
517 | if (aer) { | ||
518 | eeh_ops->read_config(dn, aer + PCI_ERR_UNCOR_MASK, | ||
519 | 4, &ctrl); | ||
520 | ctrl &= ~PCI_ERR_UNC_SURPDN; | ||
521 | eeh_ops->write_config(dn, aer + PCI_ERR_UNCOR_MASK, | ||
522 | 4, ctrl); | ||
523 | } | ||
524 | |||
501 | break; | 525 | break; |
502 | } | 526 | } |
503 | 527 | ||
504 | return 0; | 528 | return 0; |
505 | } | 529 | } |
506 | 530 | ||
531 | void pnv_pci_reset_secondary_bus(struct pci_dev *dev) | ||
532 | { | ||
533 | struct pci_controller *hose; | ||
534 | |||
535 | if (pci_is_root_bus(dev->bus)) { | ||
536 | hose = pci_bus_to_host(dev->bus); | ||
537 | ioda_eeh_root_reset(hose, EEH_RESET_HOT); | ||
538 | ioda_eeh_root_reset(hose, EEH_RESET_DEACTIVATE); | ||
539 | } else { | ||
540 | ioda_eeh_bridge_reset(dev, EEH_RESET_HOT); | ||
541 | ioda_eeh_bridge_reset(dev, EEH_RESET_DEACTIVATE); | ||
542 | } | ||
543 | } | ||
544 | |||
507 | /** | 545 | /** |
508 | * ioda_eeh_reset - Reset the indicated PE | 546 | * ioda_eeh_reset - Reset the indicated PE |
509 | * @pe: EEH PE | 547 | * @pe: EEH PE |
@@ -523,27 +561,18 @@ static int ioda_eeh_reset(struct eeh_pe *pe, int option) | |||
523 | int ret; | 561 | int ret; |
524 | 562 | ||
525 | /* | 563 | /* |
526 | * Anyway, we have to clear the problematic state for the | 564 | * For PHB reset, we always have complete reset. For those PEs whose |
527 | * corresponding PE. However, we needn't do it if the PE | 565 | * primary bus derived from root complex (root bus) or root port |
528 | * is PHB associated. That means the PHB is having fatal | 566 | * (usually bus#1), we apply hot or fundamental reset on the root port. |
529 | * errors and it needs reset. Further more, the AIB interface | 567 | * For other PEs, we always have hot reset on the PE primary bus. |
530 | * isn't reliable any more. | ||
531 | */ | ||
532 | if (!(pe->type & EEH_PE_PHB) && | ||
533 | (option == EEH_RESET_HOT || | ||
534 | option == EEH_RESET_FUNDAMENTAL)) { | ||
535 | ret = ioda_eeh_pe_clear(pe); | ||
536 | if (ret) | ||
537 | return -EIO; | ||
538 | } | ||
539 | |||
540 | /* | ||
541 | * The rules applied to reset, either fundamental or hot reset: | ||
542 | * | 568 | * |
543 | * We always reset the direct upstream bridge of the PE. If the | 569 | * Here, we have different design to pHyp, which always clear the |
544 | * direct upstream bridge isn't root bridge, we always take hot | 570 | * frozen state during PE reset. However, the good idea here from |
545 | * reset no matter what option (fundamental or hot) is. Otherwise, | 571 | * benh is to keep frozen state before we get PE reset done completely |
546 | * we should do the reset according to the required option. | 572 | * (until BAR restore). With the frozen state, HW drops illegal IO |
573 | * or MMIO access, which can incur recrusive frozen PE during PE | ||
574 | * reset. The side effect is that EEH core has to clear the frozen | ||
575 | * state explicitly after BAR restore. | ||
547 | */ | 576 | */ |
548 | if (pe->type & EEH_PE_PHB) { | 577 | if (pe->type & EEH_PE_PHB) { |
549 | ret = ioda_eeh_phb_reset(hose, option); | 578 | ret = ioda_eeh_phb_reset(hose, option); |
@@ -553,7 +582,7 @@ static int ioda_eeh_reset(struct eeh_pe *pe, int option) | |||
553 | pci_is_root_bus(bus->parent)) | 582 | pci_is_root_bus(bus->parent)) |
554 | ret = ioda_eeh_root_reset(hose, option); | 583 | ret = ioda_eeh_root_reset(hose, option); |
555 | else | 584 | else |
556 | ret = ioda_eeh_bridge_reset(hose, bus->self, option); | 585 | ret = ioda_eeh_bridge_reset(bus->self, option); |
557 | } | 586 | } |
558 | 587 | ||
559 | return ret; | 588 | return ret; |
@@ -640,22 +669,6 @@ static void ioda_eeh_hub_diag(struct pci_controller *hose) | |||
640 | } | 669 | } |
641 | } | 670 | } |
642 | 671 | ||
643 | static int ioda_eeh_get_phb_pe(struct pci_controller *hose, | ||
644 | struct eeh_pe **pe) | ||
645 | { | ||
646 | struct eeh_pe *phb_pe; | ||
647 | |||
648 | phb_pe = eeh_phb_pe_get(hose); | ||
649 | if (!phb_pe) { | ||
650 | pr_warning("%s Can't find PE for PHB#%d\n", | ||
651 | __func__, hose->global_number); | ||
652 | return -EEXIST; | ||
653 | } | ||
654 | |||
655 | *pe = phb_pe; | ||
656 | return 0; | ||
657 | } | ||
658 | |||
659 | static int ioda_eeh_get_pe(struct pci_controller *hose, | 672 | static int ioda_eeh_get_pe(struct pci_controller *hose, |
660 | u16 pe_no, struct eeh_pe **pe) | 673 | u16 pe_no, struct eeh_pe **pe) |
661 | { | 674 | { |
@@ -663,7 +676,8 @@ static int ioda_eeh_get_pe(struct pci_controller *hose, | |||
663 | struct eeh_dev dev; | 676 | struct eeh_dev dev; |
664 | 677 | ||
665 | /* Find the PHB PE */ | 678 | /* Find the PHB PE */ |
666 | if (ioda_eeh_get_phb_pe(hose, &phb_pe)) | 679 | phb_pe = eeh_phb_pe_get(hose); |
680 | if (!phb_pe) | ||
667 | return -EEXIST; | 681 | return -EEXIST; |
668 | 682 | ||
669 | /* Find the PE according to PE# */ | 683 | /* Find the PE according to PE# */ |
@@ -691,6 +705,7 @@ static int ioda_eeh_next_error(struct eeh_pe **pe) | |||
691 | { | 705 | { |
692 | struct pci_controller *hose; | 706 | struct pci_controller *hose; |
693 | struct pnv_phb *phb; | 707 | struct pnv_phb *phb; |
708 | struct eeh_pe *phb_pe; | ||
694 | u64 frozen_pe_no; | 709 | u64 frozen_pe_no; |
695 | u16 err_type, severity; | 710 | u16 err_type, severity; |
696 | long rc; | 711 | long rc; |
@@ -707,10 +722,12 @@ static int ioda_eeh_next_error(struct eeh_pe **pe) | |||
707 | list_for_each_entry(hose, &hose_list, list_node) { | 722 | list_for_each_entry(hose, &hose_list, list_node) { |
708 | /* | 723 | /* |
709 | * If the subordinate PCI buses of the PHB has been | 724 | * If the subordinate PCI buses of the PHB has been |
710 | * removed, we needn't take care of it any more. | 725 | * removed or is exactly under error recovery, we |
726 | * needn't take care of it any more. | ||
711 | */ | 727 | */ |
712 | phb = hose->private_data; | 728 | phb = hose->private_data; |
713 | if (phb->eeh_state & PNV_EEH_STATE_REMOVED) | 729 | phb_pe = eeh_phb_pe_get(hose); |
730 | if (!phb_pe || (phb_pe->state & EEH_PE_ISOLATED)) | ||
714 | continue; | 731 | continue; |
715 | 732 | ||
716 | rc = opal_pci_next_error(phb->opal_id, | 733 | rc = opal_pci_next_error(phb->opal_id, |
@@ -743,12 +760,6 @@ static int ioda_eeh_next_error(struct eeh_pe **pe) | |||
743 | switch (err_type) { | 760 | switch (err_type) { |
744 | case OPAL_EEH_IOC_ERROR: | 761 | case OPAL_EEH_IOC_ERROR: |
745 | if (severity == OPAL_EEH_SEV_IOC_DEAD) { | 762 | if (severity == OPAL_EEH_SEV_IOC_DEAD) { |
746 | list_for_each_entry(hose, &hose_list, | ||
747 | list_node) { | ||
748 | phb = hose->private_data; | ||
749 | phb->eeh_state |= PNV_EEH_STATE_REMOVED; | ||
750 | } | ||
751 | |||
752 | pr_err("EEH: dead IOC detected\n"); | 763 | pr_err("EEH: dead IOC detected\n"); |
753 | ret = EEH_NEXT_ERR_DEAD_IOC; | 764 | ret = EEH_NEXT_ERR_DEAD_IOC; |
754 | } else if (severity == OPAL_EEH_SEV_INF) { | 765 | } else if (severity == OPAL_EEH_SEV_INF) { |
@@ -761,17 +772,12 @@ static int ioda_eeh_next_error(struct eeh_pe **pe) | |||
761 | break; | 772 | break; |
762 | case OPAL_EEH_PHB_ERROR: | 773 | case OPAL_EEH_PHB_ERROR: |
763 | if (severity == OPAL_EEH_SEV_PHB_DEAD) { | 774 | if (severity == OPAL_EEH_SEV_PHB_DEAD) { |
764 | if (ioda_eeh_get_phb_pe(hose, pe)) | 775 | *pe = phb_pe; |
765 | break; | ||
766 | |||
767 | pr_err("EEH: dead PHB#%x detected\n", | 776 | pr_err("EEH: dead PHB#%x detected\n", |
768 | hose->global_number); | 777 | hose->global_number); |
769 | phb->eeh_state |= PNV_EEH_STATE_REMOVED; | ||
770 | ret = EEH_NEXT_ERR_DEAD_PHB; | 778 | ret = EEH_NEXT_ERR_DEAD_PHB; |
771 | } else if (severity == OPAL_EEH_SEV_PHB_FENCED) { | 779 | } else if (severity == OPAL_EEH_SEV_PHB_FENCED) { |
772 | if (ioda_eeh_get_phb_pe(hose, pe)) | 780 | *pe = phb_pe; |
773 | break; | ||
774 | |||
775 | pr_err("EEH: fenced PHB#%x detected\n", | 781 | pr_err("EEH: fenced PHB#%x detected\n", |
776 | hose->global_number); | 782 | hose->global_number); |
777 | ret = EEH_NEXT_ERR_FENCED_PHB; | 783 | ret = EEH_NEXT_ERR_FENCED_PHB; |
@@ -789,17 +795,21 @@ static int ioda_eeh_next_error(struct eeh_pe **pe) | |||
789 | * If we can't find the corresponding PE, the | 795 | * If we can't find the corresponding PE, the |
790 | * PEEV / PEST would be messy. So we force an | 796 | * PEEV / PEST would be messy. So we force an |
791 | * fenced PHB so that it can be recovered. | 797 | * fenced PHB so that it can be recovered. |
798 | * | ||
799 | * If the PE has been marked as isolated, that | ||
800 | * should have been removed permanently or in | ||
801 | * progress with recovery. We needn't report | ||
802 | * it again. | ||
792 | */ | 803 | */ |
793 | if (ioda_eeh_get_pe(hose, frozen_pe_no, pe)) { | 804 | if (ioda_eeh_get_pe(hose, frozen_pe_no, pe)) { |
794 | if (!ioda_eeh_get_phb_pe(hose, pe)) { | 805 | *pe = phb_pe; |
795 | pr_err("EEH: Escalated fenced PHB#%x " | 806 | pr_err("EEH: Escalated fenced PHB#%x " |
796 | "detected for PE#%llx\n", | 807 | "detected for PE#%llx\n", |
797 | hose->global_number, | 808 | hose->global_number, |
798 | frozen_pe_no); | 809 | frozen_pe_no); |
799 | ret = EEH_NEXT_ERR_FENCED_PHB; | 810 | ret = EEH_NEXT_ERR_FENCED_PHB; |
800 | } else { | 811 | } else if ((*pe)->state & EEH_PE_ISOLATED) { |
801 | ret = EEH_NEXT_ERR_NONE; | 812 | ret = EEH_NEXT_ERR_NONE; |
802 | } | ||
803 | } else { | 813 | } else { |
804 | pr_err("EEH: Frozen PE#%x on PHB#%x detected\n", | 814 | pr_err("EEH: Frozen PE#%x on PHB#%x detected\n", |
805 | (*pe)->addr, (*pe)->phb->global_number); | 815 | (*pe)->addr, (*pe)->phb->global_number); |
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index a59788e83b8b..56a206f32f77 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c | |||
@@ -126,6 +126,7 @@ static int powernv_eeh_dev_probe(struct pci_dev *dev, void *flag) | |||
126 | edev->mode &= 0xFFFFFF00; | 126 | edev->mode &= 0xFFFFFF00; |
127 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) | 127 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) |
128 | edev->mode |= EEH_DEV_BRIDGE; | 128 | edev->mode |= EEH_DEV_BRIDGE; |
129 | edev->pcix_cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); | ||
129 | if (pci_is_pcie(dev)) { | 130 | if (pci_is_pcie(dev)) { |
130 | edev->pcie_cap = pci_pcie_cap(dev); | 131 | edev->pcie_cap = pci_pcie_cap(dev); |
131 | 132 | ||
@@ -133,6 +134,9 @@ static int powernv_eeh_dev_probe(struct pci_dev *dev, void *flag) | |||
133 | edev->mode |= EEH_DEV_ROOT_PORT; | 134 | edev->mode |= EEH_DEV_ROOT_PORT; |
134 | else if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) | 135 | else if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) |
135 | edev->mode |= EEH_DEV_DS_PORT; | 136 | edev->mode |= EEH_DEV_DS_PORT; |
137 | |||
138 | edev->aer_cap = pci_find_ext_capability(dev, | ||
139 | PCI_EXT_CAP_ID_ERR); | ||
136 | } | 140 | } |
137 | 141 | ||
138 | edev->config_addr = ((dev->bus->number << 8) | dev->devfn); | 142 | edev->config_addr = ((dev->bus->number << 8) | dev->devfn); |
diff --git a/arch/powerpc/platforms/powernv/opal-flash.c b/arch/powerpc/platforms/powernv/opal-flash.c index dc487ff04704..5c21d9c07f45 100644 --- a/arch/powerpc/platforms/powernv/opal-flash.c +++ b/arch/powerpc/platforms/powernv/opal-flash.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
21 | #include <linux/vmalloc.h> | 21 | #include <linux/vmalloc.h> |
22 | #include <linux/pagemap.h> | 22 | #include <linux/pagemap.h> |
23 | #include <linux/delay.h> | ||
23 | 24 | ||
24 | #include <asm/opal.h> | 25 | #include <asm/opal.h> |
25 | 26 | ||
@@ -130,7 +131,8 @@ static inline void opal_flash_validate(void) | |||
130 | { | 131 | { |
131 | long ret; | 132 | long ret; |
132 | void *buf = validate_flash_data.buf; | 133 | void *buf = validate_flash_data.buf; |
133 | __be32 size, result; | 134 | __be32 size = cpu_to_be32(validate_flash_data.buf_size); |
135 | __be32 result; | ||
134 | 136 | ||
135 | ret = opal_validate_flash(__pa(buf), &size, &result); | 137 | ret = opal_validate_flash(__pa(buf), &size, &result); |
136 | 138 | ||
@@ -290,11 +292,6 @@ static int opal_flash_update(int op) | |||
290 | /* First entry address */ | 292 | /* First entry address */ |
291 | addr = __pa(list); | 293 | addr = __pa(list); |
292 | 294 | ||
293 | pr_alert("FLASH: Image is %u bytes\n", image_data.size); | ||
294 | pr_alert("FLASH: Image update requested\n"); | ||
295 | pr_alert("FLASH: Image will be updated during system reboot\n"); | ||
296 | pr_alert("FLASH: This will take several minutes. Do not power off!\n"); | ||
297 | |||
298 | flash: | 295 | flash: |
299 | rc = opal_update_flash(addr); | 296 | rc = opal_update_flash(addr); |
300 | 297 | ||
@@ -302,6 +299,47 @@ invalid_img: | |||
302 | return rc; | 299 | return rc; |
303 | } | 300 | } |
304 | 301 | ||
302 | /* Return CPUs to OPAL before starting FW update */ | ||
303 | static void flash_return_cpu(void *info) | ||
304 | { | ||
305 | int cpu = smp_processor_id(); | ||
306 | |||
307 | if (!cpu_online(cpu)) | ||
308 | return; | ||
309 | |||
310 | /* Disable IRQ */ | ||
311 | hard_irq_disable(); | ||
312 | |||
313 | /* Return the CPU to OPAL */ | ||
314 | opal_return_cpu(); | ||
315 | } | ||
316 | |||
317 | /* This gets called just before system reboots */ | ||
318 | void opal_flash_term_callback(void) | ||
319 | { | ||
320 | struct cpumask mask; | ||
321 | |||
322 | if (update_flash_data.status != FLASH_IMG_READY) | ||
323 | return; | ||
324 | |||
325 | pr_alert("FLASH: Flashing new firmware\n"); | ||
326 | pr_alert("FLASH: Image is %u bytes\n", image_data.size); | ||
327 | pr_alert("FLASH: Performing flash and reboot/shutdown\n"); | ||
328 | pr_alert("FLASH: This will take several minutes. Do not power off!\n"); | ||
329 | |||
330 | /* Small delay to help getting the above message out */ | ||
331 | msleep(500); | ||
332 | |||
333 | /* Return secondary CPUs to firmware */ | ||
334 | cpumask_copy(&mask, cpu_online_mask); | ||
335 | cpumask_clear_cpu(smp_processor_id(), &mask); | ||
336 | if (!cpumask_empty(&mask)) | ||
337 | smp_call_function_many(&mask, | ||
338 | flash_return_cpu, NULL, false); | ||
339 | /* Hard disable interrupts */ | ||
340 | hard_irq_disable(); | ||
341 | } | ||
342 | |||
305 | /* | 343 | /* |
306 | * Show candidate image status | 344 | * Show candidate image status |
307 | */ | 345 | */ |
diff --git a/arch/powerpc/platforms/powernv/opal-lpc.c b/arch/powerpc/platforms/powernv/opal-lpc.c index 79d83cad3d67..f04b4d8aca5a 100644 --- a/arch/powerpc/platforms/powernv/opal-lpc.c +++ b/arch/powerpc/platforms/powernv/opal-lpc.c | |||
@@ -12,12 +12,17 @@ | |||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/of.h> | 13 | #include <linux/of.h> |
14 | #include <linux/bug.h> | 14 | #include <linux/bug.h> |
15 | #include <linux/debugfs.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/slab.h> | ||
15 | 18 | ||
16 | #include <asm/machdep.h> | 19 | #include <asm/machdep.h> |
17 | #include <asm/firmware.h> | 20 | #include <asm/firmware.h> |
18 | #include <asm/xics.h> | 21 | #include <asm/xics.h> |
19 | #include <asm/opal.h> | 22 | #include <asm/opal.h> |
20 | #include <asm/prom.h> | 23 | #include <asm/prom.h> |
24 | #include <asm/uaccess.h> | ||
25 | #include <asm/debug.h> | ||
21 | 26 | ||
22 | static int opal_lpc_chip_id = -1; | 27 | static int opal_lpc_chip_id = -1; |
23 | 28 | ||
@@ -176,6 +181,152 @@ static const struct ppc_pci_io opal_lpc_io = { | |||
176 | .outsl = opal_lpc_outsl, | 181 | .outsl = opal_lpc_outsl, |
177 | }; | 182 | }; |
178 | 183 | ||
184 | #ifdef CONFIG_DEBUG_FS | ||
185 | struct lpc_debugfs_entry { | ||
186 | enum OpalLPCAddressType lpc_type; | ||
187 | }; | ||
188 | |||
189 | static ssize_t lpc_debug_read(struct file *filp, char __user *ubuf, | ||
190 | size_t count, loff_t *ppos) | ||
191 | { | ||
192 | struct lpc_debugfs_entry *lpc = filp->private_data; | ||
193 | u32 data, pos, len, todo; | ||
194 | int rc; | ||
195 | |||
196 | if (!access_ok(VERIFY_WRITE, ubuf, count)) | ||
197 | return -EFAULT; | ||
198 | |||
199 | todo = count; | ||
200 | while (todo) { | ||
201 | pos = *ppos; | ||
202 | |||
203 | /* | ||
204 | * Select access size based on count and alignment and | ||
205 | * access type. IO and MEM only support byte acceses, | ||
206 | * FW supports all 3. | ||
207 | */ | ||
208 | len = 1; | ||
209 | if (lpc->lpc_type == OPAL_LPC_FW) { | ||
210 | if (todo > 3 && (pos & 3) == 0) | ||
211 | len = 4; | ||
212 | else if (todo > 1 && (pos & 1) == 0) | ||
213 | len = 2; | ||
214 | } | ||
215 | rc = opal_lpc_read(opal_lpc_chip_id, lpc->lpc_type, pos, | ||
216 | &data, len); | ||
217 | if (rc) | ||
218 | return -ENXIO; | ||
219 | switch(len) { | ||
220 | case 4: | ||
221 | rc = __put_user((u32)data, (u32 __user *)ubuf); | ||
222 | break; | ||
223 | case 2: | ||
224 | rc = __put_user((u16)data, (u16 __user *)ubuf); | ||
225 | break; | ||
226 | default: | ||
227 | rc = __put_user((u8)data, (u8 __user *)ubuf); | ||
228 | break; | ||
229 | } | ||
230 | if (rc) | ||
231 | return -EFAULT; | ||
232 | *ppos += len; | ||
233 | ubuf += len; | ||
234 | todo -= len; | ||
235 | } | ||
236 | |||
237 | return count; | ||
238 | } | ||
239 | |||
240 | static ssize_t lpc_debug_write(struct file *filp, const char __user *ubuf, | ||
241 | size_t count, loff_t *ppos) | ||
242 | { | ||
243 | struct lpc_debugfs_entry *lpc = filp->private_data; | ||
244 | u32 data, pos, len, todo; | ||
245 | int rc; | ||
246 | |||
247 | if (!access_ok(VERIFY_READ, ubuf, count)) | ||
248 | return -EFAULT; | ||
249 | |||
250 | todo = count; | ||
251 | while (todo) { | ||
252 | pos = *ppos; | ||
253 | |||
254 | /* | ||
255 | * Select access size based on count and alignment and | ||
256 | * access type. IO and MEM only support byte acceses, | ||
257 | * FW supports all 3. | ||
258 | */ | ||
259 | len = 1; | ||
260 | if (lpc->lpc_type == OPAL_LPC_FW) { | ||
261 | if (todo > 3 && (pos & 3) == 0) | ||
262 | len = 4; | ||
263 | else if (todo > 1 && (pos & 1) == 0) | ||
264 | len = 2; | ||
265 | } | ||
266 | switch(len) { | ||
267 | case 4: | ||
268 | rc = __get_user(data, (u32 __user *)ubuf); | ||
269 | break; | ||
270 | case 2: | ||
271 | rc = __get_user(data, (u16 __user *)ubuf); | ||
272 | break; | ||
273 | default: | ||
274 | rc = __get_user(data, (u8 __user *)ubuf); | ||
275 | break; | ||
276 | } | ||
277 | if (rc) | ||
278 | return -EFAULT; | ||
279 | |||
280 | rc = opal_lpc_write(opal_lpc_chip_id, lpc->lpc_type, pos, | ||
281 | data, len); | ||
282 | if (rc) | ||
283 | return -ENXIO; | ||
284 | *ppos += len; | ||
285 | ubuf += len; | ||
286 | todo -= len; | ||
287 | } | ||
288 | |||
289 | return count; | ||
290 | } | ||
291 | |||
292 | static const struct file_operations lpc_fops = { | ||
293 | .read = lpc_debug_read, | ||
294 | .write = lpc_debug_write, | ||
295 | .open = simple_open, | ||
296 | .llseek = default_llseek, | ||
297 | }; | ||
298 | |||
299 | static int opal_lpc_debugfs_create_type(struct dentry *folder, | ||
300 | const char *fname, | ||
301 | enum OpalLPCAddressType type) | ||
302 | { | ||
303 | struct lpc_debugfs_entry *entry; | ||
304 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); | ||
305 | if (!entry) | ||
306 | return -ENOMEM; | ||
307 | entry->lpc_type = type; | ||
308 | debugfs_create_file(fname, 0600, folder, entry, &lpc_fops); | ||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static int opal_lpc_init_debugfs(void) | ||
313 | { | ||
314 | struct dentry *root; | ||
315 | int rc = 0; | ||
316 | |||
317 | if (opal_lpc_chip_id < 0) | ||
318 | return -ENODEV; | ||
319 | |||
320 | root = debugfs_create_dir("lpc", powerpc_debugfs_root); | ||
321 | |||
322 | rc |= opal_lpc_debugfs_create_type(root, "io", OPAL_LPC_IO); | ||
323 | rc |= opal_lpc_debugfs_create_type(root, "mem", OPAL_LPC_MEM); | ||
324 | rc |= opal_lpc_debugfs_create_type(root, "fw", OPAL_LPC_FW); | ||
325 | return rc; | ||
326 | } | ||
327 | device_initcall(opal_lpc_init_debugfs); | ||
328 | #endif /* CONFIG_DEBUG_FS */ | ||
329 | |||
179 | void opal_lpc_init(void) | 330 | void opal_lpc_init(void) |
180 | { | 331 | { |
181 | struct device_node *np; | 332 | struct device_node *np; |
diff --git a/arch/powerpc/platforms/powernv/opal-memory-errors.c b/arch/powerpc/platforms/powernv/opal-memory-errors.c index ec4132239cdf..b17a34b695ef 100644 --- a/arch/powerpc/platforms/powernv/opal-memory-errors.c +++ b/arch/powerpc/platforms/powernv/opal-memory-errors.c | |||
@@ -47,12 +47,12 @@ static void handle_memory_error_event(struct OpalMemoryErrorData *merr_evt) | |||
47 | __func__, merr_evt->type); | 47 | __func__, merr_evt->type); |
48 | switch (merr_evt->type) { | 48 | switch (merr_evt->type) { |
49 | case OPAL_MEM_ERR_TYPE_RESILIENCE: | 49 | case OPAL_MEM_ERR_TYPE_RESILIENCE: |
50 | paddr_start = merr_evt->u.resilience.physical_address_start; | 50 | paddr_start = be64_to_cpu(merr_evt->u.resilience.physical_address_start); |
51 | paddr_end = merr_evt->u.resilience.physical_address_end; | 51 | paddr_end = be64_to_cpu(merr_evt->u.resilience.physical_address_end); |
52 | break; | 52 | break; |
53 | case OPAL_MEM_ERR_TYPE_DYN_DALLOC: | 53 | case OPAL_MEM_ERR_TYPE_DYN_DALLOC: |
54 | paddr_start = merr_evt->u.dyn_dealloc.physical_address_start; | 54 | paddr_start = be64_to_cpu(merr_evt->u.dyn_dealloc.physical_address_start); |
55 | paddr_end = merr_evt->u.dyn_dealloc.physical_address_end; | 55 | paddr_end = be64_to_cpu(merr_evt->u.dyn_dealloc.physical_address_end); |
56 | break; | 56 | break; |
57 | default: | 57 | default: |
58 | return; | 58 | return; |
diff --git a/arch/powerpc/platforms/powernv/opal-takeover.S b/arch/powerpc/platforms/powernv/opal-takeover.S index 3cd262897c27..11a3169ee583 100644 --- a/arch/powerpc/platforms/powernv/opal-takeover.S +++ b/arch/powerpc/platforms/powernv/opal-takeover.S | |||
@@ -21,11 +21,13 @@ | |||
21 | _GLOBAL(opal_query_takeover) | 21 | _GLOBAL(opal_query_takeover) |
22 | mfcr r0 | 22 | mfcr r0 |
23 | stw r0,8(r1) | 23 | stw r0,8(r1) |
24 | stdu r1,-STACKFRAMESIZE(r1) | ||
24 | std r3,STK_PARAM(R3)(r1) | 25 | std r3,STK_PARAM(R3)(r1) |
25 | std r4,STK_PARAM(R4)(r1) | 26 | std r4,STK_PARAM(R4)(r1) |
26 | li r3,H_HAL_TAKEOVER | 27 | li r3,H_HAL_TAKEOVER |
27 | li r4,H_HAL_TAKEOVER_QUERY_MAGIC | 28 | li r4,H_HAL_TAKEOVER_QUERY_MAGIC |
28 | HVSC | 29 | HVSC |
30 | addi r1,r1,STACKFRAMESIZE | ||
29 | ld r10,STK_PARAM(R3)(r1) | 31 | ld r10,STK_PARAM(R3)(r1) |
30 | std r4,0(r10) | 32 | std r4,0(r10) |
31 | ld r10,STK_PARAM(R4)(r1) | 33 | ld r10,STK_PARAM(R4)(r1) |
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index f531ffe35b3e..4abbff22a61f 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S | |||
@@ -32,7 +32,7 @@ | |||
32 | std r12,PACASAVEDMSR(r13); \ | 32 | std r12,PACASAVEDMSR(r13); \ |
33 | andc r12,r12,r0; \ | 33 | andc r12,r12,r0; \ |
34 | mtmsrd r12,1; \ | 34 | mtmsrd r12,1; \ |
35 | LOAD_REG_ADDR(r0,.opal_return); \ | 35 | LOAD_REG_ADDR(r0,opal_return); \ |
36 | mtlr r0; \ | 36 | mtlr r0; \ |
37 | li r0,MSR_DR|MSR_IR|MSR_LE;\ | 37 | li r0,MSR_DR|MSR_IR|MSR_LE;\ |
38 | andc r12,r12,r0; \ | 38 | andc r12,r12,r0; \ |
@@ -44,7 +44,7 @@ | |||
44 | mtspr SPRN_HSRR0,r12; \ | 44 | mtspr SPRN_HSRR0,r12; \ |
45 | hrfid | 45 | hrfid |
46 | 46 | ||
47 | _STATIC(opal_return) | 47 | opal_return: |
48 | /* | 48 | /* |
49 | * Fixup endian on OPAL return... we should be able to simplify | 49 | * Fixup endian on OPAL return... we should be able to simplify |
50 | * this by instead converting the below trampoline to a set of | 50 | * this by instead converting the below trampoline to a set of |
@@ -124,6 +124,7 @@ OPAL_CALL(opal_xscom_write, OPAL_XSCOM_WRITE); | |||
124 | OPAL_CALL(opal_lpc_read, OPAL_LPC_READ); | 124 | OPAL_CALL(opal_lpc_read, OPAL_LPC_READ); |
125 | OPAL_CALL(opal_lpc_write, OPAL_LPC_WRITE); | 125 | OPAL_CALL(opal_lpc_write, OPAL_LPC_WRITE); |
126 | OPAL_CALL(opal_return_cpu, OPAL_RETURN_CPU); | 126 | OPAL_CALL(opal_return_cpu, OPAL_RETURN_CPU); |
127 | OPAL_CALL(opal_reinit_cpus, OPAL_REINIT_CPUS); | ||
127 | OPAL_CALL(opal_read_elog, OPAL_ELOG_READ); | 128 | OPAL_CALL(opal_read_elog, OPAL_ELOG_READ); |
128 | OPAL_CALL(opal_send_ack_elog, OPAL_ELOG_ACK); | 129 | OPAL_CALL(opal_send_ack_elog, OPAL_ELOG_ACK); |
129 | OPAL_CALL(opal_get_elog_size, OPAL_ELOG_SIZE); | 130 | OPAL_CALL(opal_get_elog_size, OPAL_ELOG_SIZE); |
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index f343183add07..199975613fe9 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c | |||
@@ -57,6 +57,21 @@ static DEFINE_SPINLOCK(opal_notifier_lock); | |||
57 | static uint64_t last_notified_mask = 0x0ul; | 57 | static uint64_t last_notified_mask = 0x0ul; |
58 | static atomic_t opal_notifier_hold = ATOMIC_INIT(0); | 58 | static atomic_t opal_notifier_hold = ATOMIC_INIT(0); |
59 | 59 | ||
60 | static void opal_reinit_cores(void) | ||
61 | { | ||
62 | /* Do the actual re-init, This will clobber all FPRs, VRs, etc... | ||
63 | * | ||
64 | * It will preserve non volatile GPRs and HSPRG0/1. It will | ||
65 | * also restore HIDs and other SPRs to their original value | ||
66 | * but it might clobber a bunch. | ||
67 | */ | ||
68 | #ifdef __BIG_ENDIAN__ | ||
69 | opal_reinit_cpus(OPAL_REINIT_CPUS_HILE_BE); | ||
70 | #else | ||
71 | opal_reinit_cpus(OPAL_REINIT_CPUS_HILE_LE); | ||
72 | #endif | ||
73 | } | ||
74 | |||
60 | int __init early_init_dt_scan_opal(unsigned long node, | 75 | int __init early_init_dt_scan_opal(unsigned long node, |
61 | const char *uname, int depth, void *data) | 76 | const char *uname, int depth, void *data) |
62 | { | 77 | { |
@@ -96,6 +111,13 @@ int __init early_init_dt_scan_opal(unsigned long node, | |||
96 | printk("OPAL V1 detected !\n"); | 111 | printk("OPAL V1 detected !\n"); |
97 | } | 112 | } |
98 | 113 | ||
114 | /* Reinit all cores with the right endian */ | ||
115 | opal_reinit_cores(); | ||
116 | |||
117 | /* Restore some bits */ | ||
118 | if (cur_cpu_spec->cpu_restore) | ||
119 | cur_cpu_spec->cpu_restore(); | ||
120 | |||
99 | return 1; | 121 | return 1; |
100 | } | 122 | } |
101 | 123 | ||
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 98824aa99173..de19edeaa7a7 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
16 | #include <linux/crash_dump.h> | ||
16 | #include <linux/debugfs.h> | 17 | #include <linux/debugfs.h> |
17 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
18 | #include <linux/string.h> | 19 | #include <linux/string.h> |
@@ -663,15 +664,15 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb, | |||
663 | * errors, and on the first pass the data will be a relative | 664 | * errors, and on the first pass the data will be a relative |
664 | * bus number, print that out instead. | 665 | * bus number, print that out instead. |
665 | */ | 666 | */ |
666 | tbl->it_busno = 0; | ||
667 | pe->tce_inval_reg_phys = be64_to_cpup(swinvp); | 667 | pe->tce_inval_reg_phys = be64_to_cpup(swinvp); |
668 | tbl->it_index = (unsigned long)ioremap(pe->tce_inval_reg_phys, | 668 | tbl->it_index = (unsigned long)ioremap(pe->tce_inval_reg_phys, |
669 | 8); | 669 | 8); |
670 | tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE | | 670 | tbl->it_type |= (TCE_PCI_SWINV_CREATE | |
671 | TCE_PCI_SWINV_PAIR; | 671 | TCE_PCI_SWINV_FREE | |
672 | TCE_PCI_SWINV_PAIR); | ||
672 | } | 673 | } |
673 | iommu_init_table(tbl, phb->hose->node); | 674 | iommu_init_table(tbl, phb->hose->node); |
674 | iommu_register_group(tbl, pci_domain_nr(pe->pbus), pe->pe_number); | 675 | iommu_register_group(tbl, phb->hose->global_number, pe->pe_number); |
675 | 676 | ||
676 | if (pe->pdev) | 677 | if (pe->pdev) |
677 | set_iommu_table_base_and_group(&pe->pdev->dev, tbl); | 678 | set_iommu_table_base_and_group(&pe->pdev->dev, tbl); |
@@ -793,14 +794,13 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb, | |||
793 | * errors, and on the first pass the data will be a relative | 794 | * errors, and on the first pass the data will be a relative |
794 | * bus number, print that out instead. | 795 | * bus number, print that out instead. |
795 | */ | 796 | */ |
796 | tbl->it_busno = 0; | ||
797 | pe->tce_inval_reg_phys = be64_to_cpup(swinvp); | 797 | pe->tce_inval_reg_phys = be64_to_cpup(swinvp); |
798 | tbl->it_index = (unsigned long)ioremap(pe->tce_inval_reg_phys, | 798 | tbl->it_index = (unsigned long)ioremap(pe->tce_inval_reg_phys, |
799 | 8); | 799 | 8); |
800 | tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE; | 800 | tbl->it_type |= (TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE); |
801 | } | 801 | } |
802 | iommu_init_table(tbl, phb->hose->node); | 802 | iommu_init_table(tbl, phb->hose->node); |
803 | iommu_register_group(tbl, pci_domain_nr(pe->pbus), pe->pe_number); | 803 | iommu_register_group(tbl, phb->hose->global_number, pe->pe_number); |
804 | 804 | ||
805 | if (pe->pdev) | 805 | if (pe->pdev) |
806 | set_iommu_table_base_and_group(&pe->pdev->dev, tbl); | 806 | set_iommu_table_base_and_group(&pe->pdev->dev, tbl); |
@@ -1386,12 +1386,24 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np, | |||
1386 | ppc_md.pcibios_fixup = pnv_pci_ioda_fixup; | 1386 | ppc_md.pcibios_fixup = pnv_pci_ioda_fixup; |
1387 | ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook; | 1387 | ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook; |
1388 | ppc_md.pcibios_window_alignment = pnv_pci_window_alignment; | 1388 | ppc_md.pcibios_window_alignment = pnv_pci_window_alignment; |
1389 | ppc_md.pcibios_reset_secondary_bus = pnv_pci_reset_secondary_bus; | ||
1389 | pci_add_flags(PCI_REASSIGN_ALL_RSRC); | 1390 | pci_add_flags(PCI_REASSIGN_ALL_RSRC); |
1390 | 1391 | ||
1391 | /* Reset IODA tables to a clean state */ | 1392 | /* Reset IODA tables to a clean state */ |
1392 | rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET); | 1393 | rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET); |
1393 | if (rc) | 1394 | if (rc) |
1394 | pr_warning(" OPAL Error %ld performing IODA table reset !\n", rc); | 1395 | pr_warning(" OPAL Error %ld performing IODA table reset !\n", rc); |
1396 | |||
1397 | /* If we're running in kdump kerenl, the previous kerenl never | ||
1398 | * shutdown PCI devices correctly. We already got IODA table | ||
1399 | * cleaned out. So we have to issue PHB reset to stop all PCI | ||
1400 | * transactions from previous kerenl. | ||
1401 | */ | ||
1402 | if (is_kdump_kernel()) { | ||
1403 | pr_info(" Issue PHB reset ...\n"); | ||
1404 | ioda_eeh_phb_reset(hose, EEH_RESET_FUNDAMENTAL); | ||
1405 | ioda_eeh_phb_reset(hose, OPAL_DEASSERT_RESET); | ||
1406 | } | ||
1395 | } | 1407 | } |
1396 | 1408 | ||
1397 | void __init pnv_pci_init_ioda2_phb(struct device_node *np) | 1409 | void __init pnv_pci_init_ioda2_phb(struct device_node *np) |
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 8518817dcdfd..eefbfcc3fd8c 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
@@ -131,65 +131,60 @@ static void pnv_pci_dump_p7ioc_diag_data(struct pci_controller *hose, | |||
131 | int i; | 131 | int i; |
132 | 132 | ||
133 | data = (struct OpalIoP7IOCPhbErrorData *)common; | 133 | data = (struct OpalIoP7IOCPhbErrorData *)common; |
134 | pr_info("P7IOC PHB#%d Diag-data (Version: %d)\n\n", | 134 | pr_info("P7IOC PHB#%d Diag-data (Version: %d)\n", |
135 | hose->global_number, common->version); | 135 | hose->global_number, common->version); |
136 | 136 | ||
137 | if (data->brdgCtl) | 137 | if (data->brdgCtl) |
138 | pr_info(" brdgCtl: %08x\n", | 138 | pr_info("brdgCtl: %08x\n", |
139 | data->brdgCtl); | 139 | data->brdgCtl); |
140 | if (data->portStatusReg || data->rootCmplxStatus || | 140 | if (data->portStatusReg || data->rootCmplxStatus || |
141 | data->busAgentStatus) | 141 | data->busAgentStatus) |
142 | pr_info(" UtlSts: %08x %08x %08x\n", | 142 | pr_info("UtlSts: %08x %08x %08x\n", |
143 | data->portStatusReg, data->rootCmplxStatus, | 143 | data->portStatusReg, data->rootCmplxStatus, |
144 | data->busAgentStatus); | 144 | data->busAgentStatus); |
145 | if (data->deviceStatus || data->slotStatus || | 145 | if (data->deviceStatus || data->slotStatus || |
146 | data->linkStatus || data->devCmdStatus || | 146 | data->linkStatus || data->devCmdStatus || |
147 | data->devSecStatus) | 147 | data->devSecStatus) |
148 | pr_info(" RootSts: %08x %08x %08x %08x %08x\n", | 148 | pr_info("RootSts: %08x %08x %08x %08x %08x\n", |
149 | data->deviceStatus, data->slotStatus, | 149 | data->deviceStatus, data->slotStatus, |
150 | data->linkStatus, data->devCmdStatus, | 150 | data->linkStatus, data->devCmdStatus, |
151 | data->devSecStatus); | 151 | data->devSecStatus); |
152 | if (data->rootErrorStatus || data->uncorrErrorStatus || | 152 | if (data->rootErrorStatus || data->uncorrErrorStatus || |
153 | data->corrErrorStatus) | 153 | data->corrErrorStatus) |
154 | pr_info(" RootErrSts: %08x %08x %08x\n", | 154 | pr_info("RootErrSts: %08x %08x %08x\n", |
155 | data->rootErrorStatus, data->uncorrErrorStatus, | 155 | data->rootErrorStatus, data->uncorrErrorStatus, |
156 | data->corrErrorStatus); | 156 | data->corrErrorStatus); |
157 | if (data->tlpHdr1 || data->tlpHdr2 || | 157 | if (data->tlpHdr1 || data->tlpHdr2 || |
158 | data->tlpHdr3 || data->tlpHdr4) | 158 | data->tlpHdr3 || data->tlpHdr4) |
159 | pr_info(" RootErrLog: %08x %08x %08x %08x\n", | 159 | pr_info("RootErrLog: %08x %08x %08x %08x\n", |
160 | data->tlpHdr1, data->tlpHdr2, | 160 | data->tlpHdr1, data->tlpHdr2, |
161 | data->tlpHdr3, data->tlpHdr4); | 161 | data->tlpHdr3, data->tlpHdr4); |
162 | if (data->sourceId || data->errorClass || | 162 | if (data->sourceId || data->errorClass || |
163 | data->correlator) | 163 | data->correlator) |
164 | pr_info(" RootErrLog1: %08x %016llx %016llx\n", | 164 | pr_info("RootErrLog1: %08x %016llx %016llx\n", |
165 | data->sourceId, data->errorClass, | 165 | data->sourceId, data->errorClass, |
166 | data->correlator); | 166 | data->correlator); |
167 | if (data->p7iocPlssr || data->p7iocCsr) | 167 | if (data->p7iocPlssr || data->p7iocCsr) |
168 | pr_info(" PhbSts: %016llx %016llx\n", | 168 | pr_info("PhbSts: %016llx %016llx\n", |
169 | data->p7iocPlssr, data->p7iocCsr); | 169 | data->p7iocPlssr, data->p7iocCsr); |
170 | if (data->lemFir || data->lemErrorMask || | 170 | if (data->lemFir) |
171 | data->lemWOF) | 171 | pr_info("Lem: %016llx %016llx %016llx\n", |
172 | pr_info(" Lem: %016llx %016llx %016llx\n", | ||
173 | data->lemFir, data->lemErrorMask, | 172 | data->lemFir, data->lemErrorMask, |
174 | data->lemWOF); | 173 | data->lemWOF); |
175 | if (data->phbErrorStatus || data->phbFirstErrorStatus || | 174 | if (data->phbErrorStatus) |
176 | data->phbErrorLog0 || data->phbErrorLog1) | 175 | pr_info("PhbErr: %016llx %016llx %016llx %016llx\n", |
177 | pr_info(" PhbErr: %016llx %016llx %016llx %016llx\n", | ||
178 | data->phbErrorStatus, data->phbFirstErrorStatus, | 176 | data->phbErrorStatus, data->phbFirstErrorStatus, |
179 | data->phbErrorLog0, data->phbErrorLog1); | 177 | data->phbErrorLog0, data->phbErrorLog1); |
180 | if (data->mmioErrorStatus || data->mmioFirstErrorStatus || | 178 | if (data->mmioErrorStatus) |
181 | data->mmioErrorLog0 || data->mmioErrorLog1) | 179 | pr_info("OutErr: %016llx %016llx %016llx %016llx\n", |
182 | pr_info(" OutErr: %016llx %016llx %016llx %016llx\n", | ||
183 | data->mmioErrorStatus, data->mmioFirstErrorStatus, | 180 | data->mmioErrorStatus, data->mmioFirstErrorStatus, |
184 | data->mmioErrorLog0, data->mmioErrorLog1); | 181 | data->mmioErrorLog0, data->mmioErrorLog1); |
185 | if (data->dma0ErrorStatus || data->dma0FirstErrorStatus || | 182 | if (data->dma0ErrorStatus) |
186 | data->dma0ErrorLog0 || data->dma0ErrorLog1) | 183 | pr_info("InAErr: %016llx %016llx %016llx %016llx\n", |
187 | pr_info(" InAErr: %016llx %016llx %016llx %016llx\n", | ||
188 | data->dma0ErrorStatus, data->dma0FirstErrorStatus, | 184 | data->dma0ErrorStatus, data->dma0FirstErrorStatus, |
189 | data->dma0ErrorLog0, data->dma0ErrorLog1); | 185 | data->dma0ErrorLog0, data->dma0ErrorLog1); |
190 | if (data->dma1ErrorStatus || data->dma1FirstErrorStatus || | 186 | if (data->dma1ErrorStatus) |
191 | data->dma1ErrorLog0 || data->dma1ErrorLog1) | 187 | pr_info("InBErr: %016llx %016llx %016llx %016llx\n", |
192 | pr_info(" InBErr: %016llx %016llx %016llx %016llx\n", | ||
193 | data->dma1ErrorStatus, data->dma1FirstErrorStatus, | 188 | data->dma1ErrorStatus, data->dma1FirstErrorStatus, |
194 | data->dma1ErrorLog0, data->dma1ErrorLog1); | 189 | data->dma1ErrorLog0, data->dma1ErrorLog1); |
195 | 190 | ||
@@ -198,7 +193,7 @@ static void pnv_pci_dump_p7ioc_diag_data(struct pci_controller *hose, | |||
198 | (data->pestB[i] >> 63) == 0) | 193 | (data->pestB[i] >> 63) == 0) |
199 | continue; | 194 | continue; |
200 | 195 | ||
201 | pr_info(" PE[%3d] A/B: %016llx %016llx\n", | 196 | pr_info("PE[%3d] A/B: %016llx %016llx\n", |
202 | i, data->pestA[i], data->pestB[i]); | 197 | i, data->pestA[i], data->pestB[i]); |
203 | } | 198 | } |
204 | } | 199 | } |
@@ -210,69 +205,63 @@ static void pnv_pci_dump_phb3_diag_data(struct pci_controller *hose, | |||
210 | int i; | 205 | int i; |
211 | 206 | ||
212 | data = (struct OpalIoPhb3ErrorData*)common; | 207 | data = (struct OpalIoPhb3ErrorData*)common; |
213 | pr_info("PHB3 PHB#%d Diag-data (Version: %d)\n\n", | 208 | pr_info("PHB3 PHB#%d Diag-data (Version: %d)\n", |
214 | hose->global_number, common->version); | 209 | hose->global_number, common->version); |
215 | if (data->brdgCtl) | 210 | if (data->brdgCtl) |
216 | pr_info(" brdgCtl: %08x\n", | 211 | pr_info("brdgCtl: %08x\n", |
217 | data->brdgCtl); | 212 | data->brdgCtl); |
218 | if (data->portStatusReg || data->rootCmplxStatus || | 213 | if (data->portStatusReg || data->rootCmplxStatus || |
219 | data->busAgentStatus) | 214 | data->busAgentStatus) |
220 | pr_info(" UtlSts: %08x %08x %08x\n", | 215 | pr_info("UtlSts: %08x %08x %08x\n", |
221 | data->portStatusReg, data->rootCmplxStatus, | 216 | data->portStatusReg, data->rootCmplxStatus, |
222 | data->busAgentStatus); | 217 | data->busAgentStatus); |
223 | if (data->deviceStatus || data->slotStatus || | 218 | if (data->deviceStatus || data->slotStatus || |
224 | data->linkStatus || data->devCmdStatus || | 219 | data->linkStatus || data->devCmdStatus || |
225 | data->devSecStatus) | 220 | data->devSecStatus) |
226 | pr_info(" RootSts: %08x %08x %08x %08x %08x\n", | 221 | pr_info("RootSts: %08x %08x %08x %08x %08x\n", |
227 | data->deviceStatus, data->slotStatus, | 222 | data->deviceStatus, data->slotStatus, |
228 | data->linkStatus, data->devCmdStatus, | 223 | data->linkStatus, data->devCmdStatus, |
229 | data->devSecStatus); | 224 | data->devSecStatus); |
230 | if (data->rootErrorStatus || data->uncorrErrorStatus || | 225 | if (data->rootErrorStatus || data->uncorrErrorStatus || |
231 | data->corrErrorStatus) | 226 | data->corrErrorStatus) |
232 | pr_info(" RootErrSts: %08x %08x %08x\n", | 227 | pr_info("RootErrSts: %08x %08x %08x\n", |
233 | data->rootErrorStatus, data->uncorrErrorStatus, | 228 | data->rootErrorStatus, data->uncorrErrorStatus, |
234 | data->corrErrorStatus); | 229 | data->corrErrorStatus); |
235 | if (data->tlpHdr1 || data->tlpHdr2 || | 230 | if (data->tlpHdr1 || data->tlpHdr2 || |
236 | data->tlpHdr3 || data->tlpHdr4) | 231 | data->tlpHdr3 || data->tlpHdr4) |
237 | pr_info(" RootErrLog: %08x %08x %08x %08x\n", | 232 | pr_info("RootErrLog: %08x %08x %08x %08x\n", |
238 | data->tlpHdr1, data->tlpHdr2, | 233 | data->tlpHdr1, data->tlpHdr2, |
239 | data->tlpHdr3, data->tlpHdr4); | 234 | data->tlpHdr3, data->tlpHdr4); |
240 | if (data->sourceId || data->errorClass || | 235 | if (data->sourceId || data->errorClass || |
241 | data->correlator) | 236 | data->correlator) |
242 | pr_info(" RootErrLog1: %08x %016llx %016llx\n", | 237 | pr_info("RootErrLog1: %08x %016llx %016llx\n", |
243 | data->sourceId, data->errorClass, | 238 | data->sourceId, data->errorClass, |
244 | data->correlator); | 239 | data->correlator); |
245 | if (data->nFir || data->nFirMask || | 240 | if (data->nFir) |
246 | data->nFirWOF) | 241 | pr_info("nFir: %016llx %016llx %016llx\n", |
247 | pr_info(" nFir: %016llx %016llx %016llx\n", | ||
248 | data->nFir, data->nFirMask, | 242 | data->nFir, data->nFirMask, |
249 | data->nFirWOF); | 243 | data->nFirWOF); |
250 | if (data->phbPlssr || data->phbCsr) | 244 | if (data->phbPlssr || data->phbCsr) |
251 | pr_info(" PhbSts: %016llx %016llx\n", | 245 | pr_info("PhbSts: %016llx %016llx\n", |
252 | data->phbPlssr, data->phbCsr); | 246 | data->phbPlssr, data->phbCsr); |
253 | if (data->lemFir || data->lemErrorMask || | 247 | if (data->lemFir) |
254 | data->lemWOF) | 248 | pr_info("Lem: %016llx %016llx %016llx\n", |
255 | pr_info(" Lem: %016llx %016llx %016llx\n", | ||
256 | data->lemFir, data->lemErrorMask, | 249 | data->lemFir, data->lemErrorMask, |
257 | data->lemWOF); | 250 | data->lemWOF); |
258 | if (data->phbErrorStatus || data->phbFirstErrorStatus || | 251 | if (data->phbErrorStatus) |
259 | data->phbErrorLog0 || data->phbErrorLog1) | 252 | pr_info("PhbErr: %016llx %016llx %016llx %016llx\n", |
260 | pr_info(" PhbErr: %016llx %016llx %016llx %016llx\n", | ||
261 | data->phbErrorStatus, data->phbFirstErrorStatus, | 253 | data->phbErrorStatus, data->phbFirstErrorStatus, |
262 | data->phbErrorLog0, data->phbErrorLog1); | 254 | data->phbErrorLog0, data->phbErrorLog1); |
263 | if (data->mmioErrorStatus || data->mmioFirstErrorStatus || | 255 | if (data->mmioErrorStatus) |
264 | data->mmioErrorLog0 || data->mmioErrorLog1) | 256 | pr_info("OutErr: %016llx %016llx %016llx %016llx\n", |
265 | pr_info(" OutErr: %016llx %016llx %016llx %016llx\n", | ||
266 | data->mmioErrorStatus, data->mmioFirstErrorStatus, | 257 | data->mmioErrorStatus, data->mmioFirstErrorStatus, |
267 | data->mmioErrorLog0, data->mmioErrorLog1); | 258 | data->mmioErrorLog0, data->mmioErrorLog1); |
268 | if (data->dma0ErrorStatus || data->dma0FirstErrorStatus || | 259 | if (data->dma0ErrorStatus) |
269 | data->dma0ErrorLog0 || data->dma0ErrorLog1) | 260 | pr_info("InAErr: %016llx %016llx %016llx %016llx\n", |
270 | pr_info(" InAErr: %016llx %016llx %016llx %016llx\n", | ||
271 | data->dma0ErrorStatus, data->dma0FirstErrorStatus, | 261 | data->dma0ErrorStatus, data->dma0FirstErrorStatus, |
272 | data->dma0ErrorLog0, data->dma0ErrorLog1); | 262 | data->dma0ErrorLog0, data->dma0ErrorLog1); |
273 | if (data->dma1ErrorStatus || data->dma1FirstErrorStatus || | 263 | if (data->dma1ErrorStatus) |
274 | data->dma1ErrorLog0 || data->dma1ErrorLog1) | 264 | pr_info("InBErr: %016llx %016llx %016llx %016llx\n", |
275 | pr_info(" InBErr: %016llx %016llx %016llx %016llx\n", | ||
276 | data->dma1ErrorStatus, data->dma1FirstErrorStatus, | 265 | data->dma1ErrorStatus, data->dma1FirstErrorStatus, |
277 | data->dma1ErrorLog0, data->dma1ErrorLog1); | 266 | data->dma1ErrorLog0, data->dma1ErrorLog1); |
278 | 267 | ||
@@ -281,7 +270,7 @@ static void pnv_pci_dump_phb3_diag_data(struct pci_controller *hose, | |||
281 | (data->pestB[i] >> 63) == 0) | 270 | (data->pestB[i] >> 63) == 0) |
282 | continue; | 271 | continue; |
283 | 272 | ||
284 | pr_info(" PE[%3d] A/B: %016llx %016llx\n", | 273 | pr_info("PE[%3d] A/B: %016llx %016llx\n", |
285 | i, data->pestA[i], data->pestB[i]); | 274 | i, data->pestA[i], data->pestB[i]); |
286 | } | 275 | } |
287 | } | 276 | } |
@@ -384,9 +373,6 @@ int pnv_pci_cfg_read(struct device_node *dn, | |||
384 | struct pci_dn *pdn = PCI_DN(dn); | 373 | struct pci_dn *pdn = PCI_DN(dn); |
385 | struct pnv_phb *phb = pdn->phb->private_data; | 374 | struct pnv_phb *phb = pdn->phb->private_data; |
386 | u32 bdfn = (pdn->busno << 8) | pdn->devfn; | 375 | u32 bdfn = (pdn->busno << 8) | pdn->devfn; |
387 | #ifdef CONFIG_EEH | ||
388 | struct eeh_pe *phb_pe = NULL; | ||
389 | #endif | ||
390 | s64 rc; | 376 | s64 rc; |
391 | 377 | ||
392 | switch (size) { | 378 | switch (size) { |
@@ -412,31 +398,9 @@ int pnv_pci_cfg_read(struct device_node *dn, | |||
412 | default: | 398 | default: |
413 | return PCIBIOS_FUNC_NOT_SUPPORTED; | 399 | return PCIBIOS_FUNC_NOT_SUPPORTED; |
414 | } | 400 | } |
401 | |||
415 | cfg_dbg("%s: bus: %x devfn: %x +%x/%x -> %08x\n", | 402 | cfg_dbg("%s: bus: %x devfn: %x +%x/%x -> %08x\n", |
416 | __func__, pdn->busno, pdn->devfn, where, size, *val); | 403 | __func__, pdn->busno, pdn->devfn, where, size, *val); |
417 | |||
418 | /* | ||
419 | * Check if the specified PE has been put into frozen | ||
420 | * state. On the other hand, we needn't do that while | ||
421 | * the PHB has been put into frozen state because of | ||
422 | * PHB-fatal errors. | ||
423 | */ | ||
424 | #ifdef CONFIG_EEH | ||
425 | phb_pe = eeh_phb_pe_get(pdn->phb); | ||
426 | if (phb_pe && (phb_pe->state & EEH_PE_ISOLATED)) | ||
427 | return PCIBIOS_SUCCESSFUL; | ||
428 | |||
429 | if (phb->eeh_state & PNV_EEH_STATE_ENABLED) { | ||
430 | if (*val == EEH_IO_ERROR_VALUE(size) && | ||
431 | eeh_dev_check_failure(of_node_to_eeh_dev(dn))) | ||
432 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
433 | } else { | ||
434 | pnv_pci_config_check_eeh(phb, dn); | ||
435 | } | ||
436 | #else | ||
437 | pnv_pci_config_check_eeh(phb, dn); | ||
438 | #endif | ||
439 | |||
440 | return PCIBIOS_SUCCESSFUL; | 404 | return PCIBIOS_SUCCESSFUL; |
441 | } | 405 | } |
442 | 406 | ||
@@ -463,33 +427,74 @@ int pnv_pci_cfg_write(struct device_node *dn, | |||
463 | return PCIBIOS_FUNC_NOT_SUPPORTED; | 427 | return PCIBIOS_FUNC_NOT_SUPPORTED; |
464 | } | 428 | } |
465 | 429 | ||
466 | /* Check if the PHB got frozen due to an error (no response) */ | ||
467 | #ifdef CONFIG_EEH | ||
468 | if (!(phb->eeh_state & PNV_EEH_STATE_ENABLED)) | ||
469 | pnv_pci_config_check_eeh(phb, dn); | ||
470 | #else | ||
471 | pnv_pci_config_check_eeh(phb, dn); | ||
472 | #endif | ||
473 | |||
474 | return PCIBIOS_SUCCESSFUL; | 430 | return PCIBIOS_SUCCESSFUL; |
475 | } | 431 | } |
476 | 432 | ||
433 | #if CONFIG_EEH | ||
434 | static bool pnv_pci_cfg_check(struct pci_controller *hose, | ||
435 | struct device_node *dn) | ||
436 | { | ||
437 | struct eeh_dev *edev = NULL; | ||
438 | struct pnv_phb *phb = hose->private_data; | ||
439 | |||
440 | /* EEH not enabled ? */ | ||
441 | if (!(phb->flags & PNV_PHB_FLAG_EEH)) | ||
442 | return true; | ||
443 | |||
444 | /* PE reset or device removed ? */ | ||
445 | edev = of_node_to_eeh_dev(dn); | ||
446 | if (edev) { | ||
447 | if (edev->pe && | ||
448 | (edev->pe->state & EEH_PE_RESET)) | ||
449 | return false; | ||
450 | |||
451 | if (edev->mode & EEH_DEV_REMOVED) | ||
452 | return false; | ||
453 | } | ||
454 | |||
455 | return true; | ||
456 | } | ||
457 | #else | ||
458 | static inline pnv_pci_cfg_check(struct pci_controller *hose, | ||
459 | struct device_node *dn) | ||
460 | { | ||
461 | return true; | ||
462 | } | ||
463 | #endif /* CONFIG_EEH */ | ||
464 | |||
477 | static int pnv_pci_read_config(struct pci_bus *bus, | 465 | static int pnv_pci_read_config(struct pci_bus *bus, |
478 | unsigned int devfn, | 466 | unsigned int devfn, |
479 | int where, int size, u32 *val) | 467 | int where, int size, u32 *val) |
480 | { | 468 | { |
481 | struct device_node *dn, *busdn = pci_bus_to_OF_node(bus); | 469 | struct device_node *dn, *busdn = pci_bus_to_OF_node(bus); |
482 | struct pci_dn *pdn; | 470 | struct pci_dn *pdn; |
471 | struct pnv_phb *phb; | ||
472 | bool found = false; | ||
473 | int ret; | ||
483 | 474 | ||
475 | *val = 0xFFFFFFFF; | ||
484 | for (dn = busdn->child; dn; dn = dn->sibling) { | 476 | for (dn = busdn->child; dn; dn = dn->sibling) { |
485 | pdn = PCI_DN(dn); | 477 | pdn = PCI_DN(dn); |
486 | if (pdn && pdn->devfn == devfn) | 478 | if (pdn && pdn->devfn == devfn) { |
487 | return pnv_pci_cfg_read(dn, where, size, val); | 479 | phb = pdn->phb->private_data; |
480 | found = true; | ||
481 | break; | ||
482 | } | ||
488 | } | 483 | } |
489 | 484 | ||
490 | *val = 0xFFFFFFFF; | 485 | if (!found || !pnv_pci_cfg_check(pdn->phb, dn)) |
491 | return PCIBIOS_DEVICE_NOT_FOUND; | 486 | return PCIBIOS_DEVICE_NOT_FOUND; |
492 | 487 | ||
488 | ret = pnv_pci_cfg_read(dn, where, size, val); | ||
489 | if (phb->flags & PNV_PHB_FLAG_EEH) { | ||
490 | if (*val == EEH_IO_ERROR_VALUE(size) && | ||
491 | eeh_dev_check_failure(of_node_to_eeh_dev(dn))) | ||
492 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
493 | } else { | ||
494 | pnv_pci_config_check_eeh(phb, dn); | ||
495 | } | ||
496 | |||
497 | return ret; | ||
493 | } | 498 | } |
494 | 499 | ||
495 | static int pnv_pci_write_config(struct pci_bus *bus, | 500 | static int pnv_pci_write_config(struct pci_bus *bus, |
@@ -498,14 +503,27 @@ static int pnv_pci_write_config(struct pci_bus *bus, | |||
498 | { | 503 | { |
499 | struct device_node *dn, *busdn = pci_bus_to_OF_node(bus); | 504 | struct device_node *dn, *busdn = pci_bus_to_OF_node(bus); |
500 | struct pci_dn *pdn; | 505 | struct pci_dn *pdn; |
506 | struct pnv_phb *phb; | ||
507 | bool found = false; | ||
508 | int ret; | ||
501 | 509 | ||
502 | for (dn = busdn->child; dn; dn = dn->sibling) { | 510 | for (dn = busdn->child; dn; dn = dn->sibling) { |
503 | pdn = PCI_DN(dn); | 511 | pdn = PCI_DN(dn); |
504 | if (pdn && pdn->devfn == devfn) | 512 | if (pdn && pdn->devfn == devfn) { |
505 | return pnv_pci_cfg_write(dn, where, size, val); | 513 | phb = pdn->phb->private_data; |
514 | found = true; | ||
515 | break; | ||
516 | } | ||
506 | } | 517 | } |
507 | 518 | ||
508 | return PCIBIOS_DEVICE_NOT_FOUND; | 519 | if (!found || !pnv_pci_cfg_check(pdn->phb, dn)) |
520 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
521 | |||
522 | ret = pnv_pci_cfg_write(dn, where, size, val); | ||
523 | if (!(phb->flags & PNV_PHB_FLAG_EEH)) | ||
524 | pnv_pci_config_check_eeh(phb, dn); | ||
525 | |||
526 | return ret; | ||
509 | } | 527 | } |
510 | 528 | ||
511 | struct pci_ops pnv_pci_ops = { | 529 | struct pci_ops pnv_pci_ops = { |
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index cde169442775..676232c34328 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h | |||
@@ -81,28 +81,27 @@ struct pnv_eeh_ops { | |||
81 | int (*configure_bridge)(struct eeh_pe *pe); | 81 | int (*configure_bridge)(struct eeh_pe *pe); |
82 | int (*next_error)(struct eeh_pe **pe); | 82 | int (*next_error)(struct eeh_pe **pe); |
83 | }; | 83 | }; |
84 | |||
85 | #define PNV_EEH_STATE_ENABLED (1 << 0) /* EEH enabled */ | ||
86 | #define PNV_EEH_STATE_REMOVED (1 << 1) /* PHB removed */ | ||
87 | |||
88 | #endif /* CONFIG_EEH */ | 84 | #endif /* CONFIG_EEH */ |
89 | 85 | ||
86 | #define PNV_PHB_FLAG_EEH (1 << 0) | ||
87 | |||
90 | struct pnv_phb { | 88 | struct pnv_phb { |
91 | struct pci_controller *hose; | 89 | struct pci_controller *hose; |
92 | enum pnv_phb_type type; | 90 | enum pnv_phb_type type; |
93 | enum pnv_phb_model model; | 91 | enum pnv_phb_model model; |
94 | u64 hub_id; | 92 | u64 hub_id; |
95 | u64 opal_id; | 93 | u64 opal_id; |
94 | int flags; | ||
96 | void __iomem *regs; | 95 | void __iomem *regs; |
97 | int initialized; | 96 | int initialized; |
98 | spinlock_t lock; | 97 | spinlock_t lock; |
99 | 98 | ||
100 | #ifdef CONFIG_EEH | 99 | #ifdef CONFIG_EEH |
101 | struct pnv_eeh_ops *eeh_ops; | 100 | struct pnv_eeh_ops *eeh_ops; |
102 | int eeh_state; | ||
103 | #endif | 101 | #endif |
104 | 102 | ||
105 | #ifdef CONFIG_DEBUG_FS | 103 | #ifdef CONFIG_DEBUG_FS |
104 | int has_dbgfs; | ||
106 | struct dentry *dbgfs; | 105 | struct dentry *dbgfs; |
107 | #endif | 106 | #endif |
108 | 107 | ||
@@ -205,5 +204,7 @@ extern void pnv_pci_init_ioda_hub(struct device_node *np); | |||
205 | extern void pnv_pci_init_ioda2_phb(struct device_node *np); | 204 | extern void pnv_pci_init_ioda2_phb(struct device_node *np); |
206 | extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl, | 205 | extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl, |
207 | __be64 *startp, __be64 *endp, bool rm); | 206 | __be64 *startp, __be64 *endp, bool rm); |
207 | extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev); | ||
208 | extern int ioda_eeh_phb_reset(struct pci_controller *hose, int option); | ||
208 | 209 | ||
209 | #endif /* __POWERNV_PCI_H */ | 210 | #endif /* __POWERNV_PCI_H */ |
diff --git a/arch/powerpc/platforms/powernv/powernv.h b/arch/powerpc/platforms/powernv/powernv.h index 0051e108ef0f..75501bfede7f 100644 --- a/arch/powerpc/platforms/powernv/powernv.h +++ b/arch/powerpc/platforms/powernv/powernv.h | |||
@@ -25,4 +25,6 @@ static inline int pnv_pci_dma_set_mask(struct pci_dev *pdev, u64 dma_mask) | |||
25 | 25 | ||
26 | extern void pnv_lpc_init(void); | 26 | extern void pnv_lpc_init(void); |
27 | 27 | ||
28 | bool cpu_core_split_required(void); | ||
29 | |||
28 | #endif /* _POWERNV_H */ | 30 | #endif /* _POWERNV_H */ |
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 8723d32632f5..8c16a5f96728 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
28 | #include <linux/bug.h> | 28 | #include <linux/bug.h> |
29 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
30 | #include <linux/cpufreq.h> | ||
30 | 31 | ||
31 | #include <asm/machdep.h> | 32 | #include <asm/machdep.h> |
32 | #include <asm/firmware.h> | 33 | #include <asm/firmware.h> |
@@ -98,11 +99,32 @@ static void pnv_show_cpuinfo(struct seq_file *m) | |||
98 | of_node_put(root); | 99 | of_node_put(root); |
99 | } | 100 | } |
100 | 101 | ||
102 | static void pnv_prepare_going_down(void) | ||
103 | { | ||
104 | /* | ||
105 | * Disable all notifiers from OPAL, we can't | ||
106 | * service interrupts anymore anyway | ||
107 | */ | ||
108 | opal_notifier_disable(); | ||
109 | |||
110 | /* Soft disable interrupts */ | ||
111 | local_irq_disable(); | ||
112 | |||
113 | /* | ||
114 | * Return secondary CPUs to firwmare if a flash update | ||
115 | * is pending otherwise we will get all sort of error | ||
116 | * messages about CPU being stuck etc.. This will also | ||
117 | * have the side effect of hard disabling interrupts so | ||
118 | * past this point, the kernel is effectively dead. | ||
119 | */ | ||
120 | opal_flash_term_callback(); | ||
121 | } | ||
122 | |||
101 | static void __noreturn pnv_restart(char *cmd) | 123 | static void __noreturn pnv_restart(char *cmd) |
102 | { | 124 | { |
103 | long rc = OPAL_BUSY; | 125 | long rc = OPAL_BUSY; |
104 | 126 | ||
105 | opal_notifier_disable(); | 127 | pnv_prepare_going_down(); |
106 | 128 | ||
107 | while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { | 129 | while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { |
108 | rc = opal_cec_reboot(); | 130 | rc = opal_cec_reboot(); |
@@ -119,7 +141,7 @@ static void __noreturn pnv_power_off(void) | |||
119 | { | 141 | { |
120 | long rc = OPAL_BUSY; | 142 | long rc = OPAL_BUSY; |
121 | 143 | ||
122 | opal_notifier_disable(); | 144 | pnv_prepare_going_down(); |
123 | 145 | ||
124 | while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { | 146 | while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { |
125 | rc = opal_cec_power_down(0); | 147 | rc = opal_cec_power_down(0); |
@@ -222,6 +244,13 @@ static void pnv_kexec_cpu_down(int crash_shutdown, int secondary) | |||
222 | } | 244 | } |
223 | #endif /* CONFIG_KEXEC */ | 245 | #endif /* CONFIG_KEXEC */ |
224 | 246 | ||
247 | #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE | ||
248 | static unsigned long pnv_memory_block_size(void) | ||
249 | { | ||
250 | return 256UL * 1024 * 1024; | ||
251 | } | ||
252 | #endif | ||
253 | |||
225 | static void __init pnv_setup_machdep_opal(void) | 254 | static void __init pnv_setup_machdep_opal(void) |
226 | { | 255 | { |
227 | ppc_md.get_boot_time = opal_get_boot_time; | 256 | ppc_md.get_boot_time = opal_get_boot_time; |
@@ -269,6 +298,25 @@ static int __init pnv_probe(void) | |||
269 | return 1; | 298 | return 1; |
270 | } | 299 | } |
271 | 300 | ||
301 | /* | ||
302 | * Returns the cpu frequency for 'cpu' in Hz. This is used by | ||
303 | * /proc/cpuinfo | ||
304 | */ | ||
305 | unsigned long pnv_get_proc_freq(unsigned int cpu) | ||
306 | { | ||
307 | unsigned long ret_freq; | ||
308 | |||
309 | ret_freq = cpufreq_quick_get(cpu) * 1000ul; | ||
310 | |||
311 | /* | ||
312 | * If the backend cpufreq driver does not exist, | ||
313 | * then fallback to old way of reporting the clockrate. | ||
314 | */ | ||
315 | if (!ret_freq) | ||
316 | ret_freq = ppc_proc_freq; | ||
317 | return ret_freq; | ||
318 | } | ||
319 | |||
272 | define_machine(powernv) { | 320 | define_machine(powernv) { |
273 | .name = "PowerNV", | 321 | .name = "PowerNV", |
274 | .probe = pnv_probe, | 322 | .probe = pnv_probe, |
@@ -276,6 +324,7 @@ define_machine(powernv) { | |||
276 | .setup_arch = pnv_setup_arch, | 324 | .setup_arch = pnv_setup_arch, |
277 | .init_IRQ = pnv_init_IRQ, | 325 | .init_IRQ = pnv_init_IRQ, |
278 | .show_cpuinfo = pnv_show_cpuinfo, | 326 | .show_cpuinfo = pnv_show_cpuinfo, |
327 | .get_proc_freq = pnv_get_proc_freq, | ||
279 | .progress = pnv_progress, | 328 | .progress = pnv_progress, |
280 | .machine_shutdown = pnv_shutdown, | 329 | .machine_shutdown = pnv_shutdown, |
281 | .power_save = power7_idle, | 330 | .power_save = power7_idle, |
@@ -284,4 +333,7 @@ define_machine(powernv) { | |||
284 | #ifdef CONFIG_KEXEC | 333 | #ifdef CONFIG_KEXEC |
285 | .kexec_cpu_down = pnv_kexec_cpu_down, | 334 | .kexec_cpu_down = pnv_kexec_cpu_down, |
286 | #endif | 335 | #endif |
336 | #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE | ||
337 | .memory_block_size = pnv_memory_block_size, | ||
338 | #endif | ||
287 | }; | 339 | }; |
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index bf5fcd452168..0062a43a2e0d 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <asm/xics.h> | 31 | #include <asm/xics.h> |
32 | #include <asm/opal.h> | 32 | #include <asm/opal.h> |
33 | #include <asm/runlatch.h> | 33 | #include <asm/runlatch.h> |
34 | #include <asm/code-patching.h> | ||
34 | 35 | ||
35 | #include "powernv.h" | 36 | #include "powernv.h" |
36 | 37 | ||
@@ -50,8 +51,8 @@ static void pnv_smp_setup_cpu(int cpu) | |||
50 | int pnv_smp_kick_cpu(int nr) | 51 | int pnv_smp_kick_cpu(int nr) |
51 | { | 52 | { |
52 | unsigned int pcpu = get_hard_smp_processor_id(nr); | 53 | unsigned int pcpu = get_hard_smp_processor_id(nr); |
53 | unsigned long start_here = __pa(*((unsigned long *) | 54 | unsigned long start_here = |
54 | generic_secondary_smp_init)); | 55 | __pa(ppc_function_entry(generic_secondary_smp_init)); |
55 | long rc; | 56 | long rc; |
56 | 57 | ||
57 | BUG_ON(nr < 0 || nr >= NR_CPUS); | 58 | BUG_ON(nr < 0 || nr >= NR_CPUS); |
@@ -158,17 +159,19 @@ static void pnv_smp_cpu_kill_self(void) | |||
158 | mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1); | 159 | mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1); |
159 | while (!generic_check_cpu_restart(cpu)) { | 160 | while (!generic_check_cpu_restart(cpu)) { |
160 | ppc64_runlatch_off(); | 161 | ppc64_runlatch_off(); |
161 | power7_nap(); | 162 | power7_nap(1); |
162 | ppc64_runlatch_on(); | 163 | ppc64_runlatch_on(); |
163 | if (!generic_check_cpu_restart(cpu)) { | 164 | |
165 | /* Reenable IRQs briefly to clear the IPI that woke us */ | ||
166 | local_irq_enable(); | ||
167 | local_irq_disable(); | ||
168 | mb(); | ||
169 | |||
170 | if (cpu_core_split_required()) | ||
171 | continue; | ||
172 | |||
173 | if (!generic_check_cpu_restart(cpu)) | ||
164 | DBG("CPU%d Unexpected exit while offline !\n", cpu); | 174 | DBG("CPU%d Unexpected exit while offline !\n", cpu); |
165 | /* We may be getting an IPI, so we re-enable | ||
166 | * interrupts to process it, it will be ignored | ||
167 | * since we aren't online (hopefully) | ||
168 | */ | ||
169 | local_irq_enable(); | ||
170 | local_irq_disable(); | ||
171 | } | ||
172 | } | 175 | } |
173 | mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_PECE1); | 176 | mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_PECE1); |
174 | DBG("CPU%d coming online...\n", cpu); | 177 | DBG("CPU%d coming online...\n", cpu); |
diff --git a/arch/powerpc/platforms/powernv/subcore-asm.S b/arch/powerpc/platforms/powernv/subcore-asm.S new file mode 100644 index 000000000000..39bb24aa8f34 --- /dev/null +++ b/arch/powerpc/platforms/powernv/subcore-asm.S | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * Copyright 2013, Michael (Ellerman|Neuling), IBM Corporation. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <asm/asm-offsets.h> | ||
11 | #include <asm/ppc_asm.h> | ||
12 | #include <asm/reg.h> | ||
13 | |||
14 | #include "subcore.h" | ||
15 | |||
16 | |||
17 | _GLOBAL(split_core_secondary_loop) | ||
18 | /* | ||
19 | * r3 = u8 *state, used throughout the routine | ||
20 | * r4 = temp | ||
21 | * r5 = temp | ||
22 | * .. | ||
23 | * r12 = MSR | ||
24 | */ | ||
25 | mfmsr r12 | ||
26 | |||
27 | /* Disable interrupts so SRR0/1 don't get trashed */ | ||
28 | li r4,0 | ||
29 | ori r4,r4,MSR_EE|MSR_SE|MSR_BE|MSR_RI | ||
30 | andc r4,r12,r4 | ||
31 | sync | ||
32 | mtmsrd r4 | ||
33 | |||
34 | /* Switch to real mode and leave interrupts off */ | ||
35 | li r5, MSR_IR|MSR_DR | ||
36 | andc r5, r4, r5 | ||
37 | |||
38 | LOAD_REG_ADDR(r4, real_mode) | ||
39 | |||
40 | mtspr SPRN_SRR0,r4 | ||
41 | mtspr SPRN_SRR1,r5 | ||
42 | rfid | ||
43 | b . /* prevent speculative execution */ | ||
44 | |||
45 | real_mode: | ||
46 | /* Grab values from unsplit SPRs */ | ||
47 | mfspr r6, SPRN_LDBAR | ||
48 | mfspr r7, SPRN_PMMAR | ||
49 | mfspr r8, SPRN_PMCR | ||
50 | mfspr r9, SPRN_RPR | ||
51 | mfspr r10, SPRN_SDR1 | ||
52 | |||
53 | /* Order reading the SPRs vs telling the primary we are ready to split */ | ||
54 | sync | ||
55 | |||
56 | /* Tell thread 0 we are in real mode */ | ||
57 | li r4, SYNC_STEP_REAL_MODE | ||
58 | stb r4, 0(r3) | ||
59 | |||
60 | li r5, (HID0_POWER8_4LPARMODE | HID0_POWER8_2LPARMODE)@highest | ||
61 | sldi r5, r5, 48 | ||
62 | |||
63 | /* Loop until we see the split happen in HID0 */ | ||
64 | 1: mfspr r4, SPRN_HID0 | ||
65 | and. r4, r4, r5 | ||
66 | beq 1b | ||
67 | |||
68 | /* | ||
69 | * We only need to initialise the below regs once for each subcore, | ||
70 | * but it's simpler and harmless to do it on each thread. | ||
71 | */ | ||
72 | |||
73 | /* Make sure various SPRS have sane values */ | ||
74 | li r4, 0 | ||
75 | mtspr SPRN_LPID, r4 | ||
76 | mtspr SPRN_PCR, r4 | ||
77 | mtspr SPRN_HDEC, r4 | ||
78 | |||
79 | /* Restore SPR values now we are split */ | ||
80 | mtspr SPRN_LDBAR, r6 | ||
81 | mtspr SPRN_PMMAR, r7 | ||
82 | mtspr SPRN_PMCR, r8 | ||
83 | mtspr SPRN_RPR, r9 | ||
84 | mtspr SPRN_SDR1, r10 | ||
85 | |||
86 | LOAD_REG_ADDR(r5, virtual_mode) | ||
87 | |||
88 | /* Get out of real mode */ | ||
89 | mtspr SPRN_SRR0,r5 | ||
90 | mtspr SPRN_SRR1,r12 | ||
91 | rfid | ||
92 | b . /* prevent speculative execution */ | ||
93 | |||
94 | virtual_mode: | ||
95 | blr | ||
diff --git a/arch/powerpc/platforms/powernv/subcore.c b/arch/powerpc/platforms/powernv/subcore.c new file mode 100644 index 000000000000..894ecb3eb596 --- /dev/null +++ b/arch/powerpc/platforms/powernv/subcore.c | |||
@@ -0,0 +1,392 @@ | |||
1 | /* | ||
2 | * Copyright 2013, Michael (Ellerman|Neuling), IBM Corporation. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #define pr_fmt(fmt) "powernv: " fmt | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/cpu.h> | ||
14 | #include <linux/cpumask.h> | ||
15 | #include <linux/device.h> | ||
16 | #include <linux/gfp.h> | ||
17 | #include <linux/smp.h> | ||
18 | #include <linux/stop_machine.h> | ||
19 | |||
20 | #include <asm/cputhreads.h> | ||
21 | #include <asm/kvm_ppc.h> | ||
22 | #include <asm/machdep.h> | ||
23 | #include <asm/opal.h> | ||
24 | #include <asm/smp.h> | ||
25 | |||
26 | #include "subcore.h" | ||
27 | |||
28 | |||
29 | /* | ||
30 | * Split/unsplit procedure: | ||
31 | * | ||
32 | * A core can be in one of three states, unsplit, 2-way split, and 4-way split. | ||
33 | * | ||
34 | * The mapping to subcores_per_core is simple: | ||
35 | * | ||
36 | * State | subcores_per_core | ||
37 | * ------------|------------------ | ||
38 | * Unsplit | 1 | ||
39 | * 2-way split | 2 | ||
40 | * 4-way split | 4 | ||
41 | * | ||
42 | * The core is split along thread boundaries, the mapping between subcores and | ||
43 | * threads is as follows: | ||
44 | * | ||
45 | * Unsplit: | ||
46 | * ---------------------------- | ||
47 | * Subcore | 0 | | ||
48 | * ---------------------------- | ||
49 | * Thread | 0 1 2 3 4 5 6 7 | | ||
50 | * ---------------------------- | ||
51 | * | ||
52 | * 2-way split: | ||
53 | * ------------------------------------- | ||
54 | * Subcore | 0 | 1 | | ||
55 | * ------------------------------------- | ||
56 | * Thread | 0 1 2 3 | 4 5 6 7 | | ||
57 | * ------------------------------------- | ||
58 | * | ||
59 | * 4-way split: | ||
60 | * ----------------------------------------- | ||
61 | * Subcore | 0 | 1 | 2 | 3 | | ||
62 | * ----------------------------------------- | ||
63 | * Thread | 0 1 | 2 3 | 4 5 | 6 7 | | ||
64 | * ----------------------------------------- | ||
65 | * | ||
66 | * | ||
67 | * Transitions | ||
68 | * ----------- | ||
69 | * | ||
70 | * It is not possible to transition between either of the split states, the | ||
71 | * core must first be unsplit. The legal transitions are: | ||
72 | * | ||
73 | * ----------- --------------- | ||
74 | * | | <----> | 2-way split | | ||
75 | * | | --------------- | ||
76 | * | Unsplit | | ||
77 | * | | --------------- | ||
78 | * | | <----> | 4-way split | | ||
79 | * ----------- --------------- | ||
80 | * | ||
81 | * Unsplitting | ||
82 | * ----------- | ||
83 | * | ||
84 | * Unsplitting is the simpler procedure. It requires thread 0 to request the | ||
85 | * unsplit while all other threads NAP. | ||
86 | * | ||
87 | * Thread 0 clears HID0_POWER8_DYNLPARDIS (Dynamic LPAR Disable). This tells | ||
88 | * the hardware that if all threads except 0 are napping, the hardware should | ||
89 | * unsplit the core. | ||
90 | * | ||
91 | * Non-zero threads are sent to a NAP loop, they don't exit the loop until they | ||
92 | * see the core unsplit. | ||
93 | * | ||
94 | * Core 0 spins waiting for the hardware to see all the other threads napping | ||
95 | * and perform the unsplit. | ||
96 | * | ||
97 | * Once thread 0 sees the unsplit, it IPIs the secondary threads to wake them | ||
98 | * out of NAP. They will then see the core unsplit and exit the NAP loop. | ||
99 | * | ||
100 | * Splitting | ||
101 | * --------- | ||
102 | * | ||
103 | * The basic splitting procedure is fairly straight forward. However it is | ||
104 | * complicated by the fact that after the split occurs, the newly created | ||
105 | * subcores are not in a fully initialised state. | ||
106 | * | ||
107 | * Most notably the subcores do not have the correct value for SDR1, which | ||
108 | * means they must not be running in virtual mode when the split occurs. The | ||
109 | * subcores have separate timebases SPRs but these are pre-synchronised by | ||
110 | * opal. | ||
111 | * | ||
112 | * To begin with secondary threads are sent to an assembly routine. There they | ||
113 | * switch to real mode, so they are immune to the uninitialised SDR1 value. | ||
114 | * Once in real mode they indicate that they are in real mode, and spin waiting | ||
115 | * to see the core split. | ||
116 | * | ||
117 | * Thread 0 waits to see that all secondaries are in real mode, and then begins | ||
118 | * the splitting procedure. It firstly sets HID0_POWER8_DYNLPARDIS, which | ||
119 | * prevents the hardware from unsplitting. Then it sets the appropriate HID bit | ||
120 | * to request the split, and spins waiting to see that the split has happened. | ||
121 | * | ||
122 | * Concurrently the secondaries will notice the split. When they do they set up | ||
123 | * their SPRs, notably SDR1, and then they can return to virtual mode and exit | ||
124 | * the procedure. | ||
125 | */ | ||
126 | |||
127 | /* Initialised at boot by subcore_init() */ | ||
128 | static int subcores_per_core; | ||
129 | |||
130 | /* | ||
131 | * Used to communicate to offline cpus that we want them to pop out of the | ||
132 | * offline loop and do a split or unsplit. | ||
133 | * | ||
134 | * 0 - no split happening | ||
135 | * 1 - unsplit in progress | ||
136 | * 2 - split to 2 in progress | ||
137 | * 4 - split to 4 in progress | ||
138 | */ | ||
139 | static int new_split_mode; | ||
140 | |||
141 | static cpumask_var_t cpu_offline_mask; | ||
142 | |||
143 | struct split_state { | ||
144 | u8 step; | ||
145 | u8 master; | ||
146 | }; | ||
147 | |||
148 | static DEFINE_PER_CPU(struct split_state, split_state); | ||
149 | |||
150 | static void wait_for_sync_step(int step) | ||
151 | { | ||
152 | int i, cpu = smp_processor_id(); | ||
153 | |||
154 | for (i = cpu + 1; i < cpu + threads_per_core; i++) | ||
155 | while(per_cpu(split_state, i).step < step) | ||
156 | barrier(); | ||
157 | |||
158 | /* Order the wait loop vs any subsequent loads/stores. */ | ||
159 | mb(); | ||
160 | } | ||
161 | |||
162 | static void unsplit_core(void) | ||
163 | { | ||
164 | u64 hid0, mask; | ||
165 | int i, cpu; | ||
166 | |||
167 | mask = HID0_POWER8_2LPARMODE | HID0_POWER8_4LPARMODE; | ||
168 | |||
169 | cpu = smp_processor_id(); | ||
170 | if (cpu_thread_in_core(cpu) != 0) { | ||
171 | while (mfspr(SPRN_HID0) & mask) | ||
172 | power7_nap(0); | ||
173 | |||
174 | per_cpu(split_state, cpu).step = SYNC_STEP_UNSPLIT; | ||
175 | return; | ||
176 | } | ||
177 | |||
178 | hid0 = mfspr(SPRN_HID0); | ||
179 | hid0 &= ~HID0_POWER8_DYNLPARDIS; | ||
180 | mtspr(SPRN_HID0, hid0); | ||
181 | |||
182 | while (mfspr(SPRN_HID0) & mask) | ||
183 | cpu_relax(); | ||
184 | |||
185 | /* Wake secondaries out of NAP */ | ||
186 | for (i = cpu + 1; i < cpu + threads_per_core; i++) | ||
187 | smp_send_reschedule(i); | ||
188 | |||
189 | wait_for_sync_step(SYNC_STEP_UNSPLIT); | ||
190 | } | ||
191 | |||
192 | static void split_core(int new_mode) | ||
193 | { | ||
194 | struct { u64 value; u64 mask; } split_parms[2] = { | ||
195 | { HID0_POWER8_1TO2LPAR, HID0_POWER8_2LPARMODE }, | ||
196 | { HID0_POWER8_1TO4LPAR, HID0_POWER8_4LPARMODE } | ||
197 | }; | ||
198 | int i, cpu; | ||
199 | u64 hid0; | ||
200 | |||
201 | /* Convert new_mode (2 or 4) into an index into our parms array */ | ||
202 | i = (new_mode >> 1) - 1; | ||
203 | BUG_ON(i < 0 || i > 1); | ||
204 | |||
205 | cpu = smp_processor_id(); | ||
206 | if (cpu_thread_in_core(cpu) != 0) { | ||
207 | split_core_secondary_loop(&per_cpu(split_state, cpu).step); | ||
208 | return; | ||
209 | } | ||
210 | |||
211 | wait_for_sync_step(SYNC_STEP_REAL_MODE); | ||
212 | |||
213 | /* Write new mode */ | ||
214 | hid0 = mfspr(SPRN_HID0); | ||
215 | hid0 |= HID0_POWER8_DYNLPARDIS | split_parms[i].value; | ||
216 | mtspr(SPRN_HID0, hid0); | ||
217 | |||
218 | /* Wait for it to happen */ | ||
219 | while (!(mfspr(SPRN_HID0) & split_parms[i].mask)) | ||
220 | cpu_relax(); | ||
221 | } | ||
222 | |||
223 | static void cpu_do_split(int new_mode) | ||
224 | { | ||
225 | /* | ||
226 | * At boot subcores_per_core will be 0, so we will always unsplit at | ||
227 | * boot. In the usual case where the core is already unsplit it's a | ||
228 | * nop, and this just ensures the kernel's notion of the mode is | ||
229 | * consistent with the hardware. | ||
230 | */ | ||
231 | if (subcores_per_core != 1) | ||
232 | unsplit_core(); | ||
233 | |||
234 | if (new_mode != 1) | ||
235 | split_core(new_mode); | ||
236 | |||
237 | mb(); | ||
238 | per_cpu(split_state, smp_processor_id()).step = SYNC_STEP_FINISHED; | ||
239 | } | ||
240 | |||
241 | bool cpu_core_split_required(void) | ||
242 | { | ||
243 | smp_rmb(); | ||
244 | |||
245 | if (!new_split_mode) | ||
246 | return false; | ||
247 | |||
248 | cpu_do_split(new_split_mode); | ||
249 | |||
250 | return true; | ||
251 | } | ||
252 | |||
253 | static int cpu_update_split_mode(void *data) | ||
254 | { | ||
255 | int cpu, new_mode = *(int *)data; | ||
256 | |||
257 | if (this_cpu_ptr(&split_state)->master) { | ||
258 | new_split_mode = new_mode; | ||
259 | smp_wmb(); | ||
260 | |||
261 | cpumask_andnot(cpu_offline_mask, cpu_present_mask, | ||
262 | cpu_online_mask); | ||
263 | |||
264 | /* This should work even though the cpu is offline */ | ||
265 | for_each_cpu(cpu, cpu_offline_mask) | ||
266 | smp_send_reschedule(cpu); | ||
267 | } | ||
268 | |||
269 | cpu_do_split(new_mode); | ||
270 | |||
271 | if (this_cpu_ptr(&split_state)->master) { | ||
272 | /* Wait for all cpus to finish before we touch subcores_per_core */ | ||
273 | for_each_present_cpu(cpu) { | ||
274 | if (cpu >= setup_max_cpus) | ||
275 | break; | ||
276 | |||
277 | while(per_cpu(split_state, cpu).step < SYNC_STEP_FINISHED) | ||
278 | barrier(); | ||
279 | } | ||
280 | |||
281 | new_split_mode = 0; | ||
282 | |||
283 | /* Make the new mode public */ | ||
284 | subcores_per_core = new_mode; | ||
285 | threads_per_subcore = threads_per_core / subcores_per_core; | ||
286 | |||
287 | /* Make sure the new mode is written before we exit */ | ||
288 | mb(); | ||
289 | } | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | static int set_subcores_per_core(int new_mode) | ||
295 | { | ||
296 | struct split_state *state; | ||
297 | int cpu; | ||
298 | |||
299 | if (kvm_hv_mode_active()) { | ||
300 | pr_err("Unable to change split core mode while KVM active.\n"); | ||
301 | return -EBUSY; | ||
302 | } | ||
303 | |||
304 | /* | ||
305 | * We are only called at boot, or from the sysfs write. If that ever | ||
306 | * changes we'll need a lock here. | ||
307 | */ | ||
308 | BUG_ON(new_mode < 1 || new_mode > 4 || new_mode == 3); | ||
309 | |||
310 | for_each_present_cpu(cpu) { | ||
311 | state = &per_cpu(split_state, cpu); | ||
312 | state->step = SYNC_STEP_INITIAL; | ||
313 | state->master = 0; | ||
314 | } | ||
315 | |||
316 | get_online_cpus(); | ||
317 | |||
318 | /* This cpu will update the globals before exiting stop machine */ | ||
319 | this_cpu_ptr(&split_state)->master = 1; | ||
320 | |||
321 | /* Ensure state is consistent before we call the other cpus */ | ||
322 | mb(); | ||
323 | |||
324 | stop_machine(cpu_update_split_mode, &new_mode, cpu_online_mask); | ||
325 | |||
326 | put_online_cpus(); | ||
327 | |||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | static ssize_t __used store_subcores_per_core(struct device *dev, | ||
332 | struct device_attribute *attr, const char *buf, | ||
333 | size_t count) | ||
334 | { | ||
335 | unsigned long val; | ||
336 | int rc; | ||
337 | |||
338 | /* We are serialised by the attribute lock */ | ||
339 | |||
340 | rc = sscanf(buf, "%lx", &val); | ||
341 | if (rc != 1) | ||
342 | return -EINVAL; | ||
343 | |||
344 | switch (val) { | ||
345 | case 1: | ||
346 | case 2: | ||
347 | case 4: | ||
348 | if (subcores_per_core == val) | ||
349 | /* Nothing to do */ | ||
350 | goto out; | ||
351 | break; | ||
352 | default: | ||
353 | return -EINVAL; | ||
354 | } | ||
355 | |||
356 | rc = set_subcores_per_core(val); | ||
357 | if (rc) | ||
358 | return rc; | ||
359 | |||
360 | out: | ||
361 | return count; | ||
362 | } | ||
363 | |||
364 | static ssize_t show_subcores_per_core(struct device *dev, | ||
365 | struct device_attribute *attr, char *buf) | ||
366 | { | ||
367 | return sprintf(buf, "%x\n", subcores_per_core); | ||
368 | } | ||
369 | |||
370 | static DEVICE_ATTR(subcores_per_core, 0644, | ||
371 | show_subcores_per_core, store_subcores_per_core); | ||
372 | |||
373 | static int subcore_init(void) | ||
374 | { | ||
375 | if (!cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
376 | return 0; | ||
377 | |||
378 | /* | ||
379 | * We need all threads in a core to be present to split/unsplit so | ||
380 | * continue only if max_cpus are aligned to threads_per_core. | ||
381 | */ | ||
382 | if (setup_max_cpus % threads_per_core) | ||
383 | return 0; | ||
384 | |||
385 | BUG_ON(!alloc_cpumask_var(&cpu_offline_mask, GFP_KERNEL)); | ||
386 | |||
387 | set_subcores_per_core(1); | ||
388 | |||
389 | return device_create_file(cpu_subsys.dev_root, | ||
390 | &dev_attr_subcores_per_core); | ||
391 | } | ||
392 | machine_device_initcall(powernv, subcore_init); | ||
diff --git a/arch/powerpc/platforms/powernv/subcore.h b/arch/powerpc/platforms/powernv/subcore.h new file mode 100644 index 000000000000..148abc91debf --- /dev/null +++ b/arch/powerpc/platforms/powernv/subcore.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * Copyright 2013, Michael Ellerman, IBM Corporation. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | /* These are ordered and tested with <= */ | ||
11 | #define SYNC_STEP_INITIAL 0 | ||
12 | #define SYNC_STEP_UNSPLIT 1 /* Set by secondary when it sees unsplit */ | ||
13 | #define SYNC_STEP_REAL_MODE 2 /* Set by secondary when in real mode */ | ||
14 | #define SYNC_STEP_FINISHED 3 /* Set by secondary when split/unsplit is done */ | ||
15 | |||
16 | #ifndef __ASSEMBLY__ | ||
17 | void split_core_secondary_loop(u8 *state); | ||
18 | #endif | ||
diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c index 8a8f0472d98f..0bec0c02c5e7 100644 --- a/arch/powerpc/platforms/pseries/eeh_pseries.c +++ b/arch/powerpc/platforms/pseries/eeh_pseries.c | |||
@@ -175,6 +175,36 @@ static int pseries_eeh_find_cap(struct device_node *dn, int cap) | |||
175 | return 0; | 175 | return 0; |
176 | } | 176 | } |
177 | 177 | ||
178 | static int pseries_eeh_find_ecap(struct device_node *dn, int cap) | ||
179 | { | ||
180 | struct pci_dn *pdn = PCI_DN(dn); | ||
181 | struct eeh_dev *edev = of_node_to_eeh_dev(dn); | ||
182 | u32 header; | ||
183 | int pos = 256; | ||
184 | int ttl = (4096 - 256) / 8; | ||
185 | |||
186 | if (!edev || !edev->pcie_cap) | ||
187 | return 0; | ||
188 | if (rtas_read_config(pdn, pos, 4, &header) != PCIBIOS_SUCCESSFUL) | ||
189 | return 0; | ||
190 | else if (!header) | ||
191 | return 0; | ||
192 | |||
193 | while (ttl-- > 0) { | ||
194 | if (PCI_EXT_CAP_ID(header) == cap && pos) | ||
195 | return pos; | ||
196 | |||
197 | pos = PCI_EXT_CAP_NEXT(header); | ||
198 | if (pos < 256) | ||
199 | break; | ||
200 | |||
201 | if (rtas_read_config(pdn, pos, 4, &header) != PCIBIOS_SUCCESSFUL) | ||
202 | break; | ||
203 | } | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | |||
178 | /** | 208 | /** |
179 | * pseries_eeh_of_probe - EEH probe on the given device | 209 | * pseries_eeh_of_probe - EEH probe on the given device |
180 | * @dn: OF node | 210 | * @dn: OF node |
@@ -220,7 +250,9 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag) | |||
220 | * or PCIe switch downstream port. | 250 | * or PCIe switch downstream port. |
221 | */ | 251 | */ |
222 | edev->class_code = class_code; | 252 | edev->class_code = class_code; |
253 | edev->pcix_cap = pseries_eeh_find_cap(dn, PCI_CAP_ID_PCIX); | ||
223 | edev->pcie_cap = pseries_eeh_find_cap(dn, PCI_CAP_ID_EXP); | 254 | edev->pcie_cap = pseries_eeh_find_cap(dn, PCI_CAP_ID_EXP); |
255 | edev->aer_cap = pseries_eeh_find_ecap(dn, PCI_EXT_CAP_ID_ERR); | ||
224 | edev->mode &= 0xFFFFFF00; | 256 | edev->mode &= 0xFFFFFF00; |
225 | if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) { | 257 | if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) { |
226 | edev->mode |= EEH_DEV_BRIDGE; | 258 | edev->mode |= EEH_DEV_BRIDGE; |
@@ -464,6 +496,7 @@ static int pseries_eeh_get_state(struct eeh_pe *pe, int *state) | |||
464 | } else { | 496 | } else { |
465 | result = EEH_STATE_NOT_SUPPORT; | 497 | result = EEH_STATE_NOT_SUPPORT; |
466 | } | 498 | } |
499 | break; | ||
467 | default: | 500 | default: |
468 | result = EEH_STATE_NOT_SUPPORT; | 501 | result = EEH_STATE_NOT_SUPPORT; |
469 | } | 502 | } |
@@ -499,11 +532,19 @@ static int pseries_eeh_reset(struct eeh_pe *pe, int option) | |||
499 | /* If fundamental-reset not supported, try hot-reset */ | 532 | /* If fundamental-reset not supported, try hot-reset */ |
500 | if (option == EEH_RESET_FUNDAMENTAL && | 533 | if (option == EEH_RESET_FUNDAMENTAL && |
501 | ret == -8) { | 534 | ret == -8) { |
535 | option = EEH_RESET_HOT; | ||
502 | ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL, | 536 | ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL, |
503 | config_addr, BUID_HI(pe->phb->buid), | 537 | config_addr, BUID_HI(pe->phb->buid), |
504 | BUID_LO(pe->phb->buid), EEH_RESET_HOT); | 538 | BUID_LO(pe->phb->buid), option); |
505 | } | 539 | } |
506 | 540 | ||
541 | /* We need reset hold or settlement delay */ | ||
542 | if (option == EEH_RESET_FUNDAMENTAL || | ||
543 | option == EEH_RESET_HOT) | ||
544 | msleep(EEH_PE_RST_HOLD_TIME); | ||
545 | else | ||
546 | msleep(EEH_PE_RST_SETTLE_TIME); | ||
547 | |||
507 | return ret; | 548 | return ret; |
508 | } | 549 | } |
509 | 550 | ||
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 7f75c94af822..7995135170a3 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <asm/prom.h> | 21 | #include <asm/prom.h> |
22 | #include <asm/sparsemem.h> | 22 | #include <asm/sparsemem.h> |
23 | 23 | ||
24 | static unsigned long get_memblock_size(void) | 24 | unsigned long pseries_memory_block_size(void) |
25 | { | 25 | { |
26 | struct device_node *np; | 26 | struct device_node *np; |
27 | unsigned int memblock_size = MIN_MEMORY_BLOCK_SIZE; | 27 | unsigned int memblock_size = MIN_MEMORY_BLOCK_SIZE; |
@@ -64,17 +64,6 @@ static unsigned long get_memblock_size(void) | |||
64 | return memblock_size; | 64 | return memblock_size; |
65 | } | 65 | } |
66 | 66 | ||
67 | /* WARNING: This is going to override the generic definition whenever | ||
68 | * pseries is built-in regardless of what platform is active at boot | ||
69 | * time. This is fine for now as this is the only "option" and it | ||
70 | * should work everywhere. If not, we'll have to turn this into a | ||
71 | * ppc_md. callback | ||
72 | */ | ||
73 | unsigned long memory_block_size_bytes(void) | ||
74 | { | ||
75 | return get_memblock_size(); | ||
76 | } | ||
77 | |||
78 | #ifdef CONFIG_MEMORY_HOTREMOVE | 67 | #ifdef CONFIG_MEMORY_HOTREMOVE |
79 | static int pseries_remove_memory(u64 start, u64 size) | 68 | static int pseries_remove_memory(u64 start, u64 size) |
80 | { | 69 | { |
@@ -105,7 +94,7 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_siz | |||
105 | if (!pfn_valid(start_pfn)) | 94 | if (!pfn_valid(start_pfn)) |
106 | goto out; | 95 | goto out; |
107 | 96 | ||
108 | block_sz = memory_block_size_bytes(); | 97 | block_sz = pseries_memory_block_size(); |
109 | sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; | 98 | sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; |
110 | nid = memory_add_physaddr_to_nid(base); | 99 | nid = memory_add_physaddr_to_nid(base); |
111 | 100 | ||
@@ -201,7 +190,7 @@ static int pseries_update_drconf_memory(struct of_prop_reconfig *pr) | |||
201 | u32 *p; | 190 | u32 *p; |
202 | int i, rc = -EINVAL; | 191 | int i, rc = -EINVAL; |
203 | 192 | ||
204 | memblock_size = get_memblock_size(); | 193 | memblock_size = pseries_memory_block_size(); |
205 | if (!memblock_size) | 194 | if (!memblock_size) |
206 | return -EINVAL; | 195 | return -EINVAL; |
207 | 196 | ||
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S index 444fe7759e55..99ecf0a5a929 100644 --- a/arch/powerpc/platforms/pseries/hvCall.S +++ b/arch/powerpc/platforms/pseries/hvCall.S | |||
@@ -49,7 +49,7 @@ END_FTR_SECTION(0, 1); \ | |||
49 | std r0,16(r1); \ | 49 | std r0,16(r1); \ |
50 | addi r4,r1,STK_PARAM(FIRST_REG); \ | 50 | addi r4,r1,STK_PARAM(FIRST_REG); \ |
51 | stdu r1,-STACK_FRAME_OVERHEAD(r1); \ | 51 | stdu r1,-STACK_FRAME_OVERHEAD(r1); \ |
52 | bl .__trace_hcall_entry; \ | 52 | bl __trace_hcall_entry; \ |
53 | addi r1,r1,STACK_FRAME_OVERHEAD; \ | 53 | addi r1,r1,STACK_FRAME_OVERHEAD; \ |
54 | ld r0,16(r1); \ | 54 | ld r0,16(r1); \ |
55 | ld r3,STK_PARAM(R3)(r1); \ | 55 | ld r3,STK_PARAM(R3)(r1); \ |
@@ -83,7 +83,7 @@ END_FTR_SECTION(0, 1); \ | |||
83 | mr r3,r6; \ | 83 | mr r3,r6; \ |
84 | std r0,16(r1); \ | 84 | std r0,16(r1); \ |
85 | stdu r1,-STACK_FRAME_OVERHEAD(r1); \ | 85 | stdu r1,-STACK_FRAME_OVERHEAD(r1); \ |
86 | bl .__trace_hcall_exit; \ | 86 | bl __trace_hcall_exit; \ |
87 | addi r1,r1,STACK_FRAME_OVERHEAD; \ | 87 | addi r1,r1,STACK_FRAME_OVERHEAD; \ |
88 | ld r0,16(r1); \ | 88 | ld r0,16(r1); \ |
89 | ld r3,STK_PARAM(R3)(r1); \ | 89 | ld r3,STK_PARAM(R3)(r1); \ |
@@ -106,7 +106,7 @@ END_FTR_SECTION(0, 1); \ | |||
106 | 106 | ||
107 | .text | 107 | .text |
108 | 108 | ||
109 | _GLOBAL(plpar_hcall_norets) | 109 | _GLOBAL_TOC(plpar_hcall_norets) |
110 | HMT_MEDIUM | 110 | HMT_MEDIUM |
111 | 111 | ||
112 | mfcr r0 | 112 | mfcr r0 |
@@ -122,7 +122,7 @@ _GLOBAL(plpar_hcall_norets) | |||
122 | mtcrf 0xff,r0 | 122 | mtcrf 0xff,r0 |
123 | blr /* return r3 = status */ | 123 | blr /* return r3 = status */ |
124 | 124 | ||
125 | _GLOBAL(plpar_hcall) | 125 | _GLOBAL_TOC(plpar_hcall) |
126 | HMT_MEDIUM | 126 | HMT_MEDIUM |
127 | 127 | ||
128 | mfcr r0 | 128 | mfcr r0 |
@@ -188,7 +188,7 @@ _GLOBAL(plpar_hcall_raw) | |||
188 | 188 | ||
189 | blr /* return r3 = status */ | 189 | blr /* return r3 = status */ |
190 | 190 | ||
191 | _GLOBAL(plpar_hcall9) | 191 | _GLOBAL_TOC(plpar_hcall9) |
192 | HMT_MEDIUM | 192 | HMT_MEDIUM |
193 | 193 | ||
194 | mfcr r0 | 194 | mfcr r0 |
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 99219530ea4a..361add62abf1 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h | |||
@@ -64,4 +64,6 @@ extern int dlpar_detach_node(struct device_node *); | |||
64 | struct pci_host_bridge; | 64 | struct pci_host_bridge; |
65 | int pseries_root_bridge_prepare(struct pci_host_bridge *bridge); | 65 | int pseries_root_bridge_prepare(struct pci_host_bridge *bridge); |
66 | 66 | ||
67 | unsigned long pseries_memory_block_size(void); | ||
68 | |||
67 | #endif /* _PSERIES_PSERIES_H */ | 69 | #endif /* _PSERIES_PSERIES_H */ |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 099d2df976a2..f2f40e64658f 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -510,7 +510,11 @@ static void __init pSeries_setup_arch(void) | |||
510 | static int __init pSeries_init_panel(void) | 510 | static int __init pSeries_init_panel(void) |
511 | { | 511 | { |
512 | /* Manually leave the kernel version on the panel. */ | 512 | /* Manually leave the kernel version on the panel. */ |
513 | #ifdef __BIG_ENDIAN__ | ||
513 | ppc_md.progress("Linux ppc64\n", 0); | 514 | ppc_md.progress("Linux ppc64\n", 0); |
515 | #else | ||
516 | ppc_md.progress("Linux ppc64le\n", 0); | ||
517 | #endif | ||
514 | ppc_md.progress(init_utsname()->version, 0); | 518 | ppc_md.progress(init_utsname()->version, 0); |
515 | 519 | ||
516 | return 0; | 520 | return 0; |
@@ -806,4 +810,7 @@ define_machine(pseries) { | |||
806 | #ifdef CONFIG_KEXEC | 810 | #ifdef CONFIG_KEXEC |
807 | .machine_kexec = pSeries_machine_kexec, | 811 | .machine_kexec = pSeries_machine_kexec, |
808 | #endif | 812 | #endif |
813 | #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE | ||
814 | .memory_block_size = pseries_memory_block_size, | ||
815 | #endif | ||
809 | }; | 816 | }; |
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 24f58cb0a543..a3555b10c1a5 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <asm/xics.h> | 44 | #include <asm/xics.h> |
45 | #include <asm/dbell.h> | 45 | #include <asm/dbell.h> |
46 | #include <asm/plpar_wrappers.h> | 46 | #include <asm/plpar_wrappers.h> |
47 | #include <asm/code-patching.h> | ||
47 | 48 | ||
48 | #include "pseries.h" | 49 | #include "pseries.h" |
49 | #include "offline_states.h" | 50 | #include "offline_states.h" |
@@ -96,8 +97,8 @@ int smp_query_cpu_stopped(unsigned int pcpu) | |||
96 | static inline int smp_startup_cpu(unsigned int lcpu) | 97 | static inline int smp_startup_cpu(unsigned int lcpu) |
97 | { | 98 | { |
98 | int status; | 99 | int status; |
99 | unsigned long start_here = __pa((u32)*((unsigned long *) | 100 | unsigned long start_here = |
100 | generic_secondary_smp_init)); | 101 | __pa(ppc_function_entry(generic_secondary_smp_init)); |
101 | unsigned int pcpu; | 102 | unsigned int pcpu; |
102 | int start_cpu; | 103 | int start_cpu; |
103 | 104 | ||
diff --git a/arch/powerpc/platforms/wsp/scom_smp.c b/arch/powerpc/platforms/wsp/scom_smp.c index 268bc899c1f7..8c79ce016cf1 100644 --- a/arch/powerpc/platforms/wsp/scom_smp.c +++ b/arch/powerpc/platforms/wsp/scom_smp.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <asm/reg_a2.h> | 20 | #include <asm/reg_a2.h> |
21 | #include <asm/scom.h> | 21 | #include <asm/scom.h> |
22 | #include <asm/udbg.h> | 22 | #include <asm/udbg.h> |
23 | #include <asm/code-patching.h> | ||
23 | 24 | ||
24 | #include "wsp.h" | 25 | #include "wsp.h" |
25 | 26 | ||
@@ -405,7 +406,7 @@ int a2_scom_startup_cpu(unsigned int lcpu, int thr_idx, struct device_node *np) | |||
405 | goto fail; | 406 | goto fail; |
406 | } | 407 | } |
407 | 408 | ||
408 | start_here = *(unsigned long *)(core_setup ? generic_secondary_smp_init | 409 | start_here = ppc_function_entry(core_setup ? generic_secondary_smp_init |
409 | : generic_secondary_thread_init); | 410 | : generic_secondary_thread_init); |
410 | pr_devel("CPU%d entry point at 0x%lx...\n", lcpu, start_here); | 411 | pr_devel("CPU%d entry point at 0x%lx...\n", lcpu, start_here); |
411 | 412 | ||
diff --git a/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig index 7baa70d6dc01..a19332a38715 100644 --- a/arch/powerpc/sysdev/Kconfig +++ b/arch/powerpc/sysdev/Kconfig | |||
@@ -7,6 +7,12 @@ config PPC4xx_PCI_EXPRESS | |||
7 | depends on PCI && 4xx | 7 | depends on PCI && 4xx |
8 | default n | 8 | default n |
9 | 9 | ||
10 | config PPC4xx_HSTA_MSI | ||
11 | bool | ||
12 | depends on PCI_MSI | ||
13 | depends on PCI && 4xx | ||
14 | default n | ||
15 | |||
10 | config PPC4xx_MSI | 16 | config PPC4xx_MSI |
11 | bool | 17 | bool |
12 | depends on PCI_MSI | 18 | depends on PCI_MSI |
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index afbcc37aa094..f7cb2a1b01fa 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile | |||
@@ -45,6 +45,7 @@ obj-$(CONFIG_OF_RTC) += of_rtc.o | |||
45 | ifeq ($(CONFIG_PCI),y) | 45 | ifeq ($(CONFIG_PCI),y) |
46 | obj-$(CONFIG_4xx) += ppc4xx_pci.o | 46 | obj-$(CONFIG_4xx) += ppc4xx_pci.o |
47 | endif | 47 | endif |
48 | obj-$(CONFIG_PPC4xx_HSTA_MSI) += ppc4xx_hsta_msi.o | ||
48 | obj-$(CONFIG_PPC4xx_MSI) += ppc4xx_msi.o | 49 | obj-$(CONFIG_PPC4xx_MSI) += ppc4xx_msi.o |
49 | obj-$(CONFIG_PPC4xx_CPM) += ppc4xx_cpm.o | 50 | obj-$(CONFIG_PPC4xx_CPM) += ppc4xx_cpm.o |
50 | obj-$(CONFIG_PPC4xx_GPIO) += ppc4xx_gpio.o | 51 | obj-$(CONFIG_PPC4xx_GPIO) += ppc4xx_gpio.o |
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 3f415e252ea5..4bd091a05583 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c | |||
@@ -1150,8 +1150,7 @@ static int fsl_pci_pme_probe(struct pci_controller *hose) | |||
1150 | pci = hose->private_data; | 1150 | pci = hose->private_data; |
1151 | 1151 | ||
1152 | /* Enable PTOD, ENL23D & EXL23D */ | 1152 | /* Enable PTOD, ENL23D & EXL23D */ |
1153 | out_be32(&pci->pex_pme_mes_disr, 0); | 1153 | clrbits32(&pci->pex_pme_mes_disr, |
1154 | setbits32(&pci->pex_pme_mes_disr, | ||
1155 | PME_DISR_EN_PTOD | PME_DISR_EN_ENL23D | PME_DISR_EN_EXL23D); | 1154 | PME_DISR_EN_PTOD | PME_DISR_EN_ENL23D | PME_DISR_EN_EXL23D); |
1156 | 1155 | ||
1157 | out_be32(&pci->pex_pme_mes_ier, 0); | 1156 | out_be32(&pci->pex_pme_mes_ier, 0); |
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index cf2b0840a672..c04b718307c8 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c | |||
@@ -391,8 +391,10 @@ int fsl_rio_setup(struct platform_device *dev) | |||
391 | ops->get_inb_message = fsl_get_inb_message; | 391 | ops->get_inb_message = fsl_get_inb_message; |
392 | 392 | ||
393 | rmu_node = of_parse_phandle(dev->dev.of_node, "fsl,srio-rmu-handle", 0); | 393 | rmu_node = of_parse_phandle(dev->dev.of_node, "fsl,srio-rmu-handle", 0); |
394 | if (!rmu_node) | 394 | if (!rmu_node) { |
395 | dev_err(&dev->dev, "No valid fsl,srio-rmu-handle property\n"); | ||
395 | goto err_rmu; | 396 | goto err_rmu; |
397 | } | ||
396 | rc = of_address_to_resource(rmu_node, 0, &rmu_regs); | 398 | rc = of_address_to_resource(rmu_node, 0, &rmu_regs); |
397 | if (rc) { | 399 | if (rc) { |
398 | dev_err(&dev->dev, "Can't get %s property 'reg'\n", | 400 | dev_err(&dev->dev, "Can't get %s property 'reg'\n", |
@@ -413,6 +415,7 @@ int fsl_rio_setup(struct platform_device *dev) | |||
413 | /*set up doobell node*/ | 415 | /*set up doobell node*/ |
414 | np = of_find_compatible_node(NULL, NULL, "fsl,srio-dbell-unit"); | 416 | np = of_find_compatible_node(NULL, NULL, "fsl,srio-dbell-unit"); |
415 | if (!np) { | 417 | if (!np) { |
418 | dev_err(&dev->dev, "No fsl,srio-dbell-unit node\n"); | ||
416 | rc = -ENODEV; | 419 | rc = -ENODEV; |
417 | goto err_dbell; | 420 | goto err_dbell; |
418 | } | 421 | } |
@@ -441,6 +444,7 @@ int fsl_rio_setup(struct platform_device *dev) | |||
441 | /*set up port write node*/ | 444 | /*set up port write node*/ |
442 | np = of_find_compatible_node(NULL, NULL, "fsl,srio-port-write-unit"); | 445 | np = of_find_compatible_node(NULL, NULL, "fsl,srio-port-write-unit"); |
443 | if (!np) { | 446 | if (!np) { |
447 | dev_err(&dev->dev, "No fsl,srio-port-write-unit node\n"); | ||
444 | rc = -ENODEV; | 448 | rc = -ENODEV; |
445 | goto err_pw; | 449 | goto err_pw; |
446 | } | 450 | } |
@@ -633,14 +637,18 @@ int fsl_rio_setup(struct platform_device *dev) | |||
633 | return 0; | 637 | return 0; |
634 | err: | 638 | err: |
635 | kfree(pw); | 639 | kfree(pw); |
640 | pw = NULL; | ||
636 | err_pw: | 641 | err_pw: |
637 | kfree(dbell); | 642 | kfree(dbell); |
643 | dbell = NULL; | ||
638 | err_dbell: | 644 | err_dbell: |
639 | iounmap(rmu_regs_win); | 645 | iounmap(rmu_regs_win); |
646 | rmu_regs_win = NULL; | ||
640 | err_rmu: | 647 | err_rmu: |
641 | kfree(ops); | 648 | kfree(ops); |
642 | err_ops: | 649 | err_ops: |
643 | iounmap(rio_regs_win); | 650 | iounmap(rio_regs_win); |
651 | rio_regs_win = NULL; | ||
644 | err_rio_regs: | 652 | err_rio_regs: |
645 | return rc; | 653 | return rc; |
646 | } | 654 | } |
diff --git a/arch/powerpc/sysdev/fsl_rmu.c b/arch/powerpc/sysdev/fsl_rmu.c index 00e224a1048c..b48197ae44d0 100644 --- a/arch/powerpc/sysdev/fsl_rmu.c +++ b/arch/powerpc/sysdev/fsl_rmu.c | |||
@@ -881,9 +881,9 @@ fsl_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries) | |||
881 | rc = request_irq(IRQ_RIO_RX(mport), fsl_rio_rx_handler, 0, | 881 | rc = request_irq(IRQ_RIO_RX(mport), fsl_rio_rx_handler, 0, |
882 | "msg_rx", (void *)mport); | 882 | "msg_rx", (void *)mport); |
883 | if (rc < 0) { | 883 | if (rc < 0) { |
884 | dma_free_coherent(priv->dev, RIO_MSG_BUFFER_SIZE, | 884 | dma_free_coherent(priv->dev, |
885 | rmu->msg_tx_ring.virt_buffer[i], | 885 | rmu->msg_rx_ring.size * RIO_MAX_MSG_SIZE, |
886 | rmu->msg_tx_ring.phys_buffer[i]); | 886 | rmu->msg_rx_ring.virt, rmu->msg_rx_ring.phys); |
887 | goto out; | 887 | goto out; |
888 | } | 888 | } |
889 | 889 | ||
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 8209744b2829..be33c9768ea1 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
@@ -1588,10 +1588,6 @@ void __init mpic_init(struct mpic *mpic) | |||
1588 | num_timers = 8; | 1588 | num_timers = 8; |
1589 | } | 1589 | } |
1590 | 1590 | ||
1591 | /* FSL mpic error interrupt intialization */ | ||
1592 | if (mpic->flags & MPIC_FSL_HAS_EIMR) | ||
1593 | mpic_err_int_init(mpic, MPIC_FSL_ERR_INT); | ||
1594 | |||
1595 | /* Initialize timers to our reserved vectors and mask them for now */ | 1591 | /* Initialize timers to our reserved vectors and mask them for now */ |
1596 | for (i = 0; i < num_timers; i++) { | 1592 | for (i = 0; i < num_timers; i++) { |
1597 | unsigned int offset = mpic_tm_offset(mpic, i); | 1593 | unsigned int offset = mpic_tm_offset(mpic, i); |
@@ -1675,6 +1671,10 @@ void __init mpic_init(struct mpic *mpic) | |||
1675 | irq_set_chained_handler(virq, &mpic_cascade); | 1671 | irq_set_chained_handler(virq, &mpic_cascade); |
1676 | } | 1672 | } |
1677 | } | 1673 | } |
1674 | |||
1675 | /* FSL mpic error interrupt intialization */ | ||
1676 | if (mpic->flags & MPIC_FSL_HAS_EIMR) | ||
1677 | mpic_err_int_init(mpic, MPIC_FSL_ERR_INT); | ||
1678 | } | 1678 | } |
1679 | 1679 | ||
1680 | void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio) | 1680 | void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio) |
diff --git a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c new file mode 100644 index 000000000000..11c888416f0a --- /dev/null +++ b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c | |||
@@ -0,0 +1,215 @@ | |||
1 | /* | ||
2 | * MSI support for PPC4xx SoCs using High Speed Transfer Assist (HSTA) for | ||
3 | * generation of the interrupt. | ||
4 | * | ||
5 | * Copyright © 2013 Alistair Popple <alistair@popple.id.au> IBM Corporation | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/msi.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/of_platform.h> | ||
18 | #include <linux/pci.h> | ||
19 | #include <linux/semaphore.h> | ||
20 | #include <asm/msi_bitmap.h> | ||
21 | |||
22 | struct ppc4xx_hsta_msi { | ||
23 | struct device *dev; | ||
24 | |||
25 | /* The ioremapped HSTA MSI IO space */ | ||
26 | u32 __iomem *data; | ||
27 | |||
28 | /* Physical address of HSTA MSI IO space */ | ||
29 | u64 address; | ||
30 | struct msi_bitmap bmp; | ||
31 | |||
32 | /* An array mapping offsets to hardware IRQs */ | ||
33 | int *irq_map; | ||
34 | |||
35 | /* Number of hwirqs supported */ | ||
36 | int irq_count; | ||
37 | }; | ||
38 | static struct ppc4xx_hsta_msi ppc4xx_hsta_msi; | ||
39 | |||
40 | static int hsta_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | ||
41 | { | ||
42 | struct msi_msg msg; | ||
43 | struct msi_desc *entry; | ||
44 | int irq, hwirq; | ||
45 | u64 addr; | ||
46 | |||
47 | list_for_each_entry(entry, &dev->msi_list, list) { | ||
48 | irq = msi_bitmap_alloc_hwirqs(&ppc4xx_hsta_msi.bmp, 1); | ||
49 | if (irq < 0) { | ||
50 | pr_debug("%s: Failed to allocate msi interrupt\n", | ||
51 | __func__); | ||
52 | return irq; | ||
53 | } | ||
54 | |||
55 | hwirq = ppc4xx_hsta_msi.irq_map[irq]; | ||
56 | if (hwirq == NO_IRQ) { | ||
57 | pr_err("%s: Failed mapping irq %d\n", __func__, irq); | ||
58 | return -EINVAL; | ||
59 | } | ||
60 | |||
61 | /* | ||
62 | * HSTA generates interrupts on writes to 128-bit aligned | ||
63 | * addresses. | ||
64 | */ | ||
65 | addr = ppc4xx_hsta_msi.address + irq*0x10; | ||
66 | msg.address_hi = upper_32_bits(addr); | ||
67 | msg.address_lo = lower_32_bits(addr); | ||
68 | |||
69 | /* Data is not used by the HSTA. */ | ||
70 | msg.data = 0; | ||
71 | |||
72 | pr_debug("%s: Setup irq %d (0x%0llx)\n", __func__, hwirq, | ||
73 | (((u64) msg.address_hi) << 32) | msg.address_lo); | ||
74 | |||
75 | if (irq_set_msi_desc(hwirq, entry)) { | ||
76 | pr_err( | ||
77 | "%s: Invalid hwirq %d specified in device tree\n", | ||
78 | __func__, hwirq); | ||
79 | msi_bitmap_free_hwirqs(&ppc4xx_hsta_msi.bmp, irq, 1); | ||
80 | return -EINVAL; | ||
81 | } | ||
82 | write_msi_msg(hwirq, &msg); | ||
83 | } | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static int hsta_find_hwirq_offset(int hwirq) | ||
89 | { | ||
90 | int irq; | ||
91 | |||
92 | /* Find the offset given the hwirq */ | ||
93 | for (irq = 0; irq < ppc4xx_hsta_msi.irq_count; irq++) | ||
94 | if (ppc4xx_hsta_msi.irq_map[irq] == hwirq) | ||
95 | return irq; | ||
96 | |||
97 | return -EINVAL; | ||
98 | } | ||
99 | |||
100 | static void hsta_teardown_msi_irqs(struct pci_dev *dev) | ||
101 | { | ||
102 | struct msi_desc *entry; | ||
103 | int irq; | ||
104 | |||
105 | list_for_each_entry(entry, &dev->msi_list, list) { | ||
106 | if (entry->irq == NO_IRQ) | ||
107 | continue; | ||
108 | |||
109 | irq = hsta_find_hwirq_offset(entry->irq); | ||
110 | |||
111 | /* entry->irq should always be in irq_map */ | ||
112 | BUG_ON(irq < 0); | ||
113 | irq_set_msi_desc(entry->irq, NULL); | ||
114 | msi_bitmap_free_hwirqs(&ppc4xx_hsta_msi.bmp, irq, 1); | ||
115 | pr_debug("%s: Teardown IRQ %u (index %u)\n", __func__, | ||
116 | entry->irq, irq); | ||
117 | } | ||
118 | } | ||
119 | |||
120 | static int hsta_msi_check_device(struct pci_dev *pdev, int nvec, int type) | ||
121 | { | ||
122 | /* We don't support MSI-X */ | ||
123 | if (type == PCI_CAP_ID_MSIX) { | ||
124 | pr_debug("%s: MSI-X not supported.\n", __func__); | ||
125 | return -EINVAL; | ||
126 | } | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static int hsta_msi_probe(struct platform_device *pdev) | ||
132 | { | ||
133 | struct device *dev = &pdev->dev; | ||
134 | struct resource *mem; | ||
135 | int irq, ret, irq_count; | ||
136 | |||
137 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
138 | if (IS_ERR(mem)) { | ||
139 | dev_err(dev, "Unable to get mmio space\n"); | ||
140 | return -EINVAL; | ||
141 | } | ||
142 | |||
143 | irq_count = of_irq_count(dev->of_node); | ||
144 | if (!irq_count) { | ||
145 | dev_err(dev, "Unable to find IRQ range\n"); | ||
146 | return -EINVAL; | ||
147 | } | ||
148 | |||
149 | ppc4xx_hsta_msi.dev = dev; | ||
150 | ppc4xx_hsta_msi.address = mem->start; | ||
151 | ppc4xx_hsta_msi.data = ioremap(mem->start, resource_size(mem)); | ||
152 | ppc4xx_hsta_msi.irq_count = irq_count; | ||
153 | if (IS_ERR(ppc4xx_hsta_msi.data)) { | ||
154 | dev_err(dev, "Unable to map memory\n"); | ||
155 | return -ENOMEM; | ||
156 | } | ||
157 | |||
158 | ret = msi_bitmap_alloc(&ppc4xx_hsta_msi.bmp, irq_count, dev->of_node); | ||
159 | if (ret) | ||
160 | goto out; | ||
161 | |||
162 | ppc4xx_hsta_msi.irq_map = kmalloc(sizeof(int) * irq_count, GFP_KERNEL); | ||
163 | if (IS_ERR(ppc4xx_hsta_msi.irq_map)) { | ||
164 | ret = -ENOMEM; | ||
165 | goto out1; | ||
166 | } | ||
167 | |||
168 | /* Setup a mapping from irq offsets to hardware irq numbers */ | ||
169 | for (irq = 0; irq < irq_count; irq++) { | ||
170 | ppc4xx_hsta_msi.irq_map[irq] = | ||
171 | irq_of_parse_and_map(dev->of_node, irq); | ||
172 | if (ppc4xx_hsta_msi.irq_map[irq] == NO_IRQ) { | ||
173 | dev_err(dev, "Unable to map IRQ\n"); | ||
174 | ret = -EINVAL; | ||
175 | goto out2; | ||
176 | } | ||
177 | } | ||
178 | |||
179 | ppc_md.setup_msi_irqs = hsta_setup_msi_irqs; | ||
180 | ppc_md.teardown_msi_irqs = hsta_teardown_msi_irqs; | ||
181 | ppc_md.msi_check_device = hsta_msi_check_device; | ||
182 | return 0; | ||
183 | |||
184 | out2: | ||
185 | kfree(ppc4xx_hsta_msi.irq_map); | ||
186 | |||
187 | out1: | ||
188 | msi_bitmap_free(&ppc4xx_hsta_msi.bmp); | ||
189 | |||
190 | out: | ||
191 | iounmap(ppc4xx_hsta_msi.data); | ||
192 | return ret; | ||
193 | } | ||
194 | |||
195 | static const struct of_device_id hsta_msi_ids[] = { | ||
196 | { | ||
197 | .compatible = "ibm,hsta-msi", | ||
198 | }, | ||
199 | {} | ||
200 | }; | ||
201 | |||
202 | static struct platform_driver hsta_msi_driver = { | ||
203 | .probe = hsta_msi_probe, | ||
204 | .driver = { | ||
205 | .name = "hsta-msi", | ||
206 | .owner = THIS_MODULE, | ||
207 | .of_match_table = hsta_msi_ids, | ||
208 | }, | ||
209 | }; | ||
210 | |||
211 | static int hsta_msi_init(void) | ||
212 | { | ||
213 | return platform_driver_register(&hsta_msi_driver); | ||
214 | } | ||
215 | subsys_initcall(hsta_msi_init); | ||
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index 4914fd3f41ec..df6e2fc4ff92 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c | |||
@@ -176,8 +176,12 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose, | |||
176 | return -ENXIO; | 176 | return -ENXIO; |
177 | } | 177 | } |
178 | 178 | ||
179 | /* Check that we are fully contained within 32 bits space */ | 179 | /* Check that we are fully contained within 32 bits space if we are not |
180 | if (res->end > 0xffffffff) { | 180 | * running on a 460sx or 476fpe which have 64 bit bus addresses. |
181 | */ | ||
182 | if (res->end > 0xffffffff && | ||
183 | !(of_device_is_compatible(hose->dn, "ibm,plb-pciex-460sx") | ||
184 | || of_device_is_compatible(hose->dn, "ibm,plb-pciex-476fpe"))) { | ||
181 | printk(KERN_ERR "%s: dma-ranges outside of 32 bits space\n", | 185 | printk(KERN_ERR "%s: dma-ranges outside of 32 bits space\n", |
182 | hose->dn->full_name); | 186 | hose->dn->full_name); |
183 | return -ENXIO; | 187 | return -ENXIO; |
@@ -1440,7 +1444,8 @@ static int __init ppc4xx_pciex_check_core_init(struct device_node *np) | |||
1440 | ppc4xx_pciex_hwops = &ppc405ex_pcie_hwops; | 1444 | ppc4xx_pciex_hwops = &ppc405ex_pcie_hwops; |
1441 | #endif | 1445 | #endif |
1442 | #ifdef CONFIG_476FPE | 1446 | #ifdef CONFIG_476FPE |
1443 | if (of_device_is_compatible(np, "ibm,plb-pciex-476fpe")) | 1447 | if (of_device_is_compatible(np, "ibm,plb-pciex-476fpe") |
1448 | || of_device_is_compatible(np, "ibm,plb-pciex-476gtr")) | ||
1444 | ppc4xx_pciex_hwops = &ppc_476fpe_pcie_hwops; | 1449 | ppc4xx_pciex_hwops = &ppc_476fpe_pcie_hwops; |
1445 | #endif | 1450 | #endif |
1446 | if (ppc4xx_pciex_hwops == NULL) { | 1451 | if (ppc4xx_pciex_hwops == NULL) { |
@@ -1751,7 +1756,10 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port, | |||
1751 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, | 1756 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, |
1752 | sa | DCRO_PEGPL_460SX_OMR1MSKL_UOT | 1757 | sa | DCRO_PEGPL_460SX_OMR1MSKL_UOT |
1753 | | DCRO_PEGPL_OMRxMSKL_VAL); | 1758 | | DCRO_PEGPL_OMRxMSKL_VAL); |
1754 | else if (of_device_is_compatible(port->node, "ibm,plb-pciex-476fpe")) | 1759 | else if (of_device_is_compatible( |
1760 | port->node, "ibm,plb-pciex-476fpe") || | ||
1761 | of_device_is_compatible( | ||
1762 | port->node, "ibm,plb-pciex-476gtr")) | ||
1755 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, | 1763 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, |
1756 | sa | DCRO_PEGPL_476FPE_OMR1MSKL_UOT | 1764 | sa | DCRO_PEGPL_476FPE_OMR1MSKL_UOT |
1757 | | DCRO_PEGPL_OMRxMSKL_VAL); | 1765 | | DCRO_PEGPL_OMRxMSKL_VAL); |
@@ -1881,7 +1889,10 @@ static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port, | |||
1881 | sa |= PCI_BASE_ADDRESS_MEM_PREFETCH; | 1889 | sa |= PCI_BASE_ADDRESS_MEM_PREFETCH; |
1882 | 1890 | ||
1883 | if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx") || | 1891 | if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx") || |
1884 | of_device_is_compatible(port->node, "ibm,plb-pciex-476fpe")) | 1892 | of_device_is_compatible( |
1893 | port->node, "ibm,plb-pciex-476fpe") || | ||
1894 | of_device_is_compatible( | ||
1895 | port->node, "ibm,plb-pciex-476gtr")) | ||
1885 | sa |= PCI_BASE_ADDRESS_MEM_TYPE_64; | 1896 | sa |= PCI_BASE_ADDRESS_MEM_TYPE_64; |
1886 | 1897 | ||
1887 | out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa)); | 1898 | out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa)); |
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 08504e75b2c7..d199bfa2f1fa 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
@@ -419,7 +419,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi) | |||
419 | get_output_lock(); | 419 | get_output_lock(); |
420 | excprint(regs); | 420 | excprint(regs); |
421 | if (bp) { | 421 | if (bp) { |
422 | printf("cpu 0x%x stopped at breakpoint 0x%x (", | 422 | printf("cpu 0x%x stopped at breakpoint 0x%lx (", |
423 | cpu, BP_NUM(bp)); | 423 | cpu, BP_NUM(bp)); |
424 | xmon_print_symbol(regs->nip, " ", ")\n"); | 424 | xmon_print_symbol(regs->nip, " ", ")\n"); |
425 | } | 425 | } |
@@ -513,7 +513,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi) | |||
513 | excprint(regs); | 513 | excprint(regs); |
514 | bp = at_breakpoint(regs->nip); | 514 | bp = at_breakpoint(regs->nip); |
515 | if (bp) { | 515 | if (bp) { |
516 | printf("Stopped at breakpoint %x (", BP_NUM(bp)); | 516 | printf("Stopped at breakpoint %lx (", BP_NUM(bp)); |
517 | xmon_print_symbol(regs->nip, " ", ")\n"); | 517 | xmon_print_symbol(regs->nip, " ", ")\n"); |
518 | } | 518 | } |
519 | if (unrecoverable_excp(regs)) | 519 | if (unrecoverable_excp(regs)) |
@@ -759,7 +759,7 @@ static void insert_cpu_bpts(void) | |||
759 | brk.address = dabr.address; | 759 | brk.address = dabr.address; |
760 | brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL; | 760 | brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL; |
761 | brk.len = 8; | 761 | brk.len = 8; |
762 | set_breakpoint(&brk); | 762 | __set_breakpoint(&brk); |
763 | } | 763 | } |
764 | if (iabr && cpu_has_feature(CPU_FTR_IABR)) | 764 | if (iabr && cpu_has_feature(CPU_FTR_IABR)) |
765 | mtspr(SPRN_IABR, iabr->address | 765 | mtspr(SPRN_IABR, iabr->address |
@@ -997,14 +997,14 @@ static int cpu_cmd(void) | |||
997 | last_cpu = cpu; | 997 | last_cpu = cpu; |
998 | } else { | 998 | } else { |
999 | if (last_cpu != first_cpu) | 999 | if (last_cpu != first_cpu) |
1000 | printf("-%lx", last_cpu); | 1000 | printf("-0x%lx", last_cpu); |
1001 | last_cpu = first_cpu = cpu; | 1001 | last_cpu = first_cpu = cpu; |
1002 | printf(" %lx", cpu); | 1002 | printf(" 0x%lx", cpu); |
1003 | } | 1003 | } |
1004 | } | 1004 | } |
1005 | } | 1005 | } |
1006 | if (last_cpu != first_cpu) | 1006 | if (last_cpu != first_cpu) |
1007 | printf("-%lx", last_cpu); | 1007 | printf("-0x%lx", last_cpu); |
1008 | printf("\n"); | 1008 | printf("\n"); |
1009 | return 0; | 1009 | return 0; |
1010 | } | 1010 | } |
@@ -1024,7 +1024,7 @@ static int cpu_cmd(void) | |||
1024 | /* take control back */ | 1024 | /* take control back */ |
1025 | mb(); | 1025 | mb(); |
1026 | xmon_owner = smp_processor_id(); | 1026 | xmon_owner = smp_processor_id(); |
1027 | printf("cpu %u didn't take control\n", cpu); | 1027 | printf("cpu 0x%x didn't take control\n", cpu); |
1028 | return 0; | 1028 | return 0; |
1029 | } | 1029 | } |
1030 | barrier(); | 1030 | barrier(); |
@@ -1086,7 +1086,7 @@ csum(void) | |||
1086 | fcs = 0xffff; | 1086 | fcs = 0xffff; |
1087 | for (i = 0; i < ncsum; ++i) { | 1087 | for (i = 0; i < ncsum; ++i) { |
1088 | if (mread(adrs+i, &v, 1) == 0) { | 1088 | if (mread(adrs+i, &v, 1) == 0) { |
1089 | printf("csum stopped at %x\n", adrs+i); | 1089 | printf("csum stopped at "REG"\n", adrs+i); |
1090 | break; | 1090 | break; |
1091 | } | 1091 | } |
1092 | fcs = FCS(fcs, v); | 1092 | fcs = FCS(fcs, v); |
@@ -1202,12 +1202,12 @@ bpt_cmds(void) | |||
1202 | /* assume a breakpoint address */ | 1202 | /* assume a breakpoint address */ |
1203 | bp = at_breakpoint(a); | 1203 | bp = at_breakpoint(a); |
1204 | if (bp == NULL) { | 1204 | if (bp == NULL) { |
1205 | printf("No breakpoint at %x\n", a); | 1205 | printf("No breakpoint at %lx\n", a); |
1206 | break; | 1206 | break; |
1207 | } | 1207 | } |
1208 | } | 1208 | } |
1209 | 1209 | ||
1210 | printf("Cleared breakpoint %x (", BP_NUM(bp)); | 1210 | printf("Cleared breakpoint %lx (", BP_NUM(bp)); |
1211 | xmon_print_symbol(bp->address, " ", ")\n"); | 1211 | xmon_print_symbol(bp->address, " ", ")\n"); |
1212 | bp->enabled = 0; | 1212 | bp->enabled = 0; |
1213 | break; | 1213 | break; |
@@ -1746,7 +1746,7 @@ mwrite(unsigned long adrs, void *buf, int size) | |||
1746 | __delay(200); | 1746 | __delay(200); |
1747 | n = size; | 1747 | n = size; |
1748 | } else { | 1748 | } else { |
1749 | printf("*** Error writing address %x\n", adrs + n); | 1749 | printf("*** Error writing address "REG"\n", adrs + n); |
1750 | } | 1750 | } |
1751 | catch_memory_errors = 0; | 1751 | catch_memory_errors = 0; |
1752 | return n; | 1752 | return n; |
@@ -2435,7 +2435,7 @@ static void proccall(void) | |||
2435 | ret = func(args[0], args[1], args[2], args[3], | 2435 | ret = func(args[0], args[1], args[2], args[3], |
2436 | args[4], args[5], args[6], args[7]); | 2436 | args[4], args[5], args[6], args[7]); |
2437 | sync(); | 2437 | sync(); |
2438 | printf("return value is %x\n", ret); | 2438 | printf("return value is 0x%lx\n", ret); |
2439 | } else { | 2439 | } else { |
2440 | printf("*** %x exception occurred\n", fault_except); | 2440 | printf("*** %x exception occurred\n", fault_except); |
2441 | } | 2441 | } |
@@ -2700,7 +2700,7 @@ static void dump_slb(void) | |||
2700 | unsigned long esid,vsid,valid; | 2700 | unsigned long esid,vsid,valid; |
2701 | unsigned long llp; | 2701 | unsigned long llp; |
2702 | 2702 | ||
2703 | printf("SLB contents of cpu %x\n", smp_processor_id()); | 2703 | printf("SLB contents of cpu 0x%x\n", smp_processor_id()); |
2704 | 2704 | ||
2705 | for (i = 0; i < mmu_slb_size; i++) { | 2705 | for (i = 0; i < mmu_slb_size; i++) { |
2706 | asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i)); | 2706 | asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i)); |
@@ -2732,7 +2732,7 @@ static void dump_stab(void) | |||
2732 | int i; | 2732 | int i; |
2733 | unsigned long *tmp = (unsigned long *)local_paca->stab_addr; | 2733 | unsigned long *tmp = (unsigned long *)local_paca->stab_addr; |
2734 | 2734 | ||
2735 | printf("Segment table contents of cpu %x\n", smp_processor_id()); | 2735 | printf("Segment table contents of cpu 0x%x\n", smp_processor_id()); |
2736 | 2736 | ||
2737 | for (i = 0; i < PAGE_SIZE/16; i++) { | 2737 | for (i = 0; i < PAGE_SIZE/16; i++) { |
2738 | unsigned long a, b; | 2738 | unsigned long a, b; |
diff --git a/drivers/macintosh/windfarm_pm121.c b/drivers/macintosh/windfarm_pm121.c index 7fe58b0ae8b4..b350fb86ff08 100644 --- a/drivers/macintosh/windfarm_pm121.c +++ b/drivers/macintosh/windfarm_pm121.c | |||
@@ -555,8 +555,18 @@ static void pm121_create_sys_fans(int loop_id) | |||
555 | pid_param.interval = PM121_SYS_INTERVAL; | 555 | pid_param.interval = PM121_SYS_INTERVAL; |
556 | pid_param.history_len = PM121_SYS_HISTORY_SIZE; | 556 | pid_param.history_len = PM121_SYS_HISTORY_SIZE; |
557 | pid_param.itarget = param->itarget; | 557 | pid_param.itarget = param->itarget; |
558 | pid_param.min = control->ops->get_min(control); | 558 | if(control) |
559 | pid_param.max = control->ops->get_max(control); | 559 | { |
560 | pid_param.min = control->ops->get_min(control); | ||
561 | pid_param.max = control->ops->get_max(control); | ||
562 | } else { | ||
563 | /* | ||
564 | * This is probably not the right!? | ||
565 | * Perhaps goto fail if control == NULL above? | ||
566 | */ | ||
567 | pid_param.min = 0; | ||
568 | pid_param.max = 0; | ||
569 | } | ||
560 | 570 | ||
561 | wf_pid_init(&pm121_sys_state[loop_id]->pid, &pid_param); | 571 | wf_pid_init(&pm121_sys_state[loop_id]->pid, &pid_param); |
562 | 572 | ||
@@ -571,7 +581,7 @@ static void pm121_create_sys_fans(int loop_id) | |||
571 | control the same control */ | 581 | control the same control */ |
572 | printk(KERN_WARNING "pm121: failed to set up %s loop " | 582 | printk(KERN_WARNING "pm121: failed to set up %s loop " |
573 | "setting \"%s\" to max speed.\n", | 583 | "setting \"%s\" to max speed.\n", |
574 | loop_names[loop_id], control->name); | 584 | loop_names[loop_id], control ? control->name : "uninitialized value"); |
575 | 585 | ||
576 | if (control) | 586 | if (control) |
577 | wf_control_set_max(control); | 587 | wf_control_set_max(control); |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 436a76ab4bb1..212c63d780e7 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -3179,14 +3179,7 @@ static int pci_pm_reset(struct pci_dev *dev, int probe) | |||
3179 | return 0; | 3179 | return 0; |
3180 | } | 3180 | } |
3181 | 3181 | ||
3182 | /** | 3182 | void __weak pcibios_reset_secondary_bus(struct pci_dev *dev) |
3183 | * pci_reset_bridge_secondary_bus - Reset the secondary bus on a PCI bridge. | ||
3184 | * @dev: Bridge device | ||
3185 | * | ||
3186 | * Use the bridge control register to assert reset on the secondary bus. | ||
3187 | * Devices on the secondary bus are left in power-on state. | ||
3188 | */ | ||
3189 | void pci_reset_bridge_secondary_bus(struct pci_dev *dev) | ||
3190 | { | 3183 | { |
3191 | u16 ctrl; | 3184 | u16 ctrl; |
3192 | 3185 | ||
@@ -3211,6 +3204,18 @@ void pci_reset_bridge_secondary_bus(struct pci_dev *dev) | |||
3211 | */ | 3204 | */ |
3212 | ssleep(1); | 3205 | ssleep(1); |
3213 | } | 3206 | } |
3207 | |||
3208 | /** | ||
3209 | * pci_reset_bridge_secondary_bus - Reset the secondary bus on a PCI bridge. | ||
3210 | * @dev: Bridge device | ||
3211 | * | ||
3212 | * Use the bridge control register to assert reset on the secondary bus. | ||
3213 | * Devices on the secondary bus are left in power-on state. | ||
3214 | */ | ||
3215 | void pci_reset_bridge_secondary_bus(struct pci_dev *dev) | ||
3216 | { | ||
3217 | pcibios_reset_secondary_bus(dev); | ||
3218 | } | ||
3214 | EXPORT_SYMBOL_GPL(pci_reset_bridge_secondary_bus); | 3219 | EXPORT_SYMBOL_GPL(pci_reset_bridge_secondary_bus); |
3215 | 3220 | ||
3216 | static int pci_parent_bus_reset(struct pci_dev *dev, int probe) | 3221 | static int pci_parent_bus_reset(struct pci_dev *dev, int probe) |
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile index 316194f26ff4..b3dbe9ef1a40 100644 --- a/tools/testing/selftests/powerpc/Makefile +++ b/tools/testing/selftests/powerpc/Makefile | |||
@@ -13,7 +13,7 @@ CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CUR | |||
13 | 13 | ||
14 | export CC CFLAGS | 14 | export CC CFLAGS |
15 | 15 | ||
16 | TARGETS = pmu copyloops | 16 | TARGETS = pmu copyloops mm |
17 | 17 | ||
18 | endif | 18 | endif |
19 | 19 | ||
diff --git a/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h b/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h index ccd9c84c4e3f..d1dc37425510 100644 --- a/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h +++ b/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h | |||
@@ -46,12 +46,15 @@ | |||
46 | #define R20 r20 | 46 | #define R20 r20 |
47 | #define R21 r21 | 47 | #define R21 r21 |
48 | #define R22 r22 | 48 | #define R22 r22 |
49 | #define R29 r29 | ||
50 | #define R30 r30 | ||
51 | #define R31 r31 | ||
49 | 52 | ||
50 | #define STACKFRAMESIZE 256 | 53 | #define STACKFRAMESIZE 256 |
51 | #define STK_PARAM(i) (48 + ((i)-3)*8) | ||
52 | #define STK_REG(i) (112 + ((i)-14)*8) | 54 | #define STK_REG(i) (112 + ((i)-14)*8) |
53 | 55 | ||
54 | #define _GLOBAL(A) FUNC_START(test_ ## A) | 56 | #define _GLOBAL(A) FUNC_START(test_ ## A) |
57 | #define _GLOBAL_TOC(A) _GLOBAL(A) | ||
55 | 58 | ||
56 | #define PPC_MTOCRF(A, B) mtocrf A, B | 59 | #define PPC_MTOCRF(A, B) mtocrf A, B |
57 | 60 | ||
diff --git a/tools/testing/selftests/powerpc/mm/Makefile b/tools/testing/selftests/powerpc/mm/Makefile new file mode 100644 index 000000000000..357ccbd6bad9 --- /dev/null +++ b/tools/testing/selftests/powerpc/mm/Makefile | |||
@@ -0,0 +1,18 @@ | |||
1 | noarg: | ||
2 | $(MAKE) -C ../ | ||
3 | |||
4 | PROGS := hugetlb_vs_thp_test | ||
5 | |||
6 | all: $(PROGS) | ||
7 | |||
8 | $(PROGS): ../harness.c | ||
9 | |||
10 | run_tests: all | ||
11 | @-for PROG in $(PROGS); do \ | ||
12 | ./$$PROG; \ | ||
13 | done; | ||
14 | |||
15 | clean: | ||
16 | rm -f $(PROGS) | ||
17 | |||
18 | .PHONY: all run_tests clean | ||
diff --git a/tools/testing/selftests/powerpc/mm/hugetlb_vs_thp_test.c b/tools/testing/selftests/powerpc/mm/hugetlb_vs_thp_test.c new file mode 100644 index 000000000000..3d8e5b033e1d --- /dev/null +++ b/tools/testing/selftests/powerpc/mm/hugetlb_vs_thp_test.c | |||
@@ -0,0 +1,72 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <sys/mman.h> | ||
3 | #include <unistd.h> | ||
4 | |||
5 | #include "utils.h" | ||
6 | |||
7 | /* This must match the huge page & THP size */ | ||
8 | #define SIZE (16 * 1024 * 1024) | ||
9 | |||
10 | static int test_body(void) | ||
11 | { | ||
12 | void *addr; | ||
13 | char *p; | ||
14 | |||
15 | addr = (void *)0xa0000000; | ||
16 | |||
17 | p = mmap(addr, SIZE, PROT_READ | PROT_WRITE, | ||
18 | MAP_HUGETLB | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); | ||
19 | if (p != MAP_FAILED) { | ||
20 | /* | ||
21 | * Typically the mmap will fail because no huge pages are | ||
22 | * allocated on the system. But if there are huge pages | ||
23 | * allocated the mmap will succeed. That's fine too, we just | ||
24 | * munmap here before continuing. | ||
25 | */ | ||
26 | munmap(addr, SIZE); | ||
27 | } | ||
28 | |||
29 | p = mmap(addr, SIZE, PROT_READ | PROT_WRITE, | ||
30 | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); | ||
31 | if (p == MAP_FAILED) { | ||
32 | printf("Mapping failed @ %p\n", addr); | ||
33 | perror("mmap"); | ||
34 | return 1; | ||
35 | } | ||
36 | |||
37 | /* | ||
38 | * Either a user or kernel access is sufficient to trigger the bug. | ||
39 | * A kernel access is easier to spot & debug, as it will trigger the | ||
40 | * softlockup or RCU stall detectors, and when the system is kicked | ||
41 | * into xmon we get a backtrace in the kernel. | ||
42 | * | ||
43 | * A good option is: | ||
44 | * getcwd(p, SIZE); | ||
45 | * | ||
46 | * For the purposes of this testcase it's preferable to spin in | ||
47 | * userspace, so the harness can kill us if we get stuck. That way we | ||
48 | * see a test failure rather than a dead system. | ||
49 | */ | ||
50 | *p = 0xf; | ||
51 | |||
52 | munmap(addr, SIZE); | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static int test_main(void) | ||
58 | { | ||
59 | int i; | ||
60 | |||
61 | /* 10,000 because it's a "bunch", and completes reasonably quickly */ | ||
62 | for (i = 0; i < 10000; i++) | ||
63 | if (test_body()) | ||
64 | return 1; | ||
65 | |||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | int main(void) | ||
70 | { | ||
71 | return test_harness(test_main, "hugetlb_vs_thp"); | ||
72 | } | ||