[8.09] kernel: refresh patches
[openwrt/svn-archive/archive.git] / target / linux / generic-2.6 / patches-2.6.24 / 700-powerpc_git.patch
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.
5
6 hugepages= [HW,X86-32,IA-64] Maximal number of HugeTLB pages.
7 + hugepagesz= [HW,IA-64,PPC] The size of the HugeTLB pages.
8
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
15 zImage_layout.txt
16 - info on the kernel images for Linux/PPC
17 +qe_firmware.txt
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
26 - l) Xilinx IP cores
27 + l) Freescale Communications Processor Module
28 + m) Chipselect/Local Bus
29 + n) 4xx/Axon EMAC ethernet nodes
30 + o) Xilinx IP cores
31 + p) Freescale Synchronous Serial Interface
32
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
36
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.
47
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.
53
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
62 -bus is a list of:
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
65 +of:
66
67 bus address, parent bus address, size
68
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.
72
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.
77
78 2) Note about "compatible" properties
79 -------------------------------------
80 @@ -1218,16 +1227,14 @@ platforms are moved over to use the flat
81
82 Required properties:
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"
88
89 Example:
90
91 mdio@24520 {
92 reg = <24520 20>;
93 - device_type = "mdio";
94 - compatible = "gianfar";
95 + compatible = "fsl,gianfar-mdio";
96
97 ethernet-phy@0 {
98 ......
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
102 controller.
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.
107
108 Recommended properties:
109
110 @@ -1408,7 +1419,6 @@ platforms are moved over to use the flat
111
112 Example multi port host USB controller device node :
113 usb@22000 {
114 - device_type = "usb";
115 compatible = "fsl-usb2-mph";
116 reg = <22000 1000>;
117 #address-cells = <1>;
118 @@ -1422,7 +1432,6 @@ platforms are moved over to use the flat
119
120 Example dual role USB controller device node :
121 usb@23000 {
122 - device_type = "usb";
123 compatible = "fsl-usb2-dr";
124 reg = <23000 1000>;
125 #address-cells = <1>;
126 @@ -1586,7 +1595,6 @@ platforms are moved over to use the flat
127 iii) USB (Universal Serial Bus Controller)
128
129 Required properties:
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
135
136 Example(slave):
137 usb@6c0 {
138 - device_type = "usb";
139 compatible = "qe_udc";
140 reg = <6c0 40>;
141 interrupts = <8b 0>;
142 @@ -1613,7 +1620,7 @@ platforms are moved over to use the flat
143
144 Required properties:
145 - device_type : should be "network", "hldc", "uart", "transparent"
146 - "bisync" or "atm".
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
179 };
180 };
181
182 + viii) Uploaded QE firmware
183 +
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.
188 +
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.
199 +
200 + Example:
201 +
202 + firmware {
203 + id = "Soft-UART";
204 + extended-modes = <0 0>;
205 + virtual-traps = <0 0 0 0 0 0 0 0>;
206 + }
207 +
208 j) CFI or JEDEC memory-mapped NOR flash
209
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
212
213 Example:
214 localbus@f0010100 {
215 - compatible = "fsl,mpc8272ads-localbus",
216 - "fsl,mpc8272-localbus",
217 + compatible = "fsl,mpc8272-localbus",
218 "fsl,pq2-localbus";
219 #address-cells = <2>;
220 #size-cells = <1>;
221 @@ -2254,7 +2306,7 @@ platforms are moved over to use the flat
222 available.
223 For Axon: 0x0000012a
224
225 - l) Xilinx IP cores
226 + o) Xilinx IP cores
227
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:
233
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)>;
241 };
242
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).
258
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
262
263 becomes the following device tree node:
264
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>;
277 };
278
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
288 - design.
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.
302
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
306
307 It would result in the following device tree nodes:
308
309 - opb_ps2_dual_ref_0@a9000000 {
310 + opb_ps2_dual_ref_0: opb-ps2-dual-ref@a9000000 {
311 + #address-cells = <1>;
312 + #size-cells = <1>;
313 + compatible = "xlnx,compound";
314 ranges = <0 a9000000 2000>;
315 // If this device had extra parameters, then they would
316 // go here.
317 ps2@0 {
318 compatible = "xlnx,opb-ps2-dual-ref-1.00.a";
319 reg = <0 40>;
320 - interrupt-parent = <&opb-intc>;
321 + interrupt-parent = <&opb_intc_0>;
322 interrupts = <3 0>;
323 cell-index = <0>;
324 };
325 ps2@1000 {
326 compatible = "xlnx,opb-ps2-dual-ref-1.00.a";
327 reg = <1000 40>;
328 - interrupt-parent = <&opb-intc>;
329 + interrupt-parent = <&opb_intc_0>;
330 interrupts = <3 0>;
331 cell-index = <0>;
332 };
333 @@ -2447,17 +2508,18 @@ platforms are moved over to use the flat
334
335 Gives this device tree (some properties removed for clarity):
336
337 - plb-v34-0 {
338 + plb@0 {
339 #address-cells = <1>;
340 #size-cells = <1>;
341 + compatible = "xlnx,plb-v34-1.02.a";
342 device_type = "ibm,plb";
343 ranges; // 1:1 translation
344
345 - plb-bram-if-cntrl-0@ffff0000 {
346 + plb_bram_if_cntrl_0: bram@ffff0000 {
347 reg = <ffff0000 10000>;
348 }
349
350 - opb-v20-0 {
351 + opb@20000000 {
352 #address-cells = <1>;
353 #size-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>;
358
359 - opb-uart16550-0@a0000000 {
360 + opb_uart16550_0: serial@a0000000 {
361 reg = <a00000000 2000>;
362 };
363
364 - opb-intc-0@d1000fc0 {
365 + opb_intc_0: interrupt-controller@d1000fc0 {
366 reg = <d1000fc0 20>;
367 };
368 };
369 @@ -2514,6 +2576,46 @@ platforms are moved over to use the flat
370 Requred properties:
371 - current-speed : Baud rate of uartlite
372
373 + p) Freescale Synchronous Serial Interface
374 +
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.
377 +
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
387 + have.
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
399 +
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.
404 +
405 + Child 'codec' node required properties:
406 + - compatible : compatible list, contains the name of the codec
407 +
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.
411 +
412 +
413 More devices will be defined as this spec matures.
414
415 VII - Specifying interrupt information for devices
416 --- /dev/null
417 +++ b/Documentation/powerpc/qe_firmware.txt
418 @@ -0,0 +1,295 @@
419 + Freescale QUICC Engine Firmware Uploading
420 + -----------------------------------------
421 +
422 +(c) 2007 Timur Tabi <timur at freescale.com>,
423 + Freescale Semiconductor
424 +
425 +Table of Contents
426 +=================
427 +
428 + I - Software License for Firmware
429 +
430 + II - Microcode Availability
431 +
432 + III - Description and Terminology
433 +
434 + IV - Microcode Programming Details
435 +
436 + V - Firmware Structure Layout
437 +
438 + VI - Sample Code for Creating Firmware Files
439 +
440 +Revision Information
441 +====================
442 +
443 +November 30, 2007: Rev 1.0 - Initial version
444 +
445 +I - Software License for Firmware
446 +=================================
447 +
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
450 +the firmware.
451 +
452 +II - Microcode Availability
453 +===========================
454 +
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.
458 +
459 +III - Description and Terminology
460 +================================
461 +
462 +In this document, the term 'microcode' refers to the sequence of 32-bit
463 +integers that compose the actual QE microcode.
464 +
465 +The term 'firmware' refers to a binary blob that contains the microcode as
466 +well as other data that
467 +
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
472 +
473 +Firmware files are binary files that contain only a firmware.
474 +
475 +IV - Microcode Programming Details
476 +===================================
477 +
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.
481 +
482 +QE microcode is uploaded using the following procedure:
483 +
484 +1) The microcode is placed into I-RAM at a specific location, using the
485 + IRAM.IADD and IRAM.IDATA registers.
486 +
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.
492 +
493 +3) The TIBCR trap registers are loaded with the addresses of the trap handlers
494 + in the microcode.
495 +
496 +4) The RSP.ECCR register is programmed with the value provided.
497 +
498 +5) If necessary, device drivers that need the virtual traps and extended mode
499 + data will use them.
500 +
501 +Virtual Microcode Traps
502 +
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.
508 +
509 +This structure contains 6 words that the application should copy to some
510 +specific been defined. This table describes the structure.
511 +
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 + ---------------------------------------------------------------
533 +
534 +
535 +Extended Modes
536 +
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:
541 +
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 + -----------------------------------------------------------------------
583 +
584 +V - Firmware Structure Layout
585 +==============================
586 +
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.
592 +
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
596 +the microcode.
597 +
598 +All integers are big-endian. See the comments for function
599 +qe_upload_firmware() for up-to-date implementation information.
600 +
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.
605 +
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
609 + present).
610 +
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.
614 +
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.
619 +
620 +The 'id' field is a null-terminated string(suitable for printing) that
621 +identifies the firmware.
622 +
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
626 +SOC.
627 +
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.
633 +
634 +Although it is not recommended, you can specify '0' in the soc.model
635 +field to skip matching SOCs altogether.
636 +
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.
640 +
641 +For example, to match the 8323, revision 1.0:
642 + soc.model = 8323
643 + soc.major = 1
644 + soc.minor = 0
645 +
646 +'padding' is neccessary for structure alignment. This field ensures that the
647 +'extended_modes' field is aligned on a 64-bit boundary.
648 +
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().
653 +
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().
657 +
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.
661 +
662 + The 'id' field is a null-terminated string suitable for printing that
663 + identifies this particular microcode.
664 +
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.
670 +
671 + 'eccr' is the value to program into the ECCR register.
672 +
673 + 'iram_offset' is the offset into IRAM to start writing the
674 + microcode.
675 +
676 + 'count' is the number of 32-bit words in the microcode.
677 +
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'
681 + array.
682 +
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.
686 +
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
691 + 'reserved'.
692 +
693 +After the last microcode is a 32-bit CRC. It can be calculated using
694 +this algorithm:
695 +
696 +u32 crc32(const u8 *p, unsigned int len)
697 +{
698 + unsigned int i;
699 + u32 crc = 0;
700 +
701 + while (len--) {
702 + crc ^= *p++;
703 + for (i = 0; i < 8; i++)
704 + crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
705 + }
706 + return crc;
707 +}
708 +
709 +VI - Sample Code for Creating Firmware Files
710 +============================================
711 +
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
718 default n
719
720 +config REDBOOT
721 + bool
722 +
723 config PPC64_SWSUSP
724 bool
725 depends on PPC64 && (BROKEN || (PPC_PMAC64 && EXPERIMENTAL))
726 @@ -160,11 +163,13 @@ config PPC_DCR
727
728 config PPC_OF_PLATFORM_PCI
729 bool
730 + depends on PCI
731 depends on PPC64 # not supported on 32 bits yet
732 default n
733
734 source "init/Kconfig"
735
736 +source "arch/powerpc/sysdev/Kconfig"
737 source "arch/powerpc/platforms/Kconfig"
738
739 menu "Kernel options"
740 @@ -417,7 +422,7 @@ endmenu
741
742 config ISA_DMA_API
743 bool
744 - default y
745 + default !PPC_ISERIES || PCI
746
747 menu "Bus options"
748
749 @@ -467,7 +472,7 @@ config MCA
750 config PCI
751 bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \
752 || PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \
753 - || PPC_PS3
754 + || PPC_PS3 || 44x
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
761
762 config PPC_EARLY_DEBUG
763 bool "Early debugging (dangerous)"
764 + help
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
771
772 choice
773 prompt "Early debugging console"
774 @@ -218,7 +225,16 @@ config PPC_EARLY_DEBUG_44x
775 depends on 44x
776 help
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.
781 +
782 +config PPC_EARLY_DEBUG_40x
783 + bool "Early serial debugging for IBM/AMCC 40x CPUs"
784 + depends on 40x
785 + help
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.
789
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
795 default "0x40000200"
796 + help
797 + You probably want 0x40000200 for ebony boards and
798 + 0x40000300 for taishan
799
800 config PPC_EARLY_DEBUG_44x_PHYSHIGH
801 hex "EPRN of early debug UART physical address"
802 depends on PPC_EARLY_DEBUG_44x
803 default "0x1"
804
805 +config PPC_EARLY_DEBUG_40x_PHYSADDR
806 + hex "Early debug UART physical address"
807 + depends on PPC_EARLY_DEBUG_40x
808 + default "0xef600300"
809 +
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)/%,$@)
818
819 +bootwrapper_install:
820 + $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
821 +
822 define archhelp
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
827 @@ -22,16 +22,14 @@
828 #include "dcr.h"
829
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)
833 {
834 int i;
835 unsigned long memsize, bank_config;
836
837 memsize = 0;
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);
841 -
842 + bank_config = SDRAM0_READ(sdram_bxcr[i]);
843 if (bank_config & SDRAM_CONFIG_BANK_ENABLE)
844 memsize += SDRAM_CONFIG_BANK_SIZE(bank_config);
845 }
846 @@ -39,6 +37,69 @@ void ibm4xx_fixup_memsize(void)
847 dt_fixup_memory(0, memsize);
848 }
849
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
855 +
856 +static u64 ibm440spe_decode_bas(u32 bas)
857 +{
858 + u64 base = ((u64)(bas & 0xFFE00000u)) << 2;
859 +
860 + /* open coded because I'm paranoid about invalid values */
861 + switch ((bas >> 4) & 0xFFF) {
862 + case 0:
863 + return 0;
864 + case 0xffc:
865 + return base + 0x000800000ull;
866 + case 0xff8:
867 + return base + 0x001000000ull;
868 + case 0xff0:
869 + return base + 0x002000000ull;
870 + case 0xfe0:
871 + return base + 0x004000000ull;
872 + case 0xfc0:
873 + return base + 0x008000000ull;
874 + case 0xf80:
875 + return base + 0x010000000ull;
876 + case 0xf00:
877 + return base + 0x020000000ull;
878 + case 0xe00:
879 + return base + 0x040000000ull;
880 + case 0xc00:
881 + return base + 0x080000000ull;
882 + case 0x800:
883 + return base + 0x100000000ull;
884 + }
885 + printf("Memory BAS value 0x%08x unsupported !\n", bas);
886 + return 0;
887 +}
888 +
889 +void ibm440spe_fixup_memsize(void)
890 +{
891 + u64 banktop, memsize = 0;
892 +
893 + /* Ultimately, we should directly construct the memory node
894 + * so we are able to handle holes in the memory address space
895 + */
896 + banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B0BAS));
897 + if (banktop > memsize)
898 + memsize = banktop;
899 + banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B1BAS));
900 + if (banktop > memsize)
901 + memsize = banktop;
902 + banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B2BAS));
903 + if (banktop > memsize)
904 + memsize = banktop;
905 + banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B3BAS));
906 + if (banktop > memsize)
907 + memsize = banktop;
908 +
909 + dt_fixup_memory(0, memsize);
910 +}
911 +
912 +
913 /* 4xx DDR1/2 Denali memory controller support */
914 /* DDR0 registers */
915 #define DDR0_02 2
916 @@ -77,19 +138,13 @@ void ibm4xx_fixup_memsize(void)
917
918 #define DDR_GET_VAL(val, mask, shift) (((val) >> (shift)) & (mask))
919
920 -static inline u32 mfdcr_sdram0(u32 reg)
921 -{
922 - mtdcr(DCRN_SDRAM0_CFGADDR, reg);
923 - return mfdcr(DCRN_SDRAM0_CFGDATA);
924 -}
925 -
926 void ibm4xx_denali_fixup_memsize(void)
927 {
928 u32 val, max_cs, max_col, max_row;
929 u32 cs, col, row, bank, dpath;
930 unsigned long memsize;
931
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");
936
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);
939
940 /* get CS value */
941 - val = mfdcr_sdram0(DDR0_10);
942 + val = SDRAM0_READ(DDR0_10);
943
944 val = DDR_GET_VAL(val, DDR_CS_MAP, DDR_CS_MAP_SHIFT);
945 cs = 0;
946 while (val) {
947 - if (val && 0x1)
948 + if (val & 0x1)
949 cs++;
950 val = val >> 1;
951 }
952 @@ -115,15 +170,15 @@ void ibm4xx_denali_fixup_memsize(void)
953 fatal("DDR wrong CS configuration\n");
954
955 /* get data path bytes */
956 - val = mfdcr_sdram0(DDR0_14);
957 + val = SDRAM0_READ(DDR0_14);
958
959 if (DDR_GET_VAL(val, DDR_REDUC, DDR_REDUC_SHIFT))
960 dpath = 8; /* 64 bits */
961 else
962 dpath = 4; /* 32 bits */
963
964 - /* get adress pins (rows) */
965 - val = mfdcr_sdram0(DDR0_42);
966 + /* get address pins (rows) */
967 + val = SDRAM0_READ(DDR0_42);
968
969 row = DDR_GET_VAL(val, DDR_APIN, DDR_APIN_SHIFT);
970 if (row > max_row)
971 @@ -131,7 +186,7 @@ void ibm4xx_denali_fixup_memsize(void)
972 row = max_row - row;
973
974 /* get collomn size and banks */
975 - val = mfdcr_sdram0(DDR0_43);
976 + val = SDRAM0_READ(DDR0_43);
977
978 col = DDR_GET_VAL(val, DDR_COL_SZ, DDR_COL_SZ_SHIFT);
979 if (col > max_col)
980 @@ -179,13 +234,17 @@ void ibm40x_dbcr_reset(void)
981 #define EMAC_RESET 0x20000000
982 void ibm4xx_quiesce_eth(u32 *emac0, u32 *emac1)
983 {
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
986 + * do this for us
987 + */
988 if (emac0)
989 *emac0 = EMAC_RESET;
990 if (emac1)
991 *emac1 = EMAC_RESET;
992
993 mtdcr(DCRN_MAL0_CFG, MAL_RESET);
994 + while (mfdcr(DCRN_MAL0_CFG) & MAL_RESET)
995 + ; /* loop until reset takes effect */
996 }
997
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));
1001 }
1002
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)
1007 {
1008 - u32 cpu, plb, opb, ebc, tb, uart0, m, vco;
1009 - u32 reg;
1010 - u32 fwdva, fwdvb, fbdv, lfbdv, opbdv0, perdv0, spcid0, prbdv0, tmp;
1011 -
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);
1021 -
1022 - mtdcr(DCRN_CPR0_ADDR, CPR0_OPBD0);
1023 - reg = mfdcr(DCRN_CPR0_DATA);
1024 - tmp = (reg & 0x03000000) >> 24;
1025 - opbdv0 = tmp ? tmp : 4;
1026 -
1027 - mtdcr(DCRN_CPR0_ADDR, CPR0_PERD0);
1028 - reg = mfdcr(DCRN_CPR0_DATA);
1029 - tmp = (reg & 0x07000000) >> 24;
1030 - perdv0 = tmp ? tmp : 8;
1031 -
1032 - mtdcr(DCRN_CPR0_ADDR, CPR0_PRIMBD0);
1033 - reg = mfdcr(DCRN_CPR0_DATA);
1034 - tmp = (reg & 0x07000000) >> 24;
1035 - prbdv0 = tmp ? tmp : 8;
1036 -
1037 - mtdcr(DCRN_CPR0_ADDR, CPR0_SCPID);
1038 - reg = mfdcr(DCRN_CPR0_DATA);
1039 - tmp = (reg & 0x03000000) >> 24;
1040 - spcid0 = tmp ? tmp : 4;
1041 -
1042 - /* Calculate M */
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);
1055 +
1056 + if (sys0 & CPC0_SYS0_BYPASS) {
1057 + /* Bypass system PLL */
1058 + cpu = plb = sys_clk;
1059 + } else {
1060 + if (sys0 & CPC0_SYS0_EXTSL)
1061 + /* PerClk */
1062 + m = CPC0_SYS0_FWDVB(sys0) * opdv * epdv;
1063 else
1064 - m = fbdv * lfbdv * fwdvb;
1065 + /* CPU clock */
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);
1069 }
1070 - else if (tmp == 1) /* CPU output */
1071 - m = fbdv * fwdva;
1072 +
1073 + opb = plb / opdv;
1074 + ebc = opb / epdv;
1075 +
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 */
1079 + tb = sys_clk;
1080 else
1081 - m = perdv0 * opbdv0 * fwdvb;
1082 + /* Rev. C 440GP, errata force us to use internal clock */
1083 + tb = cpu;
1084
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 */
1092 + uart0 = ser_clk;
1093 + else
1094 + /* Internal UART clock */
1095 + uart0 = plb / CPC0_CR0_UDIV(cr0);
1096
1097 - /* FIXME */
1098 - uart0 = ser_clk;
1099 + if (cr0 & CPC0_CR0_U1EC)
1100 + /* External UART clock */
1101 + uart1 = ser_clk;
1102 + else
1103 + /* Internal UART clock */
1104 + uart1 = plb / CPC0_CR0_UDIV(cr0);
1105 +
1106 + printf("PPC440GP: SysClk = %dMHz (%x)\n\r",
1107 + (sys_clk + 500000) / 1000000, sys_clk);
1108 +
1109 + dt_fixup_cpu_clocks(cpu, tb, 0);
1110 +
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);
1116 +}
1117 +
1118 +#define SPRN_CCR1 0x378
1119 +
1120 +static inline u32 __fix_zero(u32 v, u32 def)
1121 +{
1122 + return v ? v : def;
1123 +}
1124 +
1125 +static unsigned int __ibm440eplike_fixup_clocks(unsigned int sys_clk,
1126 + unsigned int tmr_clk,
1127 + int per_clk_from_opb)
1128 +{
1129 + /* PLL config */
1130 + u32 pllc = CPR0_READ(DCRN_CPR0_PLLC);
1131 + u32 plld = CPR0_READ(DCRN_CPR0_PLLD);
1132 +
1133 + /* Dividers */
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);
1142 +
1143 + /* Input clocks for primary dividers */
1144 + u32 clk_a, clk_b;
1145 +
1146 + /* Resulting clocks */
1147 + u32 cpu, plb, opb, ebc, vco;
1148 +
1149 + /* Timebase */
1150 + u32 ccr1, tb = tmr_clk;
1151 +
1152 + if (pllc & 0x40000000) {
1153 + u32 m;
1154 +
1155 + /* Feedback path */
1156 + switch ((pllc >> 24) & 7) {
1157 + case 0:
1158 + /* PLLOUTx */
1159 + m = ((pllc & 0x20000000) ? fwdvb : fwdva) * lfbdv;
1160 + break;
1161 + case 1:
1162 + /* CPU */
1163 + m = fwdva * pradv0;
1164 + break;
1165 + case 5:
1166 + /* PERClk */
1167 + m = fwdvb * prbdv0 * opbdv0 * perdv0;
1168 + break;
1169 + default:
1170 + printf("WARNING ! Invalid PLL feedback source !\n");
1171 + goto bypass;
1172 + }
1173 + m *= fbdv;
1174 + vco = sys_clk * m;
1175 + clk_a = vco / fwdva;
1176 + clk_b = vco / fwdvb;
1177 + } else {
1178 +bypass:
1179 + /* Bypass system PLL */
1180 + vco = 0;
1181 + clk_a = clk_b = sys_clk;
1182 + }
1183 +
1184 + cpu = clk_a / pradv0;
1185 + plb = clk_b / prbdv0;
1186 + opb = plb / opbdv0;
1187 + ebc = (per_clk_from_opb ? opb : plb) / perdv0;
1188
1189 /* Figure out timebase. Either CPU or default TmrClk */
1190 - asm volatile (
1191 - "mfspr %0,%1\n"
1192 - :
1193 - "=&r"(reg) : "i"(SPRN_CCR1));
1194 - if (reg & 0x0080)
1195 - tb = 25000000; /* TmrClk is 25MHz */
1196 - else
1197 + ccr1 = mfspr(SPRN_CCR1);
1198 +
1199 + /* If passed a 0 tmr_clk, force CPU clock */
1200 + if (tb == 0) {
1201 + ccr1 &= ~0x80u;
1202 + mtspr(SPRN_CCR1, ccr1);
1203 + }
1204 + if ((ccr1 & 0x0080) == 0)
1205 tb = cpu;
1206
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);
1211 +
1212 + return plb;
1213 +}
1214 +
1215 +static void eplike_fixup_uart_clk(int index, const char *path,
1216 + unsigned int ser_clk,
1217 + unsigned int plb_clk)
1218 +{
1219 + unsigned int sdr;
1220 + unsigned int clock;
1221 +
1222 + switch (index) {
1223 + case 0:
1224 + sdr = SDR0_READ(DCRN_SDR0_UART0);
1225 + break;
1226 + case 1:
1227 + sdr = SDR0_READ(DCRN_SDR0_UART1);
1228 + break;
1229 + case 2:
1230 + sdr = SDR0_READ(DCRN_SDR0_UART2);
1231 + break;
1232 + case 3:
1233 + sdr = SDR0_READ(DCRN_SDR0_UART3);
1234 + break;
1235 + default:
1236 + return;
1237 + }
1238 +
1239 + if (sdr & 0x00800000u)
1240 + clock = ser_clk;
1241 + else
1242 + clock = plb_clk / __fix_zero(sdr & 0xff, 256);
1243 +
1244 + dt_fixup_clock(path, clock);
1245 +}
1246 +
1247 +void ibm440ep_fixup_clocks(unsigned int sys_clk,
1248 + unsigned int ser_clk,
1249 + unsigned int tmr_clk)
1250 +{
1251 + unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 0);
1252 +
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);
1258 +}
1259 +
1260 +void ibm440gx_fixup_clocks(unsigned int sys_clk,
1261 + unsigned int ser_clk,
1262 + unsigned int tmr_clk)
1263 +{
1264 + unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1);
1265 +
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);
1269 +}
1270 +
1271 +void ibm440spe_fixup_clocks(unsigned int sys_clk,
1272 + unsigned int ser_clk,
1273 + unsigned int tmr_clk)
1274 +{
1275 + unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1);
1276 +
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);
1281 +}
1282 +
1283 +void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk)
1284 +{
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;
1291 +
1292 + fwdv = (8 - ((pllmr & 0xe0000000) >> 29));
1293 + fbdv = (pllmr & 0x1e000000) >> 25;
1294 + if (fbdv == 0)
1295 + fbdv = 16;
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;
1301 +
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;
1308 + else
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;
1313 + else
1314 + m = fbdv * fwdv;
1315 + else if (epdv == fbdv)
1316 + m = fbdv * cbdv * epdv;
1317 + else
1318 + m = fbdv * fwdvb * cbdv;
1319 +
1320 + cpu = sys_clk * m / fwdv;
1321 + plb = sys_clk * m / (fwdvb * cbdv);
1322 + } else {
1323 + m = fwdv * fbdv * cbdv;
1324 + cpu = sys_clk * m / fwdv;
1325 + plb = cpu / cbdv;
1326 + }
1327 + opb = plb / opdv;
1328 + ebc = plb / epdv;
1329 +
1330 + if (cpc0_cr0 & 0x80)
1331 + /* uart0 uses the external clock */
1332 + uart0 = ser_clk;
1333 + else
1334 + uart0 = cpu / udiv;
1335 +
1336 + if (cpc0_cr0 & 0x40)
1337 + /* uart1 uses the external clock */
1338 + uart1 = ser_clk;
1339 + else
1340 + uart1 = cpu / udiv;
1341 +
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);
1345 + tb = cpu;
1346 +
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);
1353 +}
1354 +
1355 +
1356 +void ibm405ep_fixup_clocks(unsigned int sys_clk)
1357 +{
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;
1364 +
1365 + fwdva = 8 - ((pllmr1 & 0x00070000) >> 16);
1366 + fwdvb = 8 - ((pllmr1 & 0x00007000) >> 12);
1367 + fbdv = (pllmr1 & 0x00f00000) >> 20;
1368 + if (fbdv == 0)
1369 + fbdv = 16;
1370 +
1371 + cbdv = ((pllmr0 & 0x00030000) >> 16) + 1; /* CPU:PLB */
1372 + epdv = ((pllmr0 & 0x00000300) >> 8) + 2; /* PLB:EBC */
1373 + opdv = ((pllmr0 & 0x00003000) >> 12) + 1; /* PLB:OPB */
1374 +
1375 + m = fbdv * fwdvb;
1376 +
1377 + pllmr0_ccdv = ((pllmr0 & 0x00300000) >> 20) + 1;
1378 + if (pllmr1 & 0x80000000)
1379 + cpu = sys_clk * m / (fwdva * pllmr0_ccdv);
1380 + else
1381 + cpu = sys_clk / pllmr0_ccdv;
1382 +
1383 + plb = cpu / cbdv;
1384 + opb = plb / opdv;
1385 + ebc = plb / epdv;
1386 + tb = cpu;
1387 + uart0 = cpu / (cpc0_ucr & 0x0000007f);
1388 + uart1 = cpu / ((cpc0_ucr & 0x00007f00) >> 8);
1389 +
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);
1399 }
1400 --- a/arch/powerpc/boot/4xx.h
1401 +++ b/arch/powerpc/boot/4xx.h
1402 @@ -11,12 +11,22 @@
1403 #ifndef _POWERPC_BOOT_4XX_H_
1404 #define _POWERPC_BOOT_4XX_H_
1405
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);
1415 +
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);
1425
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
1431 endif
1432
1433 -BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj)
1434 +BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) -I$(srctree)/$(src)/libfdt
1435
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
1441
1442 +
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))
1449
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 \
1467 + cuboot-warp.c
1468 src-boot := $(src-wlib) $(src-plat) empty.c
1469
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 $@.$$$$ $@
1473
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)
1480
1481 $(obj)/wrapper.a: $(obj-wlib) FORCE
1482 $(call if_changed,bootar)
1483
1484 -hostprogs-y := addnote addRamDisk hack-coff mktree
1485 +hostprogs-y := addnote addRamDisk hack-coff mktree dtc
1486
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
1490
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) \
1494 $(wrapper) FORCE
1495
1496 #############
1497 +# Bits for building dtc
1498 +# DTC_GENPARSER := 1 # Uncomment to rebuild flex/bison output
1499 +
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))
1503 +
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
1507 +
1508 +HOSTCFLAGS += -I$(src)/dtc-src/ -I$(src)/libfdt/
1509 +
1510 +targets += dtc-src/dtc-parser.tab.c
1511 +targets += dtc-src/dtc-lexer.lex.c
1512 +
1513 +ifdef DTC_GENPARSER
1514 +BISON = bison
1515 +FLEX = flex
1516 +
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
1521 +
1522 +$(obj)/dtc-src/dtc-parser.tab.c: $(src)/dtc-src/dtc-parser.y FORCE
1523 + $(call if_changed,bison)
1524 +
1525 +$(obj)/dtc-src/dtc-parser.tab.h: $(obj)/dtc-src/dtc-parser.tab.c
1526 +
1527 +$(obj)/dtc-src/dtc-lexer.lex.c: $(src)/dtc-src/dtc-lexer.l FORCE
1528 + $(call if_changed,flex)
1529 +endif
1530 +
1531 +#############
1532 # Bits for building various flavours of zImage
1533
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
1555 +endif
1556 +
1557 +ifneq ($(CONFIG_REDBOOT),"")
1558 +image-$(CONFIG_PPC_8xx) += zImage.redboot-8xx
1559 endif
1560
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))
1566 +
1567 +WRAPPER_OBJDIR := /usr/lib/kernel-wrapper
1568 +WRAPPER_DTSDIR := /usr/lib/kernel-wrapper/dts
1569 +WRAPPER_BINDIR := /usr/sbin
1570 +INSTALL := install
1571 +
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))
1576 +
1577 +all-installed := $(extra-installed) $(hostprogs-installed) $(wrapper-installed) $(dts-installed)
1578 +
1579 +quiet_cmd_mkdir = MKDIR $(patsubst $(INSTALL_HDR_PATH)/%,%,$@)
1580 + cmd_mkdir = mkdir -p $@
1581 +
1582 +quiet_cmd_install = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_OBJDIR)/%,%,$@)
1583 + cmd_install = $(INSTALL) -m0644 $(patsubst $(DESTDIR)$(WRAPPER_OBJDIR)/%,$(obj)/%,$@) $@
1584 +
1585 +quiet_cmd_install_dts = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_DTSDIR)/%,dts/%,$@)
1586 + cmd_install_dts = $(INSTALL) -m0644 $(patsubst $(DESTDIR)$(WRAPPER_DTSDIR)/%,$(srctree)/$(obj)/dts/%,$@) $@
1587 +
1588 +quiet_cmd_install_exe = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,%,$@)
1589 + cmd_install_exe = $(INSTALL) -m0755 $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,$(obj)/%,$@) $@
1590 +
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)%' \
1595 +
1596 +
1597 +$(DESTDIR)$(WRAPPER_OBJDIR) $(DESTDIR)$(WRAPPER_DTSDIR) $(DESTDIR)$(WRAPPER_BINDIR):
1598 + $(call cmd,mkdir)
1599 +
1600 +$(extra-installed) : $(DESTDIR)$(WRAPPER_OBJDIR)/% : $(obj)/% | $(DESTDIR)$(WRAPPER_OBJDIR)
1601 + $(call cmd,install)
1602 +
1603 +$(hostprogs-installed) : $(DESTDIR)$(WRAPPER_BINDIR)/% : $(obj)/% | $(DESTDIR)$(WRAPPER_BINDIR)
1604 + $(call cmd,install_exe)
1605 +
1606 +$(dts-installed) : $(DESTDIR)$(WRAPPER_DTSDIR)/% : $(srctree)/$(obj)/dts/% | $(DESTDIR)$(WRAPPER_DTSDIR)
1607 + $(call cmd,install_dts)
1608 +
1609 +$(wrapper-installed): $(DESTDIR)$(WRAPPER_BINDIR) $(srctree)/$(obj)/wrapper | $(DESTDIR)$(WRAPPER_BINDIR)
1610 + $(call cmd,install_wrapper)
1611 +
1612 +$(obj)/bootwrapper_install: $(all-installed)
1613 +
1614 --- a/arch/powerpc/boot/bamboo.c
1615 +++ b/arch/powerpc/boot/bamboo.c
1616 @@ -30,8 +30,8 @@ static void bamboo_fixups(void)
1617 {
1618 unsigned long sysclk = 33333333;
1619
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);
1626 }
1627 @@ -42,6 +42,6 @@ void bamboo_init(void *mac0, void *mac1)
1628 platform_ops.exit = ibm44x_dbcr_reset;
1629 bamboo_mac0 = mac0;
1630 bamboo_mac1 = mac1;
1631 - ft_init(_dtb_start, 0, 32);
1632 + fdt_init(_dtb_start);
1633 serial_console_init();
1634 }
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)
1639 {
1640 CUBOOT_INIT();
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;
1645 }
1646 --- /dev/null
1647 +++ b/arch/powerpc/boot/cuboot-824x.c
1648 @@ -0,0 +1,53 @@
1649 +/*
1650 + * Old U-boot compatibility for 824x
1651 + *
1652 + * Copyright (c) 2007 Freescale Semiconductor, Inc.
1653 + *
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.
1657 + */
1658 +
1659 +#include "ops.h"
1660 +#include "stdio.h"
1661 +#include "cuboot.h"
1662 +
1663 +#define TARGET_824x
1664 +#include "ppcboot.h"
1665 +
1666 +static bd_t bd;
1667 +
1668 +
1669 +static void platform_fixups(void)
1670 +{
1671 + void *soc;
1672 +
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);
1676 +
1677 + soc = find_node_by_devtype(NULL, "soc");
1678 + if (soc) {
1679 + void *serial = NULL;
1680 +
1681 + setprop(soc, "bus-frequency", &bd.bi_busfreq,
1682 + sizeof(bd.bi_busfreq));
1683 +
1684 + while ((serial = find_node_by_devtype(serial, "serial"))) {
1685 + if (get_parent(serial) != soc)
1686 + continue;
1687 +
1688 + setprop(serial, "clock-frequency", &bd.bi_busfreq,
1689 + sizeof(bd.bi_busfreq));
1690 + }
1691 + }
1692 +}
1693 +
1694 +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
1695 + unsigned long r6, unsigned long r7)
1696 +{
1697 + CUBOOT_INIT();
1698 + fdt_init(_dtb_start);
1699 + serial_console_init();
1700 + platform_ops.fixups = platform_fixups;
1701 +}
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)
1705 void *soc;
1706
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);
1712
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)
1716 {
1717 CUBOOT_INIT();
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;
1722 }
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)
1726 void *soc;
1727
1728 dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
1729 - dt_fixup_mac_addresses(bd.bi_enetaddr, bd.bi_enet1addr,
1730 - bd.bi_enet2addr);
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);
1735
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)
1739 {
1740 CUBOOT_INIT();
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;
1745 }
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)
1750 {
1751 CUBOOT_INIT();
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;
1756 }
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)
1761 {
1762 CUBOOT_INIT();
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;
1767 }
1768 --- /dev/null
1769 +++ b/arch/powerpc/boot/cuboot-katmai.c
1770 @@ -0,0 +1,56 @@
1771 +/*
1772 + * Old U-boot compatibility for Katmai
1773 + *
1774 + * Author: Hugh Blemings <hugh@au.ibm.com>
1775 + *
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.
1781 + *
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.
1785 + */
1786 +
1787 +#include "ops.h"
1788 +#include "stdio.h"
1789 +#include "reg.h"
1790 +#include "dcr.h"
1791 +#include "4xx.h"
1792 +#include "44x.h"
1793 +#include "cuboot.h"
1794 +
1795 +#define TARGET_44x
1796 +#include "ppcboot.h"
1797 +
1798 +static bd_t bd;
1799 +
1800 +BSS_STACK(4096);
1801 +
1802 +static void katmai_fixups(void)
1803 +{
1804 + unsigned long sysclk = 33333000;
1805 +
1806 + /* 440SP Clock logic is all but identical to 440GX
1807 + * so we just use that code for now at least
1808 + */
1809 + ibm440spe_fixup_clocks(sysclk, 6 * 1843200, 0);
1810 +
1811 + ibm440spe_fixup_memsize();
1812 +
1813 + dt_fixup_mac_address(0, bd.bi_enetaddr);
1814 +
1815 + ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
1816 +}
1817 +
1818 +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
1819 + unsigned long r6, unsigned long r7)
1820 +{
1821 + CUBOOT_INIT();
1822 +
1823 + platform_ops.fixups = katmai_fixups;
1824 + fdt_init(_dtb_start);
1825 + serial_console_init();
1826 +}
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)
1831 {
1832 CUBOOT_INIT();
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;
1837 }
1838 --- /dev/null
1839 +++ b/arch/powerpc/boot/cuboot-rainier.c
1840 @@ -0,0 +1,56 @@
1841 +/*
1842 + * Old U-boot compatibility for Rainier
1843 + *
1844 + * Valentine Barshak <vbarshak@ru.mvista.com>
1845 + * Copyright 2007 MontaVista Software, Inc
1846 + *
1847 + * Based on Ebony code by David Gibson <david@gibson.dropbear.id.au>
1848 + * Copyright IBM Corporation, 2007
1849 + *
1850 + * Based on Bamboo code by Josh Boyer <jwboyer@linux.vnet.ibm.com>
1851 + * Copyright IBM Corporation, 2007
1852 + *
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
1856 + */
1857 +
1858 +#include <stdarg.h>
1859 +#include <stddef.h>
1860 +#include "types.h"
1861 +#include "elf.h"
1862 +#include "string.h"
1863 +#include "stdio.h"
1864 +#include "page.h"
1865 +#include "ops.h"
1866 +#include "dcr.h"
1867 +#include "4xx.h"
1868 +#include "44x.h"
1869 +#include "cuboot.h"
1870 +
1871 +#define TARGET_4xx
1872 +#define TARGET_44x
1873 +#include "ppcboot.h"
1874 +
1875 +static bd_t bd;
1876 +
1877 +
1878 +static void rainier_fixups(void)
1879 +{
1880 + unsigned long sysclk = 33333333;
1881 +
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);
1886 +}
1887 +
1888 +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
1889 + unsigned long r6, unsigned long r7)
1890 +{
1891 + CUBOOT_INIT();
1892 + platform_ops.fixups = rainier_fixups;
1893 + platform_ops.exit = ibm44x_dbcr_reset;
1894 + fdt_init(_dtb_start);
1895 + serial_console_init();
1896 +}
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)
1900 {
1901 unsigned long sysclk = 33333333;
1902
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
1909 CUBOOT_INIT();
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();
1915 }
1916 --- /dev/null
1917 +++ b/arch/powerpc/boot/cuboot-taishan.c
1918 @@ -0,0 +1,54 @@
1919 +/*
1920 + * Old U-boot compatibility for Taishan
1921 + *
1922 + * Author: Hugh Blemings <hugh@au.ibm.com>
1923 + *
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.
1929 + *
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.
1933 + */
1934 +
1935 +#include "ops.h"
1936 +#include "stdio.h"
1937 +#include "cuboot.h"
1938 +#include "reg.h"
1939 +#include "dcr.h"
1940 +#include "4xx.h"
1941 +
1942 +#define TARGET_44x
1943 +#include "ppcboot.h"
1944 +
1945 +static bd_t bd;
1946 +
1947 +BSS_STACK(4096);
1948 +
1949 +static void taishan_fixups(void)
1950 +{
1951 + /* FIXME: sysclk should be derived by reading the FPGA
1952 + registers */
1953 + unsigned long sysclk = 33000000;
1954 +
1955 + ibm440gx_fixup_clocks(sysclk, 6 * 1843200, 25000000);
1956 +
1957 + ibm4xx_sdram_fixup_memsize();
1958 +
1959 + dt_fixup_mac_addresses(bd.bi_enetaddr, bd.bi_enet1addr);
1960 +
1961 + ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
1962 +}
1963 +
1964 +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
1965 + unsigned long r6, unsigned long r7)
1966 +{
1967 + CUBOOT_INIT();
1968 +
1969 + platform_ops.fixups = taishan_fixups;
1970 + fdt_init(_dtb_start);
1971 + serial_console_init();
1972 +}
1973 --- /dev/null
1974 +++ b/arch/powerpc/boot/cuboot-warp.c
1975 @@ -0,0 +1,39 @@
1976 +/*
1977 + * Copyright (c) 2008 PIKA Technologies
1978 + * Sean MacLennan <smaclennan@pikatech.com>
1979 + *
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.
1983 + */
1984 +
1985 +#include "ops.h"
1986 +#include "4xx.h"
1987 +#include "cuboot.h"
1988 +
1989 +#define TARGET_44x
1990 +#include "ppcboot.h"
1991 +
1992 +static bd_t bd;
1993 +
1994 +static void warp_fixups(void)
1995 +{
1996 + unsigned long sysclk = 66000000;
1997 +
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);
2002 +}
2003 +
2004 +
2005 +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
2006 + unsigned long r6, unsigned long r7)
2007 +{
2008 + CUBOOT_INIT();
2009 +
2010 + platform_ops.fixups = warp_fixups;
2011 + platform_ops.exit = ibm44x_dbcr_reset;
2012 + fdt_init(_dtb_start);
2013 + serial_console_init();
2014 +}
2015 --- a/arch/powerpc/boot/dcr.h
2016 +++ b/arch/powerpc/boot/dcr.h
2017 @@ -14,12 +14,20 @@
2018 #define DCRN_SDRAM0_CFGADDR 0x010
2019 #define DCRN_SDRAM0_CFGDATA 0x011
2020
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); })
2027 +
2028 #define SDRAM0_B0CR 0x40
2029 #define SDRAM0_B1CR 0x44
2030 #define SDRAM0_B2CR 0x48
2031 #define SDRAM0_B3CR 0x4c
2032
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 };
2036
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
2044 +
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
2049 +
2050 +/* 440GX Clock control etc */
2051 +
2052 +
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
2061 +
2062 +#define DCRN_SDR0_CONFIG_ADDR 0xe
2063 +#define DCRN_SDR0_CONFIG_DATA 0xf
2064 +
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); })
2072 +
2073 +#define DCRN_SDR0_UART0 0x0120
2074 +#define DCRN_SDR0_UART1 0x0121
2075 +#define DCRN_SDR0_UART2 0x0122
2076 +#define DCRN_SDR0_UART3 0x0123
2077 +
2078 +
2079 +/* CPRs read/write helper macros - based off include/asm-ppc/ibm44x.h */
2080 +
2081 +#define DCRN_CPR0_CFGADDR 0xc
2082 +#define DCRN_CPR0_CFGDATA 0xd
2083 +
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); })
2090 +
2091 +
2092
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
2097 }
2098 }
2099
2100 +void dt_fixup_mac_address_by_alias(const char *alias, const u8 *addr)
2101 +{
2102 + void *devp = find_node_by_alias(alias);
2103 +
2104 + if (devp) {
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]);
2109 +
2110 + setprop(devp, "local-mac-address", addr, 6);
2111 + }
2112 +}
2113 +
2114 void dt_fixup_mac_address(u32 index, const u8 *addr)
2115 {
2116 void *devp = find_node_by_prop_value(NULL, "linux,network-index",
2117 --- /dev/null
2118 +++ b/arch/powerpc/boot/dtc-src/Makefile.dtc
2119 @@ -0,0 +1,25 @@
2120 +# Makefile.dtc
2121 +#
2122 +# This is not a complete Makefile of itself. Instead, it is designed to
2123 +# be easily embeddable into other systems of Makefiles.
2124 +#
2125 +DTC_SRCS = dtc.c flattree.c fstree.c data.c livetree.c treesource.c srcpos.c \
2126 + checks.c
2127 +DTC_EXTRA = dtc.h srcpos.h
2128 +DTC_LEXFILES = dtc-lexer.l
2129 +DTC_BISONFILES = dtc-parser.y
2130 +
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)
2134 +
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)
2138 +
2139 +DTC_CLEANFILES = $(DTC_GEN_ALL)
2140 +
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
2143 +
2144 +$(addprefix $(DTC_objdir)/,$(DTC_GEN_SRCS:%.c=%.o)): $(addprefix $(DTC_objdir)/,$(DTC_BISON_INCLUDES))
2145 --- /dev/null
2146 +++ b/arch/powerpc/boot/dtc-src/checks.c
2147 @@ -0,0 +1,750 @@
2148 +/*
2149 + * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2007.
2150 + *
2151 + *
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.
2156 + *
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.
2161 + *
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
2165 + * USA
2166 + */
2167 +
2168 +#include "dtc.h"
2169 +
2170 +#ifdef TRACE_CHECKS
2171 +#define TRACE(c, ...) \
2172 + do { \
2173 + fprintf(stderr, "=== %s: ", (c)->name); \
2174 + fprintf(stderr, __VA_ARGS__); \
2175 + fprintf(stderr, "\n"); \
2176 + } while (0)
2177 +#else
2178 +#define TRACE(c, fmt, ...) do { } while (0)
2179 +#endif
2180 +
2181 +enum checklevel {
2182 + IGNORE = 0,
2183 + WARN = 1,
2184 + ERROR = 2,
2185 +};
2186 +
2187 +enum checkstatus {
2188 + UNCHECKED = 0,
2189 + PREREQ,
2190 + PASSED,
2191 + FAILED,
2192 +};
2193 +
2194 +struct check;
2195 +
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);
2200 +
2201 +struct check {
2202 + const char *name;
2203 + tree_check_fn tree_fn;
2204 + node_check_fn node_fn;
2205 + prop_check_fn prop_fn;
2206 + void *data;
2207 + enum checklevel level;
2208 + enum checkstatus status;
2209 + int inprogress;
2210 + int num_prereqs;
2211 + struct check **prereq;
2212 +};
2213 +
2214 +#define CHECK(nm, tfn, nfn, pfn, d, lvl, ...) \
2215 + static struct check *nm##_prereqs[] = { __VA_ARGS__ }; \
2216 + static struct check nm = { \
2217 + .name = #nm, \
2218 + .tree_fn = (tfn), \
2219 + .node_fn = (nfn), \
2220 + .prop_fn = (pfn), \
2221 + .data = (d), \
2222 + .level = (lvl), \
2223 + .status = UNCHECKED, \
2224 + .num_prereqs = ARRAY_SIZE(nm##_prereqs), \
2225 + .prereq = nm##_prereqs, \
2226 + };
2227 +
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__)
2236 +
2237 +#ifdef __GNUC__
2238 +static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
2239 +#endif
2240 +static inline void check_msg(struct check *c, const char *fmt, ...)
2241 +{
2242 + va_list ap;
2243 + va_start(ap, fmt);
2244 +
2245 + if ((c->level < WARN) || (c->level <= quiet))
2246 + return; /* Suppress message */
2247 +
2248 + fprintf(stderr, "%s (%s): ",
2249 + (c->level == ERROR) ? "ERROR" : "Warning", c->name);
2250 + vfprintf(stderr, fmt, ap);
2251 + fprintf(stderr, "\n");
2252 +}
2253 +
2254 +#define FAIL(c, ...) \
2255 + do { \
2256 + TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \
2257 + (c)->status = FAILED; \
2258 + check_msg((c), __VA_ARGS__); \
2259 + } while (0)
2260 +
2261 +static void check_nodes_props(struct check *c, struct node *dt, struct node *node)
2262 +{
2263 + struct node *child;
2264 + struct property *prop;
2265 +
2266 + TRACE(c, "%s", node->fullpath);
2267 + if (c->node_fn)
2268 + c->node_fn(c, dt, node);
2269 +
2270 + if (c->prop_fn)
2271 + for_each_property(node, prop) {
2272 + TRACE(c, "%s\t'%s'", node->fullpath, prop->name);
2273 + c->prop_fn(c, dt, node, prop);
2274 + }
2275 +
2276 + for_each_child(node, child)
2277 + check_nodes_props(c, dt, child);
2278 +}
2279 +
2280 +static int run_check(struct check *c, struct node *dt)
2281 +{
2282 + int error = 0;
2283 + int i;
2284 +
2285 + assert(!c->inprogress);
2286 +
2287 + if (c->status != UNCHECKED)
2288 + goto out;
2289 +
2290 + c->inprogress = 1;
2291 +
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);
2299 + }
2300 + }
2301 +
2302 + if (c->status != UNCHECKED)
2303 + goto out;
2304 +
2305 + if (c->node_fn || c->prop_fn)
2306 + check_nodes_props(c, dt, dt);
2307 +
2308 + if (c->tree_fn)
2309 + c->tree_fn(c, dt);
2310 + if (c->status == UNCHECKED)
2311 + c->status = PASSED;
2312 +
2313 + TRACE(c, "\tCompleted, status %d", c->status);
2314 +
2315 +out:
2316 + c->inprogress = 0;
2317 + if ((c->status != PASSED) && (c->level == ERROR))
2318 + error = 1;
2319 + return error;
2320 +}
2321 +
2322 +/*
2323 + * Utility check functions
2324 + */
2325 +
2326 +static void check_is_string(struct check *c, struct node *root,
2327 + struct node *node)
2328 +{
2329 + struct property *prop;
2330 + char *propname = c->data;
2331 +
2332 + prop = get_property(node, propname);
2333 + if (!prop)
2334 + return; /* Not present, assumed ok */
2335 +
2336 + if (!data_is_one_string(prop->val))
2337 + FAIL(c, "\"%s\" property in %s is not a string",
2338 + propname, node->fullpath);
2339 +}
2340 +#define CHECK_IS_STRING(nm, propname, lvl) \
2341 + CHECK(nm, NULL, check_is_string, NULL, (propname), (lvl))
2342 +
2343 +static void check_is_cell(struct check *c, struct node *root,
2344 + struct node *node)
2345 +{
2346 + struct property *prop;
2347 + char *propname = c->data;
2348 +
2349 + prop = get_property(node, propname);
2350 + if (!prop)
2351 + return; /* Not present, assumed ok */
2352 +
2353 + if (prop->val.len != sizeof(cell_t))
2354 + FAIL(c, "\"%s\" property in %s is not a single cell",
2355 + propname, node->fullpath);
2356 +}
2357 +#define CHECK_IS_CELL(nm, propname, lvl) \
2358 + CHECK(nm, NULL, check_is_cell, NULL, (propname), (lvl))
2359 +
2360 +/*
2361 + * Structural check functions
2362 + */
2363 +
2364 +static void check_duplicate_node_names(struct check *c, struct node *dt,
2365 + struct node *node)
2366 +{
2367 + struct node *child, *child2;
2368 +
2369 + for_each_child(node, child)
2370 + for (child2 = child->next_sibling;
2371 + child2;
2372 + child2 = child2->next_sibling)
2373 + if (streq(child->name, child2->name))
2374 + FAIL(c, "Duplicate node name %s",
2375 + child->fullpath);
2376 +}
2377 +NODE_CHECK(duplicate_node_names, NULL, ERROR);
2378 +
2379 +static void check_duplicate_property_names(struct check *c, struct node *dt,
2380 + struct node *node)
2381 +{
2382 + struct property *prop, *prop2;
2383 +
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);
2389 +}
2390 +NODE_CHECK(duplicate_property_names, NULL, ERROR);
2391 +
2392 +static void check_explicit_phandles(struct check *c, struct node *root,
2393 + struct node *node)
2394 +{
2395 + struct property *prop;
2396 + struct node *other;
2397 + cell_t phandle;
2398 +
2399 + prop = get_property(node, "linux,phandle");
2400 + if (! prop)
2401 + return; /* No phandle, that's fine */
2402 +
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);
2406 + return;
2407 + }
2408 +
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);
2413 + return;
2414 + }
2415 +
2416 + other = get_node_by_phandle(root, phandle);
2417 + if (other) {
2418 + FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)",
2419 + node->fullpath, phandle, other->fullpath);
2420 + return;
2421 + }
2422 +
2423 + node->phandle = phandle;
2424 +}
2425 +NODE_CHECK(explicit_phandles, NULL, ERROR);
2426 +
2427 +static void check_name_properties(struct check *c, struct node *root,
2428 + struct node *node)
2429 +{
2430 + struct property *prop;
2431 +
2432 + prop = get_property(node, "name");
2433 + if (!prop)
2434 + return; /* No name property, that's fine */
2435 +
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);
2440 +}
2441 +CHECK_IS_STRING(name_is_string, "name", ERROR);
2442 +NODE_CHECK(name_properties, NULL, ERROR, &name_is_string);
2443 +
2444 +/*
2445 + * Reference fixup functions
2446 + */
2447 +
2448 +static void fixup_phandle_references(struct check *c, struct node *dt,
2449 + struct node *node, struct property *prop)
2450 +{
2451 + struct marker *m = prop->val.markers;
2452 + struct node *refnode;
2453 + cell_t phandle;
2454 +
2455 + for_each_marker_of_type(m, REF_PHANDLE) {
2456 + assert(m->offset + sizeof(cell_t) <= prop->val.len);
2457 +
2458 + refnode = get_node_by_ref(dt, m->ref);
2459 + if (! refnode) {
2460 + FAIL(c, "Reference to non-existent node or label \"%s\"\n",
2461 + m->ref);
2462 + continue;
2463 + }
2464 +
2465 + phandle = get_node_phandle(dt, refnode);
2466 + *((cell_t *)(prop->val.val + m->offset)) = cpu_to_be32(phandle);
2467 + }
2468 +}
2469 +CHECK(phandle_references, NULL, NULL, fixup_phandle_references, NULL, ERROR,
2470 + &duplicate_node_names, &explicit_phandles);
2471 +
2472 +static void fixup_path_references(struct check *c, struct node *dt,
2473 + struct node *node, struct property *prop)
2474 +{
2475 + struct marker *m = prop->val.markers;
2476 + struct node *refnode;
2477 + char *path;
2478 +
2479 + for_each_marker_of_type(m, REF_PATH) {
2480 + assert(m->offset <= prop->val.len);
2481 +
2482 + refnode = get_node_by_ref(dt, m->ref);
2483 + if (!refnode) {
2484 + FAIL(c, "Reference to non-existent node or label \"%s\"\n",
2485 + m->ref);
2486 + continue;
2487 + }
2488 +
2489 + path = refnode->fullpath;
2490 + prop->val = data_insert_at_marker(prop->val, m, path,
2491 + strlen(path) + 1);
2492 + }
2493 +}
2494 +CHECK(path_references, NULL, NULL, fixup_path_references, NULL, ERROR,
2495 + &duplicate_node_names);
2496 +
2497 +/*
2498 + * Semantic checks
2499 + */
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);
2503 +
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);
2507 +
2508 +static void fixup_addr_size_cells(struct check *c, struct node *dt,
2509 + struct node *node)
2510 +{
2511 + struct property *prop;
2512 +
2513 + node->addr_cells = -1;
2514 + node->size_cells = -1;
2515 +
2516 + prop = get_property(node, "#address-cells");
2517 + if (prop)
2518 + node->addr_cells = propval_cell(prop);
2519 +
2520 + prop = get_property(node, "#size-cells");
2521 + if (prop)
2522 + node->size_cells = propval_cell(prop);
2523 +}
2524 +CHECK(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL, WARN,
2525 + &address_cells_is_cell, &size_cells_is_cell);
2526 +
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)
2531 +
2532 +static void check_reg_format(struct check *c, struct node *dt,
2533 + struct node *node)
2534 +{
2535 + struct property *prop;
2536 + int addr_cells, size_cells, entrylen;
2537 +
2538 + prop = get_property(node, "reg");
2539 + if (!prop)
2540 + return; /* No "reg", that's fine */
2541 +
2542 + if (!node->parent) {
2543 + FAIL(c, "Root node has a \"reg\" property");
2544 + return;
2545 + }
2546 +
2547 + if (prop->val.len == 0)
2548 + FAIL(c, "\"reg\" property in %s is empty", node->fullpath);
2549 +
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);
2553 +
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);
2558 +}
2559 +NODE_CHECK(reg_format, NULL, WARN, &addr_size_cells);
2560 +
2561 +static void check_ranges_format(struct check *c, struct node *dt,
2562 + struct node *node)
2563 +{
2564 + struct property *prop;
2565 + int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen;
2566 +
2567 + prop = get_property(node, "ranges");
2568 + if (!prop)
2569 + return;
2570 +
2571 + if (!node->parent) {
2572 + FAIL(c, "Root node has a \"ranges\" property");
2573 + return;
2574 + }
2575 +
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);
2581 +
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,
2587 + p_addr_cells);
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,
2592 + p_size_cells);
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);
2598 + }
2599 +}
2600 +NODE_CHECK(ranges_format, NULL, WARN, &addr_size_cells);
2601 +
2602 +/*
2603 + * Style checks
2604 + */
2605 +static void check_avoid_default_addr_size(struct check *c, struct node *dt,
2606 + struct node *node)
2607 +{
2608 + struct property *reg, *ranges;
2609 +
2610 + if (!node->parent)
2611 + return; /* Ignore root node */
2612 +
2613 + reg = get_property(node, "reg");
2614 + ranges = get_property(node, "ranges");
2615 +
2616 + if (!reg && !ranges)
2617 + return;
2618 +
2619 + if ((node->parent->addr_cells == -1))
2620 + FAIL(c, "Relying on default #address-cells value for %s",
2621 + node->fullpath);
2622 +
2623 + if ((node->parent->size_cells == -1))
2624 + FAIL(c, "Relying on default #size-cells value for %s",
2625 + node->fullpath);
2626 +}
2627 +NODE_CHECK(avoid_default_addr_size, NULL, WARN, &addr_size_cells);
2628 +
2629 +static void check_obsolete_chosen_interrupt_controller(struct check *c,
2630 + struct node *dt)
2631 +{
2632 + struct node *chosen;
2633 + struct property *prop;
2634 +
2635 + chosen = get_node_by_path(dt, "/chosen");
2636 + if (!chosen)
2637 + return;
2638 +
2639 + prop = get_property(chosen, "interrupt-controller");
2640 + if (prop)
2641 + FAIL(c, "/chosen has obsolete \"interrupt-controller\" "
2642 + "property");
2643 +}
2644 +TREE_CHECK(obsolete_chosen_interrupt_controller, NULL, WARN);
2645 +
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,
2651 +
2652 + &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
2653 + &device_type_is_string, &model_is_string, &status_is_string,
2654 +
2655 + &addr_size_cells, &reg_format, &ranges_format,
2656 +
2657 + &avoid_default_addr_size,
2658 + &obsolete_chosen_interrupt_controller,
2659 +};
2660 +
2661 +int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys);
2662 +
2663 +void process_checks(int force, struct boot_info *bi,
2664 + int checkflag, int outversion, int boot_cpuid_phys)
2665 +{
2666 + struct node *dt = bi->dt;
2667 + int i;
2668 + int error = 0;
2669 +
2670 + for (i = 0; i < ARRAY_SIZE(check_table); i++) {
2671 + struct check *c = check_table[i];
2672 +
2673 + if (c->level != IGNORE)
2674 + error = error || run_check(c, dt);
2675 + }
2676 +
2677 + if (error) {
2678 + if (!force) {
2679 + fprintf(stderr, "ERROR: Input tree has errors, aborting "
2680 + "(use -f to force output)\n");
2681 + exit(2);
2682 + } else if (quiet < 3) {
2683 + fprintf(stderr, "Warning: Input tree has errors, "
2684 + "output forced\n");
2685 + }
2686 + }
2687 +
2688 + if (checkflag) {
2689 + if (error) {
2690 + fprintf(stderr, "Warning: Skipping semantic checks due to structural errors\n");
2691 + } else {
2692 + if (!check_semantics(bi->dt, outversion,
2693 + boot_cpuid_phys))
2694 + fprintf(stderr, "Warning: Input tree has semantic errors\n");
2695 + }
2696 + }
2697 +}
2698 +
2699 +/*
2700 + * Semantic check functions
2701 + */
2702 +
2703 +#define ERRMSG(...) if (quiet < 2) fprintf(stderr, "ERROR: " __VA_ARGS__)
2704 +#define WARNMSG(...) if (quiet < 1) fprintf(stderr, "Warning: " __VA_ARGS__)
2705 +
2706 +#define DO_ERR(...) do {ERRMSG(__VA_ARGS__); ok = 0; } while (0)
2707 +
2708 +#define CHECK_HAVE(node, propname) \
2709 + do { \
2710 + if (! (prop = get_property((node), (propname)))) \
2711 + DO_ERR("Missing \"%s\" property in %s\n", (propname), \
2712 + (node)->fullpath); \
2713 + } while (0);
2714 +
2715 +#define CHECK_HAVE_WARN(node, propname) \
2716 + do { \
2717 + if (! (prop = get_property((node), (propname)))) \
2718 + WARNMSG("%s has no \"%s\" property\n", \
2719 + (node)->fullpath, (propname)); \
2720 + } while (0)
2721 +
2722 +#define CHECK_HAVE_STRING(node, propname) \
2723 + do { \
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); \
2728 + } while (0)
2729 +
2730 +#define CHECK_HAVE_STREQ(node, propname, value) \
2731 + do { \
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)); \
2737 + } while (0)
2738 +
2739 +#define CHECK_HAVE_ONECELL(node, propname) \
2740 + do { \
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); \
2744 + } while (0)
2745 +
2746 +#define CHECK_HAVE_WARN_ONECELL(node, propname) \
2747 + do { \
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); \
2751 + } while (0)
2752 +
2753 +#define CHECK_HAVE_WARN_PHANDLE(xnode, propname, root) \
2754 + do { \
2755 + struct node *ref; \
2756 + CHECK_HAVE_WARN_ONECELL((xnode), (propname)); \
2757 + if (prop) {\
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); \
2761 + } else { \
2762 + ref = get_node_by_phandle((root), propval_cell(prop)); \
2763 + if (! ref) \
2764 + DO_ERR("\"%s\" property in %s refers to non-existant phandle %x\n", (propname), (xnode)->fullpath, propval_cell(prop)); \
2765 + } \
2766 + } \
2767 + } while (0)
2768 +
2769 +#define CHECK_HAVE_WARN_STRING(node, propname) \
2770 + do { \
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); \
2775 + } while (0)
2776 +
2777 +static int check_root(struct node *root)
2778 +{
2779 + struct property *prop;
2780 + int ok = 1;
2781 +
2782 + CHECK_HAVE_STRING(root, "model");
2783 + CHECK_HAVE_WARN(root, "compatible");
2784 +
2785 + return ok;
2786 +}
2787 +
2788 +static int check_cpus(struct node *root, int outversion, int boot_cpuid_phys)
2789 +{
2790 + struct node *cpus, *cpu;
2791 + struct property *prop;
2792 + struct node *bootcpu = NULL;
2793 + int ok = 1;
2794 +
2795 + cpus = get_subnode(root, "cpus");
2796 + if (! cpus) {
2797 + ERRMSG("Missing /cpus node\n");
2798 + return 0;
2799 + }
2800 +
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);
2807 +
2808 + for_each_child(cpus, cpu) {
2809 + CHECK_HAVE_STREQ(cpu, "device_type", "cpu");
2810 +
2811 + CHECK_HAVE_ONECELL(cpu, "reg");
2812 + if (prop) {
2813 + cell_t unitnum;
2814 + char *eptr;
2815 +
2816 + unitnum = strtol(get_unitname(cpu), &eptr, 16);
2817 + if (*eptr) {
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));
2824 + }
2825 + }
2826 +
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");
2831 +
2832 + CHECK_HAVE_WARN_ONECELL(cpu, "clock-frequency");
2833 + CHECK_HAVE_WARN_ONECELL(cpu, "timebase-frequency");
2834 +
2835 + prop = get_property(cpu, "linux,boot-cpu");
2836 + if (prop) {
2837 + if (prop->val.len)
2838 + WARNMSG("\"linux,boot-cpu\" property in %s is non-empty\n",
2839 + cpu->fullpath);
2840 + if (bootcpu)
2841 + DO_ERR("Multiple boot cpus (%s and %s)\n",
2842 + bootcpu->fullpath, cpu->fullpath);
2843 + else
2844 + bootcpu = cpu;
2845 + }
2846 + }
2847 +
2848 + if (outversion < 2) {
2849 + if (! bootcpu)
2850 + WARNMSG("No cpu has \"linux,boot-cpu\" property\n");
2851 + } else {
2852 + if (bootcpu)
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");
2856 + }
2857 +
2858 + return ok;
2859 +}
2860 +
2861 +static int check_memory(struct node *root)
2862 +{
2863 + struct node *mem;
2864 + struct property *prop;
2865 + int nnodes = 0;
2866 + int ok = 1;
2867 +
2868 + for_each_child(root, mem) {
2869 + if (! strneq(mem->name, "memory", mem->basenamelen))
2870 + continue;
2871 +
2872 + nnodes++;
2873 +
2874 + CHECK_HAVE_STREQ(mem, "device_type", "memory");
2875 + CHECK_HAVE(mem, "reg");
2876 + }
2877 +
2878 + if (nnodes == 0) {
2879 + ERRMSG("No memory nodes\n");
2880 + return 0;
2881 + }
2882 +
2883 + return ok;
2884 +}
2885 +
2886 +int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys)
2887 +{
2888 + int ok = 1;
2889 +
2890 + ok = ok && check_root(dt);
2891 + ok = ok && check_cpus(dt, outversion, boot_cpuid_phys);
2892 + ok = ok && check_memory(dt);
2893 + if (! ok)
2894 + return 0;
2895 +
2896 + return 1;
2897 +}
2898 --- /dev/null
2899 +++ b/arch/powerpc/boot/dtc-src/data.c
2900 @@ -0,0 +1,321 @@
2901 +/*
2902 + * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
2903 + *
2904 + *
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.
2909 + *
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.
2914 + *
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
2918 + * USA
2919 + */
2920 +
2921 +#include "dtc.h"
2922 +
2923 +void data_free(struct data d)
2924 +{
2925 + struct marker *m, *nm;
2926 +
2927 + m = d.markers;
2928 + while (m) {
2929 + nm = m->next;
2930 + free(m->ref);
2931 + free(m);
2932 + m = nm;
2933 + }
2934 +
2935 + assert(!d.val || d.asize);
2936 +
2937 + if (d.val)
2938 + free(d.val);
2939 +}
2940 +
2941 +struct data data_grow_for(struct data d, int xlen)
2942 +{
2943 + struct data nd;
2944 + int newsize;
2945 +
2946 + /* we must start with an allocated datum */
2947 + assert(!d.val || d.asize);
2948 +
2949 + if (xlen == 0)
2950 + return d;
2951 +
2952 + nd = d;
2953 +
2954 + newsize = xlen;
2955 +
2956 + while ((d.len + xlen) > newsize)
2957 + newsize *= 2;
2958 +
2959 + nd.asize = newsize;
2960 + nd.val = xrealloc(d.val, newsize);
2961 +
2962 + assert(nd.asize >= (d.len + xlen));
2963 +
2964 + return nd;
2965 +}
2966 +
2967 +struct data data_copy_mem(const char *mem, int len)
2968 +{
2969 + struct data d;
2970 +
2971 + d = data_grow_for(empty_data, len);
2972 +
2973 + d.len = len;
2974 + memcpy(d.val, mem, len);
2975 +
2976 + return d;
2977 +}
2978 +
2979 +static char get_oct_char(const char *s, int *i)
2980 +{
2981 + char x[4];
2982 + char *endx;
2983 + long val;
2984 +
2985 + x[3] = '\0';
2986 + x[0] = s[(*i)];
2987 + if (x[0]) {
2988 + x[1] = s[(*i)+1];
2989 + if (x[1])
2990 + x[2] = s[(*i)+2];
2991 + }
2992 +
2993 + val = strtol(x, &endx, 8);
2994 + if ((endx - x) == 0)
2995 + fprintf(stderr, "Empty \\nnn escape\n");
2996 +
2997 + (*i) += endx - x;
2998 + return val;
2999 +}
3000 +
3001 +static char get_hex_char(const char *s, int *i)
3002 +{
3003 + char x[3];
3004 + char *endx;
3005 + long val;
3006 +
3007 + x[2] = '\0';
3008 + x[0] = s[(*i)];
3009 + if (x[0])
3010 + x[1] = s[(*i)+1];
3011 +
3012 + val = strtol(x, &endx, 16);
3013 + if ((endx - x) == 0)
3014 + fprintf(stderr, "Empty \\x escape\n");
3015 +
3016 + (*i) += endx - x;
3017 + return val;
3018 +}
3019 +
3020 +struct data data_copy_escape_string(const char *s, int len)
3021 +{
3022 + int i = 0;
3023 + struct data d;
3024 + char *q;
3025 +
3026 + d = data_grow_for(empty_data, strlen(s)+1);
3027 +
3028 + q = d.val;
3029 + while (i < len) {
3030 + char c = s[i++];
3031 +
3032 + if (c != '\\') {
3033 + q[d.len++] = c;
3034 + continue;
3035 + }
3036 +
3037 + c = s[i++];
3038 + assert(c);
3039 + switch (c) {
3040 + case 'a':
3041 + q[d.len++] = '\a';
3042 + break;
3043 + case 'b':
3044 + q[d.len++] = '\b';
3045 + break;
3046 + case 't':
3047 + q[d.len++] = '\t';
3048 + break;
3049 + case 'n':
3050 + q[d.len++] = '\n';
3051 + break;
3052 + case 'v':
3053 + q[d.len++] = '\v';
3054 + break;
3055 + case 'f':
3056 + q[d.len++] = '\f';
3057 + break;
3058 + case 'r':
3059 + q[d.len++] = '\r';
3060 + break;
3061 + case '0':
3062 + case '1':
3063 + case '2':
3064 + case '3':
3065 + case '4':
3066 + case '5':
3067 + case '6':
3068 + case '7':
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);
3072 + break;
3073 + case 'x':
3074 + q[d.len++] = get_hex_char(s, &i);
3075 + break;
3076 + default:
3077 + q[d.len++] = c;
3078 + }
3079 + }
3080 +
3081 + q[d.len++] = '\0';
3082 + return d;
3083 +}
3084 +
3085 +struct data data_copy_file(FILE *f, size_t len)
3086 +{
3087 + struct data d;
3088 +
3089 + d = data_grow_for(empty_data, len);
3090 +
3091 + d.len = len;
3092 + fread(d.val, len, 1, f);
3093 +
3094 + return d;
3095 +}
3096 +
3097 +struct data data_append_data(struct data d, const void *p, int len)
3098 +{
3099 + d = data_grow_for(d, len);
3100 + memcpy(d.val + d.len, p, len);
3101 + d.len += len;
3102 + return d;
3103 +}
3104 +
3105 +struct data data_insert_at_marker(struct data d, struct marker *m,
3106 + const void *p, int len)
3107 +{
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);
3111 + d.len += len;
3112 +
3113 + /* Adjust all markers after the one we're inserting at */
3114 + m = m->next;
3115 + for_each_marker(m)
3116 + m->offset += len;
3117 + return d;
3118 +}
3119 +
3120 +struct data data_append_markers(struct data d, struct marker *m)
3121 +{
3122 + struct marker **mp = &d.markers;
3123 +
3124 + /* Find the end of the markerlist */
3125 + while (*mp)
3126 + mp = &((*mp)->next);
3127 + *mp = m;
3128 + return d;
3129 +}
3130 +
3131 +struct data data_merge(struct data d1, struct data d2)
3132 +{
3133 + struct data d;
3134 + struct marker *m2 = d2.markers;
3135 +
3136 + d = data_append_markers(data_append_data(d1, d2.val, d2.len), m2);
3137 +
3138 + /* Adjust for the length of d1 */
3139 + for_each_marker(m2)
3140 + m2->offset += d1.len;
3141 +
3142 + d2.markers = NULL; /* So data_free() doesn't clobber them */
3143 + data_free(d2);
3144 +
3145 + return d;
3146 +}
3147 +
3148 +struct data data_append_cell(struct data d, cell_t word)
3149 +{
3150 + cell_t beword = cpu_to_be32(word);
3151 +
3152 + return data_append_data(d, &beword, sizeof(beword));
3153 +}
3154 +
3155 +struct data data_append_re(struct data d, const struct fdt_reserve_entry *re)
3156 +{
3157 + struct fdt_reserve_entry bere;
3158 +
3159 + bere.address = cpu_to_be64(re->address);
3160 + bere.size = cpu_to_be64(re->size);
3161 +
3162 + return data_append_data(d, &bere, sizeof(bere));
3163 +}
3164 +
3165 +struct data data_append_addr(struct data d, u64 addr)
3166 +{
3167 + u64 beaddr = cpu_to_be64(addr);
3168 +
3169 + return data_append_data(d, &beaddr, sizeof(beaddr));
3170 +}
3171 +
3172 +struct data data_append_byte(struct data d, uint8_t byte)
3173 +{
3174 + return data_append_data(d, &byte, 1);
3175 +}
3176 +
3177 +struct data data_append_zeroes(struct data d, int len)
3178 +{
3179 + d = data_grow_for(d, len);
3180 +
3181 + memset(d.val + d.len, 0, len);
3182 + d.len += len;
3183 + return d;
3184 +}
3185 +
3186 +struct data data_append_align(struct data d, int align)
3187 +{
3188 + int newlen = ALIGN(d.len, align);
3189 + return data_append_zeroes(d, newlen - d.len);
3190 +}
3191 +
3192 +struct data data_add_marker(struct data d, enum markertype type, char *ref)
3193 +{
3194 + struct marker *m;
3195 +
3196 + m = xmalloc(sizeof(*m));
3197 + m->offset = d.len;
3198 + m->type = type;
3199 + m->ref = ref;
3200 + m->next = NULL;
3201 +
3202 + return data_append_markers(d, m);
3203 +}
3204 +
3205 +int data_is_one_string(struct data d)
3206 +{
3207 + int i;
3208 + int len = d.len;
3209 +
3210 + if (len == 0)
3211 + return 0;
3212 +
3213 + for (i = 0; i < len-1; i++)
3214 + if (d.val[i] == '\0')
3215 + return 0;
3216 +
3217 + if (d.val[len-1] != '\0')
3218 + return 0;
3219 +
3220 + return 1;
3221 +}
3222 --- /dev/null
3223 +++ b/arch/powerpc/boot/dtc-src/dtc-lexer.l
3224 @@ -0,0 +1,328 @@
3225 +/*
3226 + * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
3227 + *
3228 + *
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.
3233 + *
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.
3238 + *
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
3242 + * USA
3243 + */
3244 +
3245 +%option noyywrap nounput yylineno
3246 +
3247 +%x INCLUDE
3248 +%x BYTESTRING
3249 +%x PROPNODENAME
3250 +%s V1
3251 +
3252 +PROPNODECHAR [a-zA-Z0-9,._+*#?@-]
3253 +PATHCHAR ({PROPNODECHAR}|[/])
3254 +LABEL [a-zA-Z_][a-zA-Z0-9_]*
3255 +
3256 +%{
3257 +#include "dtc.h"
3258 +#include "srcpos.h"
3259 +#include "dtc-parser.tab.h"
3260 +
3261 +
3262 +/*#define LEXDEBUG 1*/
3263 +
3264 +#ifdef LEXDEBUG
3265 +#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
3266 +#else
3267 +#define DPRINT(fmt, ...) do { } while (0)
3268 +#endif
3269 +
3270 +static int dts_version; /* = 0 */
3271 +
3272 +#define BEGIN_DEFAULT() if (dts_version == 0) { \
3273 + DPRINT("<INITIAL>\n"); \
3274 + BEGIN(INITIAL); \
3275 + } else { \
3276 + DPRINT("<V1>\n"); \
3277 + BEGIN(V1); \
3278 + }
3279 +%}
3280 +
3281 +%%
3282 +<*>"/include/" BEGIN(INCLUDE);
3283 +
3284 +<INCLUDE>\"[^"\n]*\" {
3285 + yytext[strlen(yytext) - 1] = 0;
3286 + if (!push_input_file(yytext + 1)) {
3287 + /* Some unrecoverable error.*/
3288 + exit(1);
3289 + }
3290 + BEGIN_DEFAULT();
3291 + }
3292 +
3293 +
3294 +<*><<EOF>> {
3295 + if (!pop_input_file()) {
3296 + yyterminate();
3297 + }
3298 + }
3299 +
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,
3305 + yyleng-2);
3306 + yylloc.first_line = yylineno;
3307 + return DT_STRING;
3308 + }
3309 +
3310 +<*>"/dts-v1/" {
3311 + yylloc.filenum = srcpos_filenum;
3312 + yylloc.first_line = yylineno;
3313 + DPRINT("Keyword: /dts-v1/\n");
3314 + dts_version = 1;
3315 + BEGIN_DEFAULT();
3316 + return DT_V1;
3317 + }
3318 +
3319 +<*>"/memreserve/" {
3320 + yylloc.filenum = srcpos_filenum;
3321 + yylloc.first_line = yylineno;
3322 + DPRINT("Keyword: /memreserve/\n");
3323 + BEGIN_DEFAULT();
3324 + return DT_MEMRESERVE;
3325 + }
3326 +
3327 +<*>{LABEL}: {
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';
3333 + return DT_LABEL;
3334 + }
3335 +
3336 +<INITIAL>[bodh]# {
3337 + yylloc.filenum = srcpos_filenum;
3338 + yylloc.first_line = yylineno;
3339 + if (*yytext == 'b')
3340 + yylval.cbase = 2;
3341 + else if (*yytext == 'o')
3342 + yylval.cbase = 8;
3343 + else if (*yytext == 'd')
3344 + yylval.cbase = 10;
3345 + else
3346 + yylval.cbase = 16;
3347 + DPRINT("Base: %d\n", yylval.cbase);
3348 + return DT_BASE;
3349 + }
3350 +
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;
3357 + }
3358 +
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;
3365 + }
3366 +
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);
3372 + return DT_REF;
3373 + }
3374 +
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);
3381 + return DT_REF;
3382 + }
3383 +
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);
3389 + return DT_REF;
3390 + }
3391 +
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);
3397 + return DT_BYTE;
3398 + }
3399 +
3400 +<BYTESTRING>"]" {
3401 + yylloc.filenum = srcpos_filenum;
3402 + yylloc.first_line = yylineno;
3403 + DPRINT("/BYTESTRING\n");
3404 + BEGIN_DEFAULT();
3405 + return ']';
3406 + }
3407 +
3408 +<PROPNODENAME>{PROPNODECHAR}+ {
3409 + yylloc.filenum = srcpos_filenum;
3410 + yylloc.first_line = yylineno;
3411 + DPRINT("PropNodeName: %s\n", yytext);
3412 + yylval.propnodename = strdup(yytext);
3413 + BEGIN_DEFAULT();
3414 + return DT_PROPNODENAME;
3415 + }