Timur Tabi | bc556ba | 2008-01-08 10:30:58 -0600 | [diff] [blame] | 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. |