1 --- a/Documentation/kernel-parameters.txt
2 +++ b/Documentation/kernel-parameters.txt
3 @@ -686,6 +686,7 @@ and is between 256 and 4096 characters.
4 See Documentation/isdn/README.HiSax.
6 hugepages= [HW,X86-32,IA-64] Maximal number of HugeTLB pages.
7 + hugepagesz= [HW,IA-64,PPC] The size of the HugeTLB pages.
9 i8042.direct [HW] Put keyboard port into non-translated mode
10 i8042.dumbkbd [HW] Pretend that controller can only read data from
11 --- a/Documentation/powerpc/00-INDEX
12 +++ b/Documentation/powerpc/00-INDEX
13 @@ -28,3 +28,6 @@ sound.txt
14 - info on sound support under Linux/PPC
16 - info on the kernel images for Linux/PPC
18 + - describes the layout of firmware binaries for the Freescale QUICC
19 + Engine and the code that parses and uploads the microcode therein.
20 --- a/Documentation/powerpc/booting-without-of.txt
21 +++ b/Documentation/powerpc/booting-without-of.txt
22 @@ -52,7 +52,11 @@ Table of Contents
23 i) Freescale QUICC Engine module (QE)
24 j) CFI or JEDEC memory-mapped NOR flash
25 k) Global Utilities Block
27 + l) Freescale Communications Processor Module
28 + m) Chipselect/Local Bus
29 + n) 4xx/Axon EMAC ethernet nodes
31 + p) Freescale Synchronous Serial Interface
33 VII - Specifying interrupt information for devices
34 1) interrupts property
35 @@ -671,10 +675,10 @@ device or bus to be described by the dev
37 In general, the format of an address for a device is defined by the
38 parent bus type, based on the #address-cells and #size-cells
39 -property. In the absence of such a property, the parent's parent
40 -values are used, etc... The kernel requires the root node to have
41 -those properties defining addresses format for devices directly mapped
42 -on the processor bus.
43 +properties. Note that the parent's parent definitions of #address-cells
44 +and #size-cells are not inhereted so every node with children must specify
45 +them. The kernel requires the root node to have those properties defining
46 +addresses format for devices directly mapped on the processor bus.
48 Those 2 properties define 'cells' for representing an address and a
49 size. A "cell" is a 32-bit number. For example, if both contain 2
50 @@ -711,13 +715,14 @@ define a bus type with a more complex ad
51 like address space bits, you'll have to add a bus translator to the
52 prom_parse.c file of the recent kernels for your bus type.
54 -The "reg" property only defines addresses and sizes (if #size-cells
55 -is non-0) within a given bus. In order to translate addresses upward
56 +The "reg" property only defines addresses and sizes (if #size-cells is
57 +non-0) within a given bus. In order to translate addresses upward
58 (that is into parent bus addresses, and possibly into CPU physical
59 addresses), all busses must contain a "ranges" property. If the
60 "ranges" property is missing at a given level, it's assumed that
61 -translation isn't possible. The format of the "ranges" property for a
63 +translation isn't possible, i.e., the registers are not visible on the
64 +parent bus. The format of the "ranges" property for a bus is a list
67 bus address, parent bus address, size
69 @@ -735,6 +740,10 @@ fit in a single 32-bit word. New 32-bi
70 1/1 format, unless the processor supports physical addresses greater
71 than 32-bits, in which case a 2/1 format is recommended.
73 +Alternatively, the "ranges" property may be empty, indicating that the
74 +registers are visible on the parent bus using an identity mapping
75 +translation. In other words, the parent bus address space is the same
76 +as the child bus address space.
78 2) Note about "compatible" properties
79 -------------------------------------
80 @@ -1218,16 +1227,14 @@ platforms are moved over to use the flat
83 - reg : Offset and length of the register set for the device
84 - - device_type : Should be "mdio"
85 - compatible : Should define the compatible device type for the
86 - mdio. Currently, this is most likely to be "gianfar"
87 + mdio. Currently, this is most likely to be "fsl,gianfar-mdio"
93 - device_type = "mdio";
94 - compatible = "gianfar";
95 + compatible = "fsl,gianfar-mdio";
99 @@ -1254,6 +1261,10 @@ platforms are moved over to use the flat
100 services interrupts for this device.
101 - phy-handle : The phandle for the PHY connected to this ethernet
103 + - fixed-link : <a b c d e> where a is emulated phy id - choose any,
104 + but unique to the all specified fixed-links, b is duplex - 0 half,
105 + 1 full, c is link speed - d#10/d#100/d#1000, d is pause - 0 no
106 + pause, 1 pause, e is asym_pause - 0 no asym_pause, 1 asym_pause.
108 Recommended properties:
110 @@ -1408,7 +1419,6 @@ platforms are moved over to use the flat
112 Example multi port host USB controller device node :
114 - device_type = "usb";
115 compatible = "fsl-usb2-mph";
117 #address-cells = <1>;
118 @@ -1422,7 +1432,6 @@ platforms are moved over to use the flat
120 Example dual role USB controller device node :
122 - device_type = "usb";
123 compatible = "fsl-usb2-dr";
125 #address-cells = <1>;
126 @@ -1586,7 +1595,6 @@ platforms are moved over to use the flat
127 iii) USB (Universal Serial Bus Controller)
130 - - device_type : should be "usb".
131 - compatible : could be "qe_udc" or "fhci-hcd".
132 - mode : the could be "host" or "slave".
133 - reg : Offset and length of the register set for the device
134 @@ -1600,7 +1608,6 @@ platforms are moved over to use the flat
138 - device_type = "usb";
139 compatible = "qe_udc";
142 @@ -1613,7 +1620,7 @@ platforms are moved over to use the flat
145 - device_type : should be "network", "hldc", "uart", "transparent"
147 + "bisync", "atm", or "serial".
148 - compatible : could be "ucc_geth" or "fsl_atm" and so on.
149 - model : should be "UCC".
150 - device-id : the ucc number(1-8), corresponding to UCCx in UM.
151 @@ -1626,6 +1633,26 @@ platforms are moved over to use the flat
152 - interrupt-parent : the phandle for the interrupt controller that
153 services interrupts for this device.
154 - pio-handle : The phandle for the Parallel I/O port configuration.
155 + - port-number : for UART drivers, the port number to use, between 0 and 3.
156 + This usually corresponds to the /dev/ttyQE device, e.g. <0> = /dev/ttyQE0.
157 + The port number is added to the minor number of the device. Unlike the
158 + CPM UART driver, the port-number is required for the QE UART driver.
159 + - soft-uart : for UART drivers, if specified this means the QE UART device
160 + driver should use "Soft-UART" mode, which is needed on some SOCs that have
161 + broken UART hardware. Soft-UART is provided via a microcode upload.
162 + - rx-clock-name: the UCC receive clock source
163 + "none": clock source is disabled
164 + "brg1" through "brg16": clock source is BRG1-BRG16, respectively
165 + "clk1" through "clk24": clock source is CLK1-CLK24, respectively
166 + - tx-clock-name: the UCC transmit clock source
167 + "none": clock source is disabled
168 + "brg1" through "brg16": clock source is BRG1-BRG16, respectively
169 + "clk1" through "clk24": clock source is CLK1-CLK24, respectively
170 + The following two properties are deprecated. rx-clock has been replaced
171 + with rx-clock-name, and tx-clock has been replaced with tx-clock-name.
172 + Drivers that currently use the deprecated properties should continue to
173 + do so, in order to support older device trees, but they should be updated
174 + to check for the new properties first.
175 - rx-clock : represents the UCC receive clock source.
176 0x00 : clock source is disabled;
177 0x1~0x10 : clock source is BRG1~BRG16 respectively;
178 @@ -1772,6 +1799,32 @@ platforms are moved over to use the flat
182 + viii) Uploaded QE firmware
184 + If a new firwmare has been uploaded to the QE (usually by the
185 + boot loader), then a 'firmware' child node should be added to the QE
186 + node. This node provides information on the uploaded firmware that
187 + device drivers may need.
189 + Required properties:
190 + - id: The string name of the firmware. This is taken from the 'id'
191 + member of the qe_firmware structure of the uploaded firmware.
192 + Device drivers can search this string to determine if the
193 + firmware they want is already present.
194 + - extended-modes: The Extended Modes bitfield, taken from the
195 + firmware binary. It is a 64-bit number represented
196 + as an array of two 32-bit numbers.
197 + - virtual-traps: The virtual traps, taken from the firmware binary.
198 + It is an array of 8 32-bit numbers.
204 + extended-modes = <0 0>;
205 + virtual-traps = <0 0 0 0 0 0 0 0>;
208 j) CFI or JEDEC memory-mapped NOR flash
210 Flash chips (Memory Technology Devices) are often used for solid state
211 @@ -2075,8 +2128,7 @@ platforms are moved over to use the flat
215 - compatible = "fsl,mpc8272ads-localbus",
216 - "fsl,mpc8272-localbus",
217 + compatible = "fsl,mpc8272-localbus",
219 #address-cells = <2>;
221 @@ -2254,7 +2306,7 @@ platforms are moved over to use the flat
228 The Xilinx EDK toolchain ships with a set of IP cores (devices) for use
229 in Xilinx Spartan and Virtex FPGAs. The devices cover the whole range
230 @@ -2276,7 +2328,7 @@ platforms are moved over to use the flat
231 properties of the device node. In general, device nodes for IP-cores
232 will take the following form:
234 - (name)@(base-address) {
235 + (name): (generic-name)@(base-address) {
236 compatible = "xlnx,(ip-core-name)-(HW_VER)"
237 [, (list of compatible devices), ...];
238 reg = <(baseaddr) (size)>;
239 @@ -2286,6 +2338,9 @@ platforms are moved over to use the flat
240 xlnx,(parameter2) = <(int-value)>;
243 + (generic-name): an open firmware-style name that describes the
244 + generic class of device. Preferably, this is one word, such
245 + as 'serial' or 'ethernet'.
246 (ip-core-name): the name of the ip block (given after the BEGIN
247 directive in system.mhs). Should be in lowercase
248 and all underscores '_' converted to dashes '-'.
249 @@ -2294,9 +2349,9 @@ platforms are moved over to use the flat
250 dropped from the parameter name, the name is converted
251 to lowercase and all underscore '_' characters are
252 converted to dashes '-'.
253 - (baseaddr): the C_BASEADDR parameter.
254 + (baseaddr): the baseaddr parameter value (often named C_BASEADDR).
255 (HW_VER): from the HW_VER parameter.
256 - (size): equals C_HIGHADDR - C_BASEADDR + 1
257 + (size): the address range size (often C_HIGHADDR - C_BASEADDR + 1).
259 Typically, the compatible list will include the exact IP core version
260 followed by an older IP core version which implements the same
261 @@ -2326,11 +2381,11 @@ platforms are moved over to use the flat
263 becomes the following device tree node:
265 - opb-uartlite-0@ec100000 {
266 + opb_uartlite_0: serial@ec100000 {
267 device_type = "serial";
268 compatible = "xlnx,opb-uartlite-1.00.b";
269 reg = <ec100000 10000>;
270 - interrupt-parent = <&opb-intc>;
271 + interrupt-parent = <&opb_intc_0>;
272 interrupts = <1 0>; // got this from the opb_intc parameters
273 current-speed = <d#115200>; // standard serial device prop
274 clock-frequency = <d#50000000>; // standard serial device prop
275 @@ -2339,16 +2394,19 @@ platforms are moved over to use the flat
276 xlnx,use-parity = <0>;
279 - Some IP cores actually implement 2 or more logical devices. In this case,
280 - the device should still describe the whole IP core with a single node
281 - and add a child node for each logical device. The ranges property can
282 - be used to translate from parent IP-core to the registers of each device.
283 - (Note: this makes the assumption that both logical devices have the same
284 - bus binding. If this is not true, then separate nodes should be used for
285 - each logical device). The 'cell-index' property can be used to enumerate
286 - logical devices within an IP core. For example, the following is the
287 - system.mhs entry for the dual ps2 controller found on the ml403 reference
289 + Some IP cores actually implement 2 or more logical devices. In
290 + this case, the device should still describe the whole IP core with
291 + a single node and add a child node for each logical device. The
292 + ranges property can be used to translate from parent IP-core to the
293 + registers of each device. In addition, the parent node should be
294 + compatible with the bus type 'xlnx,compound', and should contain
295 + #address-cells and #size-cells, as with any other bus. (Note: this
296 + makes the assumption that both logical devices have the same bus
297 + binding. If this is not true, then separate nodes should be used
298 + for each logical device). The 'cell-index' property can be used to
299 + enumerate logical devices within an IP core. For example, the
300 + following is the system.mhs entry for the dual ps2 controller found
301 + on the ml403 reference design.
303 BEGIN opb_ps2_dual_ref
304 PARAMETER INSTANCE = opb_ps2_dual_ref_0
305 @@ -2370,21 +2428,24 @@ platforms are moved over to use the flat
307 It would result in the following device tree nodes:
309 - opb_ps2_dual_ref_0@a9000000 {
310 + opb_ps2_dual_ref_0: opb-ps2-dual-ref@a9000000 {
311 + #address-cells = <1>;
313 + compatible = "xlnx,compound";
314 ranges = <0 a9000000 2000>;
315 // If this device had extra parameters, then they would
318 compatible = "xlnx,opb-ps2-dual-ref-1.00.a";
320 - interrupt-parent = <&opb-intc>;
321 + interrupt-parent = <&opb_intc_0>;
326 compatible = "xlnx,opb-ps2-dual-ref-1.00.a";
328 - interrupt-parent = <&opb-intc>;
329 + interrupt-parent = <&opb_intc_0>;
333 @@ -2447,17 +2508,18 @@ platforms are moved over to use the flat
335 Gives this device tree (some properties removed for clarity):
339 #address-cells = <1>;
341 + compatible = "xlnx,plb-v34-1.02.a";
342 device_type = "ibm,plb";
343 ranges; // 1:1 translation
345 - plb-bram-if-cntrl-0@ffff0000 {
346 + plb_bram_if_cntrl_0: bram@ffff0000 {
347 reg = <ffff0000 10000>;
352 #address-cells = <1>;
354 ranges = <20000000 20000000 20000000
355 @@ -2465,11 +2527,11 @@ platforms are moved over to use the flat
356 80000000 80000000 40000000
357 c0000000 c0000000 20000000>;
359 - opb-uart16550-0@a0000000 {
360 + opb_uart16550_0: serial@a0000000 {
361 reg = <a00000000 2000>;
364 - opb-intc-0@d1000fc0 {
365 + opb_intc_0: interrupt-controller@d1000fc0 {
369 @@ -2514,6 +2576,46 @@ platforms are moved over to use the flat
371 - current-speed : Baud rate of uartlite
373 + p) Freescale Synchronous Serial Interface
375 + The SSI is a serial device that communicates with audio codecs. It can
376 + be programmed in AC97, I2S, left-justified, or right-justified modes.
378 + Required properties:
379 + - compatible : compatible list, containing "fsl,ssi"
380 + - cell-index : the SSI, <0> = SSI1, <1> = SSI2, and so on
381 + - reg : offset and length of the register set for the device
382 + - interrupts : <a b> where a is the interrupt number and b is a
383 + field that represents an encoding of the sense and
384 + level information for the interrupt. This should be
385 + encoded based on the information in section 2)
386 + depending on the type of interrupt controller you
388 + - interrupt-parent : the phandle for the interrupt controller that
389 + services interrupts for this device.
390 + - fsl,mode : the operating mode for the SSI interface
391 + "i2s-slave" - I2S mode, SSI is clock slave
392 + "i2s-master" - I2S mode, SSI is clock master
393 + "lj-slave" - left-justified mode, SSI is clock slave
394 + "lj-master" - l.j. mode, SSI is clock master
395 + "rj-slave" - right-justified mode, SSI is clock slave
396 + "rj-master" - r.j., SSI is clock master
397 + "ac97-slave" - AC97 mode, SSI is clock slave
398 + "ac97-master" - AC97 mode, SSI is clock master
400 + Optional properties:
401 + - codec-handle : phandle to a 'codec' node that defines an audio
402 + codec connected to this SSI. This node is typically
403 + a child of an I2C or other control node.
405 + Child 'codec' node required properties:
406 + - compatible : compatible list, contains the name of the codec
408 + Child 'codec' node optional properties:
409 + - clock-frequency : The frequency of the input clock, which typically
410 + comes from an on-board dedicated oscillator.
413 More devices will be defined as this spec matures.
415 VII - Specifying interrupt information for devices
417 +++ b/Documentation/powerpc/qe_firmware.txt
419 + Freescale QUICC Engine Firmware Uploading
420 + -----------------------------------------
422 +(c) 2007 Timur Tabi <timur at freescale.com>,
423 + Freescale Semiconductor
428 + I - Software License for Firmware
430 + II - Microcode Availability
432 + III - Description and Terminology
434 + IV - Microcode Programming Details
436 + V - Firmware Structure Layout
438 + VI - Sample Code for Creating Firmware Files
440 +Revision Information
441 +====================
443 +November 30, 2007: Rev 1.0 - Initial version
445 +I - Software License for Firmware
446 +=================================
448 +Each firmware file comes with its own software license. For information on
449 +the particular license, please see the license text that is distributed with
452 +II - Microcode Availability
453 +===========================
455 +Firmware files are distributed through various channels. Some are available on
456 +http://opensource.freescale.com. For other firmware files, please contact
457 +your Freescale representative or your operating system vendor.
459 +III - Description and Terminology
460 +================================
462 +In this document, the term 'microcode' refers to the sequence of 32-bit
463 +integers that compose the actual QE microcode.
465 +The term 'firmware' refers to a binary blob that contains the microcode as
466 +well as other data that
468 + 1) describes the microcode's purpose
469 + 2) describes how and where to upload the microcode
470 + 3) specifies the values of various registers
471 + 4) includes additional data for use by specific device drivers
473 +Firmware files are binary files that contain only a firmware.
475 +IV - Microcode Programming Details
476 +===================================
478 +The QE architecture allows for only one microcode present in I-RAM for each
479 +RISC processor. To replace any current microcode, a full QE reset (which
480 +disables the microcode) must be performed first.
482 +QE microcode is uploaded using the following procedure:
484 +1) The microcode is placed into I-RAM at a specific location, using the
485 + IRAM.IADD and IRAM.IDATA registers.
487 +2) The CERCR.CIR bit is set to 0 or 1, depending on whether the firmware
488 + needs split I-RAM. Split I-RAM is only meaningful for SOCs that have
489 + QEs with multiple RISC processors, such as the 8360. Splitting the I-RAM
490 + allows each processor to run a different microcode, effectively creating an
491 + asymmetric multiprocessing (AMP) system.
493 +3) The TIBCR trap registers are loaded with the addresses of the trap handlers
496 +4) The RSP.ECCR register is programmed with the value provided.
498 +5) If necessary, device drivers that need the virtual traps and extended mode
499 + data will use them.
501 +Virtual Microcode Traps
503 +These virtual traps are conditional branches in the microcode. These are
504 +"soft" provisional introduced in the ROMcode in order to enable higher
505 +flexibility and save h/w traps If new features are activated or an issue is
506 +being fixed in the RAM package utilizing they should be activated. This data
507 +structure signals the microcode which of these virtual traps is active.
509 +This structure contains 6 words that the application should copy to some
510 +specific been defined. This table describes the structure.
512 + ---------------------------------------------------------------
513 + | Offset in | | Destination Offset | Size of |
514 + | array | Protocol | within PRAM | Operand |
515 + --------------------------------------------------------------|
516 + | 0 | Ethernet | 0xF8 | 4 bytes |
517 + | | interworking | | |
518 + ---------------------------------------------------------------
519 + | 4 | ATM | 0xF8 | 4 bytes |
520 + | | interworking | | |
521 + ---------------------------------------------------------------
522 + | 8 | PPP | 0xF8 | 4 bytes |
523 + | | interworking | | |
524 + ---------------------------------------------------------------
525 + | 12 | Ethernet RX | 0x22 | 1 byte |
526 + | | Distributor Page | | |
527 + ---------------------------------------------------------------
528 + | 16 | ATM Globtal | 0x28 | 1 byte |
529 + | | Params Table | | |
530 + ---------------------------------------------------------------
531 + | 20 | Insert Frame | 0xF8 | 4 bytes |
532 + ---------------------------------------------------------------
537 +This is a double word bit array (64 bits) that defines special functionality
538 +which has an impact on the softwarew drivers. Each bit has its own impact
539 +and has special instructions for the s/w associated with it. This structure is
540 +described in this table:
542 + -----------------------------------------------------------------------
543 + | Bit # | Name | Description |
544 + -----------------------------------------------------------------------
545 + | 0 | General | Indicates that prior to each host command |
546 + | | push command | given by the application, the software must |
547 + | | | assert a special host command (push command)|
548 + | | | CECDR = 0x00800000. |
549 + | | | CECR = 0x01c1000f. |
550 + -----------------------------------------------------------------------
551 + | 1 | UCC ATM | Indicates that after issuing ATM RX INIT |
552 + | | RX INIT | command, the host must issue another special|
553 + | | push command | command (push command) and immediately |
554 + | | | following that re-issue the ATM RX INIT |
555 + | | | command. (This makes the sequence of |
556 + | | | initializing the ATM receiver a sequence of |
557 + | | | three host commands) |
558 + | | | CECDR = 0x00800000. |
559 + | | | CECR = 0x01c1000f. |
560 + -----------------------------------------------------------------------
561 + | 2 | Add/remove | Indicates that following the specific host |
562 + | | command | command: "Add/Remove entry in Hash Lookup |
563 + | | validation | Table" used in Interworking setup, the user |
564 + | | | must issue another command. |
565 + | | | CECDR = 0xce000003. |
566 + | | | CECR = 0x01c10f58. |
567 + -----------------------------------------------------------------------
568 + | 3 | General push | Indicates that the s/w has to initialize |
569 + | | command | some pointers in the Ethernet thread pages |
570 + | | | which are used when Header Compression is |
571 + | | | activated. The full details of these |
572 + | | | pointers is located in the software drivers.|
573 + -----------------------------------------------------------------------
574 + | 4 | General push | Indicates that after issuing Ethernet TX |
575 + | | command | INIT command, user must issue this command |
576 + | | | for each SNUM of Ethernet TX thread. |
577 + | | | CECDR = 0x00800003. |
578 + | | | CECR = 0x7'b{0}, 8'b{Enet TX thread SNUM}, |
579 + | | | 1'b{1}, 12'b{0}, 4'b{1} |
580 + -----------------------------------------------------------------------
581 + | 5 - 31 | N/A | Reserved, set to zero. |
582 + -----------------------------------------------------------------------
584 +V - Firmware Structure Layout
585 +==============================
587 +QE microcode from Freescale is typically provided as a header file. This
588 +header file contains macros that define the microcode binary itself as well as
589 +some other data used in uploading that microcode. The format of these files
590 +do not lend themselves to simple inclusion into other code. Hence,
591 +the need for a more portable format. This section defines that format.
593 +Instead of distributing a header file, the microcode and related data are
594 +embedded into a binary blob. This blob is passed to the qe_upload_firmware()
595 +function, which parses the blob and performs everything necessary to upload
598 +All integers are big-endian. See the comments for function
599 +qe_upload_firmware() for up-to-date implementation information.
601 +This structure supports versioning, where the version of the structure is
602 +embedded into the structure itself. To ensure forward and backwards
603 +compatibility, all versions of the structure must use the same 'qe_header'
604 +structure at the beginning.
606 +'header' (type: struct qe_header):
607 + The 'length' field is the size, in bytes, of the entire structure,
608 + including all the microcode embedded in it, as well as the CRC (if
611 + The 'magic' field is an array of three bytes that contains the letters
612 + 'Q', 'E', and 'F'. This is an identifier that indicates that this
613 + structure is a QE Firmware structure.
615 + The 'version' field is a single byte that indicates the version of this
616 + structure. If the layout of the structure should ever need to be
617 + changed to add support for additional types of microcode, then the
618 + version number should also be changed.
620 +The 'id' field is a null-terminated string(suitable for printing) that
621 +identifies the firmware.
623 +The 'count' field indicates the number of 'microcode' structures. There
624 +must be one and only one 'microcode' structure for each RISC processor.
625 +Therefore, this field also represents the number of RISC processors for this
628 +The 'soc' structure contains the SOC numbers and revisions used to match
629 +the microcode to the SOC itself. Normally, the microcode loader should
630 +check the data in this structure with the SOC number and revisions, and
631 +only upload the microcode if there's a match. However, this check is not
632 +made on all platforms.
634 +Although it is not recommended, you can specify '0' in the soc.model
635 +field to skip matching SOCs altogether.
637 +The 'model' field is a 16-bit number that matches the actual SOC. The
638 +'major' and 'minor' fields are the major and minor revision numbrs,
639 +respectively, of the SOC.
641 +For example, to match the 8323, revision 1.0:
646 +'padding' is neccessary for structure alignment. This field ensures that the
647 +'extended_modes' field is aligned on a 64-bit boundary.
649 +'extended_modes' is a bitfield that defines special functionality which has an
650 +impact on the device drivers. Each bit has its own impact and has special
651 +instructions for the driver associated with it. This field is stored in
652 +the QE library and available to any driver that calles qe_get_firmware_info().
654 +'vtraps' is an array of 8 words that contain virtual trap values for each
655 +virtual traps. As with 'extended_modes', this field is stored in the QE
656 +library and available to any driver that calles qe_get_firmware_info().
658 +'microcode' (type: struct qe_microcode):
659 + For each RISC processor there is one 'microcode' structure. The first
660 + 'microcode' structure is for the first RISC, and so on.
662 + The 'id' field is a null-terminated string suitable for printing that
663 + identifies this particular microcode.
665 + 'traps' is an array of 16 words that contain hardware trap values
666 + for each of the 16 traps. If trap[i] is 0, then this particular
667 + trap is to be ignored (i.e. not written to TIBCR[i]). The entire value
668 + is written as-is to the TIBCR[i] register, so be sure to set the EN
669 + and T_IBP bits if necessary.
671 + 'eccr' is the value to program into the ECCR register.
673 + 'iram_offset' is the offset into IRAM to start writing the
676 + 'count' is the number of 32-bit words in the microcode.
678 + 'code_offset' is the offset, in bytes, from the beginning of this
679 + structure where the microcode itself can be found. The first
680 + microcode binary should be located immediately after the 'microcode'
683 + 'major', 'minor', and 'revision' are the major, minor, and revision
684 + version numbers, respectively, of the microcode. If all values are 0,
685 + then these fields are ignored.
687 + 'reserved' is necessary for structure alignment. Since 'microcode'
688 + is an array, the 64-bit 'extended_modes' field needs to be aligned
689 + on a 64-bit boundary, and this can only happen if the size of
690 + 'microcode' is a multiple of 8 bytes. To ensure that, we add
693 +After the last microcode is a 32-bit CRC. It can be calculated using
696 +u32 crc32(const u8 *p, unsigned int len)
703 + for (i = 0; i < 8; i++)
704 + crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
709 +VI - Sample Code for Creating Firmware Files
710 +============================================
712 +A Python program that creates firmware binaries from the header files normally
713 +distributed by Freescale can be found on http://opensource.freescale.com.
714 --- a/arch/powerpc/Kconfig
715 +++ b/arch/powerpc/Kconfig
716 @@ -140,6 +140,9 @@ config DEFAULT_UIMAGE
717 Used to allow a board to specify it wants a uImage built by default
725 depends on PPC64 && (BROKEN || (PPC_PMAC64 && EXPERIMENTAL))
726 @@ -160,11 +163,13 @@ config PPC_DCR
728 config PPC_OF_PLATFORM_PCI
731 depends on PPC64 # not supported on 32 bits yet
734 source "init/Kconfig"
736 +source "arch/powerpc/sysdev/Kconfig"
737 source "arch/powerpc/platforms/Kconfig"
739 menu "Kernel options"
740 @@ -417,7 +422,7 @@ endmenu
745 + default !PPC_ISERIES || PCI
749 @@ -467,7 +472,7 @@ config MCA
751 bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \
752 || PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \
755 default y if !40x && !CPM2 && !8xx && !PPC_83xx \
756 && !PPC_85xx && !PPC_86xx
757 default PCI_PERMEDIA if !4xx && !CPM2 && !8xx
758 --- a/arch/powerpc/Kconfig.debug
759 +++ b/arch/powerpc/Kconfig.debug
760 @@ -151,6 +151,13 @@ config BOOTX_TEXT
762 config PPC_EARLY_DEBUG
763 bool "Early debugging (dangerous)"
765 + Say Y to enable some early debugging facilities that may be available
766 + for your processor/board combination. Those facilities are hacks
767 + intended to debug problems early during boot, this should not be
768 + enabled in a production kernel.
769 + Note that enabling this will also cause the kernel default log level
770 + to be pushed to max automatically very early during boot
773 prompt "Early debugging console"
774 @@ -218,7 +225,16 @@ config PPC_EARLY_DEBUG_44x
777 Select this to enable early debugging for IBM 44x chips via the
778 - inbuilt serial port.
779 + inbuilt serial port. If you enable this, ensure you set
780 + PPC_EARLY_DEBUG_44x_PHYSLOW below to suit your target board.
782 +config PPC_EARLY_DEBUG_40x
783 + bool "Early serial debugging for IBM/AMCC 40x CPUs"
786 + Select this to enable early debugging for IBM 40x chips via the
787 + inbuilt serial port. This works on chips with a 16550 compatible
788 + UART. Xilinx chips with uartlite cannot use this option.
790 config PPC_EARLY_DEBUG_CPM
791 bool "Early serial debugging for Freescale CPM-based serial ports"
792 @@ -235,12 +251,20 @@ config PPC_EARLY_DEBUG_44x_PHYSLOW
793 hex "Low 32 bits of early debug UART physical address"
794 depends on PPC_EARLY_DEBUG_44x
797 + You probably want 0x40000200 for ebony boards and
798 + 0x40000300 for taishan
800 config PPC_EARLY_DEBUG_44x_PHYSHIGH
801 hex "EPRN of early debug UART physical address"
802 depends on PPC_EARLY_DEBUG_44x
805 +config PPC_EARLY_DEBUG_40x_PHYSADDR
806 + hex "Early debug UART physical address"
807 + depends on PPC_EARLY_DEBUG_40x
808 + default "0xef600300"
810 config PPC_EARLY_DEBUG_CPM_ADDR
811 hex "CPM UART early debug transmit descriptor address"
812 depends on PPC_EARLY_DEBUG_CPM
813 --- a/arch/powerpc/Makefile
814 +++ b/arch/powerpc/Makefile
815 @@ -167,6 +167,9 @@ boot := arch/$(ARCH)/boot
816 $(BOOT_TARGETS): vmlinux
817 $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
819 +bootwrapper_install:
820 + $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
823 @echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage.*)'
824 @echo ' install - Install kernel using'
825 --- a/arch/powerpc/boot/4xx.c
826 +++ b/arch/powerpc/boot/4xx.c
830 /* Read the 4xx SDRAM controller to get size of system memory. */
831 -void ibm4xx_fixup_memsize(void)
832 +void ibm4xx_sdram_fixup_memsize(void)
835 unsigned long memsize, bank_config;
838 for (i = 0; i < ARRAY_SIZE(sdram_bxcr); i++) {
839 - mtdcr(DCRN_SDRAM0_CFGADDR, sdram_bxcr[i]);
840 - bank_config = mfdcr(DCRN_SDRAM0_CFGDATA);
842 + bank_config = SDRAM0_READ(sdram_bxcr[i]);
843 if (bank_config & SDRAM_CONFIG_BANK_ENABLE)
844 memsize += SDRAM_CONFIG_BANK_SIZE(bank_config);
846 @@ -39,6 +37,69 @@ void ibm4xx_fixup_memsize(void)
847 dt_fixup_memory(0, memsize);
850 +/* Read the 440SPe MQ controller to get size of system memory. */
851 +#define DCRN_MQ0_B0BAS 0x40
852 +#define DCRN_MQ0_B1BAS 0x41
853 +#define DCRN_MQ0_B2BAS 0x42
854 +#define DCRN_MQ0_B3BAS 0x43
856 +static u64 ibm440spe_decode_bas(u32 bas)
858 + u64 base = ((u64)(bas & 0xFFE00000u)) << 2;
860 + /* open coded because I'm paranoid about invalid values */
861 + switch ((bas >> 4) & 0xFFF) {
865 + return base + 0x000800000ull;
867 + return base + 0x001000000ull;
869 + return base + 0x002000000ull;
871 + return base + 0x004000000ull;
873 + return base + 0x008000000ull;
875 + return base + 0x010000000ull;
877 + return base + 0x020000000ull;
879 + return base + 0x040000000ull;
881 + return base + 0x080000000ull;
883 + return base + 0x100000000ull;
885 + printf("Memory BAS value 0x%08x unsupported !\n", bas);
889 +void ibm440spe_fixup_memsize(void)
891 + u64 banktop, memsize = 0;
893 + /* Ultimately, we should directly construct the memory node
894 + * so we are able to handle holes in the memory address space
896 + banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B0BAS));
897 + if (banktop > memsize)
899 + banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B1BAS));
900 + if (banktop > memsize)
902 + banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B2BAS));
903 + if (banktop > memsize)
905 + banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B3BAS));
906 + if (banktop > memsize)
909 + dt_fixup_memory(0, memsize);
913 /* 4xx DDR1/2 Denali memory controller support */
916 @@ -77,19 +138,13 @@ void ibm4xx_fixup_memsize(void)
918 #define DDR_GET_VAL(val, mask, shift) (((val) >> (shift)) & (mask))
920 -static inline u32 mfdcr_sdram0(u32 reg)
922 - mtdcr(DCRN_SDRAM0_CFGADDR, reg);
923 - return mfdcr(DCRN_SDRAM0_CFGDATA);
926 void ibm4xx_denali_fixup_memsize(void)
928 u32 val, max_cs, max_col, max_row;
929 u32 cs, col, row, bank, dpath;
930 unsigned long memsize;
932 - val = mfdcr_sdram0(DDR0_02);
933 + val = SDRAM0_READ(DDR0_02);
934 if (!DDR_GET_VAL(val, DDR_START, DDR_START_SHIFT))
935 fatal("DDR controller is not initialized\n");
937 @@ -99,12 +154,12 @@ void ibm4xx_denali_fixup_memsize(void)
938 max_row = DDR_GET_VAL(val, DDR_MAX_ROW_REG, DDR_MAX_ROW_REG_SHIFT);
941 - val = mfdcr_sdram0(DDR0_10);
942 + val = SDRAM0_READ(DDR0_10);
944 val = DDR_GET_VAL(val, DDR_CS_MAP, DDR_CS_MAP_SHIFT);
952 @@ -115,15 +170,15 @@ void ibm4xx_denali_fixup_memsize(void)
953 fatal("DDR wrong CS configuration\n");
955 /* get data path bytes */
956 - val = mfdcr_sdram0(DDR0_14);
957 + val = SDRAM0_READ(DDR0_14);
959 if (DDR_GET_VAL(val, DDR_REDUC, DDR_REDUC_SHIFT))
960 dpath = 8; /* 64 bits */
962 dpath = 4; /* 32 bits */
964 - /* get adress pins (rows) */
965 - val = mfdcr_sdram0(DDR0_42);
966 + /* get address pins (rows) */
967 + val = SDRAM0_READ(DDR0_42);
969 row = DDR_GET_VAL(val, DDR_APIN, DDR_APIN_SHIFT);
971 @@ -131,7 +186,7 @@ void ibm4xx_denali_fixup_memsize(void)
974 /* get collomn size and banks */
975 - val = mfdcr_sdram0(DDR0_43);
976 + val = SDRAM0_READ(DDR0_43);
978 col = DDR_GET_VAL(val, DDR_COL_SZ, DDR_COL_SZ_SHIFT);
980 @@ -179,13 +234,17 @@ void ibm40x_dbcr_reset(void)
981 #define EMAC_RESET 0x20000000
982 void ibm4xx_quiesce_eth(u32 *emac0, u32 *emac1)
984 - /* Quiesce the MAL and EMAC(s) since PIBS/OpenBIOS don't do this for us */
985 + /* Quiesce the MAL and EMAC(s) since PIBS/OpenBIOS don't
993 mtdcr(DCRN_MAL0_CFG, MAL_RESET);
994 + while (mfdcr(DCRN_MAL0_CFG) & MAL_RESET)
995 + ; /* loop until reset takes effect */
998 /* Read 4xx EBC bus bridge registers to get mappings of the peripheral
999 @@ -217,84 +276,335 @@ void ibm4xx_fixup_ebc_ranges(const char
1000 setprop(devp, "ranges", ranges, (p - ranges) * sizeof(u32));
1003 -#define SPRN_CCR1 0x378
1004 -void ibm440ep_fixup_clocks(unsigned int sysclk, unsigned int ser_clk)
1005 +/* Calculate 440GP clocks */
1006 +void ibm440gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk)
1008 - u32 cpu, plb, opb, ebc, tb, uart0, m, vco;
1010 - u32 fwdva, fwdvb, fbdv, lfbdv, opbdv0, perdv0, spcid0, prbdv0, tmp;
1012 - mtdcr(DCRN_CPR0_ADDR, CPR0_PLLD0);
1013 - reg = mfdcr(DCRN_CPR0_DATA);
1014 - tmp = (reg & 0x000F0000) >> 16;
1015 - fwdva = tmp ? tmp : 16;
1016 - tmp = (reg & 0x00000700) >> 8;
1017 - fwdvb = tmp ? tmp : 8;
1018 - tmp = (reg & 0x1F000000) >> 24;
1019 - fbdv = tmp ? tmp : 32;
1020 - lfbdv = (reg & 0x0000007F);
1022 - mtdcr(DCRN_CPR0_ADDR, CPR0_OPBD0);
1023 - reg = mfdcr(DCRN_CPR0_DATA);
1024 - tmp = (reg & 0x03000000) >> 24;
1025 - opbdv0 = tmp ? tmp : 4;
1027 - mtdcr(DCRN_CPR0_ADDR, CPR0_PERD0);
1028 - reg = mfdcr(DCRN_CPR0_DATA);
1029 - tmp = (reg & 0x07000000) >> 24;
1030 - perdv0 = tmp ? tmp : 8;
1032 - mtdcr(DCRN_CPR0_ADDR, CPR0_PRIMBD0);
1033 - reg = mfdcr(DCRN_CPR0_DATA);
1034 - tmp = (reg & 0x07000000) >> 24;
1035 - prbdv0 = tmp ? tmp : 8;
1037 - mtdcr(DCRN_CPR0_ADDR, CPR0_SCPID);
1038 - reg = mfdcr(DCRN_CPR0_DATA);
1039 - tmp = (reg & 0x03000000) >> 24;
1040 - spcid0 = tmp ? tmp : 4;
1043 - mtdcr(DCRN_CPR0_ADDR, CPR0_PLLC0);
1044 - reg = mfdcr(DCRN_CPR0_DATA);
1045 - tmp = (reg & 0x03000000) >> 24;
1046 - if (tmp == 0) { /* PLL output */
1047 - tmp = (reg & 0x20000000) >> 29;
1048 - if (!tmp) /* PLLOUTA */
1049 - m = fbdv * lfbdv * fwdva;
1050 + u32 sys0 = mfdcr(DCRN_CPC0_SYS0);
1051 + u32 cr0 = mfdcr(DCRN_CPC0_CR0);
1052 + u32 cpu, plb, opb, ebc, tb, uart0, uart1, m;
1053 + u32 opdv = CPC0_SYS0_OPDV(sys0);
1054 + u32 epdv = CPC0_SYS0_EPDV(sys0);
1056 + if (sys0 & CPC0_SYS0_BYPASS) {
1057 + /* Bypass system PLL */
1058 + cpu = plb = sys_clk;
1060 + if (sys0 & CPC0_SYS0_EXTSL)
1062 + m = CPC0_SYS0_FWDVB(sys0) * opdv * epdv;
1064 - m = fbdv * lfbdv * fwdvb;
1066 + m = CPC0_SYS0_FBDV(sys0) * CPC0_SYS0_FWDVA(sys0);
1067 + cpu = sys_clk * m / CPC0_SYS0_FWDVA(sys0);
1068 + plb = sys_clk * m / CPC0_SYS0_FWDVB(sys0);
1070 - else if (tmp == 1) /* CPU output */
1076 + /* FIXME: Check if this is for all 440GP, or just Ebony */
1077 + if ((mfpvr() & 0xf0000fff) == 0x40000440)
1078 + /* Rev. B 440GP, use external system clock */
1081 - m = perdv0 * opbdv0 * fwdvb;
1082 + /* Rev. C 440GP, errata force us to use internal clock */
1085 - vco = (m * sysclk) + (m >> 1);
1086 - cpu = vco / fwdva;
1087 - plb = vco / fwdvb / prbdv0;
1088 - opb = plb / opbdv0;
1089 - ebc = plb / perdv0;
1090 + if (cr0 & CPC0_CR0_U0EC)
1091 + /* External UART clock */
1094 + /* Internal UART clock */
1095 + uart0 = plb / CPC0_CR0_UDIV(cr0);
1099 + if (cr0 & CPC0_CR0_U1EC)
1100 + /* External UART clock */
1103 + /* Internal UART clock */
1104 + uart1 = plb / CPC0_CR0_UDIV(cr0);
1106 + printf("PPC440GP: SysClk = %dMHz (%x)\n\r",
1107 + (sys_clk + 500000) / 1000000, sys_clk);
1109 + dt_fixup_cpu_clocks(cpu, tb, 0);
1111 + dt_fixup_clock("/plb", plb);
1112 + dt_fixup_clock("/plb/opb", opb);
1113 + dt_fixup_clock("/plb/opb/ebc", ebc);
1114 + dt_fixup_clock("/plb/opb/serial@40000200", uart0);
1115 + dt_fixup_clock("/plb/opb/serial@40000300", uart1);
1118 +#define SPRN_CCR1 0x378
1120 +static inline u32 __fix_zero(u32 v, u32 def)
1122 + return v ? v : def;
1125 +static unsigned int __ibm440eplike_fixup_clocks(unsigned int sys_clk,
1126 + unsigned int tmr_clk,
1127 + int per_clk_from_opb)
1130 + u32 pllc = CPR0_READ(DCRN_CPR0_PLLC);
1131 + u32 plld = CPR0_READ(DCRN_CPR0_PLLD);
1134 + u32 fbdv = __fix_zero((plld >> 24) & 0x1f, 32);
1135 + u32 fwdva = __fix_zero((plld >> 16) & 0xf, 16);
1136 + u32 fwdvb = __fix_zero((plld >> 8) & 7, 8);
1137 + u32 lfbdv = __fix_zero(plld & 0x3f, 64);
1138 + u32 pradv0 = __fix_zero((CPR0_READ(DCRN_CPR0_PRIMAD) >> 24) & 7, 8);
1139 + u32 prbdv0 = __fix_zero((CPR0_READ(DCRN_CPR0_PRIMBD) >> 24) & 7, 8);
1140 + u32 opbdv0 = __fix_zero((CPR0_READ(DCRN_CPR0_OPBD) >> 24) & 3, 4);
1141 + u32 perdv0 = __fix_zero((CPR0_READ(DCRN_CPR0_PERD) >> 24) & 3, 4);
1143 + /* Input clocks for primary dividers */
1146 + /* Resulting clocks */
1147 + u32 cpu, plb, opb, ebc, vco;
1150 + u32 ccr1, tb = tmr_clk;
1152 + if (pllc & 0x40000000) {
1155 + /* Feedback path */
1156 + switch ((pllc >> 24) & 7) {
1159 + m = ((pllc & 0x20000000) ? fwdvb : fwdva) * lfbdv;
1163 + m = fwdva * pradv0;
1167 + m = fwdvb * prbdv0 * opbdv0 * perdv0;
1170 + printf("WARNING ! Invalid PLL feedback source !\n");
1174 + vco = sys_clk * m;
1175 + clk_a = vco / fwdva;
1176 + clk_b = vco / fwdvb;
1179 + /* Bypass system PLL */
1181 + clk_a = clk_b = sys_clk;
1184 + cpu = clk_a / pradv0;
1185 + plb = clk_b / prbdv0;
1186 + opb = plb / opbdv0;
1187 + ebc = (per_clk_from_opb ? opb : plb) / perdv0;
1189 /* Figure out timebase. Either CPU or default TmrClk */
1193 - "=&r"(reg) : "i"(SPRN_CCR1));
1195 - tb = 25000000; /* TmrClk is 25MHz */
1197 + ccr1 = mfspr(SPRN_CCR1);
1199 + /* If passed a 0 tmr_clk, force CPU clock */
1202 + mtspr(SPRN_CCR1, ccr1);
1204 + if ((ccr1 & 0x0080) == 0)
1207 dt_fixup_cpu_clocks(cpu, tb, 0);
1208 dt_fixup_clock("/plb", plb);
1209 dt_fixup_clock("/plb/opb", opb);
1210 dt_fixup_clock("/plb/opb/ebc", ebc);
1215 +static void eplike_fixup_uart_clk(int index, const char *path,
1216 + unsigned int ser_clk,
1217 + unsigned int plb_clk)
1220 + unsigned int clock;
1224 + sdr = SDR0_READ(DCRN_SDR0_UART0);
1227 + sdr = SDR0_READ(DCRN_SDR0_UART1);
1230 + sdr = SDR0_READ(DCRN_SDR0_UART2);
1233 + sdr = SDR0_READ(DCRN_SDR0_UART3);
1239 + if (sdr & 0x00800000u)
1242 + clock = plb_clk / __fix_zero(sdr & 0xff, 256);
1244 + dt_fixup_clock(path, clock);
1247 +void ibm440ep_fixup_clocks(unsigned int sys_clk,
1248 + unsigned int ser_clk,
1249 + unsigned int tmr_clk)
1251 + unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 0);
1253 + /* serial clocks beed fixup based on int/ext */
1254 + eplike_fixup_uart_clk(0, "/plb/opb/serial@ef600300", ser_clk, plb_clk);
1255 + eplike_fixup_uart_clk(1, "/plb/opb/serial@ef600400", ser_clk, plb_clk);
1256 + eplike_fixup_uart_clk(2, "/plb/opb/serial@ef600500", ser_clk, plb_clk);
1257 + eplike_fixup_uart_clk(3, "/plb/opb/serial@ef600600", ser_clk, plb_clk);
1260 +void ibm440gx_fixup_clocks(unsigned int sys_clk,
1261 + unsigned int ser_clk,
1262 + unsigned int tmr_clk)
1264 + unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1);
1266 + /* serial clocks beed fixup based on int/ext */
1267 + eplike_fixup_uart_clk(0, "/plb/opb/serial@40000200", ser_clk, plb_clk);
1268 + eplike_fixup_uart_clk(1, "/plb/opb/serial@40000300", ser_clk, plb_clk);
1271 +void ibm440spe_fixup_clocks(unsigned int sys_clk,
1272 + unsigned int ser_clk,
1273 + unsigned int tmr_clk)
1275 + unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1);
1277 + /* serial clocks beed fixup based on int/ext */
1278 + eplike_fixup_uart_clk(0, "/plb/opb/serial@10000200", ser_clk, plb_clk);
1279 + eplike_fixup_uart_clk(1, "/plb/opb/serial@10000300", ser_clk, plb_clk);
1280 + eplike_fixup_uart_clk(2, "/plb/opb/serial@10000600", ser_clk, plb_clk);
1283 +void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk)
1285 + u32 pllmr = mfdcr(DCRN_CPC0_PLLMR);
1286 + u32 cpc0_cr0 = mfdcr(DCRN_405_CPC0_CR0);
1287 + u32 cpc0_cr1 = mfdcr(DCRN_405_CPC0_CR1);
1288 + u32 psr = mfdcr(DCRN_405_CPC0_PSR);
1289 + u32 cpu, plb, opb, ebc, tb, uart0, uart1, m;
1290 + u32 fwdv, fwdvb, fbdv, cbdv, opdv, epdv, ppdv, udiv;
1292 + fwdv = (8 - ((pllmr & 0xe0000000) >> 29));
1293 + fbdv = (pllmr & 0x1e000000) >> 25;
1296 + cbdv = ((pllmr & 0x00060000) >> 17) + 1; /* CPU:PLB */
1297 + opdv = ((pllmr & 0x00018000) >> 15) + 1; /* PLB:OPB */
1298 + ppdv = ((pllmr & 0x00001800) >> 13) + 1; /* PLB:PCI */
1299 + epdv = ((pllmr & 0x00001800) >> 11) + 2; /* PLB:EBC */
1300 + udiv = ((cpc0_cr0 & 0x3e) >> 1) + 1;
1302 + /* check for 405GPr */
1303 + if ((mfpvr() & 0xfffffff0) == (0x50910951 & 0xfffffff0)) {
1304 + fwdvb = 8 - (pllmr & 0x00000007);
1305 + if (!(psr & 0x00001000)) /* PCI async mode enable == 0 */
1306 + if (psr & 0x00000020) /* New mode enable */
1307 + m = fwdvb * 2 * ppdv;
1309 + m = fwdvb * cbdv * ppdv;
1310 + else if (psr & 0x00000020) /* New mode enable */
1311 + if (psr & 0x00000800) /* PerClk synch mode */
1312 + m = fwdvb * 2 * epdv;
1315 + else if (epdv == fbdv)
1316 + m = fbdv * cbdv * epdv;
1318 + m = fbdv * fwdvb * cbdv;
1320 + cpu = sys_clk * m / fwdv;
1321 + plb = sys_clk * m / (fwdvb * cbdv);
1323 + m = fwdv * fbdv * cbdv;
1324 + cpu = sys_clk * m / fwdv;
1330 + if (cpc0_cr0 & 0x80)
1331 + /* uart0 uses the external clock */
1334 + uart0 = cpu / udiv;
1336 + if (cpc0_cr0 & 0x40)
1337 + /* uart1 uses the external clock */
1340 + uart1 = cpu / udiv;
1342 + /* setup the timebase clock to tick at the cpu frequency */
1343 + cpc0_cr1 = cpc0_cr1 & ~0x00800000;
1344 + mtdcr(DCRN_405_CPC0_CR1, cpc0_cr1);
1347 + dt_fixup_cpu_clocks(cpu, tb, 0);
1348 + dt_fixup_clock("/plb", plb);
1349 + dt_fixup_clock("/plb/opb", opb);
1350 + dt_fixup_clock("/plb/ebc", ebc);
1351 + dt_fixup_clock("/plb/opb/serial@ef600300", uart0);
1352 + dt_fixup_clock("/plb/opb/serial@ef600400", uart1);
1356 +void ibm405ep_fixup_clocks(unsigned int sys_clk)
1358 + u32 pllmr0 = mfdcr(DCRN_CPC0_PLLMR0);
1359 + u32 pllmr1 = mfdcr(DCRN_CPC0_PLLMR1);
1360 + u32 cpc0_ucr = mfdcr(DCRN_CPC0_UCR);
1361 + u32 cpu, plb, opb, ebc, uart0, uart1;
1362 + u32 fwdva, fwdvb, fbdv, cbdv, opdv, epdv;
1363 + u32 pllmr0_ccdv, tb, m;
1365 + fwdva = 8 - ((pllmr1 & 0x00070000) >> 16);
1366 + fwdvb = 8 - ((pllmr1 & 0x00007000) >> 12);
1367 + fbdv = (pllmr1 & 0x00f00000) >> 20;
1371 + cbdv = ((pllmr0 & 0x00030000) >> 16) + 1; /* CPU:PLB */
1372 + epdv = ((pllmr0 & 0x00000300) >> 8) + 2; /* PLB:EBC */
1373 + opdv = ((pllmr0 & 0x00003000) >> 12) + 1; /* PLB:OPB */
1377 + pllmr0_ccdv = ((pllmr0 & 0x00300000) >> 20) + 1;
1378 + if (pllmr1 & 0x80000000)
1379 + cpu = sys_clk * m / (fwdva * pllmr0_ccdv);
1381 + cpu = sys_clk / pllmr0_ccdv;
1387 + uart0 = cpu / (cpc0_ucr & 0x0000007f);
1388 + uart1 = cpu / ((cpc0_ucr & 0x00007f00) >> 8);
1390 + dt_fixup_cpu_clocks(cpu, tb, 0);
1391 + dt_fixup_clock("/plb", plb);
1392 + dt_fixup_clock("/plb/opb", opb);
1393 + dt_fixup_clock("/plb/ebc", ebc);
1394 dt_fixup_clock("/plb/opb/serial@ef600300", uart0);
1395 - dt_fixup_clock("/plb/opb/serial@ef600400", uart0);
1396 - dt_fixup_clock("/plb/opb/serial@ef600500", uart0);
1397 - dt_fixup_clock("/plb/opb/serial@ef600600", uart0);
1398 + dt_fixup_clock("/plb/opb/serial@ef600400", uart1);
1400 --- a/arch/powerpc/boot/4xx.h
1401 +++ b/arch/powerpc/boot/4xx.h
1403 #ifndef _POWERPC_BOOT_4XX_H_
1404 #define _POWERPC_BOOT_4XX_H_
1406 -void ibm4xx_fixup_memsize(void);
1407 +void ibm4xx_sdram_fixup_memsize(void);
1408 +void ibm440spe_fixup_memsize(void);
1409 void ibm4xx_denali_fixup_memsize(void);
1410 void ibm44x_dbcr_reset(void);
1411 void ibm40x_dbcr_reset(void);
1412 void ibm4xx_quiesce_eth(u32 *emac0, u32 *emac1);
1413 void ibm4xx_fixup_ebc_ranges(const char *ebc);
1414 -void ibm440ep_fixup_clocks(unsigned int sysclk, unsigned int ser_clk);
1416 +void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk);
1417 +void ibm405ep_fixup_clocks(unsigned int sys_clk);
1418 +void ibm440gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk);
1419 +void ibm440ep_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk,
1420 + unsigned int tmr_clk);
1421 +void ibm440gx_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk,
1422 + unsigned int tmr_clk);
1423 +void ibm440spe_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk,
1424 + unsigned int tmr_clk);
1426 #endif /* _POWERPC_BOOT_4XX_H_ */
1427 --- a/arch/powerpc/boot/Makefile
1428 +++ b/arch/powerpc/boot/Makefile
1429 @@ -33,12 +33,15 @@ ifeq ($(call cc-option-yn, -fstack-prote
1430 BOOTCFLAGS += -fno-stack-protector
1433 -BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj)
1434 +BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) -I$(srctree)/$(src)/libfdt
1436 $(obj)/4xx.o: BOOTCFLAGS += -mcpu=440
1437 $(obj)/ebony.o: BOOTCFLAGS += -mcpu=440
1438 +$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=440
1439 +$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=440
1440 $(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405
1443 zlib := inffast.c inflate.c inftrees.c
1444 zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h
1445 zliblinuxheader := zlib.h zconf.h zutil.h
1446 @@ -46,17 +49,21 @@ zliblinuxheader := zlib.h zconf.h zutil.
1447 $(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \
1448 $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
1450 -src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
1451 +src-libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
1452 +src-wlib := string.S crt0.S stdio.c main.c \
1453 + $(addprefix libfdt/,$(src-libfdt)) libfdt-wrapper.c \
1454 ns16550.c serial.c simple_alloc.c div64.S util.S \
1455 gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
1456 4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
1457 cpm-serial.c stdlib.c mpc52xx-psc.c planetcore.c uartlite.c \
1458 fsl-soc.c mpc8xx.c pq2.c
1459 -src-plat := of.c cuboot-52xx.c cuboot-83xx.c cuboot-85xx.c holly.c \
1460 +src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c \
1461 cuboot-ebony.c treeboot-ebony.c prpmc2800.c \
1462 ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \
1463 cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c cuboot-bamboo.c \
1464 - fixed-head.S ep88xc.c cuboot-hpc2.c
1465 + fixed-head.S ep88xc.c cuboot-hpc2.c ep405.c cuboot-taishan.c \
1466 + cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \
1468 src-boot := $(src-wlib) $(src-plat) empty.c
1470 src-boot := $(addprefix $(obj)/, $(src-boot))
1471 @@ -101,24 +108,61 @@ quiet_cmd_bootar = BOOTAR $@
1472 cmd_bootar = $(CROSS32AR) -cr $@.$$$$ $(filter-out FORCE,$^); mv $@.$$$$ $@
1474 $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c FORCE
1475 + $(Q)mkdir -p $(dir $@)
1476 $(call if_changed_dep,bootcc)
1477 $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S FORCE
1478 + $(Q)mkdir -p $(dir $@)
1479 $(call if_changed_dep,bootas)
1481 $(obj)/wrapper.a: $(obj-wlib) FORCE
1482 $(call if_changed,bootar)
1484 -hostprogs-y := addnote addRamDisk hack-coff mktree
1485 +hostprogs-y := addnote addRamDisk hack-coff mktree dtc
1487 targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a)
1488 extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
1489 $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds
1491 wrapper :=$(srctree)/$(src)/wrapper
1492 -wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) \
1493 +wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree dtc) \
1497 +# Bits for building dtc
1498 +# DTC_GENPARSER := 1 # Uncomment to rebuild flex/bison output
1500 +dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o srcpos.o checks.o
1501 +dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o
1502 +dtc-objs := $(addprefix dtc-src/, $(dtc-objs))
1504 +# prerequisites on generated files needs to be explicit
1505 +$(obj)/dtc-src/dtc-parser.tab.o: $(obj)/dtc-src/dtc-parser.tab.c $(obj)/dtc-src/dtc-parser.tab.h
1506 +$(obj)/dtc-src/dtc-lexer.lex.o: $(obj)/dtc-src/dtc-lexer.lex.c $(obj)/dtc-src/dtc-parser.tab.h
1508 +HOSTCFLAGS += -I$(src)/dtc-src/ -I$(src)/libfdt/
1510 +targets += dtc-src/dtc-parser.tab.c
1511 +targets += dtc-src/dtc-lexer.lex.c
1513 +ifdef DTC_GENPARSER
1517 +quiet_cmd_bison = BISON $@
1518 + cmd_bison = $(BISON) -o$@ -d $<; cp $@ $@_shipped
1519 +quiet_cmd_flex = FLEX $@
1520 + cmd_flex = $(FLEX) -o$@ $<; cp $@ $@_shipped
1522 +$(obj)/dtc-src/dtc-parser.tab.c: $(src)/dtc-src/dtc-parser.y FORCE
1523 + $(call if_changed,bison)
1525 +$(obj)/dtc-src/dtc-parser.tab.h: $(obj)/dtc-src/dtc-parser.tab.c
1527 +$(obj)/dtc-src/dtc-lexer.lex.c: $(src)/dtc-src/dtc-lexer.l FORCE
1528 + $(call if_changed,flex)
1532 # Bits for building various flavours of zImage
1534 ifneq ($(CROSS32_COMPILE),)
1535 @@ -150,15 +194,26 @@ image-$(CONFIG_DEFAULT_UIMAGE) += uImag
1536 ifneq ($(CONFIG_DEVICE_TREE),"")
1537 image-$(CONFIG_PPC_8xx) += cuImage.8xx
1538 image-$(CONFIG_PPC_EP88XC) += zImage.ep88xc
1539 +image-$(CONFIG_EP405) += zImage.ep405
1540 image-$(CONFIG_8260) += cuImage.pq2
1541 +image-$(CONFIG_EP8248E) += zImage.ep8248e
1542 image-$(CONFIG_PPC_MPC52xx) += cuImage.52xx
1543 +image-$(CONFIG_STORCENTER) += cuImage.824x
1544 image-$(CONFIG_PPC_83xx) += cuImage.83xx
1545 image-$(CONFIG_PPC_85xx) += cuImage.85xx
1546 image-$(CONFIG_MPC7448HPC2) += cuImage.hpc2
1547 image-$(CONFIG_EBONY) += treeImage.ebony cuImage.ebony
1548 image-$(CONFIG_BAMBOO) += treeImage.bamboo cuImage.bamboo
1549 image-$(CONFIG_SEQUOIA) += cuImage.sequoia
1550 +image-$(CONFIG_RAINIER) += cuImage.rainier
1551 image-$(CONFIG_WALNUT) += treeImage.walnut
1552 +image-$(CONFIG_TAISHAN) += cuImage.taishan
1553 +image-$(CONFIG_KATMAI) += cuImage.katmai
1554 +image-$(CONFIG_WARP) += cuImage.warp
1557 +ifneq ($(CONFIG_REDBOOT),"")
1558 +image-$(CONFIG_PPC_8xx) += zImage.redboot-8xx
1561 # For 32-bit powermacs, build the COFF and miboot images
1562 @@ -243,3 +298,51 @@ clean-kernel := vmlinux.strip vmlinux.bi
1563 clean-kernel += $(addsuffix .gz,$(clean-kernel))
1564 # If not absolute clean-files are relative to $(obj).
1565 clean-files += $(addprefix $(objtree)/, $(clean-kernel))
1567 +WRAPPER_OBJDIR := /usr/lib/kernel-wrapper
1568 +WRAPPER_DTSDIR := /usr/lib/kernel-wrapper/dts
1569 +WRAPPER_BINDIR := /usr/sbin
1572 +extra-installed := $(patsubst $(obj)/%, $(DESTDIR)$(WRAPPER_OBJDIR)/%, $(extra-y))
1573 +hostprogs-installed := $(patsubst %, $(DESTDIR)$(WRAPPER_BINDIR)/%, $(hostprogs-y))
1574 +wrapper-installed := $(DESTDIR)$(WRAPPER_BINDIR)/wrapper
1575 +dts-installed := $(patsubst $(obj)/dts/%, $(DESTDIR)$(WRAPPER_DTSDIR)/%, $(wildcard $(obj)/dts/*.dts))
1577 +all-installed := $(extra-installed) $(hostprogs-installed) $(wrapper-installed) $(dts-installed)
1579 +quiet_cmd_mkdir = MKDIR $(patsubst $(INSTALL_HDR_PATH)/%,%,$@)
1580 + cmd_mkdir = mkdir -p $@
1582 +quiet_cmd_install = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_OBJDIR)/%,%,$@)
1583 + cmd_install = $(INSTALL) -m0644 $(patsubst $(DESTDIR)$(WRAPPER_OBJDIR)/%,$(obj)/%,$@) $@
1585 +quiet_cmd_install_dts = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_DTSDIR)/%,dts/%,$@)
1586 + cmd_install_dts = $(INSTALL) -m0644 $(patsubst $(DESTDIR)$(WRAPPER_DTSDIR)/%,$(srctree)/$(obj)/dts/%,$@) $@
1588 +quiet_cmd_install_exe = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,%,$@)
1589 + cmd_install_exe = $(INSTALL) -m0755 $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,$(obj)/%,$@) $@
1591 +quiet_cmd_install_wrapper = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,%,$@)
1592 + cmd_install_wrapper = $(INSTALL) -m0755 $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,$(srctree)/$(obj)/%,$@) $@ ;\
1593 + sed -i $@ -e 's%^object=.*%object=$(WRAPPER_OBJDIR)%' \
1594 + -e 's%^objbin=.*%objbin=$(WRAPPER_BINDIR)%' \
1597 +$(DESTDIR)$(WRAPPER_OBJDIR) $(DESTDIR)$(WRAPPER_DTSDIR) $(DESTDIR)$(WRAPPER_BINDIR):
1600 +$(extra-installed) : $(DESTDIR)$(WRAPPER_OBJDIR)/% : $(obj)/% | $(DESTDIR)$(WRAPPER_OBJDIR)
1601 + $(call cmd,install)
1603 +$(hostprogs-installed) : $(DESTDIR)$(WRAPPER_BINDIR)/% : $(obj)/% | $(DESTDIR)$(WRAPPER_BINDIR)
1604 + $(call cmd,install_exe)
1606 +$(dts-installed) : $(DESTDIR)$(WRAPPER_DTSDIR)/% : $(srctree)/$(obj)/dts/% | $(DESTDIR)$(WRAPPER_DTSDIR)
1607 + $(call cmd,install_dts)
1609 +$(wrapper-installed): $(DESTDIR)$(WRAPPER_BINDIR) $(srctree)/$(obj)/wrapper | $(DESTDIR)$(WRAPPER_BINDIR)
1610 + $(call cmd,install_wrapper)
1612 +$(obj)/bootwrapper_install: $(all-installed)
1614 --- a/arch/powerpc/boot/bamboo.c
1615 +++ b/arch/powerpc/boot/bamboo.c
1616 @@ -30,8 +30,8 @@ static void bamboo_fixups(void)
1618 unsigned long sysclk = 33333333;
1620 - ibm440ep_fixup_clocks(sysclk, 11059200);
1621 - ibm4xx_fixup_memsize();
1622 + ibm440ep_fixup_clocks(sysclk, 11059200, 25000000);
1623 + ibm4xx_sdram_fixup_memsize();
1624 ibm4xx_quiesce_eth((u32 *)0xef600e00, (u32 *)0xef600f00);
1625 dt_fixup_mac_addresses(bamboo_mac0, bamboo_mac1);
1627 @@ -42,6 +42,6 @@ void bamboo_init(void *mac0, void *mac1)
1628 platform_ops.exit = ibm44x_dbcr_reset;
1631 - ft_init(_dtb_start, 0, 32);
1632 + fdt_init(_dtb_start);
1633 serial_console_init();
1635 --- a/arch/powerpc/boot/cuboot-52xx.c
1636 +++ b/arch/powerpc/boot/cuboot-52xx.c
1637 @@ -53,7 +53,7 @@ void platform_init(unsigned long r3, uns
1638 unsigned long r6, unsigned long r7)
1641 - ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
1642 + fdt_init(_dtb_start);
1643 serial_console_init();
1644 platform_ops.fixups = platform_fixups;
1647 +++ b/arch/powerpc/boot/cuboot-824x.c
1650 + * Old U-boot compatibility for 824x
1652 + * Copyright (c) 2007 Freescale Semiconductor, Inc.
1654 + * This program is free software; you can redistribute it and/or modify it
1655 + * under the terms of the GNU General Public License version 2 as published
1656 + * by the Free Software Foundation.
1661 +#include "cuboot.h"
1663 +#define TARGET_824x
1664 +#include "ppcboot.h"
1669 +static void platform_fixups(void)
1673 + dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
1674 + dt_fixup_mac_addresses(bd.bi_enetaddr);
1675 + dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 4, bd.bi_busfreq);
1677 + soc = find_node_by_devtype(NULL, "soc");
1679 + void *serial = NULL;
1681 + setprop(soc, "bus-frequency", &bd.bi_busfreq,
1682 + sizeof(bd.bi_busfreq));
1684 + while ((serial = find_node_by_devtype(serial, "serial"))) {
1685 + if (get_parent(serial) != soc)
1688 + setprop(serial, "clock-frequency", &bd.bi_busfreq,
1689 + sizeof(bd.bi_busfreq));
1694 +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
1695 + unsigned long r6, unsigned long r7)
1698 + fdt_init(_dtb_start);
1699 + serial_console_init();
1700 + platform_ops.fixups = platform_fixups;
1702 --- a/arch/powerpc/boot/cuboot-83xx.c
1703 +++ b/arch/powerpc/boot/cuboot-83xx.c
1704 @@ -24,7 +24,8 @@ static void platform_fixups(void)
1707 dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
1708 - dt_fixup_mac_addresses(bd.bi_enetaddr, bd.bi_enet1addr);
1709 + dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
1710 + dt_fixup_mac_address_by_alias("ethernet1", bd.bi_enet1addr);
1711 dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 4, bd.bi_busfreq);
1713 /* Unfortunately, the specific model number is encoded in the
1714 @@ -52,7 +53,7 @@ void platform_init(unsigned long r3, uns
1715 unsigned long r6, unsigned long r7)
1718 - ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
1719 + fdt_init(_dtb_start);
1720 serial_console_init();
1721 platform_ops.fixups = platform_fixups;
1723 --- a/arch/powerpc/boot/cuboot-85xx.c
1724 +++ b/arch/powerpc/boot/cuboot-85xx.c
1725 @@ -24,8 +24,9 @@ static void platform_fixups(void)
1728 dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
1729 - dt_fixup_mac_addresses(bd.bi_enetaddr, bd.bi_enet1addr,
1731 + dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
1732 + dt_fixup_mac_address_by_alias("ethernet1", bd.bi_enet1addr);
1733 + dt_fixup_mac_address_by_alias("ethernet2", bd.bi_enet2addr);
1734 dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 8, bd.bi_busfreq);
1736 /* Unfortunately, the specific model number is encoded in the
1737 @@ -53,7 +54,7 @@ void platform_init(unsigned long r3, uns
1738 unsigned long r6, unsigned long r7)
1741 - ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
1742 + fdt_init(_dtb_start);
1743 serial_console_init();
1744 platform_ops.fixups = platform_fixups;
1746 --- a/arch/powerpc/boot/cuboot-8xx.c
1747 +++ b/arch/powerpc/boot/cuboot-8xx.c
1748 @@ -41,7 +41,7 @@ void platform_init(unsigned long r3, uns
1749 unsigned long r6, unsigned long r7)
1752 - ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
1753 + fdt_init(_dtb_start);
1754 serial_console_init();
1755 platform_ops.fixups = platform_fixups;
1757 --- a/arch/powerpc/boot/cuboot-hpc2.c
1758 +++ b/arch/powerpc/boot/cuboot-hpc2.c
1759 @@ -42,7 +42,7 @@ void platform_init(unsigned long r3, uns
1760 unsigned long r6, unsigned long r7)
1763 - ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
1764 + fdt_init(_dtb_start);
1765 serial_console_init();
1766 platform_ops.fixups = platform_fixups;
1769 +++ b/arch/powerpc/boot/cuboot-katmai.c
1772 + * Old U-boot compatibility for Katmai
1774 + * Author: Hugh Blemings <hugh@au.ibm.com>
1776 + * Copyright 2007 Hugh Blemings, IBM Corporation.
1777 + * Based on cuboot-ebony.c which is:
1778 + * Copyright 2007 David Gibson, IBM Corporation.
1779 + * Based on cuboot-83xx.c, which is:
1780 + * Copyright (c) 2007 Freescale Semiconductor, Inc.
1782 + * This program is free software; you can redistribute it and/or modify it
1783 + * under the terms of the GNU General Public License version 2 as published
1784 + * by the Free Software Foundation.
1793 +#include "cuboot.h"
1796 +#include "ppcboot.h"
1802 +static void katmai_fixups(void)
1804 + unsigned long sysclk = 33333000;
1806 + /* 440SP Clock logic is all but identical to 440GX
1807 + * so we just use that code for now at least
1809 + ibm440spe_fixup_clocks(sysclk, 6 * 1843200, 0);
1811 + ibm440spe_fixup_memsize();
1813 + dt_fixup_mac_address(0, bd.bi_enetaddr);
1815 + ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
1818 +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
1819 + unsigned long r6, unsigned long r7)
1823 + platform_ops.fixups = katmai_fixups;
1824 + fdt_init(_dtb_start);
1825 + serial_console_init();
1827 --- a/arch/powerpc/boot/cuboot-pq2.c
1828 +++ b/arch/powerpc/boot/cuboot-pq2.c
1829 @@ -255,7 +255,7 @@ void platform_init(unsigned long r3, uns
1830 unsigned long r6, unsigned long r7)
1833 - ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
1834 + fdt_init(_dtb_start);
1835 serial_console_init();
1836 platform_ops.fixups = pq2_platform_fixups;
1839 +++ b/arch/powerpc/boot/cuboot-rainier.c
1842 + * Old U-boot compatibility for Rainier
1844 + * Valentine Barshak <vbarshak@ru.mvista.com>
1845 + * Copyright 2007 MontaVista Software, Inc
1847 + * Based on Ebony code by David Gibson <david@gibson.dropbear.id.au>
1848 + * Copyright IBM Corporation, 2007
1850 + * Based on Bamboo code by Josh Boyer <jwboyer@linux.vnet.ibm.com>
1851 + * Copyright IBM Corporation, 2007
1853 + * This program is free software; you can redistribute it and/or
1854 + * modify it under the terms of the GNU General Public License
1855 + * as published by the Free Software Foundation; version 2 of the License
1858 +#include <stdarg.h>
1859 +#include <stddef.h>
1862 +#include "string.h"
1869 +#include "cuboot.h"
1873 +#include "ppcboot.h"
1878 +static void rainier_fixups(void)
1880 + unsigned long sysclk = 33333333;
1882 + ibm440ep_fixup_clocks(sysclk, 11059200, 50000000);
1883 + ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
1884 + ibm4xx_denali_fixup_memsize();
1885 + dt_fixup_mac_addresses(&bd.bi_enetaddr, &bd.bi_enet1addr);
1888 +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
1889 + unsigned long r6, unsigned long r7)
1892 + platform_ops.fixups = rainier_fixups;
1893 + platform_ops.exit = ibm44x_dbcr_reset;
1894 + fdt_init(_dtb_start);
1895 + serial_console_init();
1897 --- a/arch/powerpc/boot/cuboot-sequoia.c
1898 +++ b/arch/powerpc/boot/cuboot-sequoia.c
1899 @@ -39,7 +39,7 @@ static void sequoia_fixups(void)
1901 unsigned long sysclk = 33333333;
1903 - ibm440ep_fixup_clocks(sysclk, 11059200);
1904 + ibm440ep_fixup_clocks(sysclk, 11059200, 50000000);
1905 ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
1906 ibm4xx_denali_fixup_memsize();
1907 dt_fixup_mac_addresses(&bd.bi_enetaddr, &bd.bi_enet1addr);
1908 @@ -51,6 +51,6 @@ void platform_init(unsigned long r3, uns
1910 platform_ops.fixups = sequoia_fixups;
1911 platform_ops.exit = ibm44x_dbcr_reset;
1912 - ft_init(_dtb_start, 0, 32);
1913 + fdt_init(_dtb_start);
1914 serial_console_init();
1917 +++ b/arch/powerpc/boot/cuboot-taishan.c
1920 + * Old U-boot compatibility for Taishan
1922 + * Author: Hugh Blemings <hugh@au.ibm.com>
1924 + * Copyright 2007 Hugh Blemings, IBM Corporation.
1925 + * Based on cuboot-ebony.c which is:
1926 + * Copyright 2007 David Gibson, IBM Corporation.
1927 + * Based on cuboot-83xx.c, which is:
1928 + * Copyright (c) 2007 Freescale Semiconductor, Inc.
1930 + * This program is free software; you can redistribute it and/or modify it
1931 + * under the terms of the GNU General Public License version 2 as published
1932 + * by the Free Software Foundation.
1937 +#include "cuboot.h"
1943 +#include "ppcboot.h"
1949 +static void taishan_fixups(void)
1951 + /* FIXME: sysclk should be derived by reading the FPGA
1953 + unsigned long sysclk = 33000000;
1955 + ibm440gx_fixup_clocks(sysclk, 6 * 1843200, 25000000);
1957 + ibm4xx_sdram_fixup_memsize();
1959 + dt_fixup_mac_addresses(bd.bi_enetaddr, bd.bi_enet1addr);
1961 + ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
1964 +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
1965 + unsigned long r6, unsigned long r7)
1969 + platform_ops.fixups = taishan_fixups;
1970 + fdt_init(_dtb_start);
1971 + serial_console_init();
1974 +++ b/arch/powerpc/boot/cuboot-warp.c
1977 + * Copyright (c) 2008 PIKA Technologies
1978 + * Sean MacLennan <smaclennan@pikatech.com>
1980 + * This program is free software; you can redistribute it and/or modify it
1981 + * under the terms of the GNU General Public License version 2 as published
1982 + * by the Free Software Foundation.
1987 +#include "cuboot.h"
1990 +#include "ppcboot.h"
1994 +static void warp_fixups(void)
1996 + unsigned long sysclk = 66000000;
1998 + ibm440ep_fixup_clocks(sysclk, 11059200, 50000000);
1999 + ibm4xx_sdram_fixup_memsize();
2000 + ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
2001 + dt_fixup_mac_addresses(&bd.bi_enetaddr);
2005 +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
2006 + unsigned long r6, unsigned long r7)
2010 + platform_ops.fixups = warp_fixups;
2011 + platform_ops.exit = ibm44x_dbcr_reset;
2012 + fdt_init(_dtb_start);
2013 + serial_console_init();
2015 --- a/arch/powerpc/boot/dcr.h
2016 +++ b/arch/powerpc/boot/dcr.h
2018 #define DCRN_SDRAM0_CFGADDR 0x010
2019 #define DCRN_SDRAM0_CFGDATA 0x011
2021 +#define SDRAM0_READ(offset) ({\
2022 + mtdcr(DCRN_SDRAM0_CFGADDR, offset); \
2023 + mfdcr(DCRN_SDRAM0_CFGDATA); })
2024 +#define SDRAM0_WRITE(offset, data) ({\
2025 + mtdcr(DCRN_SDRAM0_CFGADDR, offset); \
2026 + mtdcr(DCRN_SDRAM0_CFGDATA, data); })
2028 #define SDRAM0_B0CR 0x40
2029 #define SDRAM0_B1CR 0x44
2030 #define SDRAM0_B2CR 0x48
2031 #define SDRAM0_B3CR 0x4c
2033 -static const unsigned long sdram_bxcr[] = { SDRAM0_B0CR, SDRAM0_B1CR, SDRAM0_B2CR, SDRAM0_B3CR };
2034 +static const unsigned long sdram_bxcr[] = { SDRAM0_B0CR, SDRAM0_B1CR,
2035 + SDRAM0_B2CR, SDRAM0_B3CR };
2037 #define SDRAM_CONFIG_BANK_ENABLE 0x00000001
2038 #define SDRAM_CONFIG_SIZE_MASK 0x000e0000
2039 @@ -138,5 +146,54 @@ static const unsigned long sdram_bxcr[]
2040 #define DCRN_CPC0_PLLMR 0xb0
2041 #define DCRN_405_CPC0_CR0 0xb1
2042 #define DCRN_405_CPC0_CR1 0xb2
2043 +#define DCRN_405_CPC0_PSR 0xb4
2045 +/* 405EP Clocking/Power Management/Chip Control regs */
2046 +#define DCRN_CPC0_PLLMR0 0xf0
2047 +#define DCRN_CPC0_PLLMR1 0xf4
2048 +#define DCRN_CPC0_UCR 0xf5
2050 +/* 440GX Clock control etc */
2053 +#define DCRN_CPR0_CLKUPD 0x020
2054 +#define DCRN_CPR0_PLLC 0x040
2055 +#define DCRN_CPR0_PLLD 0x060
2056 +#define DCRN_CPR0_PRIMAD 0x080
2057 +#define DCRN_CPR0_PRIMBD 0x0a0
2058 +#define DCRN_CPR0_OPBD 0x0c0
2059 +#define DCRN_CPR0_PERD 0x0e0
2060 +#define DCRN_CPR0_MALD 0x100
2062 +#define DCRN_SDR0_CONFIG_ADDR 0xe
2063 +#define DCRN_SDR0_CONFIG_DATA 0xf
2065 +/* SDR read/write helper macros */
2066 +#define SDR0_READ(offset) ({\
2067 + mtdcr(DCRN_SDR0_CONFIG_ADDR, offset); \
2068 + mfdcr(DCRN_SDR0_CONFIG_DATA); })
2069 +#define SDR0_WRITE(offset, data) ({\
2070 + mtdcr(DCRN_SDR0_CONFIG_ADDR, offset); \
2071 + mtdcr(DCRN_SDR0_CONFIG_DATA, data); })
2073 +#define DCRN_SDR0_UART0 0x0120
2074 +#define DCRN_SDR0_UART1 0x0121
2075 +#define DCRN_SDR0_UART2 0x0122
2076 +#define DCRN_SDR0_UART3 0x0123
2079 +/* CPRs read/write helper macros - based off include/asm-ppc/ibm44x.h */
2081 +#define DCRN_CPR0_CFGADDR 0xc
2082 +#define DCRN_CPR0_CFGDATA 0xd
2084 +#define CPR0_READ(offset) ({\
2085 + mtdcr(DCRN_CPR0_CFGADDR, offset); \
2086 + mfdcr(DCRN_CPR0_CFGDATA); })
2087 +#define CPR0_WRITE(offset, data) ({\
2088 + mtdcr(DCRN_CPR0_CFGADDR, offset); \
2089 + mtdcr(DCRN_CPR0_CFGDATA, data); })
2093 #endif /* _PPC_BOOT_DCR_H_ */
2094 --- a/arch/powerpc/boot/devtree.c
2095 +++ b/arch/powerpc/boot/devtree.c
2096 @@ -88,6 +88,20 @@ void dt_fixup_clock(const char *path, u3
2100 +void dt_fixup_mac_address_by_alias(const char *alias, const u8 *addr)
2102 + void *devp = find_node_by_alias(alias);
2105 + printf("%s: local-mac-address <-"
2106 + " %02x:%02x:%02x:%02x:%02x:%02x\n\r", alias,
2107 + addr[0], addr[1], addr[2],
2108 + addr[3], addr[4], addr[5]);
2110 + setprop(devp, "local-mac-address", addr, 6);
2114 void dt_fixup_mac_address(u32 index, const u8 *addr)
2116 void *devp = find_node_by_prop_value(NULL, "linux,network-index",
2118 +++ b/arch/powerpc/boot/dtc-src/Makefile.dtc
2122 +# This is not a complete Makefile of itself. Instead, it is designed to
2123 +# be easily embeddable into other systems of Makefiles.
2125 +DTC_SRCS = dtc.c flattree.c fstree.c data.c livetree.c treesource.c srcpos.c \
2127 +DTC_EXTRA = dtc.h srcpos.h
2128 +DTC_LEXFILES = dtc-lexer.l
2129 +DTC_BISONFILES = dtc-parser.y
2131 +DTC_LEX_SRCS = $(DTC_LEXFILES:%.l=%.lex.c)
2132 +DTC_BISON_SRCS = $(DTC_BISONFILES:%.y=%.tab.c)
2133 +DTC_BISON_INCLUDES = $(DTC_BISONFILES:%.y=%.tab.h)
2135 +DTC_GEN_SRCS = $(DTC_LEX_SRCS) $(DTC_BISON_SRCS)
2136 +DTC_GEN_ALL = $(DTC_GEN_SRCS) $(DTC_BISON_INCLUDES)
2137 +DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o)
2139 +DTC_CLEANFILES = $(DTC_GEN_ALL)
2141 +# We assume the containing Makefile system can do auto-dependencies for most
2142 +# things, but we supply the dependencies on generated header files explicitly
2144 +$(addprefix $(DTC_objdir)/,$(DTC_GEN_SRCS:%.c=%.o)): $(addprefix $(DTC_objdir)/,$(DTC_BISON_INCLUDES))
2146 +++ b/arch/powerpc/boot/dtc-src/checks.c
2149 + * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2007.
2152 + * This program is free software; you can redistribute it and/or
2153 + * modify it under the terms of the GNU General Public License as
2154 + * published by the Free Software Foundation; either version 2 of the
2155 + * License, or (at your option) any later version.
2157 + * This program is distributed in the hope that it will be useful,
2158 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2159 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2160 + * General Public License for more details.
2162 + * You should have received a copy of the GNU General Public License
2163 + * along with this program; if not, write to the Free Software
2164 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
2170 +#ifdef TRACE_CHECKS
2171 +#define TRACE(c, ...) \
2173 + fprintf(stderr, "=== %s: ", (c)->name); \
2174 + fprintf(stderr, __VA_ARGS__); \
2175 + fprintf(stderr, "\n"); \
2178 +#define TRACE(c, fmt, ...) do { } while (0)
2196 +typedef void (*tree_check_fn)(struct check *c, struct node *dt);
2197 +typedef void (*node_check_fn)(struct check *c, struct node *dt, struct node *node);
2198 +typedef void (*prop_check_fn)(struct check *c, struct node *dt,
2199 + struct node *node, struct property *prop);
2203 + tree_check_fn tree_fn;
2204 + node_check_fn node_fn;
2205 + prop_check_fn prop_fn;
2207 + enum checklevel level;
2208 + enum checkstatus status;
2211 + struct check **prereq;
2214 +#define CHECK(nm, tfn, nfn, pfn, d, lvl, ...) \
2215 + static struct check *nm##_prereqs[] = { __VA_ARGS__ }; \
2216 + static struct check nm = { \
2218 + .tree_fn = (tfn), \
2219 + .node_fn = (nfn), \
2220 + .prop_fn = (pfn), \
2223 + .status = UNCHECKED, \
2224 + .num_prereqs = ARRAY_SIZE(nm##_prereqs), \
2225 + .prereq = nm##_prereqs, \
2228 +#define TREE_CHECK(nm, d, lvl, ...) \
2229 + CHECK(nm, check_##nm, NULL, NULL, d, lvl, __VA_ARGS__)
2230 +#define NODE_CHECK(nm, d, lvl, ...) \
2231 + CHECK(nm, NULL, check_##nm, NULL, d, lvl, __VA_ARGS__)
2232 +#define PROP_CHECK(nm, d, lvl, ...) \
2233 + CHECK(nm, NULL, NULL, check_##nm, d, lvl, __VA_ARGS__)
2234 +#define BATCH_CHECK(nm, lvl, ...) \
2235 + CHECK(nm, NULL, NULL, NULL, NULL, lvl, __VA_ARGS__)
2238 +static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
2240 +static inline void check_msg(struct check *c, const char *fmt, ...)
2243 + va_start(ap, fmt);
2245 + if ((c->level < WARN) || (c->level <= quiet))
2246 + return; /* Suppress message */
2248 + fprintf(stderr, "%s (%s): ",
2249 + (c->level == ERROR) ? "ERROR" : "Warning", c->name);
2250 + vfprintf(stderr, fmt, ap);
2251 + fprintf(stderr, "\n");
2254 +#define FAIL(c, ...) \
2256 + TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \
2257 + (c)->status = FAILED; \
2258 + check_msg((c), __VA_ARGS__); \
2261 +static void check_nodes_props(struct check *c, struct node *dt, struct node *node)
2263 + struct node *child;
2264 + struct property *prop;
2266 + TRACE(c, "%s", node->fullpath);
2268 + c->node_fn(c, dt, node);
2271 + for_each_property(node, prop) {
2272 + TRACE(c, "%s\t'%s'", node->fullpath, prop->name);
2273 + c->prop_fn(c, dt, node, prop);
2276 + for_each_child(node, child)
2277 + check_nodes_props(c, dt, child);
2280 +static int run_check(struct check *c, struct node *dt)
2285 + assert(!c->inprogress);
2287 + if (c->status != UNCHECKED)
2290 + c->inprogress = 1;
2292 + for (i = 0; i < c->num_prereqs; i++) {
2293 + struct check *prq = c->prereq[i];
2294 + error |= run_check(prq, dt);
2295 + if (prq->status != PASSED) {
2296 + c->status = PREREQ;
2297 + check_msg(c, "Failed prerequisite '%s'",
2298 + c->prereq[i]->name);
2302 + if (c->status != UNCHECKED)
2305 + if (c->node_fn || c->prop_fn)
2306 + check_nodes_props(c, dt, dt);
2309 + c->tree_fn(c, dt);
2310 + if (c->status == UNCHECKED)
2311 + c->status = PASSED;
2313 + TRACE(c, "\tCompleted, status %d", c->status);
2316 + c->inprogress = 0;
2317 + if ((c->status != PASSED) && (c->level == ERROR))
2323 + * Utility check functions
2326 +static void check_is_string(struct check *c, struct node *root,
2327 + struct node *node)
2329 + struct property *prop;
2330 + char *propname = c->data;
2332 + prop = get_property(node, propname);
2334 + return; /* Not present, assumed ok */
2336 + if (!data_is_one_string(prop->val))
2337 + FAIL(c, "\"%s\" property in %s is not a string",
2338 + propname, node->fullpath);
2340 +#define CHECK_IS_STRING(nm, propname, lvl) \
2341 + CHECK(nm, NULL, check_is_string, NULL, (propname), (lvl))
2343 +static void check_is_cell(struct check *c, struct node *root,
2344 + struct node *node)
2346 + struct property *prop;
2347 + char *propname = c->data;
2349 + prop = get_property(node, propname);
2351 + return; /* Not present, assumed ok */
2353 + if (prop->val.len != sizeof(cell_t))
2354 + FAIL(c, "\"%s\" property in %s is not a single cell",
2355 + propname, node->fullpath);
2357 +#define CHECK_IS_CELL(nm, propname, lvl) \
2358 + CHECK(nm, NULL, check_is_cell, NULL, (propname), (lvl))
2361 + * Structural check functions
2364 +static void check_duplicate_node_names(struct check *c, struct node *dt,
2365 + struct node *node)
2367 + struct node *child, *child2;
2369 + for_each_child(node, child)
2370 + for (child2 = child->next_sibling;
2372 + child2 = child2->next_sibling)
2373 + if (streq(child->name, child2->name))
2374 + FAIL(c, "Duplicate node name %s",
2377 +NODE_CHECK(duplicate_node_names, NULL, ERROR);
2379 +static void check_duplicate_property_names(struct check *c, struct node *dt,
2380 + struct node *node)
2382 + struct property *prop, *prop2;
2384 + for_each_property(node, prop)
2385 + for (prop2 = prop->next; prop2; prop2 = prop2->next)
2386 + if (streq(prop->name, prop2->name))
2387 + FAIL(c, "Duplicate property name %s in %s",
2388 + prop->name, node->fullpath);
2390 +NODE_CHECK(duplicate_property_names, NULL, ERROR);
2392 +static void check_explicit_phandles(struct check *c, struct node *root,
2393 + struct node *node)
2395 + struct property *prop;
2396 + struct node *other;
2399 + prop = get_property(node, "linux,phandle");
2401 + return; /* No phandle, that's fine */
2403 + if (prop->val.len != sizeof(cell_t)) {
2404 + FAIL(c, "%s has bad length (%d) linux,phandle property",
2405 + node->fullpath, prop->val.len);
2409 + phandle = propval_cell(prop);
2410 + if ((phandle == 0) || (phandle == -1)) {
2411 + FAIL(c, "%s has invalid linux,phandle value 0x%x",
2412 + node->fullpath, phandle);
2416 + other = get_node_by_phandle(root, phandle);
2418 + FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)",
2419 + node->fullpath, phandle, other->fullpath);
2423 + node->phandle = phandle;
2425 +NODE_CHECK(explicit_phandles, NULL, ERROR);
2427 +static void check_name_properties(struct check *c, struct node *root,
2428 + struct node *node)
2430 + struct property *prop;
2432 + prop = get_property(node, "name");
2434 + return; /* No name property, that's fine */
2436 + if ((prop->val.len != node->basenamelen+1)
2437 + || (memcmp(prop->val.val, node->name, node->basenamelen) != 0))
2438 + FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead"
2439 + " of base node name)", node->fullpath, prop->val.val);
2441 +CHECK_IS_STRING(name_is_string, "name", ERROR);
2442 +NODE_CHECK(name_properties, NULL, ERROR, &name_is_string);
2445 + * Reference fixup functions
2448 +static void fixup_phandle_references(struct check *c, struct node *dt,
2449 + struct node *node, struct property *prop)
2451 + struct marker *m = prop->val.markers;
2452 + struct node *refnode;
2455 + for_each_marker_of_type(m, REF_PHANDLE) {
2456 + assert(m->offset + sizeof(cell_t) <= prop->val.len);
2458 + refnode = get_node_by_ref(dt, m->ref);
2460 + FAIL(c, "Reference to non-existent node or label \"%s\"\n",
2465 + phandle = get_node_phandle(dt, refnode);
2466 + *((cell_t *)(prop->val.val + m->offset)) = cpu_to_be32(phandle);
2469 +CHECK(phandle_references, NULL, NULL, fixup_phandle_references, NULL, ERROR,
2470 + &duplicate_node_names, &explicit_phandles);
2472 +static void fixup_path_references(struct check *c, struct node *dt,
2473 + struct node *node, struct property *prop)
2475 + struct marker *m = prop->val.markers;
2476 + struct node *refnode;
2479 + for_each_marker_of_type(m, REF_PATH) {
2480 + assert(m->offset <= prop->val.len);
2482 + refnode = get_node_by_ref(dt, m->ref);
2484 + FAIL(c, "Reference to non-existent node or label \"%s\"\n",
2489 + path = refnode->fullpath;
2490 + prop->val = data_insert_at_marker(prop->val, m, path,
2491 + strlen(path) + 1);
2494 +CHECK(path_references, NULL, NULL, fixup_path_references, NULL, ERROR,
2495 + &duplicate_node_names);
2500 +CHECK_IS_CELL(address_cells_is_cell, "#address-cells", WARN);
2501 +CHECK_IS_CELL(size_cells_is_cell, "#size-cells", WARN);
2502 +CHECK_IS_CELL(interrupt_cells_is_cell, "#interrupt-cells", WARN);
2504 +CHECK_IS_STRING(device_type_is_string, "device_type", WARN);
2505 +CHECK_IS_STRING(model_is_string, "model", WARN);
2506 +CHECK_IS_STRING(status_is_string, "status", WARN);
2508 +static void fixup_addr_size_cells(struct check *c, struct node *dt,
2509 + struct node *node)
2511 + struct property *prop;
2513 + node->addr_cells = -1;
2514 + node->size_cells = -1;
2516 + prop = get_property(node, "#address-cells");
2518 + node->addr_cells = propval_cell(prop);
2520 + prop = get_property(node, "#size-cells");
2522 + node->size_cells = propval_cell(prop);
2524 +CHECK(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL, WARN,
2525 + &address_cells_is_cell, &size_cells_is_cell);
2527 +#define node_addr_cells(n) \
2528 + (((n)->addr_cells == -1) ? 2 : (n)->addr_cells)
2529 +#define node_size_cells(n) \
2530 + (((n)->size_cells == -1) ? 1 : (n)->size_cells)
2532 +static void check_reg_format(struct check *c, struct node *dt,
2533 + struct node *node)
2535 + struct property *prop;
2536 + int addr_cells, size_cells, entrylen;
2538 + prop = get_property(node, "reg");
2540 + return; /* No "reg", that's fine */
2542 + if (!node->parent) {
2543 + FAIL(c, "Root node has a \"reg\" property");
2547 + if (prop->val.len == 0)
2548 + FAIL(c, "\"reg\" property in %s is empty", node->fullpath);
2550 + addr_cells = node_addr_cells(node->parent);
2551 + size_cells = node_size_cells(node->parent);
2552 + entrylen = (addr_cells + size_cells) * sizeof(cell_t);
2554 + if ((prop->val.len % entrylen) != 0)
2555 + FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) "
2556 + "(#address-cells == %d, #size-cells == %d)",
2557 + node->fullpath, prop->val.len, addr_cells, size_cells);
2559 +NODE_CHECK(reg_format, NULL, WARN, &addr_size_cells);
2561 +static void check_ranges_format(struct check *c, struct node *dt,
2562 + struct node *node)
2564 + struct property *prop;
2565 + int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen;
2567 + prop = get_property(node, "ranges");
2571 + if (!node->parent) {
2572 + FAIL(c, "Root node has a \"ranges\" property");
2576 + p_addr_cells = node_addr_cells(node->parent);
2577 + p_size_cells = node_size_cells(node->parent);
2578 + c_addr_cells = node_addr_cells(node);
2579 + c_size_cells = node_size_cells(node);
2580 + entrylen = (p_addr_cells + c_addr_cells + c_size_cells) * sizeof(cell_t);
2582 + if (prop->val.len == 0) {
2583 + if (p_addr_cells != c_addr_cells)
2584 + FAIL(c, "%s has empty \"ranges\" property but its "
2585 + "#address-cells (%d) differs from %s (%d)",
2586 + node->fullpath, c_addr_cells, node->parent->fullpath,
2588 + if (p_size_cells != c_size_cells)
2589 + FAIL(c, "%s has empty \"ranges\" property but its "
2590 + "#size-cells (%d) differs from %s (%d)",
2591 + node->fullpath, c_size_cells, node->parent->fullpath,
2593 + } else if ((prop->val.len % entrylen) != 0) {
2594 + FAIL(c, "\"ranges\" property in %s has invalid length (%d bytes) "
2595 + "(parent #address-cells == %d, child #address-cells == %d, "
2596 + "#size-cells == %d)", node->fullpath, prop->val.len,
2597 + p_addr_cells, c_addr_cells, c_size_cells);
2600 +NODE_CHECK(ranges_format, NULL, WARN, &addr_size_cells);
2605 +static void check_avoid_default_addr_size(struct check *c, struct node *dt,
2606 + struct node *node)
2608 + struct property *reg, *ranges;
2610 + if (!node->parent)
2611 + return; /* Ignore root node */
2613 + reg = get_property(node, "reg");
2614 + ranges = get_property(node, "ranges");
2616 + if (!reg && !ranges)
2619 + if ((node->parent->addr_cells == -1))
2620 + FAIL(c, "Relying on default #address-cells value for %s",
2623 + if ((node->parent->size_cells == -1))
2624 + FAIL(c, "Relying on default #size-cells value for %s",
2627 +NODE_CHECK(avoid_default_addr_size, NULL, WARN, &addr_size_cells);
2629 +static void check_obsolete_chosen_interrupt_controller(struct check *c,
2632 + struct node *chosen;
2633 + struct property *prop;
2635 + chosen = get_node_by_path(dt, "/chosen");
2639 + prop = get_property(chosen, "interrupt-controller");
2641 + FAIL(c, "/chosen has obsolete \"interrupt-controller\" "
2644 +TREE_CHECK(obsolete_chosen_interrupt_controller, NULL, WARN);
2646 +static struct check *check_table[] = {
2647 + &duplicate_node_names, &duplicate_property_names,
2648 + &name_is_string, &name_properties,
2649 + &explicit_phandles,
2650 + &phandle_references, &path_references,
2652 + &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
2653 + &device_type_is_string, &model_is_string, &status_is_string,
2655 + &addr_size_cells, ®_format, &ranges_format,
2657 + &avoid_default_addr_size,
2658 + &obsolete_chosen_interrupt_controller,
2661 +int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys);
2663 +void process_checks(int force, struct boot_info *bi,
2664 + int checkflag, int outversion, int boot_cpuid_phys)
2666 + struct node *dt = bi->dt;
2670 + for (i = 0; i < ARRAY_SIZE(check_table); i++) {
2671 + struct check *c = check_table[i];
2673 + if (c->level != IGNORE)
2674 + error = error || run_check(c, dt);
2679 + fprintf(stderr, "ERROR: Input tree has errors, aborting "
2680 + "(use -f to force output)\n");
2682 + } else if (quiet < 3) {
2683 + fprintf(stderr, "Warning: Input tree has errors, "
2684 + "output forced\n");
2690 + fprintf(stderr, "Warning: Skipping semantic checks due to structural errors\n");
2692 + if (!check_semantics(bi->dt, outversion,
2694 + fprintf(stderr, "Warning: Input tree has semantic errors\n");
2700 + * Semantic check functions
2703 +#define ERRMSG(...) if (quiet < 2) fprintf(stderr, "ERROR: " __VA_ARGS__)
2704 +#define WARNMSG(...) if (quiet < 1) fprintf(stderr, "Warning: " __VA_ARGS__)
2706 +#define DO_ERR(...) do {ERRMSG(__VA_ARGS__); ok = 0; } while (0)
2708 +#define CHECK_HAVE(node, propname) \
2710 + if (! (prop = get_property((node), (propname)))) \
2711 + DO_ERR("Missing \"%s\" property in %s\n", (propname), \
2712 + (node)->fullpath); \
2715 +#define CHECK_HAVE_WARN(node, propname) \
2717 + if (! (prop = get_property((node), (propname)))) \
2718 + WARNMSG("%s has no \"%s\" property\n", \
2719 + (node)->fullpath, (propname)); \
2722 +#define CHECK_HAVE_STRING(node, propname) \
2724 + CHECK_HAVE((node), (propname)); \
2725 + if (prop && !data_is_one_string(prop->val)) \
2726 + DO_ERR("\"%s\" property in %s is not a string\n", \
2727 + (propname), (node)->fullpath); \
2730 +#define CHECK_HAVE_STREQ(node, propname, value) \
2732 + CHECK_HAVE_STRING((node), (propname)); \
2733 + if (prop && !streq(prop->val.val, (value))) \
2734 + DO_ERR("%s has wrong %s, %s (should be %s\n", \
2735 + (node)->fullpath, (propname), \
2736 + prop->val.val, (value)); \
2739 +#define CHECK_HAVE_ONECELL(node, propname) \
2741 + CHECK_HAVE((node), (propname)); \
2742 + if (prop && (prop->val.len != sizeof(cell_t))) \
2743 + DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \
2746 +#define CHECK_HAVE_WARN_ONECELL(node, propname) \
2748 + CHECK_HAVE_WARN((node), (propname)); \
2749 + if (prop && (prop->val.len != sizeof(cell_t))) \
2750 + DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \
2753 +#define CHECK_HAVE_WARN_PHANDLE(xnode, propname, root) \
2755 + struct node *ref; \
2756 + CHECK_HAVE_WARN_ONECELL((xnode), (propname)); \
2758 + cell_t phandle = propval_cell(prop); \
2759 + if ((phandle == 0) || (phandle == -1)) { \
2760 + DO_ERR("\"%s\" property in %s contains an invalid phandle %x\n", (propname), (xnode)->fullpath, phandle); \
2762 + ref = get_node_by_phandle((root), propval_cell(prop)); \
2764 + DO_ERR("\"%s\" property in %s refers to non-existant phandle %x\n", (propname), (xnode)->fullpath, propval_cell(prop)); \
2769 +#define CHECK_HAVE_WARN_STRING(node, propname) \
2771 + CHECK_HAVE_WARN((node), (propname)); \
2772 + if (prop && !data_is_one_string(prop->val)) \
2773 + DO_ERR("\"%s\" property in %s is not a string\n", \
2774 + (propname), (node)->fullpath); \
2777 +static int check_root(struct node *root)
2779 + struct property *prop;
2782 + CHECK_HAVE_STRING(root, "model");
2783 + CHECK_HAVE_WARN(root, "compatible");
2788 +static int check_cpus(struct node *root, int outversion, int boot_cpuid_phys)
2790 + struct node *cpus, *cpu;
2791 + struct property *prop;
2792 + struct node *bootcpu = NULL;
2795 + cpus = get_subnode(root, "cpus");
2797 + ERRMSG("Missing /cpus node\n");
2801 + if (cpus->addr_cells != 1)
2802 + DO_ERR("%s has bad #address-cells value %d (should be 1)\n",
2803 + cpus->fullpath, cpus->addr_cells);
2804 + if (cpus->size_cells != 0)
2805 + DO_ERR("%s has bad #size-cells value %d (should be 0)\n",
2806 + cpus->fullpath, cpus->size_cells);
2808 + for_each_child(cpus, cpu) {
2809 + CHECK_HAVE_STREQ(cpu, "device_type", "cpu");
2811 + CHECK_HAVE_ONECELL(cpu, "reg");
2816 + unitnum = strtol(get_unitname(cpu), &eptr, 16);
2818 + WARNMSG("%s has bad format unit name %s (should be CPU number\n",
2819 + cpu->fullpath, get_unitname(cpu));
2820 + } else if (unitnum != propval_cell(prop)) {
2821 + WARNMSG("%s unit name \"%s\" does not match \"reg\" property <%x>\n",
2822 + cpu->fullpath, get_unitname(cpu),
2823 + propval_cell(prop));
2827 +/* CHECK_HAVE_ONECELL(cpu, "d-cache-line-size"); */
2828 +/* CHECK_HAVE_ONECELL(cpu, "i-cache-line-size"); */
2829 + CHECK_HAVE_ONECELL(cpu, "d-cache-size");
2830 + CHECK_HAVE_ONECELL(cpu, "i-cache-size");
2832 + CHECK_HAVE_WARN_ONECELL(cpu, "clock-frequency");
2833 + CHECK_HAVE_WARN_ONECELL(cpu, "timebase-frequency");
2835 + prop = get_property(cpu, "linux,boot-cpu");
2837 + if (prop->val.len)
2838 + WARNMSG("\"linux,boot-cpu\" property in %s is non-empty\n",
2841 + DO_ERR("Multiple boot cpus (%s and %s)\n",
2842 + bootcpu->fullpath, cpu->fullpath);
2848 + if (outversion < 2) {
2850 + WARNMSG("No cpu has \"linux,boot-cpu\" property\n");
2853 + WARNMSG("\"linux,boot-cpu\" property is deprecated in blob version 2 or higher\n");
2854 + if (boot_cpuid_phys == 0xfeedbeef)
2855 + WARNMSG("physical boot CPU not set. Use -b option to set\n");
2861 +static int check_memory(struct node *root)
2864 + struct property *prop;
2868 + for_each_child(root, mem) {
2869 + if (! strneq(mem->name, "memory", mem->basenamelen))
2874 + CHECK_HAVE_STREQ(mem, "device_type", "memory");
2875 + CHECK_HAVE(mem, "reg");
2878 + if (nnodes == 0) {
2879 + ERRMSG("No memory nodes\n");
2886 +int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys)
2890 + ok = ok && check_root(dt);
2891 + ok = ok && check_cpus(dt, outversion, boot_cpuid_phys);
2892 + ok = ok && check_memory(dt);
2899 +++ b/arch/powerpc/boot/dtc-src/data.c
2902 + * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
2905 + * This program is free software; you can redistribute it and/or
2906 + * modify it under the terms of the GNU General Public License as
2907 + * published by the Free Software Foundation; either version 2 of the
2908 + * License, or (at your option) any later version.
2910 + * This program is distributed in the hope that it will be useful,
2911 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2912 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2913 + * General Public License for more details.
2915 + * You should have received a copy of the GNU General Public License
2916 + * along with this program; if not, write to the Free Software
2917 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
2923 +void data_free(struct data d)
2925 + struct marker *m, *nm;
2935 + assert(!d.val || d.asize);
2941 +struct data data_grow_for(struct data d, int xlen)
2946 + /* we must start with an allocated datum */
2947 + assert(!d.val || d.asize);
2956 + while ((d.len + xlen) > newsize)
2959 + nd.asize = newsize;
2960 + nd.val = xrealloc(d.val, newsize);
2962 + assert(nd.asize >= (d.len + xlen));
2967 +struct data data_copy_mem(const char *mem, int len)
2971 + d = data_grow_for(empty_data, len);
2974 + memcpy(d.val, mem, len);
2979 +static char get_oct_char(const char *s, int *i)
2993 + val = strtol(x, &endx, 8);
2994 + if ((endx - x) == 0)
2995 + fprintf(stderr, "Empty \\nnn escape\n");
3001 +static char get_hex_char(const char *s, int *i)
3012 + val = strtol(x, &endx, 16);
3013 + if ((endx - x) == 0)
3014 + fprintf(stderr, "Empty \\x escape\n");
3020 +struct data data_copy_escape_string(const char *s, int len)
3026 + d = data_grow_for(empty_data, strlen(s)+1);
3041 + q[d.len++] = '\a';
3044 + q[d.len++] = '\b';
3047 + q[d.len++] = '\t';
3050 + q[d.len++] = '\n';
3053 + q[d.len++] = '\v';
3056 + q[d.len++] = '\f';
3059 + q[d.len++] = '\r';
3069 + i--; /* need to re-read the first digit as
3070 + * part of the octal value */
3071 + q[d.len++] = get_oct_char(s, &i);
3074 + q[d.len++] = get_hex_char(s, &i);
3081 + q[d.len++] = '\0';
3085 +struct data data_copy_file(FILE *f, size_t len)
3089 + d = data_grow_for(empty_data, len);
3092 + fread(d.val, len, 1, f);
3097 +struct data data_append_data(struct data d, const void *p, int len)
3099 + d = data_grow_for(d, len);
3100 + memcpy(d.val + d.len, p, len);
3105 +struct data data_insert_at_marker(struct data d, struct marker *m,
3106 + const void *p, int len)
3108 + d = data_grow_for(d, len);
3109 + memmove(d.val + m->offset + len, d.val + m->offset, d.len - m->offset);
3110 + memcpy(d.val + m->offset, p, len);
3113 + /* Adjust all markers after the one we're inserting at */
3115 + for_each_marker(m)
3120 +struct data data_append_markers(struct data d, struct marker *m)
3122 + struct marker **mp = &d.markers;
3124 + /* Find the end of the markerlist */
3126 + mp = &((*mp)->next);
3131 +struct data data_merge(struct data d1, struct data d2)
3134 + struct marker *m2 = d2.markers;
3136 + d = data_append_markers(data_append_data(d1, d2.val, d2.len), m2);
3138 + /* Adjust for the length of d1 */
3139 + for_each_marker(m2)
3140 + m2->offset += d1.len;
3142 + d2.markers = NULL; /* So data_free() doesn't clobber them */
3148 +struct data data_append_cell(struct data d, cell_t word)
3150 + cell_t beword = cpu_to_be32(word);
3152 + return data_append_data(d, &beword, sizeof(beword));
3155 +struct data data_append_re(struct data d, const struct fdt_reserve_entry *re)
3157 + struct fdt_reserve_entry bere;
3159 + bere.address = cpu_to_be64(re->address);
3160 + bere.size = cpu_to_be64(re->size);
3162 + return data_append_data(d, &bere, sizeof(bere));
3165 +struct data data_append_addr(struct data d, u64 addr)
3167 + u64 beaddr = cpu_to_be64(addr);
3169 + return data_append_data(d, &beaddr, sizeof(beaddr));
3172 +struct data data_append_byte(struct data d, uint8_t byte)
3174 + return data_append_data(d, &byte, 1);
3177 +struct data data_append_zeroes(struct data d, int len)
3179 + d = data_grow_for(d, len);
3181 + memset(d.val + d.len, 0, len);
3186 +struct data data_append_align(struct data d, int align)
3188 + int newlen = ALIGN(d.len, align);
3189 + return data_append_zeroes(d, newlen - d.len);
3192 +struct data data_add_marker(struct data d, enum markertype type, char *ref)
3196 + m = xmalloc(sizeof(*m));
3197 + m->offset = d.len;
3202 + return data_append_markers(d, m);
3205 +int data_is_one_string(struct data d)
3213 + for (i = 0; i < len-1; i++)
3214 + if (d.val[i] == '\0')
3217 + if (d.val[len-1] != '\0')
3223 +++ b/arch/powerpc/boot/dtc-src/dtc-lexer.l
3226 + * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
3229 + * This program is free software; you can redistribute it and/or
3230 + * modify it under the terms of the GNU General Public License as
3231 + * published by the Free Software Foundation; either version 2 of the
3232 + * License, or (at your option) any later version.
3234 + * This program is distributed in the hope that it will be useful,
3235 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3236 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3237 + * General Public License for more details.
3239 + * You should have received a copy of the GNU General Public License
3240 + * along with this program; if not, write to the Free Software
3241 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
3245 +%option noyywrap nounput yylineno
3252 +PROPNODECHAR [a-zA-Z0-9,._+*#?@-]
3253 +PATHCHAR ({PROPNODECHAR}|[/])
3254 +LABEL [a-zA-Z_][a-zA-Z0-9_]*
3258 +#include "srcpos.h"
3259 +#include "dtc-parser.tab.h"
3262 +/*#define LEXDEBUG 1*/
3265 +#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
3267 +#define DPRINT(fmt, ...) do { } while (0)
3270 +static int dts_version; /* = 0 */
3272 +#define BEGIN_DEFAULT() if (dts_version == 0) { \
3273 + DPRINT("<INITIAL>\n"); \
3276 + DPRINT("<V1>\n"); \
3282 +<*>"/include/" BEGIN(INCLUDE);
3284 +<INCLUDE>\"[^"\n]*\" {
3285 + yytext[strlen(yytext) - 1] = 0;
3286 + if (!push_input_file(yytext + 1)) {
3287 + /* Some unrecoverable error.*/
3295 + if (!pop_input_file()) {
3300 +<*>\"([^\\"]|\\.)*\" {
3301 + yylloc.filenum = srcpos_filenum;
3302 + yylloc.first_line = yylineno;
3303 + DPRINT("String: %s\n", yytext);
3304 + yylval.data = data_copy_escape_string(yytext+1,
3306 + yylloc.first_line = yylineno;
3311 + yylloc.filenum = srcpos_filenum;
3312 + yylloc.first_line = yylineno;
3313 + DPRINT("Keyword: /dts-v1/\n");
3319 +<*>"/memreserve/" {
3320 + yylloc.filenum = srcpos_filenum;
3321 + yylloc.first_line = yylineno;
3322 + DPRINT("Keyword: /memreserve/\n");
3324 + return DT_MEMRESERVE;
3328 + yylloc.filenum = srcpos_filenum;
3329 + yylloc.first_line = yylineno;
3330 + DPRINT("Label: %s\n", yytext);
3331 + yylval.labelref = strdup(yytext);
3332 + yylval.labelref[yyleng-1] = '\0';
3337 + yylloc.filenum = srcpos_filenum;
3338 + yylloc.first_line = yylineno;
3339 + if (*yytext == 'b')
3341 + else if (*yytext == 'o')
3343 + else if (*yytext == 'd')
3344 + yylval.cbase = 10;
3346 + yylval.cbase = 16;
3347 + DPRINT("Base: %d\n", yylval.cbase);
3351 +<INITIAL>[0-9a-fA-F]+ {
3352 + yylloc.filenum = srcpos_filenum;
3353 + yylloc.first_line = yylineno;
3354 + yylval.literal = strdup(yytext);
3355 + DPRINT("Literal: '%s'\n", yylval.literal);
3356 + return DT_LEGACYLITERAL;
3359 +<V1>[0-9]+|0[xX][0-9a-fA-F]+ {
3360 + yylloc.filenum = srcpos_filenum;
3361 + yylloc.first_line = yylineno;
3362 + yylval.literal = strdup(yytext);
3363 + DPRINT("Literal: '%s'\n", yylval.literal);
3364 + return DT_LITERAL;
3367 +\&{LABEL} { /* label reference */
3368 + yylloc.filenum = srcpos_filenum;
3369 + yylloc.first_line = yylineno;
3370 + DPRINT("Ref: %s\n", yytext+1);
3371 + yylval.labelref = strdup(yytext+1);
3375 +"&{/"{PATHCHAR}+\} { /* new-style path reference */
3376 + yylloc.filenum = srcpos_filenum;
3377 + yylloc.first_line = yylineno;
3378 + yytext[yyleng-1] = '\0';
3379 + DPRINT("Ref: %s\n", yytext+2);
3380 + yylval.labelref = strdup(yytext+2);
3384 +<INITIAL>"&/"{PATHCHAR}+ { /* old-style path reference */
3385 + yylloc.filenum = srcpos_filenum;
3386 + yylloc.first_line = yylineno;
3387 + DPRINT("Ref: %s\n", yytext+1);
3388 + yylval.labelref = strdup(yytext+1);
3392 +<BYTESTRING>[0-9a-fA-F]{2} {
3393 + yylloc.filenum = srcpos_filenum;
3394 + yylloc.first_line = yylineno;
3395 + yylval.byte = strtol(yytext, NULL, 16);
3396 + DPRINT("Byte: %02x\n", (int)yylval.byte);
3401 + yylloc.filenum = srcpos_filenum;
3402 + yylloc.first_line = yylineno;
3403 + DPRINT("/BYTESTRING\n");
3408 +<PROPNODENAME>{PROPNODECHAR}+ {
3409 + yylloc.filenum = srcpos_filenum;
3410 + yylloc.first_line = yylineno;
3411 + DPRINT("PropNodeName: %s\n", yytext);
3412 + yylval.propnodename = strdup(yytext);
3414 + return DT_PROPNODENAME;