diff options
author | Timur Tabi <timur@freescale.com> | 2008-01-08 11:30:58 -0500 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2008-01-23 20:34:06 -0500 |
commit | bc556ba940085e46e0ab1b5ed7c31428dc86dd03 (patch) | |
tree | 68d8aada0531c5d5070c3e7327de606894584971 | |
parent | a21e282a124f4679c040087ab73aa5b147d4275f (diff) |
[POWERPC] QE: Add ability to upload QE firmware
Define the layout of a binary blob that contains a QE firmware and instructions
on how to upload it. Add function qe_upload_firmware() to parse the blob
and perform the actual upload. Fully define 'struct rsp' in immap_qe.h to
include the actual RISC Special Registers. Added description of a new
QE firmware node to booting-without-of.txt.
Signed-off-by: Timur Tabi <timur@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
-rw-r--r-- | Documentation/powerpc/00-INDEX | 3 | ||||
-rw-r--r-- | Documentation/powerpc/booting-without-of.txt | 33 | ||||
-rw-r--r-- | Documentation/powerpc/qe_firmware.txt | 295 | ||||
-rw-r--r-- | arch/powerpc/platforms/Kconfig | 1 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/qe.c | 247 | ||||
-rw-r--r-- | include/asm-powerpc/immap_qe.h | 34 | ||||
-rw-r--r-- | include/asm-powerpc/qe.h | 61 |
7 files changed, 670 insertions, 4 deletions
diff --git a/Documentation/powerpc/00-INDEX b/Documentation/powerpc/00-INDEX index 94a3c577b083..3be84aa38dfe 100644 --- a/Documentation/powerpc/00-INDEX +++ b/Documentation/powerpc/00-INDEX | |||
@@ -28,3 +28,6 @@ sound.txt | |||
28 | - info on sound support under Linux/PPC | 28 | - info on sound support under Linux/PPC |
29 | zImage_layout.txt | 29 | zImage_layout.txt |
30 | - info on the kernel images for Linux/PPC | 30 | - info on the kernel images for Linux/PPC |
31 | qe_firmware.txt | ||
32 | - describes the layout of firmware binaries for the Freescale QUICC | ||
33 | Engine and the code that parses and uploads the microcode therein. | ||
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt index f920c2459e89..e8c67c9015b3 100644 --- a/Documentation/powerpc/booting-without-of.txt +++ b/Documentation/powerpc/booting-without-of.txt | |||
@@ -52,7 +52,10 @@ Table of Contents | |||
52 | i) Freescale QUICC Engine module (QE) | 52 | i) Freescale QUICC Engine module (QE) |
53 | j) CFI or JEDEC memory-mapped NOR flash | 53 | j) CFI or JEDEC memory-mapped NOR flash |
54 | k) Global Utilities Block | 54 | k) Global Utilities Block |
55 | l) Xilinx IP cores | 55 | l) Freescale Communications Processor Module |
56 | m) Chipselect/Local Bus | ||
57 | n) 4xx/Axon EMAC ethernet nodes | ||
58 | o) Xilinx IP cores | ||
56 | 59 | ||
57 | VII - Specifying interrupt information for devices | 60 | VII - Specifying interrupt information for devices |
58 | 1) interrupts property | 61 | 1) interrupts property |
@@ -1788,6 +1791,32 @@ platforms are moved over to use the flattened-device-tree model. | |||
1788 | }; | 1791 | }; |
1789 | }; | 1792 | }; |
1790 | 1793 | ||
1794 | viii) Uploaded QE firmware | ||
1795 | |||
1796 | If a new firwmare has been uploaded to the QE (usually by the | ||
1797 | boot loader), then a 'firmware' child node should be added to the QE | ||
1798 | node. This node provides information on the uploaded firmware that | ||
1799 | device drivers may need. | ||
1800 | |||
1801 | Required properties: | ||
1802 | - id: The string name of the firmware. This is taken from the 'id' | ||
1803 | member of the qe_firmware structure of the uploaded firmware. | ||
1804 | Device drivers can search this string to determine if the | ||
1805 | firmware they want is already present. | ||
1806 | - extended-modes: The Extended Modes bitfield, taken from the | ||
1807 | firmware binary. It is a 64-bit number represented | ||
1808 | as an array of two 32-bit numbers. | ||
1809 | - virtual-traps: The virtual traps, taken from the firmware binary. | ||
1810 | It is an array of 8 32-bit numbers. | ||
1811 | |||
1812 | Example: | ||
1813 | |||
1814 | firmware { | ||
1815 | id = "Soft-UART"; | ||
1816 | extended-modes = <0 0>; | ||
1817 | virtual-traps = <0 0 0 0 0 0 0 0>; | ||
1818 | } | ||
1819 | |||
1791 | j) CFI or JEDEC memory-mapped NOR flash | 1820 | j) CFI or JEDEC memory-mapped NOR flash |
1792 | 1821 | ||
1793 | Flash chips (Memory Technology Devices) are often used for solid state | 1822 | Flash chips (Memory Technology Devices) are often used for solid state |
@@ -2269,7 +2298,7 @@ platforms are moved over to use the flattened-device-tree model. | |||
2269 | available. | 2298 | available. |
2270 | For Axon: 0x0000012a | 2299 | For Axon: 0x0000012a |
2271 | 2300 | ||
2272 | l) Xilinx IP cores | 2301 | o) Xilinx IP cores |
2273 | 2302 | ||
2274 | The Xilinx EDK toolchain ships with a set of IP cores (devices) for use | 2303 | The Xilinx EDK toolchain ships with a set of IP cores (devices) for use |
2275 | in Xilinx Spartan and Virtex FPGAs. The devices cover the whole range | 2304 | in Xilinx Spartan and Virtex FPGAs. The devices cover the whole range |
diff --git a/Documentation/powerpc/qe_firmware.txt b/Documentation/powerpc/qe_firmware.txt new file mode 100644 index 000000000000..896266432d33 --- /dev/null +++ b/Documentation/powerpc/qe_firmware.txt | |||
@@ -0,0 +1,295 @@ | |||
1 | Freescale QUICC Engine Firmware Uploading | ||
2 | ----------------------------------------- | ||
3 | |||
4 | (c) 2007 Timur Tabi <timur at freescale.com>, | ||
5 | Freescale Semiconductor | ||
6 | |||
7 | Table of Contents | ||
8 | ================= | ||
9 | |||
10 | I - Software License for Firmware | ||
11 | |||
12 | II - Microcode Availability | ||
13 | |||
14 | III - Description and Terminology | ||
15 | |||
16 | IV - Microcode Programming Details | ||
17 | |||
18 | V - Firmware Structure Layout | ||
19 | |||
20 | VI - Sample Code for Creating Firmware Files | ||
21 | |||
22 | Revision Information | ||
23 | ==================== | ||
24 | |||
25 | November 30, 2007: Rev 1.0 - Initial version | ||
26 | |||
27 | I - Software License for Firmware | ||
28 | ================================= | ||
29 | |||
30 | Each firmware file comes with its own software license. For information on | ||
31 | the particular license, please see the license text that is distributed with | ||
32 | the firmware. | ||
33 | |||
34 | II - Microcode Availability | ||
35 | =========================== | ||
36 | |||
37 | Firmware files are distributed through various channels. Some are available on | ||
38 | http://opensource.freescale.com. For other firmware files, please contact | ||
39 | your Freescale representative or your operating system vendor. | ||
40 | |||
41 | III - Description and Terminology | ||
42 | ================================ | ||
43 | |||
44 | In this document, the term 'microcode' refers to the sequence of 32-bit | ||
45 | integers that compose the actual QE microcode. | ||
46 | |||
47 | The term 'firmware' refers to a binary blob that contains the microcode as | ||
48 | well as other data that | ||
49 | |||
50 | 1) describes the microcode's purpose | ||
51 | 2) describes how and where to upload the microcode | ||
52 | 3) specifies the values of various registers | ||
53 | 4) includes additional data for use by specific device drivers | ||
54 | |||
55 | Firmware files are binary files that contain only a firmware. | ||
56 | |||
57 | IV - Microcode Programming Details | ||
58 | =================================== | ||
59 | |||
60 | The QE architecture allows for only one microcode present in I-RAM for each | ||
61 | RISC processor. To replace any current microcode, a full QE reset (which | ||
62 | disables the microcode) must be performed first. | ||
63 | |||
64 | QE microcode is uploaded using the following procedure: | ||
65 | |||
66 | 1) The microcode is placed into I-RAM at a specific location, using the | ||
67 | IRAM.IADD and IRAM.IDATA registers. | ||
68 | |||
69 | 2) The CERCR.CIR bit is set to 0 or 1, depending on whether the firmware | ||
70 | needs split I-RAM. Split I-RAM is only meaningful for SOCs that have | ||
71 | QEs with multiple RISC processors, such as the 8360. Splitting the I-RAM | ||
72 | allows each processor to run a different microcode, effectively creating an | ||
73 | asymmetric multiprocessing (AMP) system. | ||
74 | |||
75 | 3) The TIBCR trap registers are loaded with the addresses of the trap handlers | ||
76 | in the microcode. | ||
77 | |||
78 | 4) The RSP.ECCR register is programmed with the value provided. | ||
79 | |||
80 | 5) If necessary, device drivers that need the virtual traps and extended mode | ||
81 | data will use them. | ||
82 | |||
83 | Virtual Microcode Traps | ||
84 | |||
85 | These virtual traps are conditional branches in the microcode. These are | ||
86 | "soft" provisional introduced in the ROMcode in order to enable higher | ||
87 | flexibility and save h/w traps If new features are activated or an issue is | ||
88 | being fixed in the RAM package utilizing they should be activated. This data | ||
89 | structure signals the microcode which of these virtual traps is active. | ||
90 | |||
91 | This structure contains 6 words that the application should copy to some | ||
92 | specific been defined. This table describes the structure. | ||
93 | |||
94 | --------------------------------------------------------------- | ||
95 | | Offset in | | Destination Offset | Size of | | ||
96 | | array | Protocol | within PRAM | Operand | | ||
97 | --------------------------------------------------------------| | ||
98 | | 0 | Ethernet | 0xF8 | 4 bytes | | ||
99 | | | interworking | | | | ||
100 | --------------------------------------------------------------- | ||
101 | | 4 | ATM | 0xF8 | 4 bytes | | ||
102 | | | interworking | | | | ||
103 | --------------------------------------------------------------- | ||
104 | | 8 | PPP | 0xF8 | 4 bytes | | ||
105 | | | interworking | | | | ||
106 | --------------------------------------------------------------- | ||
107 | | 12 | Ethernet RX | 0x22 | 1 byte | | ||
108 | | | Distributor Page | | | | ||
109 | --------------------------------------------------------------- | ||
110 | | 16 | ATM Globtal | 0x28 | 1 byte | | ||
111 | | | Params Table | | | | ||
112 | --------------------------------------------------------------- | ||
113 | | 20 | Insert Frame | 0xF8 | 4 bytes | | ||
114 | --------------------------------------------------------------- | ||
115 | |||
116 | |||
117 | Extended Modes | ||
118 | |||
119 | This is a double word bit array (64 bits) that defines special functionality | ||
120 | which has an impact on the softwarew drivers. Each bit has its own impact | ||
121 | and has special instructions for the s/w associated with it. This structure is | ||
122 | described in this table: | ||
123 | |||
124 | ----------------------------------------------------------------------- | ||
125 | | Bit # | Name | Description | | ||
126 | ----------------------------------------------------------------------- | ||
127 | | 0 | General | Indicates that prior to each host command | | ||
128 | | | push command | given by the application, the software must | | ||
129 | | | | assert a special host command (push command)| | ||
130 | | | | CECDR = 0x00800000. | | ||
131 | | | | CECR = 0x01c1000f. | | ||
132 | ----------------------------------------------------------------------- | ||
133 | | 1 | UCC ATM | Indicates that after issuing ATM RX INIT | | ||
134 | | | RX INIT | command, the host must issue another special| | ||
135 | | | push command | command (push command) and immediately | | ||
136 | | | | following that re-issue the ATM RX INIT | | ||
137 | | | | command. (This makes the sequence of | | ||
138 | | | | initializing the ATM receiver a sequence of | | ||
139 | | | | three host commands) | | ||
140 | | | | CECDR = 0x00800000. | | ||
141 | | | | CECR = 0x01c1000f. | | ||
142 | ----------------------------------------------------------------------- | ||
143 | | 2 | Add/remove | Indicates that following the specific host | | ||
144 | | | command | command: "Add/Remove entry in Hash Lookup | | ||
145 | | | validation | Table" used in Interworking setup, the user | | ||
146 | | | | must issue another command. | | ||
147 | | | | CECDR = 0xce000003. | | ||
148 | | | | CECR = 0x01c10f58. | | ||
149 | ----------------------------------------------------------------------- | ||
150 | | 3 | General push | Indicates that the s/w has to initialize | | ||
151 | | | command | some pointers in the Ethernet thread pages | | ||
152 | | | | which are used when Header Compression is | | ||
153 | | | | activated. The full details of these | | ||
154 | | | | pointers is located in the software drivers.| | ||
155 | ----------------------------------------------------------------------- | ||
156 | | 4 | General push | Indicates that after issuing Ethernet TX | | ||
157 | | | command | INIT command, user must issue this command | | ||
158 | | | | for each SNUM of Ethernet TX thread. | | ||
159 | | | | CECDR = 0x00800003. | | ||
160 | | | | CECR = 0x7'b{0}, 8'b{Enet TX thread SNUM}, | | ||
161 | | | | 1'b{1}, 12'b{0}, 4'b{1} | | ||
162 | ----------------------------------------------------------------------- | ||
163 | | 5 - 31 | N/A | Reserved, set to zero. | | ||
164 | ----------------------------------------------------------------------- | ||
165 | |||
166 | V - Firmware Structure Layout | ||
167 | ============================== | ||
168 | |||
169 | QE microcode from Freescale is typically provided as a header file. This | ||
170 | header file contains macros that define the microcode binary itself as well as | ||
171 | some other data used in uploading that microcode. The format of these files | ||
172 | do not lend themselves to simple inclusion into other code. Hence, | ||
173 | the need for a more portable format. This section defines that format. | ||
174 | |||
175 | Instead of distributing a header file, the microcode and related data are | ||
176 | embedded into a binary blob. This blob is passed to the qe_upload_firmware() | ||
177 | function, which parses the blob and performs everything necessary to upload | ||
178 | the microcode. | ||
179 | |||
180 | All integers are big-endian. See the comments for function | ||
181 | qe_upload_firmware() for up-to-date implementation information. | ||
182 | |||
183 | This structure supports versioning, where the version of the structure is | ||
184 | embedded into the structure itself. To ensure forward and backwards | ||
185 | compatibility, all versions of the structure must use the same 'qe_header' | ||
186 | structure at the beginning. | ||
187 | |||
188 | 'header' (type: struct qe_header): | ||
189 | The 'length' field is the size, in bytes, of the entire structure, | ||
190 | including all the microcode embedded in it, as well as the CRC (if | ||
191 | present). | ||
192 | |||
193 | The 'magic' field is an array of three bytes that contains the letters | ||
194 | 'Q', 'E', and 'F'. This is an identifier that indicates that this | ||
195 | structure is a QE Firmware structure. | ||
196 | |||
197 | The 'version' field is a single byte that indicates the version of this | ||
198 | structure. If the layout of the structure should ever need to be | ||
199 | changed to add support for additional types of microcode, then the | ||
200 | version number should also be changed. | ||
201 | |||
202 | The 'id' field is a null-terminated string(suitable for printing) that | ||
203 | identifies the firmware. | ||
204 | |||
205 | The 'count' field indicates the number of 'microcode' structures. There | ||
206 | must be one and only one 'microcode' structure for each RISC processor. | ||
207 | Therefore, this field also represents the number of RISC processors for this | ||
208 | SOC. | ||
209 | |||
210 | The 'soc' structure contains the SOC numbers and revisions used to match | ||
211 | the microcode to the SOC itself. Normally, the microcode loader should | ||
212 | check the data in this structure with the SOC number and revisions, and | ||
213 | only upload the microcode if there's a match. However, this check is not | ||
214 | made on all platforms. | ||
215 | |||
216 | Although it is not recommended, you can specify '0' in the soc.model | ||
217 | field to skip matching SOCs altogether. | ||
218 | |||
219 | The 'model' field is a 16-bit number that matches the actual SOC. The | ||
220 | 'major' and 'minor' fields are the major and minor revision numbrs, | ||
221 | respectively, of the SOC. | ||
222 | |||
223 | For example, to match the 8323, revision 1.0: | ||
224 | soc.model = 8323 | ||
225 | soc.major = 1 | ||
226 | soc.minor = 0 | ||
227 | |||
228 | 'padding' is neccessary for structure alignment. This field ensures that the | ||
229 | 'extended_modes' field is aligned on a 64-bit boundary. | ||
230 | |||
231 | 'extended_modes' is a bitfield that defines special functionality which has an | ||
232 | impact on the device drivers. Each bit has its own impact and has special | ||
233 | instructions for the driver associated with it. This field is stored in | ||
234 | the QE library and available to any driver that calles qe_get_firmware_info(). | ||
235 | |||
236 | 'vtraps' is an array of 8 words that contain virtual trap values for each | ||
237 | virtual traps. As with 'extended_modes', this field is stored in the QE | ||
238 | library and available to any driver that calles qe_get_firmware_info(). | ||
239 | |||
240 | 'microcode' (type: struct qe_microcode): | ||
241 | For each RISC processor there is one 'microcode' structure. The first | ||
242 | 'microcode' structure is for the first RISC, and so on. | ||
243 | |||
244 | The 'id' field is a null-terminated string suitable for printing that | ||
245 | identifies this particular microcode. | ||
246 | |||
247 | 'traps' is an array of 16 words that contain hardware trap values | ||
248 | for each of the 16 traps. If trap[i] is 0, then this particular | ||
249 | trap is to be ignored (i.e. not written to TIBCR[i]). The entire value | ||
250 | is written as-is to the TIBCR[i] register, so be sure to set the EN | ||
251 | and T_IBP bits if necessary. | ||
252 | |||
253 | 'eccr' is the value to program into the ECCR register. | ||
254 | |||
255 | 'iram_offset' is the offset into IRAM to start writing the | ||
256 | microcode. | ||
257 | |||
258 | 'count' is the number of 32-bit words in the microcode. | ||
259 | |||
260 | 'code_offset' is the offset, in bytes, from the beginning of this | ||
261 | structure where the microcode itself can be found. The first | ||
262 | microcode binary should be located immediately after the 'microcode' | ||
263 | array. | ||
264 | |||
265 | 'major', 'minor', and 'revision' are the major, minor, and revision | ||
266 | version numbers, respectively, of the microcode. If all values are 0, | ||
267 | then these fields are ignored. | ||
268 | |||
269 | 'reserved' is necessary for structure alignment. Since 'microcode' | ||
270 | is an array, the 64-bit 'extended_modes' field needs to be aligned | ||
271 | on a 64-bit boundary, and this can only happen if the size of | ||
272 | 'microcode' is a multiple of 8 bytes. To ensure that, we add | ||
273 | 'reserved'. | ||
274 | |||
275 | After the last microcode is a 32-bit CRC. It can be calculated using | ||
276 | this algorithm: | ||
277 | |||
278 | u32 crc32(const u8 *p, unsigned int len) | ||
279 | { | ||
280 | unsigned int i; | ||
281 | u32 crc = 0; | ||
282 | |||
283 | while (len--) { | ||
284 | crc ^= *p++; | ||
285 | for (i = 0; i < 8; i++) | ||
286 | crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0); | ||
287 | } | ||
288 | return crc; | ||
289 | } | ||
290 | |||
291 | VI - Sample Code for Creating Firmware Files | ||
292 | ============================================ | ||
293 | |||
294 | A Python program that creates firmware binaries from the header files normally | ||
295 | distributed by Freescale can be found on http://opensource.freescale.com. | ||
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index ea22cad2cd0a..18f101bcca94 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig | |||
@@ -265,6 +265,7 @@ config TAU_AVERAGE | |||
265 | config QUICC_ENGINE | 265 | config QUICC_ENGINE |
266 | bool | 266 | bool |
267 | select PPC_LIB_RHEAP | 267 | select PPC_LIB_RHEAP |
268 | select CRC32 | ||
268 | help | 269 | help |
269 | The QUICC Engine (QE) is a new generation of communications | 270 | The QUICC Engine (QE) is a new generation of communications |
270 | coprocessors on Freescale embedded CPUs (akin to CPM in older chips). | 271 | coprocessors on Freescale embedded CPUs (akin to CPM in older chips). |
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 21e01061aca9..3925eae9b0f5 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/ioport.h> | 27 | #include <linux/ioport.h> |
28 | #include <linux/crc32.h> | ||
28 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
29 | #include <asm/page.h> | 30 | #include <asm/page.h> |
30 | #include <asm/pgtable.h> | 31 | #include <asm/pgtable.h> |
@@ -394,3 +395,249 @@ void *qe_muram_addr(unsigned long offset) | |||
394 | return (void *)&qe_immr->muram[offset]; | 395 | return (void *)&qe_immr->muram[offset]; |
395 | } | 396 | } |
396 | EXPORT_SYMBOL(qe_muram_addr); | 397 | EXPORT_SYMBOL(qe_muram_addr); |
398 | |||
399 | /* The maximum number of RISCs we support */ | ||
400 | #define MAX_QE_RISC 2 | ||
401 | |||
402 | /* Firmware information stored here for qe_get_firmware_info() */ | ||
403 | static struct qe_firmware_info qe_firmware_info; | ||
404 | |||
405 | /* | ||
406 | * Set to 1 if QE firmware has been uploaded, and therefore | ||
407 | * qe_firmware_info contains valid data. | ||
408 | */ | ||
409 | static int qe_firmware_uploaded; | ||
410 | |||
411 | /* | ||
412 | * Upload a QE microcode | ||
413 | * | ||
414 | * This function is a worker function for qe_upload_firmware(). It does | ||
415 | * the actual uploading of the microcode. | ||
416 | */ | ||
417 | static void qe_upload_microcode(const void *base, | ||
418 | const struct qe_microcode *ucode) | ||
419 | { | ||
420 | const __be32 *code = base + be32_to_cpu(ucode->code_offset); | ||
421 | unsigned int i; | ||
422 | |||
423 | if (ucode->major || ucode->minor || ucode->revision) | ||
424 | printk(KERN_INFO "qe-firmware: " | ||
425 | "uploading microcode '%s' version %u.%u.%u\n", | ||
426 | ucode->id, ucode->major, ucode->minor, ucode->revision); | ||
427 | else | ||
428 | printk(KERN_INFO "qe-firmware: " | ||
429 | "uploading microcode '%s'\n", ucode->id); | ||
430 | |||
431 | /* Use auto-increment */ | ||
432 | out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) | | ||
433 | QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR); | ||
434 | |||
435 | for (i = 0; i < be32_to_cpu(ucode->count); i++) | ||
436 | out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i])); | ||
437 | } | ||
438 | |||
439 | /* | ||
440 | * Upload a microcode to the I-RAM at a specific address. | ||
441 | * | ||
442 | * See Documentation/powerpc/qe-firmware.txt for information on QE microcode | ||
443 | * uploading. | ||
444 | * | ||
445 | * Currently, only version 1 is supported, so the 'version' field must be | ||
446 | * set to 1. | ||
447 | * | ||
448 | * The SOC model and revision are not validated, they are only displayed for | ||
449 | * informational purposes. | ||
450 | * | ||
451 | * 'calc_size' is the calculated size, in bytes, of the firmware structure and | ||
452 | * all of the microcode structures, minus the CRC. | ||
453 | * | ||
454 | * 'length' is the size that the structure says it is, including the CRC. | ||
455 | */ | ||
456 | int qe_upload_firmware(const struct qe_firmware *firmware) | ||
457 | { | ||
458 | unsigned int i; | ||
459 | unsigned int j; | ||
460 | u32 crc; | ||
461 | size_t calc_size = sizeof(struct qe_firmware); | ||
462 | size_t length; | ||
463 | const struct qe_header *hdr; | ||
464 | |||
465 | if (!firmware) { | ||
466 | printk(KERN_ERR "qe-firmware: invalid pointer\n"); | ||
467 | return -EINVAL; | ||
468 | } | ||
469 | |||
470 | hdr = &firmware->header; | ||
471 | length = be32_to_cpu(hdr->length); | ||
472 | |||
473 | /* Check the magic */ | ||
474 | if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') || | ||
475 | (hdr->magic[2] != 'F')) { | ||
476 | printk(KERN_ERR "qe-firmware: not a microcode\n"); | ||
477 | return -EPERM; | ||
478 | } | ||
479 | |||
480 | /* Check the version */ | ||
481 | if (hdr->version != 1) { | ||
482 | printk(KERN_ERR "qe-firmware: unsupported version\n"); | ||
483 | return -EPERM; | ||
484 | } | ||
485 | |||
486 | /* Validate some of the fields */ | ||
487 | if ((firmware->count < 1) || (firmware->count >= MAX_QE_RISC)) { | ||
488 | printk(KERN_ERR "qe-firmware: invalid data\n"); | ||
489 | return -EINVAL; | ||
490 | } | ||
491 | |||
492 | /* Validate the length and check if there's a CRC */ | ||
493 | calc_size += (firmware->count - 1) * sizeof(struct qe_microcode); | ||
494 | |||
495 | for (i = 0; i < firmware->count; i++) | ||
496 | /* | ||
497 | * For situations where the second RISC uses the same microcode | ||
498 | * as the first, the 'code_offset' and 'count' fields will be | ||
499 | * zero, so it's okay to add those. | ||
500 | */ | ||
501 | calc_size += sizeof(__be32) * | ||
502 | be32_to_cpu(firmware->microcode[i].count); | ||
503 | |||
504 | /* Validate the length */ | ||
505 | if (length != calc_size + sizeof(__be32)) { | ||
506 | printk(KERN_ERR "qe-firmware: invalid length\n"); | ||
507 | return -EPERM; | ||
508 | } | ||
509 | |||
510 | /* Validate the CRC */ | ||
511 | crc = be32_to_cpu(*(__be32 *)((void *)firmware + calc_size)); | ||
512 | if (crc != crc32(0, firmware, calc_size)) { | ||
513 | printk(KERN_ERR "qe-firmware: firmware CRC is invalid\n"); | ||
514 | return -EIO; | ||
515 | } | ||
516 | |||
517 | /* | ||
518 | * If the microcode calls for it, split the I-RAM. | ||
519 | */ | ||
520 | if (!firmware->split) | ||
521 | setbits16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR); | ||
522 | |||
523 | if (firmware->soc.model) | ||
524 | printk(KERN_INFO | ||
525 | "qe-firmware: firmware '%s' for %u V%u.%u\n", | ||
526 | firmware->id, be16_to_cpu(firmware->soc.model), | ||
527 | firmware->soc.major, firmware->soc.minor); | ||
528 | else | ||
529 | printk(KERN_INFO "qe-firmware: firmware '%s'\n", | ||
530 | firmware->id); | ||
531 | |||
532 | /* | ||
533 | * The QE only supports one microcode per RISC, so clear out all the | ||
534 | * saved microcode information and put in the new. | ||
535 | */ | ||
536 | memset(&qe_firmware_info, 0, sizeof(qe_firmware_info)); | ||
537 | strcpy(qe_firmware_info.id, firmware->id); | ||
538 | qe_firmware_info.extended_modes = firmware->extended_modes; | ||
539 | memcpy(qe_firmware_info.vtraps, firmware->vtraps, | ||
540 | sizeof(firmware->vtraps)); | ||
541 | |||
542 | /* Loop through each microcode. */ | ||
543 | for (i = 0; i < firmware->count; i++) { | ||
544 | const struct qe_microcode *ucode = &firmware->microcode[i]; | ||
545 | |||
546 | /* Upload a microcode if it's present */ | ||
547 | if (ucode->code_offset) | ||
548 | qe_upload_microcode(firmware, ucode); | ||
549 | |||
550 | /* Program the traps for this processor */ | ||
551 | for (j = 0; j < 16; j++) { | ||
552 | u32 trap = be32_to_cpu(ucode->traps[j]); | ||
553 | |||
554 | if (trap) | ||
555 | out_be32(&qe_immr->rsp[i].tibcr[j], trap); | ||
556 | } | ||
557 | |||
558 | /* Enable traps */ | ||
559 | out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr)); | ||
560 | } | ||
561 | |||
562 | qe_firmware_uploaded = 1; | ||
563 | |||
564 | return 0; | ||
565 | } | ||
566 | EXPORT_SYMBOL(qe_upload_firmware); | ||
567 | |||
568 | /* | ||
569 | * Get info on the currently-loaded firmware | ||
570 | * | ||
571 | * This function also checks the device tree to see if the boot loader has | ||
572 | * uploaded a firmware already. | ||
573 | */ | ||
574 | struct qe_firmware_info *qe_get_firmware_info(void) | ||
575 | { | ||
576 | static int initialized; | ||
577 | struct property *prop; | ||
578 | struct device_node *qe; | ||
579 | struct device_node *fw = NULL; | ||
580 | const char *sprop; | ||
581 | unsigned int i; | ||
582 | |||
583 | /* | ||
584 | * If we haven't checked yet, and a driver hasn't uploaded a firmware | ||
585 | * yet, then check the device tree for information. | ||
586 | */ | ||
587 | if (initialized || qe_firmware_uploaded) | ||
588 | return NULL; | ||
589 | |||
590 | initialized = 1; | ||
591 | |||
592 | /* | ||
593 | * Newer device trees have an "fsl,qe" compatible property for the QE | ||
594 | * node, but we still need to support older device trees. | ||
595 | */ | ||
596 | qe = of_find_compatible_node(NULL, NULL, "fsl,qe"); | ||
597 | if (!qe) { | ||
598 | qe = of_find_node_by_type(NULL, "qe"); | ||
599 | if (!qe) | ||
600 | return NULL; | ||
601 | } | ||
602 | |||
603 | /* Find the 'firmware' child node */ | ||
604 | for_each_child_of_node(qe, fw) { | ||
605 | if (strcmp(fw->name, "firmware") == 0) | ||
606 | break; | ||
607 | } | ||
608 | |||
609 | of_node_put(qe); | ||
610 | |||
611 | /* Did we find the 'firmware' node? */ | ||
612 | if (!fw) | ||
613 | return NULL; | ||
614 | |||
615 | qe_firmware_uploaded = 1; | ||
616 | |||
617 | /* Copy the data into qe_firmware_info*/ | ||
618 | sprop = of_get_property(fw, "id", NULL); | ||
619 | if (sprop) | ||
620 | strncpy(qe_firmware_info.id, sprop, | ||
621 | sizeof(qe_firmware_info.id) - 1); | ||
622 | |||
623 | prop = of_find_property(fw, "extended-modes", NULL); | ||
624 | if (prop && (prop->length == sizeof(u64))) { | ||
625 | const u64 *iprop = prop->value; | ||
626 | |||
627 | qe_firmware_info.extended_modes = *iprop; | ||
628 | } | ||
629 | |||
630 | prop = of_find_property(fw, "virtual-traps", NULL); | ||
631 | if (prop && (prop->length == 32)) { | ||
632 | const u32 *iprop = prop->value; | ||
633 | |||
634 | for (i = 0; i < ARRAY_SIZE(qe_firmware_info.vtraps); i++) | ||
635 | qe_firmware_info.vtraps[i] = iprop[i]; | ||
636 | } | ||
637 | |||
638 | of_node_put(fw); | ||
639 | |||
640 | return &qe_firmware_info; | ||
641 | } | ||
642 | EXPORT_SYMBOL(qe_get_firmware_info); | ||
643 | |||
diff --git a/include/asm-powerpc/immap_qe.h b/include/asm-powerpc/immap_qe.h index aba9806b31c9..82a452615097 100644 --- a/include/asm-powerpc/immap_qe.h +++ b/include/asm-powerpc/immap_qe.h | |||
@@ -393,9 +393,39 @@ struct dbg { | |||
393 | u8 res2[0x48]; | 393 | u8 res2[0x48]; |
394 | } __attribute__ ((packed)); | 394 | } __attribute__ ((packed)); |
395 | 395 | ||
396 | /* RISC Special Registers (Trap and Breakpoint) */ | 396 | /* |
397 | * RISC Special Registers (Trap and Breakpoint). These are described in | ||
398 | * the QE Developer's Handbook. | ||
399 | */ | ||
397 | struct rsp { | 400 | struct rsp { |
398 | u32 reg[0x40]; /* 64 32-bit registers */ | 401 | __be32 tibcr[16]; /* Trap/instruction breakpoint control regs */ |
402 | u8 res0[64]; | ||
403 | __be32 ibcr0; | ||
404 | __be32 ibs0; | ||
405 | __be32 ibcnr0; | ||
406 | u8 res1[4]; | ||
407 | __be32 ibcr1; | ||
408 | __be32 ibs1; | ||
409 | __be32 ibcnr1; | ||
410 | __be32 npcr; | ||
411 | __be32 dbcr; | ||
412 | __be32 dbar; | ||
413 | __be32 dbamr; | ||
414 | __be32 dbsr; | ||
415 | __be32 dbcnr; | ||
416 | u8 res2[12]; | ||
417 | __be32 dbdr_h; | ||
418 | __be32 dbdr_l; | ||
419 | __be32 dbdmr_h; | ||
420 | __be32 dbdmr_l; | ||
421 | __be32 bsr; | ||
422 | __be32 bor; | ||
423 | __be32 bior; | ||
424 | u8 res3[4]; | ||
425 | __be32 iatr[4]; | ||
426 | __be32 eccr; /* Exception control configuration register */ | ||
427 | __be32 eicr; | ||
428 | u8 res4[0x100-0xf8]; | ||
399 | } __attribute__ ((packed)); | 429 | } __attribute__ ((packed)); |
400 | 430 | ||
401 | struct qe_immap { | 431 | struct qe_immap { |
diff --git a/include/asm-powerpc/qe.h b/include/asm-powerpc/qe.h index a24b7b14958f..430dc77b35fc 100644 --- a/include/asm-powerpc/qe.h +++ b/include/asm-powerpc/qe.h | |||
@@ -94,6 +94,58 @@ unsigned long qe_muram_alloc_fixed(unsigned long offset, int size); | |||
94 | void qe_muram_dump(void); | 94 | void qe_muram_dump(void); |
95 | void *qe_muram_addr(unsigned long offset); | 95 | void *qe_muram_addr(unsigned long offset); |
96 | 96 | ||
97 | /* Structure that defines QE firmware binary files. | ||
98 | * | ||
99 | * See Documentation/powerpc/qe-firmware.txt for a description of these | ||
100 | * fields. | ||
101 | */ | ||
102 | struct qe_firmware { | ||
103 | struct qe_header { | ||
104 | __be32 length; /* Length of the entire structure, in bytes */ | ||
105 | u8 magic[3]; /* Set to { 'Q', 'E', 'F' } */ | ||
106 | u8 version; /* Version of this layout. First ver is '1' */ | ||
107 | } header; | ||
108 | u8 id[62]; /* Null-terminated identifier string */ | ||
109 | u8 split; /* 0 = shared I-RAM, 1 = split I-RAM */ | ||
110 | u8 count; /* Number of microcode[] structures */ | ||
111 | struct { | ||
112 | __be16 model; /* The SOC model */ | ||
113 | u8 major; /* The SOC revision major */ | ||
114 | u8 minor; /* The SOC revision minor */ | ||
115 | } __attribute__ ((packed)) soc; | ||
116 | u8 padding[4]; /* Reserved, for alignment */ | ||
117 | __be64 extended_modes; /* Extended modes */ | ||
118 | __be32 vtraps[8]; /* Virtual trap addresses */ | ||
119 | u8 reserved[4]; /* Reserved, for future expansion */ | ||
120 | struct qe_microcode { | ||
121 | u8 id[32]; /* Null-terminated identifier */ | ||
122 | __be32 traps[16]; /* Trap addresses, 0 == ignore */ | ||
123 | __be32 eccr; /* The value for the ECCR register */ | ||
124 | __be32 iram_offset; /* Offset into I-RAM for the code */ | ||
125 | __be32 count; /* Number of 32-bit words of the code */ | ||
126 | __be32 code_offset; /* Offset of the actual microcode */ | ||
127 | u8 major; /* The microcode version major */ | ||
128 | u8 minor; /* The microcode version minor */ | ||
129 | u8 revision; /* The microcode version revision */ | ||
130 | u8 padding; /* Reserved, for alignment */ | ||
131 | u8 reserved[4]; /* Reserved, for future expansion */ | ||
132 | } __attribute__ ((packed)) microcode[1]; | ||
133 | /* All microcode binaries should be located here */ | ||
134 | /* CRC32 should be located here, after the microcode binaries */ | ||
135 | } __attribute__ ((packed)); | ||
136 | |||
137 | struct qe_firmware_info { | ||
138 | char id[64]; /* Firmware name */ | ||
139 | u32 vtraps[8]; /* Virtual trap addresses */ | ||
140 | u64 extended_modes; /* Extended modes */ | ||
141 | }; | ||
142 | |||
143 | /* Upload a firmware to the QE */ | ||
144 | int qe_upload_firmware(const struct qe_firmware *firmware); | ||
145 | |||
146 | /* Obtain information on the uploaded firmware */ | ||
147 | struct qe_firmware_info *qe_get_firmware_info(void); | ||
148 | |||
97 | /* Buffer descriptors */ | 149 | /* Buffer descriptors */ |
98 | struct qe_bd { | 150 | struct qe_bd { |
99 | __be16 status; | 151 | __be16 status; |
@@ -329,6 +381,15 @@ enum comm_dir { | |||
329 | 381 | ||
330 | #define QE_SDEBCR_BA_MASK 0x01FFFFFF | 382 | #define QE_SDEBCR_BA_MASK 0x01FFFFFF |
331 | 383 | ||
384 | /* Communication Processor */ | ||
385 | #define QE_CP_CERCR_MEE 0x8000 /* Multi-user RAM ECC enable */ | ||
386 | #define QE_CP_CERCR_IEE 0x4000 /* Instruction RAM ECC enable */ | ||
387 | #define QE_CP_CERCR_CIR 0x0800 /* Common instruction RAM */ | ||
388 | |||
389 | /* I-RAM */ | ||
390 | #define QE_IRAM_IADD_AIE 0x80000000 /* Auto Increment Enable */ | ||
391 | #define QE_IRAM_IADD_BADDR 0x00080000 /* Base Address */ | ||
392 | |||
332 | /* UPC */ | 393 | /* UPC */ |
333 | #define UPGCR_PROTOCOL 0x80000000 /* protocol ul2 or pl2 */ | 394 | #define UPGCR_PROTOCOL 0x80000000 /* protocol ul2 or pl2 */ |
334 | #define UPGCR_TMS 0x40000000 /* Transmit master/slave mode */ | 395 | #define UPGCR_TMS 0x40000000 /* Transmit master/slave mode */ |