mirror of
https://github.com/joel16/android_kernel_sony_msm8994_rework.git
synced 2024-11-24 04:19:51 +00:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc
* master.kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc: (194 commits) [POWERPC] Add missing EXPORTS for mpc52xx support [POWERPC] Remove obsolete PPC_52xx and update CLASSIC32 comment [POWERPC] ps3: add a default zImage target [POWERPC] Add of_platform_bus support to mpc52xx psc uart driver [POWERPC] typo fix and whitespace cleanup on mpc52xx-uart driver [POWERPC] Fix debug printks for 32-bit resources in the PCI code [POWERPC] Replace kmalloc+memset with kzalloc [POWERPC] Linkstation / kurobox support [POWERPC] Add the e300c3 core to the CPU table. [POWERPC] ppc: m48t35 add missing bracket [POWERPC] iSeries: don't build head_64.o unnecessarily [POWERPC] iSeries: stop dt_mod.o being rebuilt unnecessarily [POWERPC] Fix cputable.h for combined build [POWERPC] Allow CONFIG_BOOTX_TEXT on iSeries [POWERPC] Allow xmon to build on legacy iSeries [POWERPC] Change ppc64_defconfig to use AUTOFS_V4 not V3 [POWERPC] Tell firmware we can handle POWER6 compatible mode [POWERPC] Clean images in arch/powerpc/boot [POWERPC] Fix OF pci flags parsing [POWERPC] defconfig for lite5200 board ...
This commit is contained in:
commit
15a4cb9c25
@ -6,6 +6,8 @@
|
||||
IBM Corp.
|
||||
(c) 2005 Becky Bruce <becky.bruce at freescale.com>,
|
||||
Freescale Semiconductor, FSL SOC and 32-bit additions
|
||||
(c) 2006 MontaVista Software, Inc.
|
||||
Flash chip node definition
|
||||
|
||||
May 18, 2005: Rev 0.1 - Initial draft, no chapter III yet.
|
||||
|
||||
@ -1693,6 +1695,43 @@ platforms are moved over to use the flattened-device-tree model.
|
||||
};
|
||||
};
|
||||
|
||||
g) Flash chip nodes
|
||||
|
||||
Flash chips (Memory Technology Devices) are often used for solid state
|
||||
file systems on embedded devices.
|
||||
|
||||
Required properties:
|
||||
|
||||
- device_type : has to be "rom"
|
||||
- compatible : Should specify what this ROM device is compatible with
|
||||
(i.e. "onenand"). Currently, this is most likely to be "direct-mapped"
|
||||
(which corresponds to the MTD physmap mapping driver).
|
||||
- regs : Offset and length of the register set (or memory mapping) for
|
||||
the device.
|
||||
|
||||
Recommended properties :
|
||||
|
||||
- bank-width : Width of the flash data bus in bytes. Required
|
||||
for the NOR flashes (compatible == "direct-mapped" and others) ONLY.
|
||||
- partitions : Several pairs of 32-bit values where the first value is
|
||||
partition's offset from the start of the device and the second one is
|
||||
partition size in bytes with LSB used to signify a read only
|
||||
partititon (so, the parition size should always be an even number).
|
||||
- partition-names : The list of concatenated zero terminated strings
|
||||
representing the partition names.
|
||||
|
||||
Example:
|
||||
|
||||
flash@ff000000 {
|
||||
device_type = "rom";
|
||||
compatible = "direct-mapped";
|
||||
regs = <ff000000 01000000>;
|
||||
bank-width = <4>;
|
||||
partitions = <00000000 00f80000
|
||||
00f80000 00080001>;
|
||||
partition-names = "fs\0firmware";
|
||||
};
|
||||
|
||||
More devices will be defined as this spec matures.
|
||||
|
||||
|
||||
|
189
Documentation/powerpc/mpc52xx-device-tree-bindings.txt
Normal file
189
Documentation/powerpc/mpc52xx-device-tree-bindings.txt
Normal file
@ -0,0 +1,189 @@
|
||||
MPC52xx Device Tree Bindings
|
||||
----------------------------
|
||||
|
||||
(c) 2006 Secret Lab Technologies Ltd
|
||||
Grant Likely <grant.likely at secretlab.ca>
|
||||
|
||||
I - Introduction
|
||||
================
|
||||
Boards supported by the arch/powerpc architecture require device tree be
|
||||
passed by the boot loader to the kernel at boot time. The device tree
|
||||
describes what devices are present on the board and how they are
|
||||
connected. The device tree can either be passed as a binary blob (as
|
||||
described in Documentation/powerpc/booting-without-of.txt), or passed
|
||||
by Open Firmare (IEEE 1275) compatible firmware using an OF compatible
|
||||
client interface API.
|
||||
|
||||
This document specifies the requirements on the device-tree for mpc52xx
|
||||
based boards. These requirements are above and beyond the details
|
||||
specified in either the OpenFirmware spec or booting-without-of.txt
|
||||
|
||||
All new mpc52xx-based boards are expected to match this document. In
|
||||
cases where this document is not sufficient to support a new board port,
|
||||
this document should be updated as part of adding the new board support.
|
||||
|
||||
II - Philosophy
|
||||
===============
|
||||
The core of this document is naming convention. The whole point of
|
||||
defining this convention is to reduce or eliminate the number of
|
||||
special cases required to support a 52xx board. If all 52xx boards
|
||||
follow the same convention, then generic 52xx support code will work
|
||||
rather than coding special cases for each new board.
|
||||
|
||||
This section tries to capture the thought process behind why the naming
|
||||
convention is what it is.
|
||||
|
||||
1. Node names
|
||||
-------------
|
||||
There is strong convention/requirements already established for children
|
||||
of the root node. 'cpus' describes the processor cores, 'memory'
|
||||
describes memory, and 'chosen' provides boot configuration. Other nodes
|
||||
are added to describe devices attached to the processor local bus.
|
||||
Following convention already established with other system-on-chip
|
||||
processors, MPC52xx boards must have an 'soc5200' node as a child of the
|
||||
root node.
|
||||
|
||||
The soc5200 node holds child nodes for all on chip devices. Child nodes
|
||||
are typically named after the configured function. ie. the FEC node is
|
||||
named 'ethernet', and a PSC in uart mode is named 'serial'.
|
||||
|
||||
2. device_type property
|
||||
-----------------------
|
||||
similar to the node name convention above; the device_type reflects the
|
||||
configured function of a device. ie. 'serial' for a uart and 'spi' for
|
||||
an spi controller. However, while node names *should* reflect the
|
||||
configured function, device_type *must* match the configured function
|
||||
exactly.
|
||||
|
||||
3. compatible property
|
||||
----------------------
|
||||
Since device_type isn't enough to match devices to drivers, there also
|
||||
needs to be a naming convention for the compatible property. Compatible
|
||||
is an list of device descriptions sorted from specific to generic. For
|
||||
the mpc52xx, the required format for each compatible value is
|
||||
<chip>-<device>[-<mode>]. At the minimum, the list shall contain two
|
||||
items; the first specifying the exact chip, and the second specifying
|
||||
mpc52xx for the chip.
|
||||
|
||||
ie. ethernet on mpc5200b: compatible = "mpc5200b-ethernet\0mpc52xx-ethernet"
|
||||
|
||||
The idea here is that most drivers will match to the most generic field
|
||||
in the compatible list (mpc52xx-*), but can also test the more specific
|
||||
field for enabling bug fixes or extra features.
|
||||
|
||||
Modal devices, like PSCs, also append the configured function to the
|
||||
end of the compatible field. ie. A PSC in i2s mode would specify
|
||||
"mpc52xx-psc-i2s", not "mpc52xx-i2s". This convention is chosen to
|
||||
avoid naming conflicts with non-psc devices providing the same
|
||||
function. For example, "mpc52xx-spi" and "mpc52xx-psc-spi" describe
|
||||
the mpc5200 simple spi device and a PSC spi mode respectively.
|
||||
|
||||
If the soc device is more generic and present on other SOCs, the
|
||||
compatible property can specify the more generic device type also.
|
||||
|
||||
ie. mscan: compatible = "mpc5200-mscan\0mpc52xx-mscan\0fsl,mscan";
|
||||
|
||||
At the time of writing, exact chip may be either 'mpc5200' or
|
||||
'mpc5200b'.
|
||||
|
||||
Device drivers should always try to match as generically as possible.
|
||||
|
||||
III - Structure
|
||||
===============
|
||||
The device tree for an mpc52xx board follows the structure defined in
|
||||
booting-without-of.txt with the following additional notes:
|
||||
|
||||
0) the root node
|
||||
----------------
|
||||
Typical root description node; see booting-without-of
|
||||
|
||||
1) The cpus node
|
||||
----------------
|
||||
The cpus node follows the basic layout described in booting-without-of.
|
||||
The bus-frequency property holds the XLB bus frequency
|
||||
The clock-frequency property holds the core frequency
|
||||
|
||||
2) The memory node
|
||||
------------------
|
||||
Typical memory description node; see booting-without-of.
|
||||
|
||||
3) The soc5200 node
|
||||
-------------------
|
||||
This node describes the on chip SOC peripherals. Every mpc52xx based
|
||||
board will have this node, and as such there is a common naming
|
||||
convention for SOC devices.
|
||||
|
||||
Required properties:
|
||||
name type description
|
||||
---- ---- -----------
|
||||
device_type string must be "soc"
|
||||
ranges int should be <0 baseaddr baseaddr+10000>
|
||||
reg int must be <baseaddr 10000>
|
||||
|
||||
Recommended properties:
|
||||
name type description
|
||||
---- ---- -----------
|
||||
compatible string should be "<chip>-soc\0mpc52xx-soc"
|
||||
ie. "mpc5200b-soc\0mpc52xx-soc"
|
||||
#interrupt-cells int must be <3>. If it is not defined
|
||||
here then it must be defined in every
|
||||
soc device node.
|
||||
bus-frequency int IPB bus frequency in HZ. Clock rate
|
||||
used by most of the soc devices.
|
||||
Defining it here avoids needing it
|
||||
added to every device node.
|
||||
|
||||
4) soc5200 child nodes
|
||||
----------------------
|
||||
Any on chip SOC devices available to Linux must appear as soc5200 child nodes.
|
||||
|
||||
Note: in the tables below, '*' matches all <chip> values. ie.
|
||||
*-pic would translate to "mpc5200-pic\0mpc52xx-pic"
|
||||
|
||||
Required soc5200 child nodes:
|
||||
name device_type compatible Description
|
||||
---- ----------- ---------- -----------
|
||||
cdm@<addr> cdm *-cmd Clock Distribution
|
||||
pic@<addr> interrupt-controller *-pic need an interrupt
|
||||
controller to boot
|
||||
bestcomm@<addr> dma-controller *-bestcomm 52xx pic also requires
|
||||
the bestcomm device
|
||||
|
||||
Recommended soc5200 child nodes; populate as needed for your board
|
||||
name device_type compatible Description
|
||||
---- ----------- ---------- -----------
|
||||
gpt@<addr> gpt *-gpt General purpose timers
|
||||
rtc@<addr> rtc *-rtc Real time clock
|
||||
mscan@<addr> mscan *-mscan CAN bus controller
|
||||
pci@<addr> pci *-pci PCI bridge
|
||||
serial@<addr> serial *-psc-uart PSC in serial mode
|
||||
i2s@<addr> i2s *-psc-i2s PSC in i2s mode
|
||||
ac97@<addr> ac97 *-psc-ac97 PSC in ac97 mode
|
||||
spi@<addr> spi *-psc-spi PSC in spi mode
|
||||
irda@<addr> irda *-psc-irda PSC in IrDA mode
|
||||
spi@<addr> spi *-spi MPC52xx spi device
|
||||
ethernet@<addr> network *-fec MPC52xx ethernet device
|
||||
ata@<addr> ata *-ata IDE ATA interface
|
||||
i2c@<addr> i2c *-i2c I2C controller
|
||||
usb@<addr> usb-ohci-be *-ohci,ohci-be USB controller
|
||||
xlb@<addr> xlb *-xlb XLB arbritrator
|
||||
|
||||
IV - Extra Notes
|
||||
================
|
||||
|
||||
1. Interrupt mapping
|
||||
--------------------
|
||||
The mpc52xx pic driver splits hardware IRQ numbers into two levels. The
|
||||
split reflects the layout of the PIC hardware itself, which groups
|
||||
interrupts into one of three groups; CRIT, MAIN or PERP. Also, the
|
||||
Bestcomm dma engine has it's own set of interrupt sources which are
|
||||
cascaded off of peripheral interrupt 0, which the driver interprets as a
|
||||
fourth group, SDMA.
|
||||
|
||||
The interrupts property for device nodes using the mpc52xx pic consists
|
||||
of three cells; <L1 L2 level>
|
||||
|
||||
L1 := [CRIT=0, MAIN=1, PERP=2, SDMA=3]
|
||||
L2 := interrupt number; directly mapped from the value in the
|
||||
"ICTL PerStat, MainStat, CritStat Encoded Register"
|
||||
level := [LEVEL_HIGH=0, EDGE_RISING=1, EDGE_FALLING=2, LEVEL_LOW=3]
|
@ -2438,6 +2438,13 @@ M: promise@pnd-pc.demon.co.uk
|
||||
W: http://www.pnd-pc.demon.co.uk/promise/
|
||||
S: Maintained
|
||||
|
||||
PS3 PLATFORM SUPPORT
|
||||
P: Geoff Levand
|
||||
M: geoffrey.levand@am.sony.com
|
||||
L: linuxppc-dev@ozlabs.org
|
||||
L: cbe-oss-dev@ozlabs.org
|
||||
S: Supported
|
||||
|
||||
PVRUSB2 VIDEO4LINUX DRIVER
|
||||
P: Mike Isely
|
||||
M: isely@pobox.com
|
||||
|
1
arch/powerpc/.gitignore
vendored
Normal file
1
arch/powerpc/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
include
|
@ -112,7 +112,7 @@ choice
|
||||
default 6xx
|
||||
|
||||
config CLASSIC32
|
||||
bool "6xx/7xx/74xx"
|
||||
bool "52xx/6xx/7xx/74xx"
|
||||
select PPC_FPU
|
||||
select 6xx
|
||||
help
|
||||
@ -121,16 +121,18 @@ config CLASSIC32
|
||||
versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the AMCC
|
||||
embedded versions (403 and 405) and the high end 64 bit Power
|
||||
processors (POWER 3, POWER4, and IBM PPC970 also known as G5).
|
||||
|
||||
This option is the catch-all for 6xx types, including some of the
|
||||
embedded versions. Unless there is see an option for the specific
|
||||
chip family you are using, you want this option.
|
||||
|
||||
You do not want this if you are building a kernel for a 64 bit
|
||||
IBM RS/6000 or an Apple G5, choose 6xx.
|
||||
|
||||
If unsure, select this option
|
||||
|
||||
Unless you are building a kernel for one of the embedded processor
|
||||
systems, 64 bit IBM RS/6000 or an Apple G5, choose 6xx.
|
||||
Note that the kernel runs in 32-bit mode even on 64-bit chips.
|
||||
|
||||
config PPC_52xx
|
||||
bool "Freescale 52xx"
|
||||
select 6xx
|
||||
select PPC_FPU
|
||||
|
||||
config PPC_82xx
|
||||
bool "Freescale 82xx"
|
||||
select 6xx
|
||||
@ -160,9 +162,11 @@ config PPC_86xx
|
||||
|
||||
config 40x
|
||||
bool "AMCC 40x"
|
||||
select PPC_DCR_NATIVE
|
||||
|
||||
config 44x
|
||||
bool "AMCC 44x"
|
||||
select PPC_DCR_NATIVE
|
||||
|
||||
config 8xx
|
||||
bool "Freescale 8xx"
|
||||
@ -208,6 +212,24 @@ config PPC_FPU
|
||||
bool
|
||||
default y if PPC64
|
||||
|
||||
config PPC_DCR_NATIVE
|
||||
bool
|
||||
default n
|
||||
|
||||
config PPC_DCR_MMIO
|
||||
bool
|
||||
default n
|
||||
|
||||
config PPC_DCR
|
||||
bool
|
||||
depends on PPC_DCR_NATIVE || PPC_DCR_MMIO
|
||||
default y
|
||||
|
||||
config PPC_OF_PLATFORM_PCI
|
||||
bool
|
||||
depends on PPC64 # not supported on 32 bits yet
|
||||
default n
|
||||
|
||||
config BOOKE
|
||||
bool
|
||||
depends on E200 || E500
|
||||
@ -227,6 +249,7 @@ config PTE_64BIT
|
||||
config PHYS_64BIT
|
||||
bool 'Large physical address support' if E500
|
||||
depends on 44x || E500
|
||||
select RESOURCES_64BIT
|
||||
default y if 44x
|
||||
---help---
|
||||
This option enables kernel support for larger than 32-bit physical
|
||||
@ -369,11 +392,13 @@ config PPC_PSERIES
|
||||
select PPC_RTAS
|
||||
select RTAS_ERROR_LOGGING
|
||||
select PPC_UDBG_16550
|
||||
select PPC_NATIVE
|
||||
default y
|
||||
|
||||
config PPC_ISERIES
|
||||
bool "IBM Legacy iSeries"
|
||||
depends on PPC_MULTIPLATFORM && PPC64
|
||||
select PPC_INDIRECT_IO
|
||||
|
||||
config PPC_CHRP
|
||||
bool "Common Hardware Reference Platform (CHRP) based machines"
|
||||
@ -384,14 +409,35 @@ config PPC_CHRP
|
||||
select PPC_RTAS
|
||||
select PPC_MPC106
|
||||
select PPC_UDBG_16550
|
||||
select PPC_NATIVE
|
||||
default y
|
||||
|
||||
config PPC_MPC52xx
|
||||
bool
|
||||
default n
|
||||
|
||||
config PPC_EFIKA
|
||||
bool "bPlan Efika 5k2. MPC5200B based computer"
|
||||
depends on PPC_MULTIPLATFORM && PPC32
|
||||
select PPC_RTAS
|
||||
select RTAS_PROC
|
||||
select PPC_MPC52xx
|
||||
select PPC_NATIVE
|
||||
default y
|
||||
|
||||
config PPC_LITE5200
|
||||
bool "Freescale Lite5200 Eval Board"
|
||||
depends on PPC_MULTIPLATFORM && PPC32
|
||||
select PPC_MPC52xx
|
||||
default n
|
||||
|
||||
config PPC_PMAC
|
||||
bool "Apple PowerMac based machines"
|
||||
depends on PPC_MULTIPLATFORM
|
||||
select MPIC
|
||||
select PPC_INDIRECT_PCI if PPC32
|
||||
select PPC_MPC106 if PPC32
|
||||
select PPC_NATIVE
|
||||
default y
|
||||
|
||||
config PPC_PMAC64
|
||||
@ -411,6 +457,7 @@ config PPC_PREP
|
||||
select PPC_I8259
|
||||
select PPC_INDIRECT_PCI
|
||||
select PPC_UDBG_16550
|
||||
select PPC_NATIVE
|
||||
default y
|
||||
|
||||
config PPC_MAPLE
|
||||
@ -422,6 +469,7 @@ config PPC_MAPLE
|
||||
select GENERIC_TBSYNC
|
||||
select PPC_UDBG_16550
|
||||
select PPC_970_NAP
|
||||
select PPC_NATIVE
|
||||
default n
|
||||
help
|
||||
This option enables support for the Maple 970FX Evaluation Board.
|
||||
@ -434,6 +482,7 @@ config PPC_PASEMI
|
||||
select MPIC
|
||||
select PPC_UDBG_16550
|
||||
select GENERIC_TBSYNC
|
||||
select PPC_NATIVE
|
||||
help
|
||||
This option enables support for PA Semi's PWRficient line
|
||||
of SoC processors, including PA6T-1682M
|
||||
@ -445,6 +494,11 @@ config PPC_CELL
|
||||
config PPC_CELL_NATIVE
|
||||
bool
|
||||
select PPC_CELL
|
||||
select PPC_DCR_MMIO
|
||||
select PPC_OF_PLATFORM_PCI
|
||||
select PPC_INDIRECT_IO
|
||||
select PPC_NATIVE
|
||||
select MPIC
|
||||
default n
|
||||
|
||||
config PPC_IBM_CELL_BLADE
|
||||
@ -456,6 +510,22 @@ config PPC_IBM_CELL_BLADE
|
||||
select PPC_UDBG_16550
|
||||
select UDBG_RTAS_CONSOLE
|
||||
|
||||
config PPC_PS3
|
||||
bool "Sony PS3"
|
||||
depends on PPC_MULTIPLATFORM && PPC64
|
||||
select PPC_CELL
|
||||
help
|
||||
This option enables support for the Sony PS3 game console
|
||||
and other platforms using the PS3 hypervisor.
|
||||
|
||||
config PPC_NATIVE
|
||||
bool
|
||||
depends on PPC_MULTIPLATFORM
|
||||
help
|
||||
Support for running natively on the hardware, i.e. without
|
||||
a hypervisor. This option is not user-selectable but should
|
||||
be selected by all platforms that need it.
|
||||
|
||||
config UDBG_RTAS_CONSOLE
|
||||
bool "RTAS based debug console"
|
||||
depends on PPC_RTAS
|
||||
@ -517,6 +587,15 @@ config PPC_970_NAP
|
||||
bool
|
||||
default n
|
||||
|
||||
config PPC_INDIRECT_IO
|
||||
bool
|
||||
select GENERIC_IOMAP
|
||||
default n
|
||||
|
||||
config GENERIC_IOMAP
|
||||
bool
|
||||
default n
|
||||
|
||||
source "drivers/cpufreq/Kconfig"
|
||||
|
||||
config CPU_FREQ_PMAC
|
||||
@ -594,12 +673,6 @@ config TAU_AVERAGE
|
||||
|
||||
If in doubt, say N here.
|
||||
|
||||
config PPC_TODC
|
||||
depends on EMBEDDED6xx
|
||||
bool "Generic Time-of-day Clock (TODC) support"
|
||||
---help---
|
||||
This adds support for many TODC/RTC chips.
|
||||
|
||||
endmenu
|
||||
|
||||
source arch/powerpc/platforms/embedded6xx/Kconfig
|
||||
@ -610,6 +683,7 @@ source arch/powerpc/platforms/85xx/Kconfig
|
||||
source arch/powerpc/platforms/86xx/Kconfig
|
||||
source arch/powerpc/platforms/8xx/Kconfig
|
||||
source arch/powerpc/platforms/cell/Kconfig
|
||||
source arch/powerpc/platforms/ps3/Kconfig
|
||||
|
||||
menu "Kernel options"
|
||||
|
||||
@ -790,7 +864,6 @@ source "arch/powerpc/platforms/prep/Kconfig"
|
||||
|
||||
config CMDLINE_BOOL
|
||||
bool "Default bootloader kernel arguments"
|
||||
depends on !PPC_ISERIES
|
||||
|
||||
config CMDLINE
|
||||
string "Initial kernel command string"
|
||||
@ -880,7 +953,7 @@ config MCA
|
||||
|
||||
config PCI
|
||||
bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \
|
||||
|| PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) || MPC7448HPC2
|
||||
|| PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) || MPC7448HPC2 || PPC_PS3
|
||||
default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx \
|
||||
&& !PPC_85xx && !PPC_86xx
|
||||
default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS
|
||||
|
@ -77,7 +77,7 @@ config KGDB_CONSOLE
|
||||
|
||||
config XMON
|
||||
bool "Include xmon kernel debugger"
|
||||
depends on DEBUGGER && !PPC_ISERIES
|
||||
depends on DEBUGGER
|
||||
help
|
||||
Include in-kernel hooks for the xmon kernel monitor/debugger.
|
||||
Unless you are intending to debug the kernel, say N here.
|
||||
@ -98,6 +98,15 @@ config XMON_DEFAULT
|
||||
xmon is normally disabled unless booted with 'xmon=on'.
|
||||
Use 'xmon=off' to disable xmon init during runtime.
|
||||
|
||||
config XMON_DISASSEMBLY
|
||||
bool "Include disassembly support in xmon"
|
||||
depends on XMON
|
||||
default y
|
||||
help
|
||||
Include support for disassembling in xmon. You probably want
|
||||
to say Y here, unless you're building for a memory-constrained
|
||||
system.
|
||||
|
||||
config IRQSTACKS
|
||||
bool "Use separate kernel stacks when processing interrupts"
|
||||
depends on PPC64
|
||||
@ -116,7 +125,7 @@ config BDI_SWITCH
|
||||
|
||||
config BOOTX_TEXT
|
||||
bool "Support for early boot text console (BootX or OpenFirmware only)"
|
||||
depends PPC_OF && !PPC_ISERIES
|
||||
depends PPC_OF
|
||||
help
|
||||
Say Y here to see progress messages from the boot firmware in text
|
||||
mode. Requires either BootX or Open Firmware.
|
||||
|
13
arch/powerpc/boot/.gitignore
vendored
13
arch/powerpc/boot/.gitignore
vendored
@ -1,19 +1,32 @@
|
||||
addnote
|
||||
empty.c
|
||||
hack-coff
|
||||
infblock.c
|
||||
infblock.h
|
||||
infcodes.c
|
||||
infcodes.h
|
||||
inffast.c
|
||||
inffast.h
|
||||
inffixed.h
|
||||
inflate.c
|
||||
inflate.h
|
||||
inftrees.c
|
||||
inftrees.h
|
||||
infutil.c
|
||||
infutil.h
|
||||
kernel-vmlinux.strip.c
|
||||
kernel-vmlinux.strip.gz
|
||||
mktree
|
||||
uImage
|
||||
zImage
|
||||
zImage.chrp
|
||||
zImage.coff
|
||||
zImage.coff.lds
|
||||
zImage.lds
|
||||
zImage.miboot
|
||||
zImage.pmac
|
||||
zImage.pseries
|
||||
zImage.sandpoint
|
||||
zImage.vmode
|
||||
zconf.h
|
||||
zlib.h
|
||||
|
@ -40,7 +40,8 @@ zliblinuxheader := zlib.h zconf.h zutil.h
|
||||
$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) \
|
||||
$(addprefix $(obj)/,$(zlibheader))
|
||||
|
||||
src-wlib := string.S stdio.c main.c div64.S $(zlib)
|
||||
src-wlib := string.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
|
||||
ns16550.c serial.c simple_alloc.c div64.S util.S $(zlib)
|
||||
src-plat := of.c
|
||||
src-boot := crt0.S $(src-wlib) $(src-plat) empty.c
|
||||
|
||||
@ -74,7 +75,7 @@ $(obj)/zImage.lds $(obj)/zImage.coff.lds: $(obj)/%: $(srctree)/$(src)/%.S
|
||||
@cp $< $@
|
||||
|
||||
clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \
|
||||
$(obj)/empty.c
|
||||
empty.c zImage zImage.coff.lds zImage.lds zImage.sandpoint
|
||||
|
||||
quiet_cmd_bootcc = BOOTCC $@
|
||||
cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
|
||||
@ -93,13 +94,13 @@ $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S
|
||||
$(obj)/wrapper.a: $(obj-wlib)
|
||||
$(call cmd,bootar)
|
||||
|
||||
hostprogs-y := addnote addRamDisk hack-coff
|
||||
hostprogs-y := addnote addRamDisk hack-coff mktree
|
||||
|
||||
extra-y := $(obj)/crt0.o $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
|
||||
$(obj)/zImage.lds $(obj)/zImage.coff.lds
|
||||
|
||||
wrapper :=$(srctree)/$(src)/wrapper
|
||||
wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff)
|
||||
wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree)
|
||||
|
||||
#############
|
||||
# Bits for building various flavours of zImage
|
||||
@ -148,13 +149,18 @@ $(obj)/zImage.miboot: vmlinux $(wrapperbits)
|
||||
$(obj)/zImage.initrd.miboot: vmlinux $(wrapperbits)
|
||||
$(call cmd,wrap_initrd,miboot)
|
||||
|
||||
$(obj)/zImage.ps3: vmlinux
|
||||
$(STRIP) -s -R .comment $< -o $@
|
||||
|
||||
$(obj)/uImage: vmlinux $(wrapperbits)
|
||||
$(call cmd,wrap,uboot)
|
||||
|
||||
image-$(CONFIG_PPC_PSERIES) += zImage.pseries
|
||||
image-$(CONFIG_PPC_MAPLE) += zImage.pseries
|
||||
image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries
|
||||
image-$(CONFIG_PPC_PS3) += zImage.ps3
|
||||
image-$(CONFIG_PPC_CHRP) += zImage.chrp
|
||||
image-$(CONFIG_PPC_EFIKA) += zImage.chrp
|
||||
image-$(CONFIG_PPC_PMAC) += zImage.pmac
|
||||
image-$(CONFIG_DEFAULT_UIMAGE) += uImage
|
||||
|
||||
@ -176,3 +182,4 @@ install: $(CONFIGURE) $(image-y)
|
||||
|
||||
clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.strip.gz)
|
||||
clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.bin.gz)
|
||||
clean-files += $(image-)
|
||||
|
148
arch/powerpc/boot/dts/kuroboxHG.dts
Normal file
148
arch/powerpc/boot/dts/kuroboxHG.dts
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Device Tree Souce for Buffalo KuroboxHG
|
||||
*
|
||||
* Choose CONFIG_LINKSTATION to build a kernel for KuroboxHG, or use
|
||||
* the default configuration linkstation_defconfig.
|
||||
*
|
||||
* Based on sandpoint.dts
|
||||
*
|
||||
* 2006 (c) G. Liakhovetski <g.liakhovetski@gmx.de>
|
||||
*
|
||||
* This file is licensed under
|
||||
* the terms of the GNU General Public License version 2. This program
|
||||
* is licensed "as is" without any warranty of any kind, whether express
|
||||
* or implied.
|
||||
|
||||
XXXX add flash parts, rtc, ??
|
||||
|
||||
build with: "dtc -f -I dts -O dtb -o kuroboxHG.dtb -V 16 kuroboxHG.dts"
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/ {
|
||||
linux,phandle = <1000>;
|
||||
model = "KuroboxHG";
|
||||
compatible = "linkstation";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
cpus {
|
||||
linux,phandle = <2000>;
|
||||
#cpus = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
PowerPC,603e { /* Really 8241 */
|
||||
linux,phandle = <2100>;
|
||||
linux,boot-cpu;
|
||||
device_type = "cpu";
|
||||
reg = <0>;
|
||||
clock-frequency = <fdad680>; /* Fixed by bootwrapper */
|
||||
timebase-frequency = <1F04000>; /* Fixed by bootwrapper */
|
||||
bus-frequency = <0>; /* From bootloader */
|
||||
/* Following required by dtc but not used */
|
||||
i-cache-line-size = <0>;
|
||||
d-cache-line-size = <0>;
|
||||
i-cache-size = <4000>;
|
||||
d-cache-size = <4000>;
|
||||
};
|
||||
};
|
||||
|
||||
memory {
|
||||
linux,phandle = <3000>;
|
||||
device_type = "memory";
|
||||
reg = <00000000 08000000>;
|
||||
};
|
||||
|
||||
soc10x { /* AFAICT need to make soc for 8245's uarts to be defined */
|
||||
linux,phandle = <4000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
#interrupt-cells = <2>;
|
||||
device_type = "soc";
|
||||
compatible = "mpc10x";
|
||||
store-gathering = <0>; /* 0 == off, !0 == on */
|
||||
reg = <80000000 00100000>;
|
||||
ranges = <80000000 80000000 70000000 /* pci mem space */
|
||||
fc000000 fc000000 00100000 /* EUMB */
|
||||
fe000000 fe000000 00c00000 /* pci i/o space */
|
||||
fec00000 fec00000 00300000 /* pci cfg regs */
|
||||
fef00000 fef00000 00100000>; /* pci iack */
|
||||
|
||||
i2c@80003000 {
|
||||
linux,phandle = <4300>;
|
||||
device_type = "i2c";
|
||||
compatible = "fsl-i2c";
|
||||
reg = <80003000 1000>;
|
||||
interrupts = <5 2>;
|
||||
interrupt-parent = <4400>;
|
||||
};
|
||||
|
||||
serial@80004500 {
|
||||
linux,phandle = <4511>;
|
||||
device_type = "serial";
|
||||
compatible = "ns16550";
|
||||
reg = <80004500 8>;
|
||||
clock-frequency = <7c044a8>;
|
||||
current-speed = <2580>;
|
||||
interrupts = <9 2>;
|
||||
interrupt-parent = <4400>;
|
||||
};
|
||||
|
||||
serial@80004600 {
|
||||
linux,phandle = <4512>;
|
||||
device_type = "serial";
|
||||
compatible = "ns16550";
|
||||
reg = <80004600 8>;
|
||||
clock-frequency = <7c044a8>;
|
||||
current-speed = <e100>;
|
||||
interrupts = <a 0>;
|
||||
interrupt-parent = <4400>;
|
||||
};
|
||||
|
||||
pic@80040000 {
|
||||
linux,phandle = <4400>;
|
||||
#interrupt-cells = <2>;
|
||||
#address-cells = <0>;
|
||||
device_type = "open-pic";
|
||||
compatible = "chrp,open-pic";
|
||||
interrupt-controller;
|
||||
reg = <80040000 40000>;
|
||||
built-in;
|
||||
};
|
||||
|
||||
pci@fec00000 {
|
||||
linux,phandle = <4500>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
device_type = "pci";
|
||||
compatible = "mpc10x-pci";
|
||||
reg = <fec00000 400000>;
|
||||
ranges = <01000000 0 0 fe000000 0 00c00000
|
||||
02000000 0 80000000 80000000 0 70000000>;
|
||||
bus-range = <0 ff>;
|
||||
clock-frequency = <7f28155>;
|
||||
interrupt-parent = <4400>;
|
||||
interrupt-map-mask = <f800 0 0 7>;
|
||||
interrupt-map = <
|
||||
/* IDSEL 0x11 - IRQ0 ETH */
|
||||
5800 0 0 1 4400 0 1
|
||||
5800 0 0 2 4400 1 1
|
||||
5800 0 0 3 4400 2 1
|
||||
5800 0 0 4 4400 3 1
|
||||
/* IDSEL 0x12 - IRQ1 IDE0 */
|
||||
6000 0 0 1 4400 1 1
|
||||
6000 0 0 2 4400 2 1
|
||||
6000 0 0 3 4400 3 1
|
||||
6000 0 0 4 4400 0 1
|
||||
/* IDSEL 0x14 - IRQ3 USB2.0 */
|
||||
7000 0 0 1 4400 3 1
|
||||
7000 0 0 2 4400 3 1
|
||||
7000 0 0 3 4400 3 1
|
||||
7000 0 0 4 4400 3 1
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
313
arch/powerpc/boot/dts/lite5200.dts
Normal file
313
arch/powerpc/boot/dts/lite5200.dts
Normal file
@ -0,0 +1,313 @@
|
||||
/*
|
||||
* Lite5200 board Device Tree Source
|
||||
*
|
||||
* Copyright 2006 Secret Lab Technologies Ltd.
|
||||
* Grant Likely <grant.likely@secretlab.ca>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
/ {
|
||||
model = "Lite5200";
|
||||
compatible = "lite5200\0lite52xx\0mpc5200\0mpc52xx";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
cpus {
|
||||
#cpus = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
PowerPC,5200@0 {
|
||||
device_type = "cpu";
|
||||
reg = <0>;
|
||||
d-cache-line-size = <20>;
|
||||
i-cache-line-size = <20>;
|
||||
d-cache-size = <4000>; // L1, 16K
|
||||
i-cache-size = <4000>; // L1, 16K
|
||||
timebase-frequency = <0>; // from bootloader
|
||||
bus-frequency = <0>; // from bootloader
|
||||
clock-frequency = <0>; // from bootloader
|
||||
32-bit;
|
||||
};
|
||||
};
|
||||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
reg = <00000000 04000000>; // 64MB
|
||||
};
|
||||
|
||||
soc5200@f0000000 {
|
||||
#interrupt-cells = <3>;
|
||||
device_type = "soc";
|
||||
ranges = <0 f0000000 f0010000>;
|
||||
reg = <f0000000 00010000>;
|
||||
bus-frequency = <0>; // from bootloader
|
||||
|
||||
cdm@200 {
|
||||
compatible = "mpc5200-cdm\0mpc52xx-cdm";
|
||||
reg = <200 38>;
|
||||
};
|
||||
|
||||
pic@500 {
|
||||
// 5200 interrupts are encoded into two levels;
|
||||
linux,phandle = <500>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <3>;
|
||||
device_type = "interrupt-controller";
|
||||
compatible = "mpc5200-pic\0mpc52xx-pic";
|
||||
reg = <500 80>;
|
||||
built-in;
|
||||
};
|
||||
|
||||
gpt@600 { // General Purpose Timer
|
||||
compatible = "mpc5200-gpt\0mpc52xx-gpt";
|
||||
device_type = "gpt";
|
||||
reg = <600 10>;
|
||||
interrupts = <1 9 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
gpt@610 { // General Purpose Timer
|
||||
compatible = "mpc5200-gpt\0mpc52xx-gpt";
|
||||
device_type = "gpt";
|
||||
reg = <610 10>;
|
||||
interrupts = <1 a 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
gpt@620 { // General Purpose Timer
|
||||
compatible = "mpc5200-gpt\0mpc52xx-gpt";
|
||||
device_type = "gpt";
|
||||
reg = <620 10>;
|
||||
interrupts = <1 b 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
gpt@630 { // General Purpose Timer
|
||||
compatible = "mpc5200-gpt\0mpc52xx-gpt";
|
||||
device_type = "gpt";
|
||||
reg = <630 10>;
|
||||
interrupts = <1 c 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
gpt@640 { // General Purpose Timer
|
||||
compatible = "mpc5200-gpt\0mpc52xx-gpt";
|
||||
device_type = "gpt";
|
||||
reg = <640 10>;
|
||||
interrupts = <1 d 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
gpt@650 { // General Purpose Timer
|
||||
compatible = "mpc5200-gpt\0mpc52xx-gpt";
|
||||
device_type = "gpt";
|
||||
reg = <650 10>;
|
||||
interrupts = <1 e 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
gpt@660 { // General Purpose Timer
|
||||
compatible = "mpc5200-gpt\0mpc52xx-gpt";
|
||||
device_type = "gpt";
|
||||
reg = <660 10>;
|
||||
interrupts = <1 f 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
gpt@670 { // General Purpose Timer
|
||||
compatible = "mpc5200-gpt\0mpc52xx-gpt";
|
||||
device_type = "gpt";
|
||||
reg = <670 10>;
|
||||
interrupts = <1 10 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
rtc@800 { // Real time clock
|
||||
compatible = "mpc5200-rtc\0mpc52xx-rtc";
|
||||
device_type = "rtc";
|
||||
reg = <800 100>;
|
||||
interrupts = <1 5 0 1 6 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
mscan@900 {
|
||||
device_type = "mscan";
|
||||
compatible = "mpc5200-mscan\0mpc52xx-mscan";
|
||||
interrupts = <2 11 0>;
|
||||
interrupt-parent = <500>;
|
||||
reg = <900 80>;
|
||||
};
|
||||
|
||||
mscan@980 {
|
||||
device_type = "mscan";
|
||||
compatible = "mpc5200-mscan\0mpc52xx-mscan";
|
||||
interrupts = <1 12 0>;
|
||||
interrupt-parent = <500>;
|
||||
reg = <980 80>;
|
||||
};
|
||||
|
||||
gpio@b00 {
|
||||
compatible = "mpc5200-gpio\0mpc52xx-gpio";
|
||||
reg = <b00 40>;
|
||||
interrupts = <1 7 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
gpio-wkup@b00 {
|
||||
compatible = "mpc5200-gpio-wkup\0mpc52xx-gpio-wkup";
|
||||
reg = <c00 40>;
|
||||
interrupts = <1 8 0 0 3 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
pci@0d00 {
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
device_type = "pci";
|
||||
compatible = "mpc5200-pci\0mpc52xx-pci";
|
||||
reg = <d00 100>;
|
||||
interrupt-map-mask = <f800 0 0 7>;
|
||||
interrupt-map = <c000 0 0 1 500 0 0 3
|
||||
c000 0 0 2 500 0 0 3
|
||||
c000 0 0 3 500 0 0 3
|
||||
c000 0 0 4 500 0 0 3>;
|
||||
clock-frequency = <0>; // From boot loader
|
||||
interrupts = <2 8 0 2 9 0 2 a 0>;
|
||||
interrupt-parent = <500>;
|
||||
bus-range = <0 0>;
|
||||
ranges = <42000000 0 80000000 80000000 0 20000000
|
||||
02000000 0 a0000000 a0000000 0 10000000
|
||||
01000000 0 00000000 b0000000 0 01000000>;
|
||||
};
|
||||
|
||||
spi@f00 {
|
||||
device_type = "spi";
|
||||
compatible = "mpc5200-spi\0mpc52xx-spi";
|
||||
reg = <f00 20>;
|
||||
interrupts = <2 d 0 2 e 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
usb@1000 {
|
||||
device_type = "usb-ohci-be";
|
||||
compatible = "mpc5200-ohci\0mpc52xx-ohci\0ohci-be";
|
||||
reg = <1000 ff>;
|
||||
interrupts = <2 6 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
bestcomm@1200 {
|
||||
device_type = "dma-controller";
|
||||
compatible = "mpc5200-bestcomm\0mpc52xx-bestcomm";
|
||||
reg = <1200 80>;
|
||||
interrupts = <3 0 0 3 1 0 3 2 0 3 3 0
|
||||
3 4 0 3 5 0 3 6 0 3 7 0
|
||||
3 8 0 3 9 0 3 a 0 3 b 0
|
||||
3 c 0 3 d 0 3 e 0 3 f 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
xlb@1f00 {
|
||||
compatible = "mpc5200-xlb\0mpc52xx-xlb";
|
||||
reg = <1f00 100>;
|
||||
};
|
||||
|
||||
serial@2000 { // PSC1
|
||||
device_type = "serial";
|
||||
compatible = "mpc5200-psc-uart\0mpc52xx-psc-uart";
|
||||
port-number = <0>; // Logical port assignment
|
||||
reg = <2000 100>;
|
||||
interrupts = <2 1 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
// PSC2 in spi mode example
|
||||
spi@2200 { // PSC2
|
||||
device_type = "spi";
|
||||
compatible = "mpc5200-psc-spi\0mpc52xx-psc-spi";
|
||||
reg = <2200 100>;
|
||||
interrupts = <2 2 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
// PSC3 in CODEC mode example
|
||||
i2s@2400 { // PSC3
|
||||
device_type = "i2s";
|
||||
compatible = "mpc5200-psc-i2s\0mpc52xx-psc-i2s";
|
||||
reg = <2400 100>;
|
||||
interrupts = <2 3 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
// PSC4 unconfigured
|
||||
//serial@2600 { // PSC4
|
||||
// device_type = "serial";
|
||||
// compatible = "mpc5200-psc-uart\0mpc52xx-psc-uart";
|
||||
// reg = <2600 100>;
|
||||
// interrupts = <2 b 0>;
|
||||
// interrupt-parent = <500>;
|
||||
//};
|
||||
|
||||
// PSC5 unconfigured
|
||||
//serial@2800 { // PSC5
|
||||
// device_type = "serial";
|
||||
// compatible = "mpc5200-psc-uart\0mpc52xx-psc-uart";
|
||||
// reg = <2800 100>;
|
||||
// interrupts = <2 c 0>;
|
||||
// interrupt-parent = <500>;
|
||||
//};
|
||||
|
||||
// PSC6 in AC97 mode example
|
||||
ac97@2c00 { // PSC6
|
||||
device_type = "ac97";
|
||||
compatible = "mpc5200-psc-ac97\0mpc52xx-psc-ac97";
|
||||
reg = <2c00 100>;
|
||||
interrupts = <2 4 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
ethernet@3000 {
|
||||
device_type = "network";
|
||||
compatible = "mpc5200-fec\0mpc52xx-fec";
|
||||
reg = <3000 800>;
|
||||
mac-address = [ 02 03 04 05 06 07 ]; // Bad!
|
||||
interrupts = <2 5 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
ata@3a00 {
|
||||
device_type = "ata";
|
||||
compatible = "mpc5200-ata\0mpc52xx-ata";
|
||||
reg = <3a00 100>;
|
||||
interrupts = <2 7 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
i2c@3d00 {
|
||||
device_type = "i2c";
|
||||
compatible = "mpc5200-i2c\0mpc52xx-i2c";
|
||||
reg = <3d00 40>;
|
||||
interrupts = <2 f 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
i2c@3d40 {
|
||||
device_type = "i2c";
|
||||
compatible = "mpc5200-i2c\0mpc52xx-i2c";
|
||||
reg = <3d40 40>;
|
||||
interrupts = <2 10 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
sram@8000 {
|
||||
device_type = "sram";
|
||||
compatible = "mpc5200-sram\0mpc52xx-sram\0sram";
|
||||
reg = <8000 4000>;
|
||||
};
|
||||
};
|
||||
};
|
318
arch/powerpc/boot/dts/lite5200b.dts
Normal file
318
arch/powerpc/boot/dts/lite5200b.dts
Normal file
@ -0,0 +1,318 @@
|
||||
/*
|
||||
* Lite5200B board Device Tree Source
|
||||
*
|
||||
* Copyright 2006 Secret Lab Technologies Ltd.
|
||||
* Grant Likely <grant.likely@secretlab.ca>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
/ {
|
||||
model = "Lite5200b";
|
||||
compatible = "lite5200b\0lite52xx\0mpc5200b\0mpc52xx";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
cpus {
|
||||
#cpus = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
PowerPC,5200@0 {
|
||||
device_type = "cpu";
|
||||
reg = <0>;
|
||||
d-cache-line-size = <20>;
|
||||
i-cache-line-size = <20>;
|
||||
d-cache-size = <4000>; // L1, 16K
|
||||
i-cache-size = <4000>; // L1, 16K
|
||||
timebase-frequency = <0>; // from bootloader
|
||||
bus-frequency = <0>; // from bootloader
|
||||
clock-frequency = <0>; // from bootloader
|
||||
32-bit;
|
||||
};
|
||||
};
|
||||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
reg = <00000000 10000000>; // 256MB
|
||||
};
|
||||
|
||||
soc5200@f0000000 {
|
||||
#interrupt-cells = <3>;
|
||||
device_type = "soc";
|
||||
ranges = <0 f0000000 f0010000>;
|
||||
reg = <f0000000 00010000>;
|
||||
bus-frequency = <0>; // from bootloader
|
||||
|
||||
cdm@200 {
|
||||
compatible = "mpc5200b-cdm\0mpc52xx-cdm";
|
||||
reg = <200 38>;
|
||||
};
|
||||
|
||||
pic@500 {
|
||||
// 5200 interrupts are encoded into two levels;
|
||||
linux,phandle = <500>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <3>;
|
||||
device_type = "interrupt-controller";
|
||||
compatible = "mpc5200b-pic\0mpc52xx-pic";
|
||||
reg = <500 80>;
|
||||
built-in;
|
||||
};
|
||||
|
||||
gpt@600 { // General Purpose Timer
|
||||
compatible = "mpc5200b-gpt\0mpc52xx-gpt";
|
||||
device_type = "gpt";
|
||||
reg = <600 10>;
|
||||
interrupts = <1 9 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
gpt@610 { // General Purpose Timer
|
||||
compatible = "mpc5200b-gpt\0mpc52xx-gpt";
|
||||
device_type = "gpt";
|
||||
reg = <610 10>;
|
||||
interrupts = <1 a 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
gpt@620 { // General Purpose Timer
|
||||
compatible = "mpc5200b-gpt\0mpc52xx-gpt";
|
||||
device_type = "gpt";
|
||||
reg = <620 10>;
|
||||
interrupts = <1 b 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
gpt@630 { // General Purpose Timer
|
||||
compatible = "mpc5200b-gpt\0mpc52xx-gpt";
|
||||
device_type = "gpt";
|
||||
reg = <630 10>;
|
||||
interrupts = <1 c 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
gpt@640 { // General Purpose Timer
|
||||
compatible = "mpc5200b-gpt\0mpc52xx-gpt";
|
||||
device_type = "gpt";
|
||||
reg = <640 10>;
|
||||
interrupts = <1 d 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
gpt@650 { // General Purpose Timer
|
||||
compatible = "mpc5200b-gpt\0mpc52xx-gpt";
|
||||
device_type = "gpt";
|
||||
reg = <650 10>;
|
||||
interrupts = <1 e 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
gpt@660 { // General Purpose Timer
|
||||
compatible = "mpc5200b-gpt\0mpc52xx-gpt";
|
||||
device_type = "gpt";
|
||||
reg = <660 10>;
|
||||
interrupts = <1 f 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
gpt@670 { // General Purpose Timer
|
||||
compatible = "mpc5200b-gpt\0mpc52xx-gpt";
|
||||
device_type = "gpt";
|
||||
reg = <670 10>;
|
||||
interrupts = <1 10 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
rtc@800 { // Real time clock
|
||||
compatible = "mpc5200b-rtc\0mpc52xx-rtc";
|
||||
device_type = "rtc";
|
||||
reg = <800 100>;
|
||||
interrupts = <1 5 0 1 6 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
mscan@900 {
|
||||
device_type = "mscan";
|
||||
compatible = "mpc5200b-mscan\0mpc52xx-mscan";
|
||||
interrupts = <2 11 0>;
|
||||
interrupt-parent = <500>;
|
||||
reg = <900 80>;
|
||||
};
|
||||
|
||||
mscan@980 {
|
||||
device_type = "mscan";
|
||||
compatible = "mpc5200b-mscan\0mpc52xx-mscan";
|
||||
interrupts = <1 12 0>;
|
||||
interrupt-parent = <500>;
|
||||
reg = <980 80>;
|
||||
};
|
||||
|
||||
gpio@b00 {
|
||||
compatible = "mpc5200b-gpio\0mpc52xx-gpio";
|
||||
reg = <b00 40>;
|
||||
interrupts = <1 7 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
gpio-wkup@b00 {
|
||||
compatible = "mpc5200b-gpio-wkup\0mpc52xx-gpio-wkup";
|
||||
reg = <c00 40>;
|
||||
interrupts = <1 8 0 0 3 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
pci@0d00 {
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
device_type = "pci";
|
||||
compatible = "mpc5200b-pci\0mpc52xx-pci";
|
||||
reg = <d00 100>;
|
||||
interrupt-map-mask = <f800 0 0 7>;
|
||||
interrupt-map = <c000 0 0 1 500 0 0 3 // 1st slot
|
||||
c000 0 0 2 500 1 1 3
|
||||
c000 0 0 3 500 1 2 3
|
||||
c000 0 0 4 500 1 3 3
|
||||
|
||||
c800 0 0 1 500 1 1 3 // 2nd slot
|
||||
c800 0 0 2 500 1 2 3
|
||||
c800 0 0 3 500 1 3 3
|
||||
c800 0 0 4 500 0 0 3>;
|
||||
clock-frequency = <0>; // From boot loader
|
||||
interrupts = <2 8 0 2 9 0 2 a 0>;
|
||||
interrupt-parent = <500>;
|
||||
bus-range = <0 0>;
|
||||
ranges = <42000000 0 80000000 80000000 0 20000000
|
||||
02000000 0 a0000000 a0000000 0 10000000
|
||||
01000000 0 00000000 b0000000 0 01000000>;
|
||||
};
|
||||
|
||||
spi@f00 {
|
||||
device_type = "spi";
|
||||
compatible = "mpc5200b-spi\0mpc52xx-spi";
|
||||
reg = <f00 20>;
|
||||
interrupts = <2 d 0 2 e 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
usb@1000 {
|
||||
device_type = "usb-ohci-be";
|
||||
compatible = "mpc5200b-ohci\0mpc52xx-ohci\0ohci-be";
|
||||
reg = <1000 ff>;
|
||||
interrupts = <2 6 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
bestcomm@1200 {
|
||||
device_type = "dma-controller";
|
||||
compatible = "mpc5200b-bestcomm\0mpc52xx-bestcomm";
|
||||
reg = <1200 80>;
|
||||
interrupts = <3 0 0 3 1 0 3 2 0 3 3 0
|
||||
3 4 0 3 5 0 3 6 0 3 7 0
|
||||
3 8 0 3 9 0 3 a 0 3 b 0
|
||||
3 c 0 3 d 0 3 e 0 3 f 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
xlb@1f00 {
|
||||
compatible = "mpc5200b-xlb\0mpc52xx-xlb";
|
||||
reg = <1f00 100>;
|
||||
};
|
||||
|
||||
serial@2000 { // PSC1
|
||||
device_type = "serial";
|
||||
compatible = "mpc5200b-psc-uart\0mpc52xx-psc-uart";
|
||||
port-number = <0>; // Logical port assignment
|
||||
reg = <2000 100>;
|
||||
interrupts = <2 1 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
// PSC2 in spi mode example
|
||||
spi@2200 { // PSC2
|
||||
device_type = "spi";
|
||||
compatible = "mpc5200b-psc-spi\0mpc52xx-psc-spi";
|
||||
reg = <2200 100>;
|
||||
interrupts = <2 2 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
// PSC3 in CODEC mode example
|
||||
i2s@2400 { // PSC3
|
||||
device_type = "i2s";
|
||||
compatible = "mpc5200b-psc-i2s\0mpc52xx-psc-i2s";
|
||||
reg = <2400 100>;
|
||||
interrupts = <2 3 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
// PSC4 unconfigured
|
||||
//serial@2600 { // PSC4
|
||||
// device_type = "serial";
|
||||
// compatible = "mpc5200b-psc-uart\0mpc52xx-psc-uart";
|
||||
// reg = <2600 100>;
|
||||
// interrupts = <2 b 0>;
|
||||
// interrupt-parent = <500>;
|
||||
//};
|
||||
|
||||
// PSC5 unconfigured
|
||||
//serial@2800 { // PSC5
|
||||
// device_type = "serial";
|
||||
// compatible = "mpc5200b-psc-uart\0mpc52xx-psc-uart";
|
||||
// reg = <2800 100>;
|
||||
// interrupts = <2 c 0>;
|
||||
// interrupt-parent = <500>;
|
||||
//};
|
||||
|
||||
// PSC6 in AC97 mode example
|
||||
ac97@2c00 { // PSC6
|
||||
device_type = "ac97";
|
||||
compatible = "mpc5200b-psc-ac97\0mpc52xx-psc-ac97";
|
||||
reg = <2c00 100>;
|
||||
interrupts = <2 4 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
ethernet@3000 {
|
||||
device_type = "network";
|
||||
compatible = "mpc5200b-fec\0mpc52xx-fec";
|
||||
reg = <3000 800>;
|
||||
mac-address = [ 02 03 04 05 06 07 ]; // Bad!
|
||||
interrupts = <2 5 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
ata@3a00 {
|
||||
device_type = "ata";
|
||||
compatible = "mpc5200b-ata\0mpc52xx-ata";
|
||||
reg = <3a00 100>;
|
||||
interrupts = <2 7 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
i2c@3d00 {
|
||||
device_type = "i2c";
|
||||
compatible = "mpc5200b-i2c\0mpc52xx-i2c";
|
||||
reg = <3d00 40>;
|
||||
interrupts = <2 f 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
|
||||
i2c@3d40 {
|
||||
device_type = "i2c";
|
||||
compatible = "mpc5200b-i2c\0mpc52xx-i2c";
|
||||
reg = <3d40 40>;
|
||||
interrupts = <2 10 0>;
|
||||
interrupt-parent = <500>;
|
||||
};
|
||||
sram@8000 {
|
||||
device_type = "sram";
|
||||
compatible = "mpc5200b-sram\0mpc52xx-sram\0sram";
|
||||
reg = <8000 4000>;
|
||||
};
|
||||
};
|
||||
};
|
@ -161,29 +161,41 @@
|
||||
interrupt-map = <
|
||||
|
||||
/* IDSEL 0x11 */
|
||||
0800 0 0 1 7400 24 0
|
||||
0800 0 0 2 7400 25 0
|
||||
0800 0 0 3 7400 26 0
|
||||
0800 0 0 4 7400 27 0
|
||||
0800 0 0 1 1180 24 0
|
||||
0800 0 0 2 1180 25 0
|
||||
0800 0 0 3 1180 26 0
|
||||
0800 0 0 4 1180 27 0
|
||||
|
||||
/* IDSEL 0x12 */
|
||||
1000 0 0 1 7400 25 0
|
||||
1000 0 0 2 7400 26 0
|
||||
1000 0 0 3 7400 27 0
|
||||
1000 0 0 4 7400 24 0
|
||||
1000 0 0 1 1180 25 0
|
||||
1000 0 0 2 1180 26 0
|
||||
1000 0 0 3 1180 27 0
|
||||
1000 0 0 4 1180 24 0
|
||||
|
||||
/* IDSEL 0x13 */
|
||||
1800 0 0 1 7400 26 0
|
||||
1800 0 0 2 7400 27 0
|
||||
1800 0 0 3 7400 24 0
|
||||
1800 0 0 4 7400 25 0
|
||||
1800 0 0 1 1180 26 0
|
||||
1800 0 0 2 1180 27 0
|
||||
1800 0 0 3 1180 24 0
|
||||
1800 0 0 4 1180 25 0
|
||||
|
||||
/* IDSEL 0x14 */
|
||||
2000 0 0 1 7400 27 0
|
||||
2000 0 0 2 7400 24 0
|
||||
2000 0 0 3 7400 25 0
|
||||
2000 0 0 4 7400 26 0
|
||||
2000 0 0 1 1180 27 0
|
||||
2000 0 0 2 1180 24 0
|
||||
2000 0 0 3 1180 25 0
|
||||
2000 0 0 4 1180 26 0
|
||||
>;
|
||||
router@1180 {
|
||||
linux,phandle = <1180>;
|
||||
clock-frequency = <0>;
|
||||
interrupt-controller;
|
||||
device_type = "pic-router";
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <2>;
|
||||
built-in;
|
||||
big-endian;
|
||||
interrupts = <17 2>;
|
||||
interrupt-parent = <7400>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
880
arch/powerpc/boot/flatdevtree.c
Normal file
880
arch/powerpc/boot/flatdevtree.c
Normal file
@ -0,0 +1,880 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright Pantelis Antoniou 2006
|
||||
* Copyright (C) IBM Corporation 2006
|
||||
*
|
||||
* Authors: Pantelis Antoniou <pantelis@embeddedalley.com>
|
||||
* Hollis Blanchard <hollisb@us.ibm.com>
|
||||
* Mark A. Greer <mgreer@mvista.com>
|
||||
* Paul Mackerras <paulus@samba.org>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include "flatdevtree.h"
|
||||
#include "flatdevtree_env.h"
|
||||
|
||||
#define _ALIGN(x, al) (((x) + (al) - 1) & ~((al) - 1))
|
||||
|
||||
/* Routines for keeping node ptrs returned by ft_find_device current */
|
||||
/* First entry not used b/c it would return 0 and be taken as NULL/error */
|
||||
static void *ft_node_add(struct ft_cxt *cxt, char *node)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 1; i < cxt->nodes_used; i++) /* already there? */
|
||||
if (cxt->node_tbl[i] == node)
|
||||
return (void *)i;
|
||||
|
||||
if (cxt->nodes_used < cxt->node_max) {
|
||||
cxt->node_tbl[cxt->nodes_used] = node;
|
||||
return (void *)cxt->nodes_used++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *ft_node_ph2node(struct ft_cxt *cxt, const void *phandle)
|
||||
{
|
||||
unsigned int i = (unsigned int)phandle;
|
||||
|
||||
if (i < cxt->nodes_used)
|
||||
return cxt->node_tbl[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void ft_node_update_before(struct ft_cxt *cxt, char *addr, int shift)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (shift == 0)
|
||||
return;
|
||||
|
||||
for (i = 1; i < cxt->nodes_used; i++)
|
||||
if (cxt->node_tbl[i] < addr)
|
||||
cxt->node_tbl[i] += shift;
|
||||
}
|
||||
|
||||
static void ft_node_update_after(struct ft_cxt *cxt, char *addr, int shift)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (shift == 0)
|
||||
return;
|
||||
|
||||
for (i = 1; i < cxt->nodes_used; i++)
|
||||
if (cxt->node_tbl[i] >= addr)
|
||||
cxt->node_tbl[i] += shift;
|
||||
}
|
||||
|
||||
/* Struct used to return info from ft_next() */
|
||||
struct ft_atom {
|
||||
u32 tag;
|
||||
const char *name;
|
||||
void *data;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
/* Set ptrs to current one's info; return addr of next one */
|
||||
static char *ft_next(struct ft_cxt *cxt, char *p, struct ft_atom *ret)
|
||||
{
|
||||
u32 sz;
|
||||
|
||||
if (p >= cxt->rgn[FT_STRUCT].start + cxt->rgn[FT_STRUCT].size)
|
||||
return NULL;
|
||||
|
||||
ret->tag = be32_to_cpu(*(u32 *) p);
|
||||
p += 4;
|
||||
|
||||
switch (ret->tag) { /* Tag */
|
||||
case OF_DT_BEGIN_NODE:
|
||||
ret->name = p;
|
||||
ret->data = (void *)(p - 4); /* start of node */
|
||||
p += _ALIGN(strlen(p) + 1, 4);
|
||||
break;
|
||||
case OF_DT_PROP:
|
||||
ret->size = sz = be32_to_cpu(*(u32 *) p);
|
||||
ret->name = cxt->str_anchor + be32_to_cpu(*(u32 *) (p + 4));
|
||||
ret->data = (void *)(p + 8);
|
||||
p += 8 + _ALIGN(sz, 4);
|
||||
break;
|
||||
case OF_DT_END_NODE:
|
||||
case OF_DT_NOP:
|
||||
break;
|
||||
case OF_DT_END:
|
||||
default:
|
||||
p = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
#define HDR_SIZE _ALIGN(sizeof(struct boot_param_header), 8)
|
||||
#define EXPAND_INCR 1024 /* alloc this much extra when expanding */
|
||||
|
||||
/* See if the regions are in the standard order and non-overlapping */
|
||||
static int ft_ordered(struct ft_cxt *cxt)
|
||||
{
|
||||
char *p = (char *)cxt->bph + HDR_SIZE;
|
||||
enum ft_rgn_id r;
|
||||
|
||||
for (r = FT_RSVMAP; r <= FT_STRINGS; ++r) {
|
||||
if (p > cxt->rgn[r].start)
|
||||
return 0;
|
||||
p = cxt->rgn[r].start + cxt->rgn[r].size;
|
||||
}
|
||||
return p <= (char *)cxt->bph + cxt->max_size;
|
||||
}
|
||||
|
||||
/* Copy the tree to a newly-allocated region and put things in order */
|
||||
static int ft_reorder(struct ft_cxt *cxt, int nextra)
|
||||
{
|
||||
unsigned long tot;
|
||||
enum ft_rgn_id r;
|
||||
char *p, *pend;
|
||||
int stroff;
|
||||
|
||||
tot = HDR_SIZE + EXPAND_INCR;
|
||||
for (r = FT_RSVMAP; r <= FT_STRINGS; ++r)
|
||||
tot += cxt->rgn[r].size;
|
||||
if (nextra > 0)
|
||||
tot += nextra;
|
||||
tot = _ALIGN(tot, 8);
|
||||
|
||||
if (!cxt->realloc)
|
||||
return 0;
|
||||
p = cxt->realloc(NULL, tot);
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
memcpy(p, cxt->bph, sizeof(struct boot_param_header));
|
||||
/* offsets get fixed up later */
|
||||
|
||||
cxt->bph = (struct boot_param_header *)p;
|
||||
cxt->max_size = tot;
|
||||
pend = p + tot;
|
||||
p += HDR_SIZE;
|
||||
|
||||
memcpy(p, cxt->rgn[FT_RSVMAP].start, cxt->rgn[FT_RSVMAP].size);
|
||||
cxt->rgn[FT_RSVMAP].start = p;
|
||||
p += cxt->rgn[FT_RSVMAP].size;
|
||||
|
||||
memcpy(p, cxt->rgn[FT_STRUCT].start, cxt->rgn[FT_STRUCT].size);
|
||||
ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start,
|
||||
p - cxt->rgn[FT_STRUCT].start);
|
||||
cxt->p += p - cxt->rgn[FT_STRUCT].start;
|
||||
cxt->rgn[FT_STRUCT].start = p;
|
||||
|
||||
p = pend - cxt->rgn[FT_STRINGS].size;
|
||||
memcpy(p, cxt->rgn[FT_STRINGS].start, cxt->rgn[FT_STRINGS].size);
|
||||
stroff = cxt->str_anchor - cxt->rgn[FT_STRINGS].start;
|
||||
cxt->rgn[FT_STRINGS].start = p;
|
||||
cxt->str_anchor = p + stroff;
|
||||
|
||||
cxt->isordered = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline char *prev_end(struct ft_cxt *cxt, enum ft_rgn_id r)
|
||||
{
|
||||
if (r > FT_RSVMAP)
|
||||
return cxt->rgn[r - 1].start + cxt->rgn[r - 1].size;
|
||||
return (char *)cxt->bph + HDR_SIZE;
|
||||
}
|
||||
|
||||
static inline char *next_start(struct ft_cxt *cxt, enum ft_rgn_id r)
|
||||
{
|
||||
if (r < FT_STRINGS)
|
||||
return cxt->rgn[r + 1].start;
|
||||
return (char *)cxt->bph + cxt->max_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* See if we can expand region rgn by nextra bytes by using up
|
||||
* free space after or before the region.
|
||||
*/
|
||||
static int ft_shuffle(struct ft_cxt *cxt, char **pp, enum ft_rgn_id rgn,
|
||||
int nextra)
|
||||
{
|
||||
char *p = *pp;
|
||||
char *rgn_start, *rgn_end;
|
||||
|
||||
rgn_start = cxt->rgn[rgn].start;
|
||||
rgn_end = rgn_start + cxt->rgn[rgn].size;
|
||||
if (nextra <= 0 || rgn_end + nextra <= next_start(cxt, rgn)) {
|
||||
/* move following stuff */
|
||||
if (p < rgn_end) {
|
||||
if (nextra < 0)
|
||||
memmove(p, p - nextra, rgn_end - p + nextra);
|
||||
else
|
||||
memmove(p + nextra, p, rgn_end - p);
|
||||
if (rgn == FT_STRUCT)
|
||||
ft_node_update_after(cxt, p, nextra);
|
||||
}
|
||||
cxt->rgn[rgn].size += nextra;
|
||||
if (rgn == FT_STRINGS)
|
||||
/* assumes strings only added at beginning */
|
||||
cxt->str_anchor += nextra;
|
||||
return 1;
|
||||
}
|
||||
if (prev_end(cxt, rgn) <= rgn_start - nextra) {
|
||||
/* move preceding stuff */
|
||||
if (p > rgn_start) {
|
||||
memmove(rgn_start - nextra, rgn_start, p - rgn_start);
|
||||
if (rgn == FT_STRUCT)
|
||||
ft_node_update_before(cxt, p, -nextra);
|
||||
}
|
||||
*p -= nextra;
|
||||
cxt->rgn[rgn].start -= nextra;
|
||||
cxt->rgn[rgn].size += nextra;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ft_make_space(struct ft_cxt *cxt, char **pp, enum ft_rgn_id rgn,
|
||||
int nextra)
|
||||
{
|
||||
unsigned long size, ssize, tot;
|
||||
char *str, *next;
|
||||
enum ft_rgn_id r;
|
||||
|
||||
if (!cxt->isordered && !ft_reorder(cxt, nextra))
|
||||
return 0;
|
||||
if (ft_shuffle(cxt, pp, rgn, nextra))
|
||||
return 1;
|
||||
|
||||
/* See if there is space after the strings section */
|
||||
ssize = cxt->rgn[FT_STRINGS].size;
|
||||
if (cxt->rgn[FT_STRINGS].start + ssize
|
||||
< (char *)cxt->bph + cxt->max_size) {
|
||||
/* move strings up as far as possible */
|
||||
str = (char *)cxt->bph + cxt->max_size - ssize;
|
||||
cxt->str_anchor += str - cxt->rgn[FT_STRINGS].start;
|
||||
memmove(str, cxt->rgn[FT_STRINGS].start, ssize);
|
||||
cxt->rgn[FT_STRINGS].start = str;
|
||||
/* enough space now? */
|
||||
if (rgn >= FT_STRUCT && ft_shuffle(cxt, pp, rgn, nextra))
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* how much total free space is there following this region? */
|
||||
tot = 0;
|
||||
for (r = rgn; r < FT_STRINGS; ++r) {
|
||||
char *r_end = cxt->rgn[r].start + cxt->rgn[r].size;
|
||||
tot += next_start(cxt, rgn) - r_end;
|
||||
}
|
||||
|
||||
/* cast is to shut gcc up; we know nextra >= 0 */
|
||||
if (tot < (unsigned int)nextra) {
|
||||
/* have to reallocate */
|
||||
char *newp, *new_start;
|
||||
int shift;
|
||||
|
||||
if (!cxt->realloc)
|
||||
return 0;
|
||||
size = _ALIGN(cxt->max_size + (nextra - tot) + EXPAND_INCR, 8);
|
||||
newp = cxt->realloc(cxt->bph, size);
|
||||
if (!newp)
|
||||
return 0;
|
||||
cxt->max_size = size;
|
||||
shift = newp - (char *)cxt->bph;
|
||||
|
||||
if (shift) { /* realloc can return same addr */
|
||||
cxt->bph = (struct boot_param_header *)newp;
|
||||
ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start,
|
||||
shift);
|
||||
for (r = FT_RSVMAP; r <= FT_STRINGS; ++r) {
|
||||
new_start = cxt->rgn[r].start + shift;
|
||||
cxt->rgn[r].start = new_start;
|
||||
}
|
||||
*pp += shift;
|
||||
cxt->str_anchor += shift;
|
||||
}
|
||||
|
||||
/* move strings up to the end */
|
||||
str = newp + size - ssize;
|
||||
cxt->str_anchor += str - cxt->rgn[FT_STRINGS].start;
|
||||
memmove(str, cxt->rgn[FT_STRINGS].start, ssize);
|
||||
cxt->rgn[FT_STRINGS].start = str;
|
||||
|
||||
if (ft_shuffle(cxt, pp, rgn, nextra))
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* must be FT_RSVMAP and we need to move FT_STRUCT up */
|
||||
if (rgn == FT_RSVMAP) {
|
||||
next = cxt->rgn[FT_RSVMAP].start + cxt->rgn[FT_RSVMAP].size
|
||||
+ nextra;
|
||||
ssize = cxt->rgn[FT_STRUCT].size;
|
||||
if (next + ssize >= cxt->rgn[FT_STRINGS].start)
|
||||
return 0; /* "can't happen" */
|
||||
memmove(next, cxt->rgn[FT_STRUCT].start, ssize);
|
||||
ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start, nextra);
|
||||
cxt->rgn[FT_STRUCT].start = next;
|
||||
|
||||
if (ft_shuffle(cxt, pp, rgn, nextra))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0; /* "can't happen" */
|
||||
}
|
||||
|
||||
static void ft_put_word(struct ft_cxt *cxt, u32 v)
|
||||
{
|
||||
*(u32 *) cxt->p = cpu_to_be32(v);
|
||||
cxt->p += 4;
|
||||
}
|
||||
|
||||
static void ft_put_bin(struct ft_cxt *cxt, const void *data, unsigned int sz)
|
||||
{
|
||||
unsigned long sza = _ALIGN(sz, 4);
|
||||
|
||||
/* zero out the alignment gap if necessary */
|
||||
if (sz < sza)
|
||||
*(u32 *) (cxt->p + sza - 4) = 0;
|
||||
|
||||
/* copy in the data */
|
||||
memcpy(cxt->p, data, sz);
|
||||
|
||||
cxt->p += sza;
|
||||
}
|
||||
|
||||
int ft_begin_node(struct ft_cxt *cxt, const char *name)
|
||||
{
|
||||
unsigned long nlen = strlen(name) + 1;
|
||||
unsigned long len = 8 + _ALIGN(nlen, 4);
|
||||
|
||||
if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, len))
|
||||
return -1;
|
||||
ft_put_word(cxt, OF_DT_BEGIN_NODE);
|
||||
ft_put_bin(cxt, name, strlen(name) + 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ft_end_node(struct ft_cxt *cxt)
|
||||
{
|
||||
ft_put_word(cxt, OF_DT_END_NODE);
|
||||
}
|
||||
|
||||
void ft_nop(struct ft_cxt *cxt)
|
||||
{
|
||||
if (ft_make_space(cxt, &cxt->p, FT_STRUCT, 4))
|
||||
ft_put_word(cxt, OF_DT_NOP);
|
||||
}
|
||||
|
||||
#define NO_STRING 0x7fffffff
|
||||
|
||||
static int lookup_string(struct ft_cxt *cxt, const char *name)
|
||||
{
|
||||
char *p, *end;
|
||||
|
||||
p = cxt->rgn[FT_STRINGS].start;
|
||||
end = p + cxt->rgn[FT_STRINGS].size;
|
||||
while (p < end) {
|
||||
if (strcmp(p, (char *)name) == 0)
|
||||
return p - cxt->str_anchor;
|
||||
p += strlen(p) + 1;
|
||||
}
|
||||
|
||||
return NO_STRING;
|
||||
}
|
||||
|
||||
/* lookup string and insert if not found */
|
||||
static int map_string(struct ft_cxt *cxt, const char *name)
|
||||
{
|
||||
int off;
|
||||
char *p;
|
||||
|
||||
off = lookup_string(cxt, name);
|
||||
if (off != NO_STRING)
|
||||
return off;
|
||||
p = cxt->rgn[FT_STRINGS].start;
|
||||
if (!ft_make_space(cxt, &p, FT_STRINGS, strlen(name) + 1))
|
||||
return NO_STRING;
|
||||
strcpy(p, name);
|
||||
return p - cxt->str_anchor;
|
||||
}
|
||||
|
||||
int ft_prop(struct ft_cxt *cxt, const char *name, const void *data,
|
||||
unsigned int sz)
|
||||
{
|
||||
int off, len;
|
||||
|
||||
off = lookup_string(cxt, name);
|
||||
if (off == NO_STRING)
|
||||
return -1;
|
||||
|
||||
len = 12 + _ALIGN(sz, 4);
|
||||
if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, len))
|
||||
return -1;
|
||||
|
||||
ft_put_word(cxt, OF_DT_PROP);
|
||||
ft_put_word(cxt, sz);
|
||||
ft_put_word(cxt, off);
|
||||
ft_put_bin(cxt, data, sz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str)
|
||||
{
|
||||
return ft_prop(cxt, name, str, strlen(str) + 1);
|
||||
}
|
||||
|
||||
int ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val)
|
||||
{
|
||||
u32 v = cpu_to_be32((u32) val);
|
||||
|
||||
return ft_prop(cxt, name, &v, 4);
|
||||
}
|
||||
|
||||
/* Calculate the size of the reserved map */
|
||||
static unsigned long rsvmap_size(struct ft_cxt *cxt)
|
||||
{
|
||||
struct ft_reserve *res;
|
||||
|
||||
res = (struct ft_reserve *)cxt->rgn[FT_RSVMAP].start;
|
||||
while (res->start || res->len)
|
||||
++res;
|
||||
return (char *)(res + 1) - cxt->rgn[FT_RSVMAP].start;
|
||||
}
|
||||
|
||||
/* Calculate the size of the struct region by stepping through it */
|
||||
static unsigned long struct_size(struct ft_cxt *cxt)
|
||||
{
|
||||
char *p = cxt->rgn[FT_STRUCT].start;
|
||||
char *next;
|
||||
struct ft_atom atom;
|
||||
|
||||
/* make check in ft_next happy */
|
||||
if (cxt->rgn[FT_STRUCT].size == 0)
|
||||
cxt->rgn[FT_STRUCT].size = 0xfffffffful - (unsigned long)p;
|
||||
|
||||
while ((next = ft_next(cxt, p, &atom)) != NULL)
|
||||
p = next;
|
||||
return p + 4 - cxt->rgn[FT_STRUCT].start;
|
||||
}
|
||||
|
||||
/* add `adj' on to all string offset values in the struct area */
|
||||
static void adjust_string_offsets(struct ft_cxt *cxt, int adj)
|
||||
{
|
||||
char *p = cxt->rgn[FT_STRUCT].start;
|
||||
char *next;
|
||||
struct ft_atom atom;
|
||||
int off;
|
||||
|
||||
while ((next = ft_next(cxt, p, &atom)) != NULL) {
|
||||
if (atom.tag == OF_DT_PROP) {
|
||||
off = be32_to_cpu(*(u32 *) (p + 8));
|
||||
*(u32 *) (p + 8) = cpu_to_be32(off + adj);
|
||||
}
|
||||
p = next;
|
||||
}
|
||||
}
|
||||
|
||||
/* start construction of the flat OF tree from scratch */
|
||||
void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size,
|
||||
void *(*realloc_fn) (void *, unsigned long))
|
||||
{
|
||||
struct boot_param_header *bph = blob;
|
||||
char *p;
|
||||
struct ft_reserve *pres;
|
||||
|
||||
/* clear the cxt */
|
||||
memset(cxt, 0, sizeof(*cxt));
|
||||
|
||||
cxt->bph = bph;
|
||||
cxt->max_size = max_size;
|
||||
cxt->realloc = realloc_fn;
|
||||
cxt->isordered = 1;
|
||||
|
||||
/* zero everything in the header area */
|
||||
memset(bph, 0, sizeof(*bph));
|
||||
|
||||
bph->magic = cpu_to_be32(OF_DT_HEADER);
|
||||
bph->version = cpu_to_be32(0x10);
|
||||
bph->last_comp_version = cpu_to_be32(0x10);
|
||||
|
||||
/* start pointers */
|
||||
cxt->rgn[FT_RSVMAP].start = p = blob + HDR_SIZE;
|
||||
cxt->rgn[FT_RSVMAP].size = sizeof(struct ft_reserve);
|
||||
pres = (struct ft_reserve *)p;
|
||||
cxt->rgn[FT_STRUCT].start = p += sizeof(struct ft_reserve);
|
||||
cxt->rgn[FT_STRUCT].size = 4;
|
||||
cxt->rgn[FT_STRINGS].start = blob + max_size;
|
||||
cxt->rgn[FT_STRINGS].size = 0;
|
||||
|
||||
/* init rsvmap and struct */
|
||||
pres->start = 0;
|
||||
pres->len = 0;
|
||||
*(u32 *) p = cpu_to_be32(OF_DT_END);
|
||||
|
||||
cxt->str_anchor = blob;
|
||||
}
|
||||
|
||||
/* open up an existing blob to be examined or modified */
|
||||
int ft_open(struct ft_cxt *cxt, void *blob, unsigned int max_size,
|
||||
unsigned int max_find_device,
|
||||
void *(*realloc_fn) (void *, unsigned long))
|
||||
{
|
||||
struct boot_param_header *bph = blob;
|
||||
|
||||
/* can't cope with version < 16 */
|
||||
if (be32_to_cpu(bph->version) < 16)
|
||||
return -1;
|
||||
|
||||
/* clear the cxt */
|
||||
memset(cxt, 0, sizeof(*cxt));
|
||||
|
||||
/* alloc node_tbl to track node ptrs returned by ft_find_device */
|
||||
++max_find_device;
|
||||
cxt->node_tbl = realloc_fn(NULL, max_find_device * sizeof(char *));
|
||||
if (!cxt->node_tbl)
|
||||
return -1;
|
||||
memset(cxt->node_tbl, 0, max_find_device * sizeof(char *));
|
||||
cxt->node_max = max_find_device;
|
||||
cxt->nodes_used = 1; /* don't use idx 0 b/c looks like NULL */
|
||||
|
||||
cxt->bph = bph;
|
||||
cxt->max_size = max_size;
|
||||
cxt->realloc = realloc_fn;
|
||||
|
||||
cxt->rgn[FT_RSVMAP].start = blob + be32_to_cpu(bph->off_mem_rsvmap);
|
||||
cxt->rgn[FT_RSVMAP].size = rsvmap_size(cxt);
|
||||
cxt->rgn[FT_STRUCT].start = blob + be32_to_cpu(bph->off_dt_struct);
|
||||
cxt->rgn[FT_STRUCT].size = struct_size(cxt);
|
||||
cxt->rgn[FT_STRINGS].start = blob + be32_to_cpu(bph->off_dt_strings);
|
||||
cxt->rgn[FT_STRINGS].size = be32_to_cpu(bph->dt_strings_size);
|
||||
/* Leave as '0' to force first ft_make_space call to do a ft_reorder
|
||||
* and move dt to an area allocated by realloc.
|
||||
cxt->isordered = ft_ordered(cxt);
|
||||
*/
|
||||
|
||||
cxt->p = cxt->rgn[FT_STRUCT].start;
|
||||
cxt->str_anchor = cxt->rgn[FT_STRINGS].start;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* add a reserver physical area to the rsvmap */
|
||||
int ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size)
|
||||
{
|
||||
char *p;
|
||||
struct ft_reserve *pres;
|
||||
|
||||
p = cxt->rgn[FT_RSVMAP].start + cxt->rgn[FT_RSVMAP].size
|
||||
- sizeof(struct ft_reserve);
|
||||
if (!ft_make_space(cxt, &p, FT_RSVMAP, sizeof(struct ft_reserve)))
|
||||
return -1;
|
||||
|
||||
pres = (struct ft_reserve *)p;
|
||||
pres->start = cpu_to_be64(physaddr);
|
||||
pres->len = cpu_to_be64(size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ft_begin_tree(struct ft_cxt *cxt)
|
||||
{
|
||||
cxt->p = cxt->rgn[FT_STRUCT].start;
|
||||
}
|
||||
|
||||
void ft_end_tree(struct ft_cxt *cxt)
|
||||
{
|
||||
struct boot_param_header *bph = cxt->bph;
|
||||
char *p, *oldstr, *str, *endp;
|
||||
unsigned long ssize;
|
||||
int adj;
|
||||
|
||||
if (!cxt->isordered)
|
||||
return; /* we haven't touched anything */
|
||||
|
||||
/* adjust string offsets */
|
||||
oldstr = cxt->rgn[FT_STRINGS].start;
|
||||
adj = cxt->str_anchor - oldstr;
|
||||
if (adj)
|
||||
adjust_string_offsets(cxt, adj);
|
||||
|
||||
/* make strings end on 8-byte boundary */
|
||||
ssize = cxt->rgn[FT_STRINGS].size;
|
||||
endp = (char *)_ALIGN((unsigned long)cxt->rgn[FT_STRUCT].start
|
||||
+ cxt->rgn[FT_STRUCT].size + ssize, 8);
|
||||
str = endp - ssize;
|
||||
|
||||
/* move strings down to end of structs */
|
||||
memmove(str, oldstr, ssize);
|
||||
cxt->str_anchor = str;
|
||||
cxt->rgn[FT_STRINGS].start = str;
|
||||
|
||||
/* fill in header fields */
|
||||
p = (char *)bph;
|
||||
bph->totalsize = cpu_to_be32(endp - p);
|
||||
bph->off_mem_rsvmap = cpu_to_be32(cxt->rgn[FT_RSVMAP].start - p);
|
||||
bph->off_dt_struct = cpu_to_be32(cxt->rgn[FT_STRUCT].start - p);
|
||||
bph->off_dt_strings = cpu_to_be32(cxt->rgn[FT_STRINGS].start - p);
|
||||
bph->dt_strings_size = cpu_to_be32(ssize);
|
||||
}
|
||||
|
||||
void *ft_find_device(struct ft_cxt *cxt, const char *srch_path)
|
||||
{
|
||||
char *node;
|
||||
|
||||
/* require absolute path */
|
||||
if (srch_path[0] != '/')
|
||||
return NULL;
|
||||
node = ft_find_descendent(cxt, cxt->rgn[FT_STRUCT].start, srch_path);
|
||||
return ft_node_add(cxt, node);
|
||||
}
|
||||
|
||||
void *ft_find_descendent(struct ft_cxt *cxt, void *top, const char *srch_path)
|
||||
{
|
||||
struct ft_atom atom;
|
||||
char *p;
|
||||
const char *cp, *q;
|
||||
int cl;
|
||||
int depth = -1;
|
||||
int dmatch = 0;
|
||||
const char *path_comp[FT_MAX_DEPTH];
|
||||
|
||||
cp = srch_path;
|
||||
cl = 0;
|
||||
p = top;
|
||||
|
||||
while ((p = ft_next(cxt, p, &atom)) != NULL) {
|
||||
switch (atom.tag) {
|
||||
case OF_DT_BEGIN_NODE:
|
||||
++depth;
|
||||
if (depth != dmatch)
|
||||
break;
|
||||
cxt->genealogy[depth] = atom.data;
|
||||
cxt->genealogy[depth + 1] = NULL;
|
||||
if (depth && !(strncmp(atom.name, cp, cl) == 0
|
||||
&& (atom.name[cl] == '/'
|
||||
|| atom.name[cl] == '\0'
|
||||
|| atom.name[cl] == '@')))
|
||||
break;
|
||||
path_comp[dmatch] = cp;
|
||||
/* it matches so far, advance to next path component */
|
||||
cp += cl;
|
||||
/* skip slashes */
|
||||
while (*cp == '/')
|
||||
++cp;
|
||||
/* we're done if this is the end of the string */
|
||||
if (*cp == 0)
|
||||
return atom.data;
|
||||
/* look for end of this component */
|
||||
q = strchr(cp, '/');
|
||||
if (q)
|
||||
cl = q - cp;
|
||||
else
|
||||
cl = strlen(cp);
|
||||
++dmatch;
|
||||
break;
|
||||
case OF_DT_END_NODE:
|
||||
if (depth == 0)
|
||||
return NULL;
|
||||
if (dmatch > depth) {
|
||||
--dmatch;
|
||||
cl = cp - path_comp[dmatch] - 1;
|
||||
cp = path_comp[dmatch];
|
||||
while (cl > 0 && cp[cl - 1] == '/')
|
||||
--cl;
|
||||
}
|
||||
--depth;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *ft_get_parent(struct ft_cxt *cxt, const void *phandle)
|
||||
{
|
||||
void *node;
|
||||
int d;
|
||||
struct ft_atom atom;
|
||||
char *p;
|
||||
|
||||
node = ft_node_ph2node(cxt, phandle);
|
||||
if (node == NULL)
|
||||
return NULL;
|
||||
|
||||
for (d = 0; cxt->genealogy[d] != NULL; ++d)
|
||||
if (cxt->genealogy[d] == node)
|
||||
return cxt->genealogy[d > 0 ? d - 1 : 0];
|
||||
|
||||
/* have to do it the hard way... */
|
||||
p = cxt->rgn[FT_STRUCT].start;
|
||||
d = 0;
|
||||
while ((p = ft_next(cxt, p, &atom)) != NULL) {
|
||||
switch (atom.tag) {
|
||||
case OF_DT_BEGIN_NODE:
|
||||
cxt->genealogy[d] = atom.data;
|
||||
if (node == atom.data) {
|
||||
/* found it */
|
||||
cxt->genealogy[d + 1] = NULL;
|
||||
return d > 0 ? cxt->genealogy[d - 1] : node;
|
||||
}
|
||||
++d;
|
||||
break;
|
||||
case OF_DT_END_NODE:
|
||||
--d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
|
||||
void *buf, const unsigned int buflen)
|
||||
{
|
||||
struct ft_atom atom;
|
||||
void *node;
|
||||
char *p;
|
||||
int depth;
|
||||
unsigned int size;
|
||||
|
||||
node = ft_node_ph2node(cxt, phandle);
|
||||
if (node == NULL)
|
||||
return -1;
|
||||
|
||||
depth = 0;
|
||||
p = (char *)node;
|
||||
|
||||
while ((p = ft_next(cxt, p, &atom)) != NULL) {
|
||||
switch (atom.tag) {
|
||||
case OF_DT_BEGIN_NODE:
|
||||
++depth;
|
||||
break;
|
||||
case OF_DT_PROP:
|
||||
if ((depth != 1) || strcmp(atom.name, propname))
|
||||
break;
|
||||
size = min(atom.size, buflen);
|
||||
memcpy(buf, atom.data, size);
|
||||
return atom.size;
|
||||
case OF_DT_END_NODE:
|
||||
if (--depth <= 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
|
||||
const void *buf, const unsigned int buflen)
|
||||
{
|
||||
struct ft_atom atom;
|
||||
void *node;
|
||||
char *p, *next;
|
||||
int nextra, depth;
|
||||
|
||||
node = ft_node_ph2node(cxt, phandle);
|
||||
if (node == NULL)
|
||||
return -1;
|
||||
|
||||
depth = 0;
|
||||
p = node;
|
||||
|
||||
while ((next = ft_next(cxt, p, &atom)) != NULL) {
|
||||
switch (atom.tag) {
|
||||
case OF_DT_BEGIN_NODE:
|
||||
++depth;
|
||||
break;
|
||||
case OF_DT_END_NODE:
|
||||
if (--depth > 0)
|
||||
break;
|
||||
/* haven't found the property, insert here */
|
||||
cxt->p = p;
|
||||
return ft_prop(cxt, propname, buf, buflen);
|
||||
case OF_DT_PROP:
|
||||
if ((depth != 1) || strcmp(atom.name, propname))
|
||||
break;
|
||||
/* found an existing property, overwrite it */
|
||||
nextra = _ALIGN(buflen, 4) - _ALIGN(atom.size, 4);
|
||||
cxt->p = atom.data;
|
||||
if (nextra && !ft_make_space(cxt, &cxt->p, FT_STRUCT,
|
||||
nextra))
|
||||
return -1;
|
||||
*(u32 *) (cxt->p - 8) = cpu_to_be32(buflen);
|
||||
ft_put_bin(cxt, buf, buflen);
|
||||
return 0;
|
||||
}
|
||||
p = next;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ft_del_prop(struct ft_cxt *cxt, const void *phandle, const char *propname)
|
||||
{
|
||||
struct ft_atom atom;
|
||||
void *node;
|
||||
char *p, *next;
|
||||
int size;
|
||||
|
||||
node = ft_node_ph2node(cxt, phandle);
|
||||
if (node == NULL)
|
||||
return -1;
|
||||
|
||||
p = node;
|
||||
while ((next = ft_next(cxt, p, &atom)) != NULL) {
|
||||
switch (atom.tag) {
|
||||
case OF_DT_BEGIN_NODE:
|
||||
case OF_DT_END_NODE:
|
||||
return -1;
|
||||
case OF_DT_PROP:
|
||||
if (strcmp(atom.name, propname))
|
||||
break;
|
||||
/* found the property, remove it */
|
||||
size = 12 + -_ALIGN(atom.size, 4);
|
||||
cxt->p = p;
|
||||
if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, -size))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
p = next;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *path)
|
||||
{
|
||||
struct ft_atom atom;
|
||||
char *p, *next;
|
||||
int depth = 0;
|
||||
|
||||
p = cxt->rgn[FT_STRUCT].start;
|
||||
while ((next = ft_next(cxt, p, &atom)) != NULL) {
|
||||
switch (atom.tag) {
|
||||
case OF_DT_BEGIN_NODE:
|
||||
++depth;
|
||||
if (depth == 1 && strcmp(atom.name, path) == 0)
|
||||
/* duplicate node path, return error */
|
||||
return NULL;
|
||||
break;
|
||||
case OF_DT_END_NODE:
|
||||
--depth;
|
||||
if (depth > 0)
|
||||
break;
|
||||
/* end of node, insert here */
|
||||
cxt->p = p;
|
||||
ft_begin_node(cxt, path);
|
||||
ft_end_node(cxt);
|
||||
return p;
|
||||
}
|
||||
p = next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
#ifndef FLATDEVTREE_H
|
||||
#define FLATDEVTREE_H
|
||||
|
||||
#include "types.h"
|
||||
#include "flatdevtree_env.h"
|
||||
|
||||
/* Definitions used by the flattened device tree */
|
||||
#define OF_DT_HEADER 0xd00dfeed /* marker */
|
||||
@ -43,4 +43,64 @@ struct boot_param_header {
|
||||
u32 dt_strings_size; /* size of the DT strings block */
|
||||
};
|
||||
|
||||
struct ft_reserve {
|
||||
u64 start;
|
||||
u64 len;
|
||||
};
|
||||
|
||||
struct ft_region {
|
||||
char *start;
|
||||
unsigned long size;
|
||||
};
|
||||
|
||||
enum ft_rgn_id {
|
||||
FT_RSVMAP,
|
||||
FT_STRUCT,
|
||||
FT_STRINGS,
|
||||
FT_N_REGION
|
||||
};
|
||||
|
||||
#define FT_MAX_DEPTH 50
|
||||
|
||||
struct ft_cxt {
|
||||
struct boot_param_header *bph;
|
||||
int max_size; /* maximum size of tree */
|
||||
int isordered; /* everything in standard order */
|
||||
void *(*realloc)(void *, unsigned long);
|
||||
char *str_anchor;
|
||||
char *p; /* current insertion point in structs */
|
||||
struct ft_region rgn[FT_N_REGION];
|
||||
void *genealogy[FT_MAX_DEPTH+1];
|
||||
char **node_tbl;
|
||||
unsigned int node_max;
|
||||
unsigned int nodes_used;
|
||||
};
|
||||
|
||||
int ft_begin_node(struct ft_cxt *cxt, const char *name);
|
||||
void ft_end_node(struct ft_cxt *cxt);
|
||||
|
||||
void ft_begin_tree(struct ft_cxt *cxt);
|
||||
void ft_end_tree(struct ft_cxt *cxt);
|
||||
|
||||
void ft_nop(struct ft_cxt *cxt);
|
||||
int ft_prop(struct ft_cxt *cxt, const char *name,
|
||||
const void *data, unsigned int sz);
|
||||
int ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str);
|
||||
int ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val);
|
||||
void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size,
|
||||
void *(*realloc_fn)(void *, unsigned long));
|
||||
int ft_open(struct ft_cxt *cxt, void *blob, unsigned int max_size,
|
||||
unsigned int max_find_device,
|
||||
void *(*realloc_fn)(void *, unsigned long));
|
||||
int ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size);
|
||||
|
||||
void ft_dump_blob(const void *bphp);
|
||||
void ft_merge_blob(struct ft_cxt *cxt, void *blob);
|
||||
void *ft_find_device(struct ft_cxt *cxt, const char *srch_path);
|
||||
void *ft_find_descendent(struct ft_cxt *cxt, void *top, const char *srch_path);
|
||||
int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
|
||||
void *buf, const unsigned int buflen);
|
||||
int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
|
||||
const void *buf, const unsigned int buflen);
|
||||
|
||||
#endif /* FLATDEVTREE_H */
|
||||
|
47
arch/powerpc/boot/flatdevtree_env.h
Normal file
47
arch/powerpc/boot/flatdevtree_env.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file adds the header file glue so that the shared files
|
||||
* flatdevicetree.[ch] can compile and work in the powerpc bootwrapper.
|
||||
*
|
||||
* strncmp & strchr copied from <file:lib/strings.c>
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*
|
||||
* Maintained by: Mark A. Greer <mgreer@mvista.com>
|
||||
*/
|
||||
#ifndef _PPC_BOOT_FLATDEVTREE_ENV_H_
|
||||
#define _PPC_BOOT_FLATDEVTREE_ENV_H_
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include "types.h"
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
#include "ops.h"
|
||||
|
||||
#define be16_to_cpu(x) (x)
|
||||
#define cpu_to_be16(x) (x)
|
||||
#define be32_to_cpu(x) (x)
|
||||
#define cpu_to_be32(x) (x)
|
||||
#define be64_to_cpu(x) (x)
|
||||
#define cpu_to_be64(x) (x)
|
||||
|
||||
static inline int strncmp(const char *cs, const char *ct, size_t count)
|
||||
{
|
||||
signed char __res = 0;
|
||||
|
||||
while (count) {
|
||||
if ((__res = *cs - *ct++) != 0 || !*cs++)
|
||||
break;
|
||||
count--;
|
||||
}
|
||||
return __res;
|
||||
}
|
||||
|
||||
static inline char *strchr(const char *s, int c)
|
||||
{
|
||||
for (; *s != (char)c; ++s)
|
||||
if (*s == '\0')
|
||||
return NULL;
|
||||
return (char *)s;
|
||||
}
|
||||
|
||||
#endif /* _PPC_BOOT_FLATDEVTREE_ENV_H_ */
|
51
arch/powerpc/boot/flatdevtree_misc.c
Normal file
51
arch/powerpc/boot/flatdevtree_misc.c
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* This file does the necessary interface mapping between the bootwrapper
|
||||
* device tree operations and the interface provided by shared source
|
||||
* files flatdevicetree.[ch].
|
||||
*
|
||||
* Author: Mark A. Greer <mgreer@mvista.com>
|
||||
*
|
||||
* 2006 (c) MontaVista Software, Inc. This file is licensed under
|
||||
* the terms of the GNU General Public License version 2. This program
|
||||
* is licensed "as is" without any warranty of any kind, whether express
|
||||
* or implied.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include "flatdevtree.h"
|
||||
#include "ops.h"
|
||||
|
||||
static struct ft_cxt cxt;
|
||||
|
||||
static void *ft_finddevice(const char *name)
|
||||
{
|
||||
return ft_find_device(&cxt, name);
|
||||
}
|
||||
|
||||
static int ft_getprop(const void *phandle, const char *propname, void *buf,
|
||||
const int buflen)
|
||||
{
|
||||
return ft_get_prop(&cxt, phandle, propname, buf, buflen);
|
||||
}
|
||||
|
||||
static int ft_setprop(const void *phandle, const char *propname,
|
||||
const void *buf, const int buflen)
|
||||
{
|
||||
return ft_set_prop(&cxt, phandle, propname, buf, buflen);
|
||||
}
|
||||
|
||||
static unsigned long ft_finalize(void)
|
||||
{
|
||||
ft_end_tree(&cxt);
|
||||
return (unsigned long)cxt.bph;
|
||||
}
|
||||
|
||||
int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device)
|
||||
{
|
||||
dt_ops.finddevice = ft_finddevice;
|
||||
dt_ops.getprop = ft_getprop;
|
||||
dt_ops.setprop = ft_setprop;
|
||||
dt_ops.finalize = ft_finalize;
|
||||
|
||||
return ft_open(&cxt, dt_blob, max_size, max_find_device,
|
||||
platform_ops.realloc);
|
||||
}
|
53
arch/powerpc/boot/io.h
Normal file
53
arch/powerpc/boot/io.h
Normal file
@ -0,0 +1,53 @@
|
||||
#ifndef _IO_H
|
||||
#define __IO_H
|
||||
/*
|
||||
* Low-level I/O routines.
|
||||
*
|
||||
* Copied from <file:include/asm-powerpc/io.h> (which has no copyright)
|
||||
*/
|
||||
static inline int in_8(const volatile unsigned char *addr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
__asm__ __volatile__("lbz%U1%X1 %0,%1; twi 0,%0,0; isync"
|
||||
: "=r" (ret) : "m" (*addr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void out_8(volatile unsigned char *addr, int val)
|
||||
{
|
||||
__asm__ __volatile__("stb%U0%X0 %1,%0; sync"
|
||||
: "=m" (*addr) : "r" (val));
|
||||
}
|
||||
|
||||
static inline unsigned in_le32(const volatile unsigned *addr)
|
||||
{
|
||||
unsigned ret;
|
||||
|
||||
__asm__ __volatile__("lwbrx %0,0,%1; twi 0,%0,0; isync"
|
||||
: "=r" (ret) : "r" (addr), "m" (*addr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline unsigned in_be32(const volatile unsigned *addr)
|
||||
{
|
||||
unsigned ret;
|
||||
|
||||
__asm__ __volatile__("lwz%U1%X1 %0,%1; twi 0,%0,0; isync"
|
||||
: "=r" (ret) : "m" (*addr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void out_le32(volatile unsigned *addr, int val)
|
||||
{
|
||||
__asm__ __volatile__("stwbrx %1,0,%2; sync" : "=m" (*addr)
|
||||
: "r" (val), "r" (addr));
|
||||
}
|
||||
|
||||
static inline void out_be32(volatile unsigned *addr, int val)
|
||||
{
|
||||
__asm__ __volatile__("stw%U0%X0 %1,%0; sync"
|
||||
: "=m" (*addr) : "r" (val));
|
||||
}
|
||||
|
||||
#endif /* _IO_H */
|
@ -27,6 +27,8 @@ extern char _vmlinux_start[];
|
||||
extern char _vmlinux_end[];
|
||||
extern char _initrd_start[];
|
||||
extern char _initrd_end[];
|
||||
extern char _dtb_start[];
|
||||
extern char _dtb_end[];
|
||||
|
||||
struct addr_range {
|
||||
unsigned long addr;
|
||||
@ -167,7 +169,7 @@ static int is_elf32(void *hdr)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void prep_kernel(unsigned long *a1, unsigned long *a2)
|
||||
static void prep_kernel(unsigned long a1, unsigned long a2)
|
||||
{
|
||||
int len;
|
||||
|
||||
@ -203,11 +205,14 @@ static void prep_kernel(unsigned long *a1, unsigned long *a2)
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we try to alloc memory for the initrd (and copy it there)
|
||||
* Now find the initrd
|
||||
*
|
||||
* First see if we have an image attached to us. If so
|
||||
* allocate memory for it and copy it there.
|
||||
*/
|
||||
initrd.size = (unsigned long)(_initrd_end - _initrd_start);
|
||||
initrd.memsize = initrd.size;
|
||||
if ( initrd.size > 0 ) {
|
||||
if (initrd.size > 0) {
|
||||
printf("Allocating 0x%lx bytes for initrd ...\n\r",
|
||||
initrd.size);
|
||||
initrd.addr = (unsigned long)malloc((u32)initrd.size);
|
||||
@ -216,8 +221,6 @@ static void prep_kernel(unsigned long *a1, unsigned long *a2)
|
||||
"ramdisk !\n\r");
|
||||
exit();
|
||||
}
|
||||
*a1 = initrd.addr;
|
||||
*a2 = initrd.size;
|
||||
printf("initial ramdisk moving 0x%lx <- 0x%lx "
|
||||
"(0x%lx bytes)\n\r", initrd.addr,
|
||||
(unsigned long)_initrd_start, initrd.size);
|
||||
@ -225,6 +228,12 @@ static void prep_kernel(unsigned long *a1, unsigned long *a2)
|
||||
initrd.size);
|
||||
printf("initrd head: 0x%lx\n\r",
|
||||
*((unsigned long *)initrd.addr));
|
||||
} else if (a2 != 0) {
|
||||
/* Otherwise, see if yaboot or another loader gave us an initrd */
|
||||
initrd.addr = a1;
|
||||
initrd.memsize = initrd.size = a2;
|
||||
printf("Using loader supplied initrd at 0x%lx (0x%lx bytes)\n\r",
|
||||
initrd.addr, initrd.size);
|
||||
}
|
||||
|
||||
/* Eventually gunzip the kernel */
|
||||
@ -250,10 +259,6 @@ static void prep_kernel(unsigned long *a1, unsigned long *a2)
|
||||
flush_cache((void *)vmlinux.addr, vmlinux.size);
|
||||
}
|
||||
|
||||
void __attribute__ ((weak)) ft_init(void *dt_blob)
|
||||
{
|
||||
}
|
||||
|
||||
/* A buffer that may be edited by tools operating on a zImage binary so as to
|
||||
* edit the command line passed to vmlinux (by setting /chosen/bootargs).
|
||||
* The buffer is put in it's own section so that tools may locate it easier.
|
||||
@ -285,36 +290,22 @@ static void set_cmdline(char *buf)
|
||||
setprop(devp, "bootargs", buf, strlen(buf) + 1);
|
||||
}
|
||||
|
||||
/* Section where ft can be tacked on after zImage is built */
|
||||
union blobspace {
|
||||
struct boot_param_header hdr;
|
||||
char space[8*1024];
|
||||
} dt_blob __attribute__((__section__("__builtin_ft")));
|
||||
|
||||
struct platform_ops platform_ops;
|
||||
struct dt_ops dt_ops;
|
||||
struct console_ops console_ops;
|
||||
|
||||
void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
|
||||
{
|
||||
int have_dt = 0;
|
||||
kernel_entry_t kentry;
|
||||
char cmdline[COMMAND_LINE_SIZE];
|
||||
unsigned long ft_addr = 0;
|
||||
|
||||
memset(__bss_start, 0, _end - __bss_start);
|
||||
memset(&platform_ops, 0, sizeof(platform_ops));
|
||||
memset(&dt_ops, 0, sizeof(dt_ops));
|
||||
memset(&console_ops, 0, sizeof(console_ops));
|
||||
|
||||
/* Override the dt_ops and device tree if there was an flat dev
|
||||
* tree attached to the zImage.
|
||||
*/
|
||||
if (dt_blob.hdr.magic == OF_DT_HEADER) {
|
||||
have_dt = 1;
|
||||
ft_init(&dt_blob);
|
||||
}
|
||||
|
||||
if (platform_init(promptr))
|
||||
if (platform_init(promptr, _dtb_start, _dtb_end))
|
||||
exit();
|
||||
if (console_ops.open && (console_ops.open() < 0))
|
||||
exit();
|
||||
@ -324,7 +315,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
|
||||
printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r",
|
||||
_start, sp);
|
||||
|
||||
prep_kernel(&a1, &a2);
|
||||
prep_kernel(a1, a2);
|
||||
|
||||
/* If cmdline came from zimage wrapper or if we can edit the one
|
||||
* in the dt, print it out and edit it, if possible.
|
||||
@ -338,15 +329,23 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
|
||||
set_cmdline(cmdline);
|
||||
}
|
||||
|
||||
printf("Finalizing device tree...");
|
||||
if (dt_ops.finalize)
|
||||
ft_addr = dt_ops.finalize();
|
||||
if (ft_addr)
|
||||
printf(" flat tree at 0x%lx\n\r", ft_addr);
|
||||
else
|
||||
printf(" using OF tree (promptr=%p)\n\r", promptr);
|
||||
|
||||
if (console_ops.close)
|
||||
console_ops.close();
|
||||
|
||||
kentry = (kernel_entry_t) vmlinux.addr;
|
||||
if (have_dt)
|
||||
kentry(dt_ops.ft_addr(), 0, NULL);
|
||||
if (ft_addr)
|
||||
kentry(ft_addr, 0, NULL);
|
||||
else
|
||||
/* XXX initrd addr/size should be passed in properties */
|
||||
kentry(a1, a2, promptr);
|
||||
kentry(initrd.addr, initrd.size, promptr);
|
||||
|
||||
/* console closed so printf below may not work */
|
||||
printf("Error: Linux kernel returned to zImage boot wrapper!\n\r");
|
||||
|
152
arch/powerpc/boot/mktree.c
Normal file
152
arch/powerpc/boot/mktree.c
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Makes a tree bootable image for IBM Evaluation boards.
|
||||
* Basically, just take a zImage, skip the ELF header, and stuff
|
||||
* a 32 byte header on the front.
|
||||
*
|
||||
* We use htonl, which is a network macro, to make sure we're doing
|
||||
* The Right Thing on an LE machine. It's non-obvious, but it should
|
||||
* work on anything BSD'ish.
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#ifdef __sun__
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
/* This gets tacked on the front of the image. There are also a few
|
||||
* bytes allocated after the _start label used by the boot rom (see
|
||||
* head.S for details).
|
||||
*/
|
||||
typedef struct boot_block {
|
||||
uint32_t bb_magic; /* 0x0052504F */
|
||||
uint32_t bb_dest; /* Target address of the image */
|
||||
uint32_t bb_num_512blocks; /* Size, rounded-up, in 512 byte blks */
|
||||
uint32_t bb_debug_flag; /* Run debugger or image after load */
|
||||
uint32_t bb_entry_point; /* The image address to start */
|
||||
uint32_t bb_checksum; /* 32 bit checksum including header */
|
||||
uint32_t reserved[2];
|
||||
} boot_block_t;
|
||||
|
||||
#define IMGBLK 512
|
||||
char tmpbuf[IMGBLK];
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int in_fd, out_fd;
|
||||
int nblks, i;
|
||||
uint cksum, *cp;
|
||||
struct stat st;
|
||||
boot_block_t bt;
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "usage: %s <zImage-file> <boot-image> [entry-point]\n",argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (stat(argv[1], &st) < 0) {
|
||||
perror("stat");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
nblks = (st.st_size + IMGBLK) / IMGBLK;
|
||||
|
||||
bt.bb_magic = htonl(0x0052504F);
|
||||
|
||||
/* If we have the optional entry point parameter, use it */
|
||||
if (argc == 4)
|
||||
bt.bb_dest = bt.bb_entry_point = htonl(strtoul(argv[3], NULL, 0));
|
||||
else
|
||||
bt.bb_dest = bt.bb_entry_point = htonl(0x500000);
|
||||
|
||||
/* We know these from the linker command.
|
||||
* ...and then move it up into memory a little more so the
|
||||
* relocation can happen.
|
||||
*/
|
||||
bt.bb_num_512blocks = htonl(nblks);
|
||||
bt.bb_debug_flag = 0;
|
||||
|
||||
bt.bb_checksum = 0;
|
||||
|
||||
/* To be neat and tidy :-).
|
||||
*/
|
||||
bt.reserved[0] = 0;
|
||||
bt.reserved[1] = 0;
|
||||
|
||||
if ((in_fd = open(argv[1], O_RDONLY)) < 0) {
|
||||
perror("zImage open");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
if ((out_fd = open(argv[2], (O_RDWR | O_CREAT | O_TRUNC), 0666)) < 0) {
|
||||
perror("bootfile open");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
cksum = 0;
|
||||
cp = (void *)&bt;
|
||||
for (i=0; i<sizeof(bt)/sizeof(uint); i++)
|
||||
cksum += *cp++;
|
||||
|
||||
/* Assume zImage is an ELF file, and skip the 64K header.
|
||||
*/
|
||||
if (read(in_fd, tmpbuf, IMGBLK) != IMGBLK) {
|
||||
fprintf(stderr, "%s is too small to be an ELF image\n",
|
||||
argv[1]);
|
||||
exit(4);
|
||||
}
|
||||
|
||||
if ((*(uint *)tmpbuf) != htonl(0x7f454c46)) {
|
||||
fprintf(stderr, "%s is not an ELF image\n", argv[1]);
|
||||
exit(4);
|
||||
}
|
||||
|
||||
if (lseek(in_fd, (64 * 1024), SEEK_SET) < 0) {
|
||||
fprintf(stderr, "%s failed to seek in ELF image\n", argv[1]);
|
||||
exit(4);
|
||||
}
|
||||
|
||||
nblks -= (64 * 1024) / IMGBLK;
|
||||
|
||||
/* And away we go......
|
||||
*/
|
||||
if (write(out_fd, &bt, sizeof(bt)) != sizeof(bt)) {
|
||||
perror("boot-image write");
|
||||
exit(5);
|
||||
}
|
||||
|
||||
while (nblks-- > 0) {
|
||||
if (read(in_fd, tmpbuf, IMGBLK) < 0) {
|
||||
perror("zImage read");
|
||||
exit(5);
|
||||
}
|
||||
cp = (uint *)tmpbuf;
|
||||
for (i=0; i<sizeof(tmpbuf)/sizeof(uint); i++)
|
||||
cksum += *cp++;
|
||||
if (write(out_fd, tmpbuf, sizeof(tmpbuf)) != sizeof(tmpbuf)) {
|
||||
perror("boot-image write");
|
||||
exit(5);
|
||||
}
|
||||
}
|
||||
|
||||
/* rewrite the header with the computed checksum.
|
||||
*/
|
||||
bt.bb_checksum = htonl(cksum);
|
||||
if (lseek(out_fd, 0, SEEK_SET) < 0) {
|
||||
perror("rewrite seek");
|
||||
exit(1);
|
||||
}
|
||||
if (write(out_fd, &bt, sizeof(bt)) != sizeof(bt)) {
|
||||
perror("boot-image rewrite");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
74
arch/powerpc/boot/ns16550.c
Normal file
74
arch/powerpc/boot/ns16550.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 16550 serial console support.
|
||||
*
|
||||
* Original copied from <file:arch/ppc/boot/common/ns16550.c>
|
||||
* (which had no copyright)
|
||||
* Modifications: 2006 (c) MontaVista Software, Inc.
|
||||
*
|
||||
* Modified by: Mark A. Greer <mgreer@mvista.com>
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include "types.h"
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
#include "io.h"
|
||||
#include "ops.h"
|
||||
|
||||
#define UART_DLL 0 /* Out: Divisor Latch Low */
|
||||
#define UART_DLM 1 /* Out: Divisor Latch High */
|
||||
#define UART_FCR 2 /* Out: FIFO Control Register */
|
||||
#define UART_LCR 3 /* Out: Line Control Register */
|
||||
#define UART_MCR 4 /* Out: Modem Control Register */
|
||||
#define UART_LSR 5 /* In: Line Status Register */
|
||||
#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
|
||||
#define UART_LSR_DR 0x01 /* Receiver data ready */
|
||||
#define UART_MSR 6 /* In: Modem Status Register */
|
||||
#define UART_SCR 7 /* I/O: Scratch Register */
|
||||
|
||||
static unsigned char *reg_base;
|
||||
static u32 reg_shift;
|
||||
|
||||
static int ns16550_open(void)
|
||||
{
|
||||
out_8(reg_base + (UART_FCR << reg_shift), 0x06);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ns16550_putc(unsigned char c)
|
||||
{
|
||||
while ((in_8(reg_base + (UART_LSR << reg_shift)) & UART_LSR_THRE) == 0);
|
||||
out_8(reg_base, c);
|
||||
}
|
||||
|
||||
static unsigned char ns16550_getc(void)
|
||||
{
|
||||
while ((in_8(reg_base + (UART_LSR << reg_shift)) & UART_LSR_DR) == 0);
|
||||
return in_8(reg_base);
|
||||
}
|
||||
|
||||
static u8 ns16550_tstc(void)
|
||||
{
|
||||
return ((in_8(reg_base + (UART_LSR << reg_shift)) & UART_LSR_DR) != 0);
|
||||
}
|
||||
|
||||
int ns16550_console_init(void *devp, struct serial_console_data *scdp)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = getprop(devp, "virtual-reg", ®_base, sizeof(reg_base));
|
||||
if (n != sizeof(reg_base))
|
||||
return -1;
|
||||
|
||||
n = getprop(devp, "reg-shift", ®_shift, sizeof(reg_shift));
|
||||
if (n != sizeof(reg_shift))
|
||||
reg_shift = 0;
|
||||
|
||||
scdp->open = ns16550_open;
|
||||
scdp->putc = ns16550_putc;
|
||||
scdp->getc = ns16550_getc;
|
||||
scdp->tstc = ns16550_tstc;
|
||||
scdp->close = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
@ -256,24 +256,18 @@ static void of_console_write(char *buf, int len)
|
||||
call_prom("write", 3, 1, of_stdout_handle, buf, len);
|
||||
}
|
||||
|
||||
int platform_init(void *promptr)
|
||||
int platform_init(void *promptr, char *dt_blob_start, char *dt_blob_end)
|
||||
{
|
||||
platform_ops.fixups = NULL;
|
||||
platform_ops.image_hdr = of_image_hdr;
|
||||
platform_ops.malloc = of_try_claim;
|
||||
platform_ops.free = NULL;
|
||||
platform_ops.exit = of_exit;
|
||||
|
||||
dt_ops.finddevice = of_finddevice;
|
||||
dt_ops.getprop = of_getprop;
|
||||
dt_ops.setprop = of_setprop;
|
||||
dt_ops.translate_addr = NULL;
|
||||
|
||||
console_ops.open = of_console_open;
|
||||
console_ops.write = of_console_write;
|
||||
console_ops.edit_cmdline = NULL;
|
||||
console_ops.close = NULL;
|
||||
console_ops.data = NULL;
|
||||
|
||||
prom = (int (*)(void *))promptr;
|
||||
return 0;
|
||||
|
@ -22,7 +22,8 @@ struct platform_ops {
|
||||
void (*fixups)(void);
|
||||
void (*image_hdr)(const void *);
|
||||
void * (*malloc)(u32 size);
|
||||
void (*free)(void *ptr, u32 size);
|
||||
void (*free)(void *ptr);
|
||||
void * (*realloc)(void *ptr, unsigned long size);
|
||||
void (*exit)(void);
|
||||
};
|
||||
extern struct platform_ops platform_ops;
|
||||
@ -30,13 +31,11 @@ extern struct platform_ops platform_ops;
|
||||
/* Device Tree operations */
|
||||
struct dt_ops {
|
||||
void * (*finddevice)(const char *name);
|
||||
int (*getprop)(const void *node, const char *name, void *buf,
|
||||
int (*getprop)(const void *phandle, const char *name, void *buf,
|
||||
const int buflen);
|
||||
int (*setprop)(const void *node, const char *name,
|
||||
int (*setprop)(const void *phandle, const char *name,
|
||||
const void *buf, const int buflen);
|
||||
u64 (*translate_addr)(const char *path, const u32 *in_addr,
|
||||
const u32 addr_len);
|
||||
unsigned long (*ft_addr)(void);
|
||||
unsigned long (*finalize)(void);
|
||||
};
|
||||
extern struct dt_ops dt_ops;
|
||||
|
||||
@ -59,10 +58,13 @@ struct serial_console_data {
|
||||
void (*close)(void);
|
||||
};
|
||||
|
||||
extern int platform_init(void *promptr);
|
||||
extern void simple_alloc_init(void);
|
||||
extern void ft_init(void *dt_blob);
|
||||
extern int serial_console_init(void);
|
||||
int platform_init(void *promptr, char *dt_blob_start, char *dt_blob_end);
|
||||
int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device);
|
||||
int serial_console_init(void);
|
||||
int ns16550_console_init(void *devp, struct serial_console_data *scdp);
|
||||
void *simple_alloc_init(char *base, u32 heap_size, u32 granularity,
|
||||
u32 max_allocs);
|
||||
|
||||
|
||||
static inline void *finddevice(const char *name)
|
||||
{
|
||||
@ -84,10 +86,10 @@ static inline void *malloc(u32 size)
|
||||
return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL;
|
||||
}
|
||||
|
||||
static inline void free(void *ptr, u32 size)
|
||||
static inline void free(void *ptr)
|
||||
{
|
||||
if (platform_ops.free)
|
||||
platform_ops.free(ptr, size);
|
||||
platform_ops.free(ptr);
|
||||
}
|
||||
|
||||
static inline void exit(void)
|
||||
|
142
arch/powerpc/boot/serial.c
Normal file
142
arch/powerpc/boot/serial.c
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Generic serial console support
|
||||
*
|
||||
* Author: Mark A. Greer <mgreer@mvista.com>
|
||||
*
|
||||
* Code in serial_edit_cmdline() copied from <file:arch/ppc/boot/simple/misc.c>
|
||||
* and was written by Matt Porter <mporter@kernel.crashing.org>.
|
||||
*
|
||||
* 2001,2006 (c) MontaVista Software, Inc. This file is licensed under
|
||||
* the terms of the GNU General Public License version 2. This program
|
||||
* is licensed "as is" without any warranty of any kind, whether express
|
||||
* or implied.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include "types.h"
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
#include "io.h"
|
||||
#include "ops.h"
|
||||
|
||||
extern void udelay(long delay);
|
||||
|
||||
static int serial_open(void)
|
||||
{
|
||||
struct serial_console_data *scdp = console_ops.data;
|
||||
return scdp->open();
|
||||
}
|
||||
|
||||
static void serial_write(char *buf, int len)
|
||||
{
|
||||
struct serial_console_data *scdp = console_ops.data;
|
||||
|
||||
while (*buf != '\0')
|
||||
scdp->putc(*buf++);
|
||||
}
|
||||
|
||||
static void serial_edit_cmdline(char *buf, int len)
|
||||
{
|
||||
int timer = 0, count;
|
||||
char ch, *cp;
|
||||
struct serial_console_data *scdp = console_ops.data;
|
||||
|
||||
cp = buf;
|
||||
count = strlen(buf);
|
||||
cp = &buf[count];
|
||||
count++;
|
||||
|
||||
while (timer++ < 5*1000) {
|
||||
if (scdp->tstc()) {
|
||||
while (((ch = scdp->getc()) != '\n') && (ch != '\r')) {
|
||||
/* Test for backspace/delete */
|
||||
if ((ch == '\b') || (ch == '\177')) {
|
||||
if (cp != buf) {
|
||||
cp--;
|
||||
count--;
|
||||
printf("\b \b");
|
||||
}
|
||||
/* Test for ^x/^u (and wipe the line) */
|
||||
} else if ((ch == '\030') || (ch == '\025')) {
|
||||
while (cp != buf) {
|
||||
cp--;
|
||||
count--;
|
||||
printf("\b \b");
|
||||
}
|
||||
} else if (count < len) {
|
||||
*cp++ = ch;
|
||||
count++;
|
||||
scdp->putc(ch);
|
||||
}
|
||||
}
|
||||
break; /* Exit 'timer' loop */
|
||||
}
|
||||
udelay(1000); /* 1 msec */
|
||||
}
|
||||
*cp = 0;
|
||||
}
|
||||
|
||||
static void serial_close(void)
|
||||
{
|
||||
struct serial_console_data *scdp = console_ops.data;
|
||||
|
||||
if (scdp->close)
|
||||
scdp->close();
|
||||
}
|
||||
|
||||
static void *serial_get_stdout_devp(void)
|
||||
{
|
||||
void *devp;
|
||||
char devtype[MAX_PROP_LEN];
|
||||
char path[MAX_PATH_LEN];
|
||||
|
||||
devp = finddevice("/chosen");
|
||||
if (devp == NULL)
|
||||
goto err_out;
|
||||
|
||||
if (getprop(devp, "linux,stdout-path", path, MAX_PATH_LEN) > 0) {
|
||||
devp = finddevice(path);
|
||||
if (devp == NULL)
|
||||
goto err_out;
|
||||
|
||||
if ((getprop(devp, "device_type", devtype, sizeof(devtype)) > 0)
|
||||
&& !strcmp(devtype, "serial"))
|
||||
return devp;
|
||||
}
|
||||
err_out:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct serial_console_data serial_cd;
|
||||
|
||||
/* Node's "compatible" property determines which serial driver to use */
|
||||
int serial_console_init(void)
|
||||
{
|
||||
void *devp;
|
||||
int rc = -1;
|
||||
char compat[MAX_PROP_LEN];
|
||||
|
||||
devp = serial_get_stdout_devp();
|
||||
if (devp == NULL)
|
||||
goto err_out;
|
||||
|
||||
if (getprop(devp, "compatible", compat, sizeof(compat)) < 0)
|
||||
goto err_out;
|
||||
|
||||
if (!strcmp(compat, "ns16550"))
|
||||
rc = ns16550_console_init(devp, &serial_cd);
|
||||
|
||||
/* Add other serial console driver calls here */
|
||||
|
||||
if (!rc) {
|
||||
console_ops.open = serial_open;
|
||||
console_ops.write = serial_write;
|
||||
console_ops.edit_cmdline = serial_edit_cmdline;
|
||||
console_ops.close = serial_close;
|
||||
console_ops.data = &serial_cd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
err_out:
|
||||
return -1;
|
||||
}
|
149
arch/powerpc/boot/simple_alloc.c
Normal file
149
arch/powerpc/boot/simple_alloc.c
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Implement primitive realloc(3) functionality.
|
||||
*
|
||||
* Author: Mark A. Greer <mgreer@mvista.com>
|
||||
*
|
||||
* 2006 (c) MontaVista, Software, Inc. This file is licensed under
|
||||
* the terms of the GNU General Public License version 2. This program
|
||||
* is licensed "as is" without any warranty of any kind, whether express
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "types.h"
|
||||
#include "page.h"
|
||||
#include "string.h"
|
||||
#include "ops.h"
|
||||
|
||||
#define ENTRY_BEEN_USED 0x01
|
||||
#define ENTRY_IN_USE 0x02
|
||||
|
||||
static struct alloc_info {
|
||||
u32 flags;
|
||||
u32 base;
|
||||
u32 size;
|
||||
} *alloc_tbl;
|
||||
|
||||
static u32 tbl_entries;
|
||||
static u32 alloc_min;
|
||||
static u32 next_base;
|
||||
static u32 space_left;
|
||||
|
||||
/*
|
||||
* First time an entry is used, its base and size are set.
|
||||
* An entry can be freed and re-malloc'd but its base & size don't change.
|
||||
* Should be smart enough for needs of bootwrapper.
|
||||
*/
|
||||
static void *simple_malloc(u32 size)
|
||||
{
|
||||
u32 i;
|
||||
struct alloc_info *p = alloc_tbl;
|
||||
|
||||
if (size == 0)
|
||||
goto err_out;
|
||||
|
||||
size = _ALIGN_UP(size, alloc_min);
|
||||
|
||||
for (i=0; i<tbl_entries; i++, p++)
|
||||
if (!(p->flags & ENTRY_BEEN_USED)) { /* never been used */
|
||||
if (size <= space_left) {
|
||||
p->base = next_base;
|
||||
p->size = size;
|
||||
p->flags = ENTRY_BEEN_USED | ENTRY_IN_USE;
|
||||
next_base += size;
|
||||
space_left -= size;
|
||||
return (void *)p->base;
|
||||
}
|
||||
goto err_out; /* not enough space left */
|
||||
}
|
||||
/* reuse an entry keeping same base & size */
|
||||
else if (!(p->flags & ENTRY_IN_USE) && (size <= p->size)) {
|
||||
p->flags |= ENTRY_IN_USE;
|
||||
return (void *)p->base;
|
||||
}
|
||||
err_out:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct alloc_info *simple_find_entry(void *ptr)
|
||||
{
|
||||
u32 i;
|
||||
struct alloc_info *p = alloc_tbl;
|
||||
|
||||
for (i=0; i<tbl_entries; i++,p++) {
|
||||
if (!(p->flags & ENTRY_BEEN_USED))
|
||||
break;
|
||||
if ((p->flags & ENTRY_IN_USE) && (p->base == (u32)ptr))
|
||||
return p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void simple_free(void *ptr)
|
||||
{
|
||||
struct alloc_info *p = simple_find_entry(ptr);
|
||||
|
||||
if (p != NULL)
|
||||
p->flags &= ~ENTRY_IN_USE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change size of area pointed to by 'ptr' to 'size'.
|
||||
* If 'ptr' is NULL, then its a malloc(). If 'size' is 0, then its a free().
|
||||
* 'ptr' must be NULL or a pointer to a non-freed area previously returned by
|
||||
* simple_realloc() or simple_malloc().
|
||||
*/
|
||||
static void *simple_realloc(void *ptr, unsigned long size)
|
||||
{
|
||||
struct alloc_info *p;
|
||||
void *new;
|
||||
|
||||
if (size == 0) {
|
||||
simple_free(ptr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ptr == NULL)
|
||||
return simple_malloc(size);
|
||||
|
||||
p = simple_find_entry(ptr);
|
||||
if (p == NULL) /* ptr not from simple_malloc/simple_realloc */
|
||||
return NULL;
|
||||
if (size <= p->size) /* fits in current block */
|
||||
return ptr;
|
||||
|
||||
new = simple_malloc(size);
|
||||
memcpy(new, ptr, p->size);
|
||||
simple_free(ptr);
|
||||
return new;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns addr of first byte after heap so caller can see if it took
|
||||
* too much space. If so, change args & try again.
|
||||
*/
|
||||
void *simple_alloc_init(char *base, u32 heap_size, u32 granularity,
|
||||
u32 max_allocs)
|
||||
{
|
||||
u32 heap_base, tbl_size;
|
||||
|
||||
heap_size = _ALIGN_UP(heap_size, granularity);
|
||||
alloc_min = granularity;
|
||||
tbl_entries = max_allocs;
|
||||
|
||||
tbl_size = tbl_entries * sizeof(struct alloc_info);
|
||||
|
||||
alloc_tbl = (struct alloc_info *)_ALIGN_UP((unsigned long)base, 8);
|
||||
memset(alloc_tbl, 0, tbl_size);
|
||||
|
||||
heap_base = _ALIGN_UP((u32)alloc_tbl + tbl_size, alloc_min);
|
||||
|
||||
next_base = heap_base;
|
||||
space_left = heap_size;
|
||||
|
||||
platform_ops.malloc = simple_malloc;
|
||||
platform_ops.free = simple_free;
|
||||
platform_ops.realloc = simple_realloc;
|
||||
|
||||
return (void *)(heap_base + heap_size);
|
||||
}
|
@ -320,6 +320,7 @@ printf(const char *fmt, ...)
|
||||
va_start(args, fmt);
|
||||
n = vsprintf(sprint_buf, fmt, args);
|
||||
va_end(args);
|
||||
console_ops.write(sprint_buf, n);
|
||||
if (console_ops.write)
|
||||
console_ops.write(sprint_buf, n);
|
||||
return n;
|
||||
}
|
||||
|
88
arch/powerpc/boot/util.S
Normal file
88
arch/powerpc/boot/util.S
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copied from <file:arch/powerpc/kernel/misc_32.S>
|
||||
*
|
||||
* This file contains miscellaneous low-level functions.
|
||||
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
|
||||
*
|
||||
* Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
|
||||
* and Paul Mackerras.
|
||||
*
|
||||
* kexec bits:
|
||||
* Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com>
|
||||
* GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
#include "ppc_asm.h"
|
||||
|
||||
#define SPRN_PVR 0x11F /* Processor Version Register */
|
||||
|
||||
.text
|
||||
|
||||
/* udelay (on non-601 processors) needs to know the period of the
|
||||
* timebase in nanoseconds. This used to be hardcoded to be 60ns
|
||||
* (period of 66MHz/4). Now a variable is used that is initialized to
|
||||
* 60 for backward compatibility, but it can be overridden as necessary
|
||||
* with code something like this:
|
||||
* extern unsigned long timebase_period_ns;
|
||||
* timebase_period_ns = 1000000000 / bd->bi_tbfreq;
|
||||
*/
|
||||
.data
|
||||
.globl timebase_period_ns
|
||||
timebase_period_ns:
|
||||
.long 60
|
||||
|
||||
.text
|
||||
/*
|
||||
* Delay for a number of microseconds
|
||||
*/
|
||||
.globl udelay
|
||||
udelay:
|
||||
mfspr r4,SPRN_PVR
|
||||
srwi r4,r4,16
|
||||
cmpwi 0,r4,1 /* 601 ? */
|
||||
bne .udelay_not_601
|
||||
00: li r0,86 /* Instructions / microsecond? */
|
||||
mtctr r0
|
||||
10: addi r0,r0,0 /* NOP */
|
||||
bdnz 10b
|
||||
subic. r3,r3,1
|
||||
bne 00b
|
||||
blr
|
||||
|
||||
.udelay_not_601:
|
||||
mulli r4,r3,1000 /* nanoseconds */
|
||||
/* Change r4 to be the number of ticks using:
|
||||
* (nanoseconds + (timebase_period_ns - 1 )) / timebase_period_ns
|
||||
* timebase_period_ns defaults to 60 (16.6MHz) */
|
||||
mflr r5
|
||||
bl 0f
|
||||
0: mflr r6
|
||||
mtlr r5
|
||||
lis r5,0b@ha
|
||||
addi r5,r5,0b@l
|
||||
subf r5,r5,r6 /* In case we're relocated */
|
||||
addis r5,r5,timebase_period_ns@ha
|
||||
lwz r5,timebase_period_ns@l(r5)
|
||||
add r4,r4,r5
|
||||
addi r4,r4,-1
|
||||
divw r4,r4,r5 /* BUS ticks */
|
||||
1: mftbu r5
|
||||
mftb r6
|
||||
mftbu r7
|
||||
cmpw 0,r5,r7
|
||||
bne 1b /* Get [synced] base time */
|
||||
addc r9,r6,r4 /* Compute end time */
|
||||
addze r8,r5
|
||||
2: mftbu r5
|
||||
cmpw 0,r5,r8
|
||||
blt 2b
|
||||
bgt 3f
|
||||
mftb r6
|
||||
cmpw 0,r6,r9
|
||||
blt 2b
|
||||
3: blr
|
@ -184,6 +184,9 @@ fi
|
||||
|
||||
if [ -n "$dtb" ]; then
|
||||
addsec $tmp "$dtb" .kernel:dtb
|
||||
if [ -n "$dts" ]; then
|
||||
rm $dtb
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$platform" != "miboot" ]; then
|
||||
|
@ -21,6 +21,10 @@ SECTIONS
|
||||
*(.got2)
|
||||
__got2_end = .;
|
||||
|
||||
_dtb_start = .;
|
||||
*(.kernel:dtb)
|
||||
_dtb_end = .;
|
||||
|
||||
_vmlinux_start = .;
|
||||
*(.kernel:vmlinux.strip)
|
||||
_vmlinux_end = .;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.18
|
||||
# Wed Oct 4 15:30:50 2006
|
||||
# Linux kernel version: 2.6.19-rc6
|
||||
# Wed Nov 22 15:33:04 2006
|
||||
#
|
||||
CONFIG_PPC64=y
|
||||
CONFIG_64BIT=y
|
||||
@ -32,6 +32,10 @@ CONFIG_AUDIT_ARCH=y
|
||||
CONFIG_POWER3=y
|
||||
CONFIG_POWER4=y
|
||||
CONFIG_PPC_FPU=y
|
||||
# CONFIG_PPC_DCR_NATIVE is not set
|
||||
CONFIG_PPC_DCR_MMIO=y
|
||||
CONFIG_PPC_DCR=y
|
||||
CONFIG_PPC_OF_PLATFORM_PCI=y
|
||||
CONFIG_ALTIVEC=y
|
||||
CONFIG_PPC_STD_MMU=y
|
||||
CONFIG_VIRT_CPU_ACCOUNTING=y
|
||||
@ -67,7 +71,7 @@ CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||
CONFIG_SYSCTL=y
|
||||
# CONFIG_EMBEDDED is not set
|
||||
# CONFIG_SYSCTL_SYSCALL is not set
|
||||
CONFIG_SYSCTL_SYSCALL=y
|
||||
CONFIG_KALLSYMS=y
|
||||
# CONFIG_KALLSYMS_ALL is not set
|
||||
# CONFIG_KALLSYMS_EXTRA_PASS is not set
|
||||
@ -131,6 +135,7 @@ CONFIG_PPC_CELL=y
|
||||
CONFIG_PPC_CELL_NATIVE=y
|
||||
CONFIG_PPC_IBM_CELL_BLADE=y
|
||||
CONFIG_UDBG_RTAS_CONSOLE=y
|
||||
CONFIG_PPC_PS3=y
|
||||
# CONFIG_U3_DART is not set
|
||||
CONFIG_PPC_RTAS=y
|
||||
# CONFIG_RTAS_ERROR_LOGGING is not set
|
||||
@ -139,9 +144,23 @@ CONFIG_RTAS_FLASH=y
|
||||
CONFIG_MMIO_NVRAM=y
|
||||
# CONFIG_PPC_MPC106 is not set
|
||||
# CONFIG_PPC_970_NAP is not set
|
||||
# CONFIG_CPU_FREQ is not set
|
||||
CONFIG_PPC_INDIRECT_IO=y
|
||||
CONFIG_GENERIC_IOMAP=y
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_TABLE=y
|
||||
CONFIG_CPU_FREQ_DEBUG=y
|
||||
CONFIG_CPU_FREQ_STAT=y
|
||||
# CONFIG_CPU_FREQ_STAT_DETAILS is not set
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
|
||||
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
|
||||
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
|
||||
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
|
||||
# CONFIG_CPU_FREQ_PMAC64 is not set
|
||||
# CONFIG_WANT_EARLY_SERIAL is not set
|
||||
# CONFIG_MPIC is not set
|
||||
CONFIG_MPIC=y
|
||||
|
||||
#
|
||||
# Cell Broadband Engine options
|
||||
@ -149,6 +168,15 @@ CONFIG_MMIO_NVRAM=y
|
||||
CONFIG_SPU_FS=m
|
||||
CONFIG_SPU_BASE=y
|
||||
CONFIG_CBE_RAS=y
|
||||
CONFIG_CBE_THERM=m
|
||||
CONFIG_CBE_CPUFREQ=m
|
||||
|
||||
#
|
||||
# PS3 Platform Options
|
||||
#
|
||||
CONFIG_PS3_HTAB_SIZE=20
|
||||
# CONFIG_PS3_DYNAMIC_DMA is not set
|
||||
CONFIG_PS3_USE_LPAR_ADDR=y
|
||||
|
||||
#
|
||||
# Kernel options
|
||||
@ -166,13 +194,14 @@ CONFIG_BINFMT_MISC=m
|
||||
CONFIG_FORCE_MAX_ZONEORDER=9
|
||||
# CONFIG_IOMMU_VMERGE is not set
|
||||
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
|
||||
CONFIG_KEXEC=y
|
||||
# CONFIG_KEXEC is not set
|
||||
# CONFIG_CRASH_DUMP is not set
|
||||
CONFIG_IRQ_ALL_CPUS=y
|
||||
CONFIG_NUMA=y
|
||||
CONFIG_NODES_SHIFT=4
|
||||
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
|
||||
CONFIG_ARCH_SPARSEMEM_ENABLE=y
|
||||
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
|
||||
CONFIG_ARCH_POPULATES_NODE_MAP=y
|
||||
CONFIG_SELECT_MEMORY_MODEL=y
|
||||
# CONFIG_FLATMEM_MANUAL is not set
|
||||
@ -189,6 +218,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
|
||||
CONFIG_MIGRATION=y
|
||||
CONFIG_RESOURCES_64BIT=y
|
||||
CONFIG_ARCH_MEMORY_PROBE=y
|
||||
CONFIG_NODES_SPAN_OTHER_NODES=y
|
||||
CONFIG_PPC_64K_PAGES=y
|
||||
CONFIG_SCHED_SMT=y
|
||||
CONFIG_PROC_DEVICETREE=y
|
||||
@ -207,7 +237,6 @@ CONFIG_GENERIC_ISA_DMA=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PCIEPORTBUS=y
|
||||
# CONFIG_PCI_MULTITHREAD_PROBE is not set
|
||||
# CONFIG_PCI_DEBUG is not set
|
||||
|
||||
#
|
||||
@ -280,7 +309,6 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y
|
||||
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
|
||||
# CONFIG_IPV6_SIT is not set
|
||||
CONFIG_IPV6_TUNNEL=m
|
||||
# CONFIG_IPV6_SUBTREES is not set
|
||||
# CONFIG_IPV6_MULTIPLE_TABLES is not set
|
||||
# CONFIG_NETWORK_SECMARK is not set
|
||||
CONFIG_NETFILTER=y
|
||||
@ -1107,7 +1135,8 @@ CONFIG_PLIST=y
|
||||
#
|
||||
# Instrumentation Support
|
||||
#
|
||||
# CONFIG_PROFILING is not set
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_OPROFILE=y
|
||||
# CONFIG_KPROBES is not set
|
||||
|
||||
#
|
||||
@ -1142,6 +1171,7 @@ CONFIG_DEBUG_FS=y
|
||||
CONFIG_DEBUGGER=y
|
||||
CONFIG_XMON=y
|
||||
CONFIG_XMON_DEFAULT=y
|
||||
CONFIG_XMON_DISASSEMBLY=y
|
||||
CONFIG_IRQSTACKS=y
|
||||
# CONFIG_BOOTX_TEXT is not set
|
||||
# CONFIG_PPC_EARLY_DEBUG is not set
|
||||
@ -1159,7 +1189,7 @@ CONFIG_CRYPTO=y
|
||||
CONFIG_CRYPTO_ALGAPI=y
|
||||
CONFIG_CRYPTO_BLKCIPHER=m
|
||||
CONFIG_CRYPTO_HASH=y
|
||||
# CONFIG_CRYPTO_MANAGER is not set
|
||||
CONFIG_CRYPTO_MANAGER=y
|
||||
CONFIG_CRYPTO_HMAC=y
|
||||
# CONFIG_CRYPTO_NULL is not set
|
||||
# CONFIG_CRYPTO_MD4 is not set
|
||||
|
1583
arch/powerpc/configs/linkstation_defconfig
Normal file
1583
arch/powerpc/configs/linkstation_defconfig
Normal file
File diff suppressed because it is too large
Load Diff
931
arch/powerpc/configs/lite5200_defconfig
Normal file
931
arch/powerpc/configs/lite5200_defconfig
Normal file
@ -0,0 +1,931 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.19-rc6
|
||||
# Mon Nov 27 11:08:20 2006
|
||||
#
|
||||
# CONFIG_PPC64 is not set
|
||||
CONFIG_PPC32=y
|
||||
CONFIG_PPC_MERGE=y
|
||||
CONFIG_MMU=y
|
||||
CONFIG_GENERIC_HARDIRQS=y
|
||||
CONFIG_IRQ_PER_CPU=y
|
||||
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
|
||||
CONFIG_GENERIC_HWEIGHT=y
|
||||
CONFIG_GENERIC_CALIBRATE_DELAY=y
|
||||
CONFIG_GENERIC_FIND_NEXT_BIT=y
|
||||
CONFIG_PPC=y
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
CONFIG_GENERIC_NVRAM=y
|
||||
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
|
||||
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
|
||||
CONFIG_PPC_OF=y
|
||||
# CONFIG_PPC_UDBG_16550 is not set
|
||||
# CONFIG_GENERIC_TBSYNC is not set
|
||||
CONFIG_AUDIT_ARCH=y
|
||||
# CONFIG_DEFAULT_UIMAGE is not set
|
||||
|
||||
#
|
||||
# Processor support
|
||||
#
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_52xx is not set
|
||||
# CONFIG_PPC_82xx is not set
|
||||
# CONFIG_PPC_83xx is not set
|
||||
# CONFIG_PPC_85xx is not set
|
||||
# CONFIG_PPC_86xx is not set
|
||||
# CONFIG_40x is not set
|
||||
# CONFIG_44x is not set
|
||||
# CONFIG_8xx is not set
|
||||
# CONFIG_E200 is not set
|
||||
CONFIG_6xx=y
|
||||
CONFIG_PPC_FPU=y
|
||||
# CONFIG_PPC_DCR_NATIVE is not set
|
||||
# CONFIG_PPC_DCR_MMIO is not set
|
||||
# CONFIG_ALTIVEC is not set
|
||||
CONFIG_PPC_STD_MMU=y
|
||||
CONFIG_PPC_STD_MMU_32=y
|
||||
# CONFIG_SMP is not set
|
||||
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
|
||||
|
||||
#
|
||||
# Code maturity level options
|
||||
#
|
||||
CONFIG_EXPERIMENTAL=y
|
||||
CONFIG_BROKEN_ON_SMP=y
|
||||
CONFIG_INIT_ENV_ARG_LIMIT=32
|
||||
|
||||
#
|
||||
# General setup
|
||||
#
|
||||
CONFIG_LOCALVERSION=""
|
||||
CONFIG_LOCALVERSION_AUTO=y
|
||||
CONFIG_SWAP=y
|
||||
CONFIG_SYSVIPC=y
|
||||
# CONFIG_IPC_NS is not set
|
||||
# CONFIG_POSIX_MQUEUE is not set
|
||||
# CONFIG_BSD_PROCESS_ACCT is not set
|
||||
# CONFIG_TASKSTATS is not set
|
||||
# CONFIG_UTS_NS is not set
|
||||
# CONFIG_AUDIT is not set
|
||||
# CONFIG_IKCONFIG is not set
|
||||
# CONFIG_RELAY is not set
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
|
||||
CONFIG_SYSCTL=y
|
||||
CONFIG_EMBEDDED=y
|
||||
# CONFIG_SYSCTL_SYSCALL is not set
|
||||
# CONFIG_KALLSYMS is not set
|
||||
CONFIG_HOTPLUG=y
|
||||
CONFIG_PRINTK=y
|
||||
CONFIG_BUG=y
|
||||
CONFIG_ELF_CORE=y
|
||||
CONFIG_BASE_FULL=y
|
||||
CONFIG_FUTEX=y
|
||||
# CONFIG_EPOLL is not set
|
||||
CONFIG_SHMEM=y
|
||||
CONFIG_SLAB=y
|
||||
CONFIG_VM_EVENT_COUNTERS=y
|
||||
CONFIG_RT_MUTEXES=y
|
||||
# CONFIG_TINY_SHMEM is not set
|
||||
CONFIG_BASE_SMALL=0
|
||||
# CONFIG_SLOB is not set
|
||||
|
||||
#
|
||||
# Loadable module support
|
||||
#
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
# CONFIG_MODULE_FORCE_UNLOAD is not set
|
||||
# CONFIG_MODVERSIONS is not set
|
||||
# CONFIG_MODULE_SRCVERSION_ALL is not set
|
||||
# CONFIG_KMOD is not set
|
||||
|
||||
#
|
||||
# Block layer
|
||||
#
|
||||
CONFIG_BLOCK=y
|
||||
# CONFIG_LBD is not set
|
||||
# CONFIG_BLK_DEV_IO_TRACE is not set
|
||||
# CONFIG_LSF is not set
|
||||
|
||||
#
|
||||
# IO Schedulers
|
||||
#
|
||||
CONFIG_IOSCHED_NOOP=y
|
||||
CONFIG_IOSCHED_AS=y
|
||||
CONFIG_IOSCHED_DEADLINE=y
|
||||
CONFIG_IOSCHED_CFQ=y
|
||||
CONFIG_DEFAULT_AS=y
|
||||
# CONFIG_DEFAULT_DEADLINE is not set
|
||||
# CONFIG_DEFAULT_CFQ is not set
|
||||
# CONFIG_DEFAULT_NOOP is not set
|
||||
CONFIG_DEFAULT_IOSCHED="anticipatory"
|
||||
|
||||
#
|
||||
# Platform support
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
# CONFIG_EMBEDDED6xx is not set
|
||||
# CONFIG_APUS is not set
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
CONFIG_PPC_MPC52xx=y
|
||||
# CONFIG_PPC_EFIKA is not set
|
||||
CONFIG_PPC_LITE5200=y
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_PPC_CELL is not set
|
||||
# CONFIG_PPC_CELL_NATIVE is not set
|
||||
# CONFIG_PPC_RTAS is not set
|
||||
# CONFIG_MMIO_NVRAM is not set
|
||||
# CONFIG_PPC_MPC106 is not set
|
||||
# CONFIG_PPC_970_NAP is not set
|
||||
# CONFIG_PPC_INDIRECT_IO is not set
|
||||
# CONFIG_GENERIC_IOMAP is not set
|
||||
# CONFIG_CPU_FREQ is not set
|
||||
# CONFIG_TAU is not set
|
||||
# CONFIG_WANT_EARLY_SERIAL is not set
|
||||
# CONFIG_MPIC is not set
|
||||
|
||||
#
|
||||
# Kernel options
|
||||
#
|
||||
# CONFIG_HIGHMEM is not set
|
||||
# CONFIG_HZ_100 is not set
|
||||
CONFIG_HZ_250=y
|
||||
# CONFIG_HZ_1000 is not set
|
||||
CONFIG_HZ=250
|
||||
CONFIG_PREEMPT_NONE=y
|
||||
# CONFIG_PREEMPT_VOLUNTARY is not set
|
||||
# CONFIG_PREEMPT is not set
|
||||
CONFIG_BINFMT_ELF=y
|
||||
# CONFIG_BINFMT_MISC is not set
|
||||
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
|
||||
# CONFIG_KEXEC is not set
|
||||
CONFIG_ARCH_FLATMEM_ENABLE=y
|
||||
CONFIG_ARCH_POPULATES_NODE_MAP=y
|
||||
CONFIG_SELECT_MEMORY_MODEL=y
|
||||
CONFIG_FLATMEM_MANUAL=y
|
||||
# CONFIG_DISCONTIGMEM_MANUAL is not set
|
||||
# CONFIG_SPARSEMEM_MANUAL is not set
|
||||
CONFIG_FLATMEM=y
|
||||
CONFIG_FLAT_NODE_MEM_MAP=y
|
||||
# CONFIG_SPARSEMEM_STATIC is not set
|
||||
CONFIG_SPLIT_PTLOCK_CPUS=4
|
||||
# CONFIG_RESOURCES_64BIT is not set
|
||||
CONFIG_PROC_DEVICETREE=y
|
||||
# CONFIG_CMDLINE_BOOL is not set
|
||||
CONFIG_PM=y
|
||||
# CONFIG_PM_LEGACY is not set
|
||||
# CONFIG_PM_DEBUG is not set
|
||||
# CONFIG_PM_SYSFS_DEPRECATED is not set
|
||||
# CONFIG_SOFTWARE_SUSPEND is not set
|
||||
CONFIG_SECCOMP=y
|
||||
CONFIG_ISA_DMA_API=y
|
||||
|
||||
#
|
||||
# Bus options
|
||||
#
|
||||
CONFIG_GENERIC_ISA_DMA=y
|
||||
# CONFIG_MPIC_WEIRD is not set
|
||||
# CONFIG_PPC_I8259 is not set
|
||||
# CONFIG_PPC_INDIRECT_PCI is not set
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
# CONFIG_PCIEPORTBUS is not set
|
||||
# CONFIG_PCI_DEBUG is not set
|
||||
|
||||
#
|
||||
# PCCARD (PCMCIA/CardBus) support
|
||||
#
|
||||
# CONFIG_PCCARD is not set
|
||||
|
||||
#
|
||||
# PCI Hotplug Support
|
||||
#
|
||||
# CONFIG_HOTPLUG_PCI is not set
|
||||
|
||||
#
|
||||
# Advanced setup
|
||||
#
|
||||
# CONFIG_ADVANCED_OPTIONS is not set
|
||||
|
||||
#
|
||||
# Default settings for advanced configuration options are used
|
||||
#
|
||||
CONFIG_HIGHMEM_START=0xfe000000
|
||||
CONFIG_LOWMEM_SIZE=0x30000000
|
||||
CONFIG_KERNEL_START=0xc0000000
|
||||
CONFIG_TASK_SIZE=0x80000000
|
||||
CONFIG_BOOT_LOAD=0x00800000
|
||||
|
||||
#
|
||||
# Networking
|
||||
#
|
||||
CONFIG_NET=y
|
||||
|
||||
#
|
||||
# Networking options
|
||||
#
|
||||
# CONFIG_NETDEBUG is not set
|
||||
CONFIG_PACKET=y
|
||||
# CONFIG_PACKET_MMAP is not set
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM=y
|
||||
CONFIG_XFRM_USER=m
|
||||
# CONFIG_XFRM_SUB_POLICY is not set
|
||||
# CONFIG_NET_KEY is not set
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
# CONFIG_IP_ADVANCED_ROUTER is not set
|
||||
CONFIG_IP_FIB_HASH=y
|
||||
CONFIG_IP_PNP=y
|
||||
CONFIG_IP_PNP_DHCP=y
|
||||
CONFIG_IP_PNP_BOOTP=y
|
||||
# CONFIG_IP_PNP_RARP is not set
|
||||
# CONFIG_NET_IPIP is not set
|
||||
# CONFIG_NET_IPGRE is not set
|
||||
# CONFIG_IP_MROUTE is not set
|
||||
# CONFIG_ARPD is not set
|
||||
CONFIG_SYN_COOKIES=y
|
||||
# CONFIG_INET_AH is not set
|
||||
# CONFIG_INET_ESP is not set
|
||||
# CONFIG_INET_IPCOMP is not set
|
||||
# CONFIG_INET_XFRM_TUNNEL is not set
|
||||
# CONFIG_INET_TUNNEL is not set
|
||||
CONFIG_INET_XFRM_MODE_TRANSPORT=y
|
||||
CONFIG_INET_XFRM_MODE_TUNNEL=y
|
||||
CONFIG_INET_XFRM_MODE_BEET=y
|
||||
CONFIG_INET_DIAG=y
|
||||
CONFIG_INET_TCP_DIAG=y
|
||||
# CONFIG_TCP_CONG_ADVANCED is not set
|
||||
CONFIG_TCP_CONG_CUBIC=y
|
||||
CONFIG_DEFAULT_TCP_CONG="cubic"
|
||||
# CONFIG_IPV6 is not set
|
||||
# CONFIG_INET6_XFRM_TUNNEL is not set
|
||||
# CONFIG_INET6_TUNNEL is not set
|
||||
# CONFIG_NETWORK_SECMARK is not set
|
||||
# CONFIG_NETFILTER is not set
|
||||
|
||||
#
|
||||
# DCCP Configuration (EXPERIMENTAL)
|
||||
#
|
||||
# CONFIG_IP_DCCP is not set
|
||||
|
||||
#
|
||||
# SCTP Configuration (EXPERIMENTAL)
|
||||
#
|
||||
# CONFIG_IP_SCTP is not set
|
||||
|
||||
#
|
||||
# TIPC Configuration (EXPERIMENTAL)
|
||||
#
|
||||
# CONFIG_TIPC is not set
|
||||
# CONFIG_ATM is not set
|
||||
# CONFIG_BRIDGE is not set
|
||||
# CONFIG_VLAN_8021Q is not set
|
||||
# CONFIG_DECNET is not set
|
||||
# CONFIG_LLC2 is not set
|
||||
# CONFIG_IPX is not set
|
||||
# CONFIG_ATALK is not set
|
||||
# CONFIG_X25 is not set
|
||||
# CONFIG_LAPB is not set
|
||||
# CONFIG_ECONET is not set
|
||||
# CONFIG_WAN_ROUTER is not set
|
||||
|
||||
#
|
||||
# QoS and/or fair queueing
|
||||
#
|
||||
# CONFIG_NET_SCHED is not set
|
||||
|
||||
#
|
||||
# Network testing
|
||||
#
|
||||
# CONFIG_NET_PKTGEN is not set
|
||||
# CONFIG_HAMRADIO is not set
|
||||
# CONFIG_IRDA is not set
|
||||
# CONFIG_BT is not set
|
||||
# CONFIG_IEEE80211 is not set
|
||||
|
||||
#
|
||||
# Device Drivers
|
||||
#
|
||||
|
||||
#
|
||||
# Generic Driver Options
|
||||
#
|
||||
CONFIG_STANDALONE=y
|
||||
CONFIG_PREVENT_FIRMWARE_BUILD=y
|
||||
# CONFIG_FW_LOADER is not set
|
||||
# CONFIG_DEBUG_DRIVER is not set
|
||||
# CONFIG_SYS_HYPERVISOR is not set
|
||||
|
||||
#
|
||||
# Connector - unified userspace <-> kernelspace linker
|
||||
#
|
||||
# CONFIG_CONNECTOR is not set
|
||||
|
||||
#
|
||||
# Memory Technology Devices (MTD)
|
||||
#
|
||||
# CONFIG_MTD is not set
|
||||
|
||||
#
|
||||
# Parallel port support
|
||||
#
|
||||
# CONFIG_PARPORT is not set
|
||||
|
||||
#
|
||||
# Plug and Play support
|
||||
#
|
||||
|
||||
#
|
||||
# Block devices
|
||||
#
|
||||
# CONFIG_BLK_DEV_FD is not set
|
||||
# CONFIG_BLK_CPQ_DA is not set
|
||||
# CONFIG_BLK_CPQ_CISS_DA is not set
|
||||
# CONFIG_BLK_DEV_DAC960 is not set
|
||||
# CONFIG_BLK_DEV_UMEM is not set
|
||||
# CONFIG_BLK_DEV_COW_COMMON is not set
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
|
||||
# CONFIG_BLK_DEV_NBD is not set
|
||||
# CONFIG_BLK_DEV_SX8 is not set
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_COUNT=16
|
||||
CONFIG_BLK_DEV_RAM_SIZE=32768
|
||||
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_CDROM_PKTCDVD is not set
|
||||
# CONFIG_ATA_OVER_ETH is not set
|
||||
|
||||
#
|
||||
# Misc devices
|
||||
#
|
||||
# CONFIG_SGI_IOC4 is not set
|
||||
# CONFIG_TIFM_CORE is not set
|
||||
|
||||
#
|
||||
# ATA/ATAPI/MFM/RLL support
|
||||
#
|
||||
# CONFIG_IDE is not set
|
||||
|
||||
#
|
||||
# SCSI device support
|
||||
#
|
||||
# CONFIG_RAID_ATTRS is not set
|
||||
CONFIG_SCSI=y
|
||||
# CONFIG_SCSI_NETLINK is not set
|
||||
# CONFIG_SCSI_PROC_FS is not set
|
||||
|
||||
#
|
||||
# SCSI support type (disk, tape, CD-ROM)
|
||||
#
|
||||
# CONFIG_BLK_DEV_SD is not set
|
||||
# CONFIG_CHR_DEV_ST is not set
|
||||
# CONFIG_CHR_DEV_OSST is not set
|
||||
# CONFIG_BLK_DEV_SR is not set
|
||||
# CONFIG_CHR_DEV_SG is not set
|
||||
# CONFIG_CHR_DEV_SCH is not set
|
||||
|
||||
#
|
||||
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
|
||||
#
|
||||
# CONFIG_SCSI_MULTI_LUN is not set
|
||||
# CONFIG_SCSI_CONSTANTS is not set
|
||||
# CONFIG_SCSI_LOGGING is not set
|
||||
|
||||
#
|
||||
# SCSI Transports
|
||||
#
|
||||
# CONFIG_SCSI_SPI_ATTRS is not set
|
||||
# CONFIG_SCSI_FC_ATTRS is not set
|
||||
# CONFIG_SCSI_ISCSI_ATTRS is not set
|
||||
# CONFIG_SCSI_SAS_ATTRS is not set
|
||||
# CONFIG_SCSI_SAS_LIBSAS is not set
|
||||
|
||||
#
|
||||
# SCSI low-level drivers
|
||||
#
|
||||
# CONFIG_ISCSI_TCP is not set
|
||||
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
|
||||
# CONFIG_SCSI_3W_9XXX is not set
|
||||
# CONFIG_SCSI_ACARD is not set
|
||||
# CONFIG_SCSI_AACRAID is not set
|
||||
# CONFIG_SCSI_AIC7XXX is not set
|
||||
# CONFIG_SCSI_AIC7XXX_OLD is not set
|
||||
# CONFIG_SCSI_AIC79XX is not set
|
||||
# CONFIG_SCSI_AIC94XX is not set
|
||||
# CONFIG_SCSI_DPT_I2O is not set
|
||||
# CONFIG_SCSI_ARCMSR is not set
|
||||
# CONFIG_MEGARAID_NEWGEN is not set
|
||||
# CONFIG_MEGARAID_LEGACY is not set
|
||||
# CONFIG_MEGARAID_SAS is not set
|
||||
# CONFIG_SCSI_HPTIOP is not set
|
||||
# CONFIG_SCSI_BUSLOGIC is not set
|
||||
# CONFIG_SCSI_DMX3191D is not set
|
||||
# CONFIG_SCSI_EATA is not set
|
||||
# CONFIG_SCSI_FUTURE_DOMAIN is not set
|
||||
# CONFIG_SCSI_GDTH is not set
|
||||
# CONFIG_SCSI_IPS is not set
|
||||
# CONFIG_SCSI_INITIO is not set
|
||||
# CONFIG_SCSI_INIA100 is not set
|
||||
# CONFIG_SCSI_STEX is not set
|
||||
# CONFIG_SCSI_SYM53C8XX_2 is not set
|
||||
# CONFIG_SCSI_IPR is not set
|
||||
# CONFIG_SCSI_QLOGIC_1280 is not set
|
||||
# CONFIG_SCSI_QLA_FC is not set
|
||||
# CONFIG_SCSI_QLA_ISCSI is not set
|
||||
# CONFIG_SCSI_LPFC is not set
|
||||
# CONFIG_SCSI_DC395x is not set
|
||||
# CONFIG_SCSI_DC390T is not set
|
||||
# CONFIG_SCSI_NSP32 is not set
|
||||
# CONFIG_SCSI_DEBUG is not set
|
||||
|
||||
#
|
||||
# Serial ATA (prod) and Parallel ATA (experimental) drivers
|
||||
#
|
||||
CONFIG_ATA=y
|
||||
# CONFIG_SATA_AHCI is not set
|
||||
# CONFIG_SATA_SVW is not set
|
||||
# CONFIG_ATA_PIIX is not set
|
||||
# CONFIG_SATA_MV is not set
|
||||
# CONFIG_SATA_NV is not set
|
||||
# CONFIG_PDC_ADMA is not set
|
||||
# CONFIG_SATA_QSTOR is not set
|
||||
# CONFIG_SATA_PROMISE is not set
|
||||
# CONFIG_SATA_SX4 is not set
|
||||
# CONFIG_SATA_SIL is not set
|
||||
# CONFIG_SATA_SIL24 is not set
|
||||
# CONFIG_SATA_SIS is not set
|
||||
# CONFIG_SATA_ULI is not set
|
||||
# CONFIG_SATA_VIA is not set
|
||||
# CONFIG_SATA_VITESSE is not set
|
||||
# CONFIG_PATA_ALI is not set
|
||||
# CONFIG_PATA_AMD is not set
|
||||
# CONFIG_PATA_ARTOP is not set
|
||||
# CONFIG_PATA_ATIIXP is not set
|
||||
# CONFIG_PATA_CMD64X is not set
|
||||
# CONFIG_PATA_CS5520 is not set
|
||||
# CONFIG_PATA_CS5530 is not set
|
||||
# CONFIG_PATA_CYPRESS is not set
|
||||
# CONFIG_PATA_EFAR is not set
|
||||
# CONFIG_ATA_GENERIC is not set
|
||||
# CONFIG_PATA_HPT366 is not set
|
||||
# CONFIG_PATA_HPT37X is not set
|
||||
# CONFIG_PATA_HPT3X2N is not set
|
||||
# CONFIG_PATA_HPT3X3 is not set
|
||||
# CONFIG_PATA_IT821X is not set
|
||||
# CONFIG_PATA_JMICRON is not set
|
||||
# CONFIG_PATA_TRIFLEX is not set
|
||||
CONFIG_PATA_MPC52xx=y
|
||||
# CONFIG_PATA_MPIIX is not set
|
||||
# CONFIG_PATA_OLDPIIX is not set
|
||||
# CONFIG_PATA_NETCELL is not set
|
||||
# CONFIG_PATA_NS87410 is not set
|
||||
# CONFIG_PATA_OPTI is not set
|
||||
# CONFIG_PATA_OPTIDMA is not set
|
||||
# CONFIG_PATA_PDC_OLD is not set
|
||||
# CONFIG_PATA_RADISYS is not set
|
||||
# CONFIG_PATA_RZ1000 is not set
|
||||
# CONFIG_PATA_SC1200 is not set
|
||||
# CONFIG_PATA_SERVERWORKS is not set
|
||||
# CONFIG_PATA_PDC2027X is not set
|
||||
# CONFIG_PATA_SIL680 is not set
|
||||
# CONFIG_PATA_SIS is not set
|
||||
# CONFIG_PATA_VIA is not set
|
||||
# CONFIG_PATA_WINBOND is not set
|
||||
|
||||
#
|
||||
# Multi-device support (RAID and LVM)
|
||||
#
|
||||
# CONFIG_MD is not set
|
||||
|
||||
#
|
||||
# Fusion MPT device support
|
||||
#
|
||||
# CONFIG_FUSION is not set
|
||||
# CONFIG_FUSION_SPI is not set
|
||||
# CONFIG_FUSION_FC is not set
|
||||
# CONFIG_FUSION_SAS is not set
|
||||
|
||||
#
|
||||
# IEEE 1394 (FireWire) support
|
||||
#
|
||||
# CONFIG_IEEE1394 is not set
|
||||
|
||||
#
|
||||
# I2O device support
|
||||
#
|
||||
# CONFIG_I2O is not set
|
||||
|
||||
#
|
||||
# Macintosh device drivers
|
||||
#
|
||||
# CONFIG_WINDFARM is not set
|
||||
|
||||
#
|
||||
# Network device support
|
||||
#
|
||||
CONFIG_NETDEVICES=y
|
||||
# CONFIG_DUMMY is not set
|
||||
# CONFIG_BONDING is not set
|
||||
# CONFIG_EQUALIZER is not set
|
||||
# CONFIG_TUN is not set
|
||||
|
||||
#
|
||||
# ARCnet devices
|
||||
#
|
||||
# CONFIG_ARCNET is not set
|
||||
|
||||
#
|
||||
# PHY device support
|
||||
#
|
||||
|
||||
#
|
||||
# Ethernet (10 or 100Mbit)
|
||||
#
|
||||
# CONFIG_NET_ETHERNET is not set
|
||||
|
||||
#
|
||||
# Ethernet (1000 Mbit)
|
||||
#
|
||||
# CONFIG_ACENIC is not set
|
||||
# CONFIG_DL2K is not set
|
||||
# CONFIG_E1000 is not set
|
||||
# CONFIG_NS83820 is not set
|
||||
# CONFIG_HAMACHI is not set
|
||||
# CONFIG_YELLOWFIN is not set
|
||||
# CONFIG_R8169 is not set
|
||||
# CONFIG_SIS190 is not set
|
||||
# CONFIG_SKGE is not set
|
||||
# CONFIG_SKY2 is not set
|
||||
# CONFIG_SK98LIN is not set
|
||||
# CONFIG_TIGON3 is not set
|
||||
# CONFIG_BNX2 is not set
|
||||
# CONFIG_MV643XX_ETH is not set
|
||||
# CONFIG_QLA3XXX is not set
|
||||
|
||||
#
|
||||
# Ethernet (10000 Mbit)
|
||||
#
|
||||
# CONFIG_CHELSIO_T1 is not set
|
||||
# CONFIG_IXGB is not set
|
||||
# CONFIG_S2IO is not set
|
||||
# CONFIG_MYRI10GE is not set
|
||||
|
||||
#
|
||||
# Token Ring devices
|
||||
#
|
||||
# CONFIG_TR is not set
|
||||
|
||||
#
|
||||
# Wireless LAN (non-hamradio)
|
||||
#
|
||||
# CONFIG_NET_RADIO is not set
|
||||
|
||||
#
|
||||
# Wan interfaces
|
||||
#
|
||||
# CONFIG_WAN is not set
|
||||
# CONFIG_FDDI is not set
|
||||
# CONFIG_HIPPI is not set
|
||||
# CONFIG_PPP is not set
|
||||
# CONFIG_SLIP is not set
|
||||
# CONFIG_NET_FC is not set
|
||||
# CONFIG_SHAPER is not set
|
||||
# CONFIG_NETCONSOLE is not set
|
||||
# CONFIG_NETPOLL is not set
|
||||
# CONFIG_NET_POLL_CONTROLLER is not set
|
||||
|
||||
#
|
||||
# ISDN subsystem
|
||||
#
|
||||
# CONFIG_ISDN is not set
|
||||
|
||||
#
|
||||
# Telephony Support
|
||||
#
|
||||
# CONFIG_PHONE is not set
|
||||
|
||||
#
|
||||
# Input device support
|
||||
#
|
||||
# CONFIG_INPUT is not set
|
||||
|
||||
#
|
||||
# Hardware I/O ports
|
||||
#
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_GAMEPORT is not set
|
||||
|
||||
#
|
||||
# Character devices
|
||||
#
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_SERIAL_NONSTANDARD is not set
|
||||
|
||||
#
|
||||
# Serial drivers
|
||||
#
|
||||
# CONFIG_SERIAL_8250 is not set
|
||||
|
||||
#
|
||||
# Non-8250 serial port support
|
||||
#
|
||||
CONFIG_SERIAL_CORE=y
|
||||
CONFIG_SERIAL_CORE_CONSOLE=y
|
||||
CONFIG_SERIAL_MPC52xx=y
|
||||
CONFIG_SERIAL_MPC52xx_CONSOLE=y
|
||||
CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=9600
|
||||
# CONFIG_SERIAL_JSM is not set
|
||||
CONFIG_UNIX98_PTYS=y
|
||||
CONFIG_LEGACY_PTYS=y
|
||||
CONFIG_LEGACY_PTY_COUNT=256
|
||||
|
||||
#
|
||||
# IPMI
|
||||
#
|
||||
# CONFIG_IPMI_HANDLER is not set
|
||||
|
||||
#
|
||||
# Watchdog Cards
|
||||
#
|
||||
# CONFIG_WATCHDOG is not set
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
# CONFIG_NVRAM is not set
|
||||
# CONFIG_GEN_RTC is not set
|
||||
# CONFIG_DTLK is not set
|
||||
# CONFIG_R3964 is not set
|
||||
# CONFIG_APPLICOM is not set
|
||||
|
||||
#
|
||||
# Ftape, the floppy tape device driver
|
||||
#
|
||||
# CONFIG_AGP is not set
|
||||
# CONFIG_DRM is not set
|
||||
# CONFIG_RAW_DRIVER is not set
|
||||
|
||||
#
|
||||
# TPM devices
|
||||
#
|
||||
# CONFIG_TCG_TPM is not set
|
||||
|
||||
#
|
||||
# I2C support
|
||||
#
|
||||
# CONFIG_I2C is not set
|
||||
|
||||
#
|
||||
# SPI support
|
||||
#
|
||||
# CONFIG_SPI is not set
|
||||
# CONFIG_SPI_MASTER is not set
|
||||
|
||||
#
|
||||
# Dallas's 1-wire bus
|
||||
#
|
||||
# CONFIG_W1 is not set
|
||||
|
||||
#
|
||||
# Hardware Monitoring support
|
||||
#
|
||||
# CONFIG_HWMON is not set
|
||||
# CONFIG_HWMON_VID is not set
|
||||
|
||||
#
|
||||
# Multimedia devices
|
||||
#
|
||||
# CONFIG_VIDEO_DEV is not set
|
||||
|
||||
#
|
||||
# Digital Video Broadcasting Devices
|
||||
#
|
||||
# CONFIG_DVB is not set
|
||||
|
||||
#
|
||||
# Graphics support
|
||||
#
|
||||
# CONFIG_FIRMWARE_EDID is not set
|
||||
# CONFIG_FB is not set
|
||||
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
|
||||
|
||||
#
|
||||
# Sound
|
||||
#
|
||||
# CONFIG_SOUND is not set
|
||||
|
||||
#
|
||||
# USB support
|
||||
#
|
||||
CONFIG_USB_ARCH_HAS_HCD=y
|
||||
CONFIG_USB_ARCH_HAS_OHCI=y
|
||||
CONFIG_USB_ARCH_HAS_EHCI=y
|
||||
# CONFIG_USB is not set
|
||||
|
||||
#
|
||||
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
|
||||
#
|
||||
|
||||
#
|
||||
# USB Gadget Support
|
||||
#
|
||||
# CONFIG_USB_GADGET is not set
|
||||
|
||||
#
|
||||
# MMC/SD Card support
|
||||
#
|
||||
# CONFIG_MMC is not set
|
||||
|
||||
#
|
||||
# LED devices
|
||||
#
|
||||
# CONFIG_NEW_LEDS is not set
|
||||
|
||||
#
|
||||
# LED drivers
|
||||
#
|
||||
|
||||
#
|
||||
# LED Triggers
|
||||
#
|
||||
|
||||
#
|
||||
# InfiniBand support
|
||||
#
|
||||
# CONFIG_INFINIBAND is not set
|
||||
|
||||
#
|
||||
# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
|
||||
#
|
||||
|
||||
#
|
||||
# Real Time Clock
|
||||
#
|
||||
# CONFIG_RTC_CLASS is not set
|
||||
|
||||
#
|
||||
# DMA Engine support
|
||||
#
|
||||
# CONFIG_DMA_ENGINE is not set
|
||||
|
||||
#
|
||||
# DMA Clients
|
||||
#
|
||||
|
||||
#
|
||||
# DMA Devices
|
||||
#
|
||||
|
||||
#
|
||||
# File systems
|
||||
#
|
||||
CONFIG_EXT2_FS=y
|
||||
# CONFIG_EXT2_FS_XATTR is not set
|
||||
# CONFIG_EXT2_FS_XIP is not set
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT3_FS_XATTR=y
|
||||
# CONFIG_EXT3_FS_POSIX_ACL is not set
|
||||
# CONFIG_EXT3_FS_SECURITY is not set
|
||||
# CONFIG_EXT4DEV_FS is not set
|
||||
CONFIG_JBD=y
|
||||
# CONFIG_JBD_DEBUG is not set
|
||||
CONFIG_FS_MBCACHE=y
|
||||
# CONFIG_REISERFS_FS is not set
|
||||
# CONFIG_JFS_FS is not set
|
||||
# CONFIG_FS_POSIX_ACL is not set
|
||||
# CONFIG_XFS_FS is not set
|
||||
# CONFIG_GFS2_FS is not set
|
||||
# CONFIG_OCFS2_FS is not set
|
||||
# CONFIG_MINIX_FS is not set
|
||||
# CONFIG_ROMFS_FS is not set
|
||||
CONFIG_INOTIFY=y
|
||||
CONFIG_INOTIFY_USER=y
|
||||
# CONFIG_QUOTA is not set
|
||||
CONFIG_DNOTIFY=y
|
||||
# CONFIG_AUTOFS_FS is not set
|
||||
# CONFIG_AUTOFS4_FS is not set
|
||||
# CONFIG_FUSE_FS is not set
|
||||
|
||||
#
|
||||
# CD-ROM/DVD Filesystems
|
||||
#
|
||||
# CONFIG_ISO9660_FS is not set
|
||||
# CONFIG_UDF_FS is not set
|
||||
|
||||
#
|
||||
# DOS/FAT/NT Filesystems
|
||||
#
|
||||
# CONFIG_MSDOS_FS is not set
|
||||
# CONFIG_VFAT_FS is not set
|
||||
# CONFIG_NTFS_FS is not set
|
||||
|
||||
#
|
||||
# Pseudo filesystems
|
||||
#
|
||||
CONFIG_PROC_FS=y
|
||||
CONFIG_PROC_KCORE=y
|
||||
CONFIG_PROC_SYSCTL=y
|
||||
CONFIG_SYSFS=y
|
||||
CONFIG_TMPFS=y
|
||||
# CONFIG_TMPFS_POSIX_ACL is not set
|
||||
# CONFIG_HUGETLB_PAGE is not set
|
||||
CONFIG_RAMFS=y
|
||||
# CONFIG_CONFIGFS_FS is not set
|
||||
|
||||
#
|
||||
# Miscellaneous filesystems
|
||||
#
|
||||
# CONFIG_ADFS_FS is not set
|
||||
# CONFIG_AFFS_FS is not set
|
||||
# CONFIG_HFS_FS is not set
|
||||
# CONFIG_HFSPLUS_FS is not set
|
||||
# CONFIG_BEFS_FS is not set
|
||||
# CONFIG_BFS_FS is not set
|
||||
# CONFIG_EFS_FS is not set
|
||||
# CONFIG_CRAMFS is not set
|
||||
# CONFIG_VXFS_FS is not set
|
||||
# CONFIG_HPFS_FS is not set
|
||||
# CONFIG_QNX4FS_FS is not set
|
||||
# CONFIG_SYSV_FS is not set
|
||||
# CONFIG_UFS_FS is not set
|
||||
|
||||
#
|
||||
# Network File Systems
|
||||
#
|
||||
# CONFIG_NFS_FS is not set
|
||||
# CONFIG_NFSD is not set
|
||||
# CONFIG_SMB_FS is not set
|
||||
# CONFIG_CIFS is not set
|
||||
# CONFIG_NCP_FS is not set
|
||||
# CONFIG_CODA_FS is not set
|
||||
# CONFIG_AFS_FS is not set
|
||||
# CONFIG_9P_FS is not set
|
||||
|
||||
#
|
||||
# Partition Types
|
||||
#
|
||||
# CONFIG_PARTITION_ADVANCED is not set
|
||||
CONFIG_MSDOS_PARTITION=y
|
||||
|
||||
#
|
||||
# Native Language Support
|
||||
#
|
||||
# CONFIG_NLS is not set
|
||||
|
||||
#
|
||||
# Library routines
|
||||
#
|
||||
# CONFIG_CRC_CCITT is not set
|
||||
# CONFIG_CRC16 is not set
|
||||
# CONFIG_CRC32 is not set
|
||||
# CONFIG_LIBCRC32C is not set
|
||||
CONFIG_PLIST=y
|
||||
|
||||
#
|
||||
# Instrumentation Support
|
||||
#
|
||||
# CONFIG_PROFILING is not set
|
||||
|
||||
#
|
||||
# Kernel hacking
|
||||
#
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_ENABLE_MUST_CHECK=y
|
||||
# CONFIG_MAGIC_SYSRQ is not set
|
||||
# CONFIG_UNUSED_SYMBOLS is not set
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_LOG_BUF_SHIFT=14
|
||||
CONFIG_DETECT_SOFTLOCKUP=y
|
||||
# CONFIG_SCHEDSTATS is not set
|
||||
# CONFIG_DEBUG_SLAB is not set
|
||||
# CONFIG_DEBUG_RT_MUTEXES is not set
|
||||
# CONFIG_RT_MUTEX_TESTER is not set
|
||||
# CONFIG_DEBUG_SPINLOCK is not set
|
||||
# CONFIG_DEBUG_MUTEXES is not set
|
||||
# CONFIG_DEBUG_RWSEMS is not set
|
||||
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
|
||||
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
|
||||
# CONFIG_DEBUG_KOBJECT is not set
|
||||
CONFIG_DEBUG_INFO=y
|
||||
# CONFIG_DEBUG_FS is not set
|
||||
# CONFIG_DEBUG_VM is not set
|
||||
# CONFIG_DEBUG_LIST is not set
|
||||
CONFIG_FORCED_INLINING=y
|
||||
# CONFIG_HEADERS_CHECK is not set
|
||||
# CONFIG_RCU_TORTURE_TEST is not set
|
||||
# CONFIG_DEBUGGER is not set
|
||||
# CONFIG_BDI_SWITCH is not set
|
||||
# CONFIG_BOOTX_TEXT is not set
|
||||
# CONFIG_SERIAL_TEXT_DEBUG is not set
|
||||
# CONFIG_PPC_EARLY_DEBUG is not set
|
||||
|
||||
#
|
||||
# Security options
|
||||
#
|
||||
# CONFIG_KEYS is not set
|
||||
# CONFIG_SECURITY is not set
|
||||
|
||||
#
|
||||
# Cryptographic options
|
||||
#
|
||||
# CONFIG_CRYPTO is not set
|
@ -1386,8 +1386,8 @@ CONFIG_INOTIFY=y
|
||||
CONFIG_INOTIFY_USER=y
|
||||
# CONFIG_QUOTA is not set
|
||||
CONFIG_DNOTIFY=y
|
||||
CONFIG_AUTOFS_FS=y
|
||||
# CONFIG_AUTOFS4_FS is not set
|
||||
# CONFIG_AUTOFS_FS is not set
|
||||
CONFIG_AUTOFS4_FS=m
|
||||
# CONFIG_FUSE_FS is not set
|
||||
|
||||
#
|
||||
|
837
arch/powerpc/configs/ps3_defconfig
Normal file
837
arch/powerpc/configs/ps3_defconfig
Normal file
@ -0,0 +1,837 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.19-rc6
|
||||
# Tue Nov 21 19:38:53 2006
|
||||
#
|
||||
CONFIG_PPC64=y
|
||||
CONFIG_64BIT=y
|
||||
CONFIG_PPC_MERGE=y
|
||||
CONFIG_MMU=y
|
||||
CONFIG_GENERIC_HARDIRQS=y
|
||||
CONFIG_IRQ_PER_CPU=y
|
||||
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
|
||||
CONFIG_GENERIC_HWEIGHT=y
|
||||
CONFIG_GENERIC_CALIBRATE_DELAY=y
|
||||
CONFIG_GENERIC_FIND_NEXT_BIT=y
|
||||
CONFIG_PPC=y
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
CONFIG_COMPAT=y
|
||||
CONFIG_SYSVIPC_COMPAT=y
|
||||
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
|
||||
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
|
||||
CONFIG_PPC_OF=y
|
||||
# CONFIG_PPC_UDBG_16550 is not set
|
||||
# CONFIG_GENERIC_TBSYNC is not set
|
||||
CONFIG_AUDIT_ARCH=y
|
||||
# CONFIG_DEFAULT_UIMAGE is not set
|
||||
|
||||
#
|
||||
# Processor support
|
||||
#
|
||||
# CONFIG_POWER4_ONLY is not set
|
||||
CONFIG_POWER3=y
|
||||
CONFIG_POWER4=y
|
||||
CONFIG_PPC_FPU=y
|
||||
# CONFIG_PPC_DCR_NATIVE is not set
|
||||
# CONFIG_PPC_DCR_MMIO is not set
|
||||
# CONFIG_PPC_OF_PLATFORM_PCI is not set
|
||||
CONFIG_ALTIVEC=y
|
||||
CONFIG_PPC_STD_MMU=y
|
||||
CONFIG_VIRT_CPU_ACCOUNTING=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_NR_CPUS=2
|
||||
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
|
||||
|
||||
#
|
||||
# Code maturity level options
|
||||
#
|
||||
CONFIG_EXPERIMENTAL=y
|
||||
CONFIG_LOCK_KERNEL=y
|
||||
CONFIG_INIT_ENV_ARG_LIMIT=32
|
||||
|
||||
#
|
||||
# General setup
|
||||
#
|
||||
CONFIG_LOCALVERSION=""
|
||||
CONFIG_LOCALVERSION_AUTO=y
|
||||
CONFIG_SWAP=y
|
||||
CONFIG_SYSVIPC=y
|
||||
# CONFIG_IPC_NS is not set
|
||||
# CONFIG_POSIX_MQUEUE is not set
|
||||
# CONFIG_BSD_PROCESS_ACCT is not set
|
||||
# CONFIG_TASKSTATS is not set
|
||||
# CONFIG_UTS_NS is not set
|
||||
# CONFIG_AUDIT is not set
|
||||
# CONFIG_IKCONFIG is not set
|
||||
# CONFIG_CPUSETS is not set
|
||||
# CONFIG_RELAY is not set
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
|
||||
CONFIG_SYSCTL=y
|
||||
CONFIG_EMBEDDED=y
|
||||
# CONFIG_SYSCTL_SYSCALL is not set
|
||||
CONFIG_KALLSYMS=y
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
CONFIG_KALLSYMS_EXTRA_PASS=y
|
||||
CONFIG_HOTPLUG=y
|
||||
CONFIG_PRINTK=y
|
||||
CONFIG_BUG=y
|
||||
CONFIG_ELF_CORE=y
|
||||
CONFIG_BASE_FULL=y
|
||||
CONFIG_FUTEX=y
|
||||
CONFIG_EPOLL=y
|
||||
CONFIG_SHMEM=y
|
||||
CONFIG_SLAB=y
|
||||
CONFIG_VM_EVENT_COUNTERS=y
|
||||
CONFIG_RT_MUTEXES=y
|
||||
# CONFIG_TINY_SHMEM is not set
|
||||
CONFIG_BASE_SMALL=0
|
||||
# CONFIG_SLOB is not set
|
||||
|
||||
#
|
||||
# Loadable module support
|
||||
#
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
# CONFIG_MODULE_FORCE_UNLOAD is not set
|
||||
# CONFIG_MODVERSIONS is not set
|
||||
# CONFIG_MODULE_SRCVERSION_ALL is not set
|
||||
CONFIG_KMOD=y
|
||||
CONFIG_STOP_MACHINE=y
|
||||
|
||||
#
|
||||
# Block layer
|
||||
#
|
||||
CONFIG_BLOCK=y
|
||||
# CONFIG_BLK_DEV_IO_TRACE is not set
|
||||
|
||||
#
|
||||
# IO Schedulers
|
||||
#
|
||||
CONFIG_IOSCHED_NOOP=y
|
||||
CONFIG_IOSCHED_AS=y
|
||||
CONFIG_IOSCHED_DEADLINE=y
|
||||
CONFIG_IOSCHED_CFQ=y
|
||||
CONFIG_DEFAULT_AS=y
|
||||
# CONFIG_DEFAULT_DEADLINE is not set
|
||||
# CONFIG_DEFAULT_CFQ is not set
|
||||
# CONFIG_DEFAULT_NOOP is not set
|
||||
CONFIG_DEFAULT_IOSCHED="anticipatory"
|
||||
|
||||
#
|
||||
# Platform support
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
# CONFIG_EMBEDDED6xx is not set
|
||||
# CONFIG_APUS is not set
|
||||
# CONFIG_PPC_PSERIES is not set
|
||||
# CONFIG_PPC_ISERIES is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_PPC_MAPLE is not set
|
||||
# CONFIG_PPC_PASEMI is not set
|
||||
CONFIG_PPC_CELL=y
|
||||
# CONFIG_PPC_CELL_NATIVE is not set
|
||||
# CONFIG_PPC_IBM_CELL_BLADE is not set
|
||||
CONFIG_PPC_PS3=y
|
||||
# CONFIG_U3_DART is not set
|
||||
# CONFIG_PPC_RTAS is not set
|
||||
# CONFIG_MMIO_NVRAM is not set
|
||||
# CONFIG_PPC_MPC106 is not set
|
||||
# CONFIG_PPC_970_NAP is not set
|
||||
# CONFIG_PPC_INDIRECT_IO is not set
|
||||
# CONFIG_GENERIC_IOMAP is not set
|
||||
# CONFIG_CPU_FREQ is not set
|
||||
# CONFIG_WANT_EARLY_SERIAL is not set
|
||||
# CONFIG_MPIC is not set
|
||||
|
||||
#
|
||||
# Cell Broadband Engine options
|
||||
#
|
||||
CONFIG_SPU_FS=y
|
||||
CONFIG_SPU_BASE=y
|
||||
# CONFIG_CBE_RAS is not set
|
||||
|
||||
#
|
||||
# PS3 Platform Options
|
||||
#
|
||||
CONFIG_PS3_HTAB_SIZE=20
|
||||
CONFIG_PS3_DYNAMIC_DMA=y
|
||||
CONFIG_PS3_USE_LPAR_ADDR=y
|
||||
|
||||
#
|
||||
# Kernel options
|
||||
#
|
||||
# CONFIG_HZ_100 is not set
|
||||
CONFIG_HZ_250=y
|
||||
# CONFIG_HZ_1000 is not set
|
||||
CONFIG_HZ=250
|
||||
CONFIG_PREEMPT_NONE=y
|
||||
# CONFIG_PREEMPT_VOLUNTARY is not set
|
||||
# CONFIG_PREEMPT is not set
|
||||
# CONFIG_PREEMPT_BKL is not set
|
||||
CONFIG_BINFMT_ELF=y
|
||||
CONFIG_BINFMT_MISC=y
|
||||
CONFIG_FORCE_MAX_ZONEORDER=9
|
||||
# CONFIG_IOMMU_VMERGE is not set
|
||||
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
|
||||
# CONFIG_KEXEC is not set
|
||||
# CONFIG_CRASH_DUMP is not set
|
||||
# CONFIG_IRQ_ALL_CPUS is not set
|
||||
# CONFIG_NUMA is not set
|
||||
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
|
||||
CONFIG_ARCH_FLATMEM_ENABLE=y
|
||||
CONFIG_ARCH_SPARSEMEM_ENABLE=y
|
||||
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
|
||||
CONFIG_ARCH_POPULATES_NODE_MAP=y
|
||||
CONFIG_SELECT_MEMORY_MODEL=y
|
||||
# CONFIG_FLATMEM_MANUAL is not set
|
||||
# CONFIG_DISCONTIGMEM_MANUAL is not set
|
||||
CONFIG_SPARSEMEM_MANUAL=y
|
||||
CONFIG_SPARSEMEM=y
|
||||
CONFIG_HAVE_MEMORY_PRESENT=y
|
||||
# CONFIG_SPARSEMEM_STATIC is not set
|
||||
CONFIG_SPARSEMEM_EXTREME=y
|
||||
CONFIG_MEMORY_HOTPLUG=y
|
||||
CONFIG_MEMORY_HOTPLUG_SPARSE=y
|
||||
CONFIG_SPLIT_PTLOCK_CPUS=4
|
||||
CONFIG_RESOURCES_64BIT=y
|
||||
CONFIG_ARCH_MEMORY_PROBE=y
|
||||
CONFIG_PPC_64K_PAGES=y
|
||||
# CONFIG_SCHED_SMT is not set
|
||||
CONFIG_PROC_DEVICETREE=y
|
||||
CONFIG_CMDLINE_BOOL=y
|
||||
CONFIG_CMDLINE="root=/dev/nfs rw ip=dhcp"
|
||||
# CONFIG_PM is not set
|
||||
# CONFIG_SECCOMP is not set
|
||||
CONFIG_ISA_DMA_API=y
|
||||
|
||||
#
|
||||
# Bus options
|
||||
#
|
||||
CONFIG_GENERIC_ISA_DMA=y
|
||||
# CONFIG_MPIC_WEIRD is not set
|
||||
# CONFIG_PPC_I8259 is not set
|
||||
# CONFIG_PCI is not set
|
||||
# CONFIG_PCI_DOMAINS is not set
|
||||
|
||||
#
|
||||
# PCCARD (PCMCIA/CardBus) support
|
||||
#
|
||||
# CONFIG_PCCARD is not set
|
||||
|
||||
#
|
||||
# PCI Hotplug Support
|
||||
#
|
||||
CONFIG_KERNEL_START=0xc000000000000000
|
||||
|
||||
#
|
||||
# Networking
|
||||
#
|
||||
CONFIG_NET=y
|
||||
|
||||
#
|
||||
# Networking options
|
||||
#
|
||||
# CONFIG_NETDEBUG is not set
|
||||
# CONFIG_PACKET is not set
|
||||
CONFIG_UNIX=y
|
||||
# CONFIG_NET_KEY is not set
|
||||
CONFIG_INET=y
|
||||
# CONFIG_IP_MULTICAST is not set
|
||||
# CONFIG_IP_ADVANCED_ROUTER is not set
|
||||
CONFIG_IP_FIB_HASH=y
|
||||
CONFIG_IP_PNP=y
|
||||
CONFIG_IP_PNP_DHCP=y
|
||||
# CONFIG_IP_PNP_BOOTP is not set
|
||||
# CONFIG_IP_PNP_RARP is not set
|
||||
# CONFIG_NET_IPIP is not set
|
||||
# CONFIG_NET_IPGRE is not set
|
||||
# CONFIG_ARPD is not set
|
||||
# CONFIG_SYN_COOKIES is not set
|
||||
# CONFIG_INET_AH is not set
|
||||
# CONFIG_INET_ESP is not set
|
||||
# CONFIG_INET_IPCOMP is not set
|
||||
# CONFIG_INET_XFRM_TUNNEL is not set
|
||||
# CONFIG_INET_TUNNEL is not set
|
||||
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
|
||||
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
|
||||
# CONFIG_INET_XFRM_MODE_BEET is not set
|
||||
# CONFIG_INET_DIAG is not set
|
||||
# CONFIG_TCP_CONG_ADVANCED is not set
|
||||
CONFIG_TCP_CONG_CUBIC=y
|
||||
CONFIG_DEFAULT_TCP_CONG="cubic"
|
||||
# CONFIG_IPV6 is not set
|
||||
# CONFIG_INET6_XFRM_TUNNEL is not set
|
||||
# CONFIG_INET6_TUNNEL is not set
|
||||
# CONFIG_NETWORK_SECMARK is not set
|
||||
# CONFIG_NETFILTER is not set
|
||||
|
||||
#
|
||||
# DCCP Configuration (EXPERIMENTAL)
|
||||
#
|
||||
# CONFIG_IP_DCCP is not set
|
||||
|
||||
#
|
||||
# SCTP Configuration (EXPERIMENTAL)
|
||||
#
|
||||
# CONFIG_IP_SCTP is not set
|
||||
|
||||
#
|
||||
# TIPC Configuration (EXPERIMENTAL)
|
||||
#
|
||||
# CONFIG_TIPC is not set
|
||||
# CONFIG_ATM is not set
|
||||
# CONFIG_BRIDGE is not set
|
||||
# CONFIG_VLAN_8021Q is not set
|
||||
# CONFIG_DECNET is not set
|
||||
# CONFIG_LLC2 is not set
|
||||
# CONFIG_IPX is not set
|
||||
# CONFIG_ATALK is not set
|
||||
# CONFIG_X25 is not set
|
||||
# CONFIG_LAPB is not set
|
||||
# CONFIG_ECONET is not set
|
||||
# CONFIG_WAN_ROUTER is not set
|
||||
|
||||
#
|
||||
# QoS and/or fair queueing
|
||||
#
|
||||
# CONFIG_NET_SCHED is not set
|
||||
|
||||
#
|
||||
# Network testing
|
||||
#
|
||||
# CONFIG_NET_PKTGEN is not set
|
||||
# CONFIG_HAMRADIO is not set
|
||||
# CONFIG_IRDA is not set
|
||||
# CONFIG_BT is not set
|
||||
# CONFIG_IEEE80211 is not set
|
||||
|
||||
#
|
||||
# Device Drivers
|
||||
#
|
||||
|
||||
#
|
||||
# Generic Driver Options
|
||||
#
|
||||
CONFIG_STANDALONE=y
|
||||
CONFIG_PREVENT_FIRMWARE_BUILD=y
|
||||
# CONFIG_FW_LOADER is not set
|
||||
# CONFIG_DEBUG_DRIVER is not set
|
||||
# CONFIG_SYS_HYPERVISOR is not set
|
||||
|
||||
#
|
||||
# Connector - unified userspace <-> kernelspace linker
|
||||
#
|
||||
# CONFIG_CONNECTOR is not set
|
||||
|
||||
#
|
||||
# Memory Technology Devices (MTD)
|
||||
#
|
||||
# CONFIG_MTD is not set
|
||||
|
||||
#
|
||||
# Parallel port support
|
||||
#
|
||||
# CONFIG_PARPORT is not set
|
||||
|
||||
#
|
||||
# Plug and Play support
|
||||
#
|
||||
|
||||
#
|
||||
# Block devices
|
||||
#
|
||||
# CONFIG_BLK_DEV_FD is not set
|
||||
# CONFIG_BLK_DEV_COW_COMMON is not set
|
||||
# CONFIG_BLK_DEV_LOOP is not set
|
||||
# CONFIG_BLK_DEV_NBD is not set
|
||||
# CONFIG_BLK_DEV_RAM is not set
|
||||
# CONFIG_BLK_DEV_INITRD is not set
|
||||
# CONFIG_CDROM_PKTCDVD is not set
|
||||
# CONFIG_ATA_OVER_ETH is not set
|
||||
|
||||
#
|
||||
# Misc devices
|
||||
#
|
||||
# CONFIG_TIFM_CORE is not set
|
||||
|
||||
#
|
||||
# ATA/ATAPI/MFM/RLL support
|
||||
#
|
||||
# CONFIG_IDE is not set
|
||||
|
||||
#
|
||||
# SCSI device support
|
||||
#
|
||||
# CONFIG_RAID_ATTRS is not set
|
||||
CONFIG_SCSI=y
|
||||
# CONFIG_SCSI_NETLINK is not set
|
||||
CONFIG_SCSI_PROC_FS=y
|
||||
|
||||
#
|
||||
# SCSI support type (disk, tape, CD-ROM)
|
||||
#
|
||||
# CONFIG_BLK_DEV_SD is not set
|
||||
# CONFIG_CHR_DEV_ST is not set
|
||||
# CONFIG_CHR_DEV_OSST is not set
|
||||
# CONFIG_BLK_DEV_SR is not set
|
||||
# CONFIG_CHR_DEV_SG is not set
|
||||
# CONFIG_CHR_DEV_SCH is not set
|
||||
|
||||
#
|
||||
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
|
||||
#
|
||||
# CONFIG_SCSI_MULTI_LUN is not set
|
||||
# CONFIG_SCSI_CONSTANTS is not set
|
||||
# CONFIG_SCSI_LOGGING is not set
|
||||
|
||||
#
|
||||
# SCSI Transports
|
||||
#
|
||||
# CONFIG_SCSI_SPI_ATTRS is not set
|
||||
# CONFIG_SCSI_FC_ATTRS is not set
|
||||
# CONFIG_SCSI_ISCSI_ATTRS is not set
|
||||
# CONFIG_SCSI_SAS_ATTRS is not set
|
||||
# CONFIG_SCSI_SAS_LIBSAS is not set
|
||||
|
||||
#
|
||||
# SCSI low-level drivers
|
||||
#
|
||||
# CONFIG_ISCSI_TCP is not set
|
||||
# CONFIG_SCSI_DEBUG is not set
|
||||
|
||||
#
|
||||
# Serial ATA (prod) and Parallel ATA (experimental) drivers
|
||||
#
|
||||
# CONFIG_ATA is not set
|
||||
|
||||
#
|
||||
# Multi-device support (RAID and LVM)
|
||||
#
|
||||
# CONFIG_MD is not set
|
||||
|
||||
#
|
||||
# Fusion MPT device support
|
||||
#
|
||||
# CONFIG_FUSION is not set
|
||||
|
||||
#
|
||||
# IEEE 1394 (FireWire) support
|
||||
#
|
||||
|
||||
#
|
||||
# I2O device support
|
||||
#
|
||||
|
||||
#
|
||||
# Macintosh device drivers
|
||||
#
|
||||
# CONFIG_WINDFARM is not set
|
||||
|
||||
#
|
||||
# Network device support
|
||||
#
|
||||
CONFIG_NETDEVICES=y
|
||||
# CONFIG_DUMMY is not set
|
||||
# CONFIG_BONDING is not set
|
||||
# CONFIG_EQUALIZER is not set
|
||||
# CONFIG_TUN is not set
|
||||
|
||||
#
|
||||
# PHY device support
|
||||
#
|
||||
|
||||
#
|
||||
# Ethernet (10 or 100Mbit)
|
||||
#
|
||||
# CONFIG_NET_ETHERNET is not set
|
||||
|
||||
#
|
||||
# Ethernet (1000 Mbit)
|
||||
#
|
||||
|
||||
#
|
||||
# Ethernet (10000 Mbit)
|
||||
#
|
||||
|
||||
#
|
||||
# Token Ring devices
|
||||
#
|
||||
|
||||
#
|
||||
# Wireless LAN (non-hamradio)
|
||||
#
|
||||
# CONFIG_NET_RADIO is not set
|
||||
|
||||
#
|
||||
# Wan interfaces
|
||||
#
|
||||
# CONFIG_WAN is not set
|
||||
# CONFIG_PPP is not set
|
||||
# CONFIG_SLIP is not set
|
||||
# CONFIG_SHAPER is not set
|
||||
# CONFIG_NETCONSOLE is not set
|
||||
# CONFIG_NETPOLL is not set
|
||||
# CONFIG_NET_POLL_CONTROLLER is not set
|
||||
|
||||
#
|
||||
# ISDN subsystem
|
||||
#
|
||||
# CONFIG_ISDN is not set
|
||||
|
||||
#
|
||||
# Telephony Support
|
||||
#
|
||||
# CONFIG_PHONE is not set
|
||||
|
||||
#
|
||||
# Input device support
|
||||
#
|
||||
CONFIG_INPUT=y
|
||||
# CONFIG_INPUT_FF_MEMLESS is not set
|
||||
|
||||
#
|
||||
# Userland interfaces
|
||||
#
|
||||
# CONFIG_INPUT_MOUSEDEV is not set
|
||||
# CONFIG_INPUT_JOYDEV is not set
|
||||
# CONFIG_INPUT_TSDEV is not set
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
# CONFIG_INPUT_EVBUG is not set
|
||||
|
||||
#
|
||||
# Input Device Drivers
|
||||
#
|
||||
# CONFIG_INPUT_KEYBOARD is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
# CONFIG_INPUT_JOYSTICK is not set
|
||||
# CONFIG_INPUT_TOUCHSCREEN is not set
|
||||
# CONFIG_INPUT_MISC is not set
|
||||
|
||||
#
|
||||
# Hardware I/O ports
|
||||
#
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_GAMEPORT is not set
|
||||
|
||||
#
|
||||
# Character devices
|
||||
#
|
||||
CONFIG_VT=y
|
||||
CONFIG_VT_CONSOLE=y
|
||||
CONFIG_HW_CONSOLE=y
|
||||
# CONFIG_VT_HW_CONSOLE_BINDING is not set
|
||||
# CONFIG_SERIAL_NONSTANDARD is not set
|
||||
|
||||
#
|
||||
# Serial drivers
|
||||
#
|
||||
# CONFIG_SERIAL_8250 is not set
|
||||
|
||||
#
|
||||
# Non-8250 serial port support
|
||||
#
|
||||
CONFIG_UNIX98_PTYS=y
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
|
||||
#
|
||||
# IPMI
|
||||
#
|
||||
# CONFIG_IPMI_HANDLER is not set
|
||||
|
||||
#
|
||||
# Watchdog Cards
|
||||
#
|
||||
# CONFIG_WATCHDOG is not set
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
CONFIG_GEN_RTC=y
|
||||
# CONFIG_GEN_RTC_X is not set
|
||||
# CONFIG_DTLK is not set
|
||||
# CONFIG_R3964 is not set
|
||||
|
||||
#
|
||||
# Ftape, the floppy tape device driver
|
||||
#
|
||||
# CONFIG_RAW_DRIVER is not set
|
||||
# CONFIG_HANGCHECK_TIMER is not set
|
||||
|
||||
#
|
||||
# TPM devices
|
||||
#
|
||||
# CONFIG_TCG_TPM is not set
|
||||
|
||||
#
|
||||
# I2C support
|
||||
#
|
||||
# CONFIG_I2C is not set
|
||||
|
||||
#
|
||||
# SPI support
|
||||
#
|
||||
# CONFIG_SPI is not set
|
||||
# CONFIG_SPI_MASTER is not set
|
||||
|
||||
#
|
||||
# Dallas's 1-wire bus
|
||||
#
|
||||
# CONFIG_W1 is not set
|
||||
|
||||
#
|
||||
# Hardware Monitoring support
|
||||
#
|
||||
# CONFIG_HWMON is not set
|
||||
# CONFIG_HWMON_VID is not set
|
||||
|
||||
#
|
||||
# Multimedia devices
|
||||
#
|
||||
# CONFIG_VIDEO_DEV is not set
|
||||
|
||||
#
|
||||
# Digital Video Broadcasting Devices
|
||||
#
|
||||
# CONFIG_DVB is not set
|
||||
|
||||
#
|
||||
# Graphics support
|
||||
#
|
||||
# CONFIG_FIRMWARE_EDID is not set
|
||||
# CONFIG_FB is not set
|
||||
|
||||
#
|
||||
# Console display driver support
|
||||
#
|
||||
# CONFIG_VGA_CONSOLE is not set
|
||||
CONFIG_DUMMY_CONSOLE=y
|
||||
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
|
||||
|
||||
#
|
||||
# Sound
|
||||
#
|
||||
# CONFIG_SOUND is not set
|
||||
|
||||
#
|
||||
# USB support
|
||||
#
|
||||
# CONFIG_USB_ARCH_HAS_HCD is not set
|
||||
# CONFIG_USB_ARCH_HAS_OHCI is not set
|
||||
# CONFIG_USB_ARCH_HAS_EHCI is not set
|
||||
|
||||
#
|
||||
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
|
||||
#
|
||||
|
||||
#
|
||||
# USB Gadget Support
|
||||
#
|
||||
# CONFIG_USB_GADGET is not set
|
||||
|
||||
#
|
||||
# MMC/SD Card support
|
||||
#
|
||||
# CONFIG_MMC is not set
|
||||
|
||||
#
|
||||
# LED devices
|
||||
#
|
||||
# CONFIG_NEW_LEDS is not set
|
||||
|
||||
#
|
||||
# LED drivers
|
||||
#
|
||||
|
||||
#
|
||||
# LED Triggers
|
||||
#
|
||||
|
||||
#
|
||||
# InfiniBand support
|
||||
#
|
||||
|
||||
#
|
||||
# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
|
||||
#
|
||||
|
||||
#
|
||||
# Real Time Clock
|
||||
#
|
||||
# CONFIG_RTC_CLASS is not set
|
||||
|
||||
#
|
||||
# DMA Engine support
|
||||
#
|
||||
# CONFIG_DMA_ENGINE is not set
|
||||
|
||||
#
|
||||
# DMA Clients
|
||||
#
|
||||
|
||||
#
|
||||
# DMA Devices
|
||||
#
|
||||
|
||||
#
|
||||
# File systems
|
||||
#
|
||||
# CONFIG_EXT2_FS is not set
|
||||
# CONFIG_EXT3_FS is not set
|
||||
# CONFIG_EXT4DEV_FS is not set
|
||||
# CONFIG_REISERFS_FS is not set
|
||||
# CONFIG_JFS_FS is not set
|
||||
# CONFIG_FS_POSIX_ACL is not set
|
||||
# CONFIG_XFS_FS is not set
|
||||
# CONFIG_GFS2_FS is not set
|
||||
# CONFIG_OCFS2_FS is not set
|
||||
# CONFIG_MINIX_FS is not set
|
||||
# CONFIG_ROMFS_FS is not set
|
||||
CONFIG_INOTIFY=y
|
||||
CONFIG_INOTIFY_USER=y
|
||||
# CONFIG_QUOTA is not set
|
||||
CONFIG_DNOTIFY=y
|
||||
# CONFIG_AUTOFS_FS is not set
|
||||
# CONFIG_AUTOFS4_FS is not set
|
||||
# CONFIG_FUSE_FS is not set
|
||||
|
||||
#
|
||||
# CD-ROM/DVD Filesystems
|
||||
#
|
||||
# CONFIG_ISO9660_FS is not set
|
||||
# CONFIG_UDF_FS is not set
|
||||
|
||||
#
|
||||
# DOS/FAT/NT Filesystems
|
||||
#
|
||||
# CONFIG_MSDOS_FS is not set
|
||||
# CONFIG_VFAT_FS is not set
|
||||
# CONFIG_NTFS_FS is not set
|
||||
|
||||
#
|
||||
# Pseudo filesystems
|
||||
#
|
||||
CONFIG_PROC_FS=y
|
||||
CONFIG_PROC_KCORE=y
|
||||
CONFIG_PROC_SYSCTL=y
|
||||
CONFIG_SYSFS=y
|
||||
CONFIG_TMPFS=y
|
||||
# CONFIG_TMPFS_POSIX_ACL is not set
|
||||
# CONFIG_HUGETLBFS is not set
|
||||
# CONFIG_HUGETLB_PAGE is not set
|
||||
CONFIG_RAMFS=y
|
||||
# CONFIG_CONFIGFS_FS is not set
|
||||
|
||||
#
|
||||
# Miscellaneous filesystems
|
||||
#
|
||||
# CONFIG_ADFS_FS is not set
|
||||
# CONFIG_AFFS_FS is not set
|
||||
# CONFIG_HFS_FS is not set
|
||||
# CONFIG_HFSPLUS_FS is not set
|
||||
# CONFIG_BEFS_FS is not set
|
||||
# CONFIG_BFS_FS is not set
|
||||
# CONFIG_EFS_FS is not set
|
||||
# CONFIG_CRAMFS is not set
|
||||
# CONFIG_VXFS_FS is not set
|
||||
# CONFIG_HPFS_FS is not set
|
||||
# CONFIG_QNX4FS_FS is not set
|
||||
# CONFIG_SYSV_FS is not set
|
||||
# CONFIG_UFS_FS is not set
|
||||
|
||||
#
|
||||
# Network File Systems
|
||||
#
|
||||
CONFIG_NFS_FS=y
|
||||
CONFIG_NFS_V3=y
|
||||
# CONFIG_NFS_V3_ACL is not set
|
||||
# CONFIG_NFS_V4 is not set
|
||||
# CONFIG_NFS_DIRECTIO is not set
|
||||
# CONFIG_NFSD is not set
|
||||
CONFIG_ROOT_NFS=y
|
||||
CONFIG_LOCKD=y
|
||||
CONFIG_LOCKD_V4=y
|
||||
CONFIG_NFS_COMMON=y
|
||||
CONFIG_SUNRPC=y
|
||||
# CONFIG_RPCSEC_GSS_KRB5 is not set
|
||||
# CONFIG_RPCSEC_GSS_SPKM3 is not set
|
||||
# CONFIG_SMB_FS is not set
|
||||
# CONFIG_CIFS is not set
|
||||
# CONFIG_NCP_FS is not set
|
||||
# CONFIG_CODA_FS is not set
|
||||
# CONFIG_AFS_FS is not set
|
||||
# CONFIG_9P_FS is not set
|
||||
|
||||
#
|
||||
# Partition Types
|
||||
#
|
||||
# CONFIG_PARTITION_ADVANCED is not set
|
||||
CONFIG_MSDOS_PARTITION=y
|
||||
|
||||
#
|
||||
# Native Language Support
|
||||
#
|
||||
# CONFIG_NLS is not set
|
||||
|
||||
#
|
||||
# Library routines
|
||||
#
|
||||
# CONFIG_CRC_CCITT is not set
|
||||
# CONFIG_CRC16 is not set
|
||||
# CONFIG_CRC32 is not set
|
||||
# CONFIG_LIBCRC32C is not set
|
||||
CONFIG_PLIST=y
|
||||
|
||||
#
|
||||
# Instrumentation Support
|
||||
#
|
||||
# CONFIG_PROFILING is not set
|
||||
# CONFIG_KPROBES is not set
|
||||
|
||||
#
|
||||
# Kernel hacking
|
||||
#
|
||||
# CONFIG_PRINTK_TIME is not set
|
||||
CONFIG_ENABLE_MUST_CHECK=y
|
||||
# CONFIG_MAGIC_SYSRQ is not set
|
||||
# CONFIG_UNUSED_SYMBOLS is not set
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_LOG_BUF_SHIFT=17
|
||||
CONFIG_DETECT_SOFTLOCKUP=y
|
||||
# CONFIG_SCHEDSTATS is not set
|
||||
# CONFIG_DEBUG_SLAB is not set
|
||||
# CONFIG_DEBUG_RT_MUTEXES is not set
|
||||
# CONFIG_RT_MUTEX_TESTER is not set
|
||||
CONFIG_DEBUG_SPINLOCK=y
|
||||
# CONFIG_DEBUG_MUTEXES is not set
|
||||
# CONFIG_DEBUG_RWSEMS is not set
|
||||
CONFIG_DEBUG_SPINLOCK_SLEEP=y
|
||||
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
|
||||
# CONFIG_DEBUG_KOBJECT is not set
|
||||
CONFIG_DEBUG_INFO=y
|
||||
# CONFIG_DEBUG_FS is not set
|
||||
# CONFIG_DEBUG_VM is not set
|
||||
CONFIG_DEBUG_LIST=y
|
||||
CONFIG_FORCED_INLINING=y
|
||||
# CONFIG_HEADERS_CHECK is not set
|
||||
# CONFIG_RCU_TORTURE_TEST is not set
|
||||
# CONFIG_DEBUG_STACKOVERFLOW is not set
|
||||
# CONFIG_DEBUG_STACK_USAGE is not set
|
||||
# CONFIG_DEBUGGER is not set
|
||||
CONFIG_IRQSTACKS=y
|
||||
# CONFIG_BOOTX_TEXT is not set
|
||||
CONFIG_PPC_EARLY_DEBUG=y
|
||||
# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
|
||||
# CONFIG_PPC_EARLY_DEBUG_G5 is not set
|
||||
# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set
|
||||
# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
|
||||
# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
|
||||
# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
|
||||
|
||||
#
|
||||
# Security options
|
||||
#
|
||||
# CONFIG_KEYS is not set
|
||||
# CONFIG_SECURITY is not set
|
||||
|
||||
#
|
||||
# Cryptographic options
|
||||
#
|
||||
# CONFIG_CRYPTO is not set
|
@ -17,11 +17,11 @@ obj-y += vdso32/
|
||||
obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
|
||||
signal_64.o ptrace32.o \
|
||||
paca.o cpu_setup_ppc970.o \
|
||||
firmware.o sysfs.o
|
||||
firmware.o sysfs.o nvram_64.o
|
||||
obj-$(CONFIG_PPC64) += vdso64/
|
||||
obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
|
||||
obj-$(CONFIG_PPC_970_NAP) += idle_power4.o
|
||||
obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o
|
||||
obj-$(CONFIG_PPC_OF) += of_device.o of_platform.o prom_parse.o
|
||||
procfs-$(CONFIG_PPC64) := proc_ppc64.o
|
||||
obj-$(CONFIG_PROC_FS) += $(procfs-y)
|
||||
rtaspci-$(CONFIG_PPC64) := rtas_pci.o
|
||||
@ -32,7 +32,6 @@ obj-$(CONFIG_LPARCFG) += lparcfg.o
|
||||
obj-$(CONFIG_IBMVIO) += vio.o
|
||||
obj-$(CONFIG_IBMEBUS) += ibmebus.o
|
||||
obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
|
||||
obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o
|
||||
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
|
||||
obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o
|
||||
obj-$(CONFIG_TAU) += tau_6xx.o
|
||||
@ -59,11 +58,11 @@ obj-$(CONFIG_BOOTX_TEXT) += btext.o
|
||||
obj-$(CONFIG_SMP) += smp.o
|
||||
obj-$(CONFIG_KPROBES) += kprobes.o
|
||||
obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o
|
||||
|
||||
module-$(CONFIG_PPC64) += module_64.o
|
||||
obj-$(CONFIG_MODULES) += $(module-y)
|
||||
|
||||
pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \
|
||||
pci_direct_iommu.o iomap.o
|
||||
pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o
|
||||
pci32-$(CONFIG_PPC32) := pci_32.o
|
||||
obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y)
|
||||
kexec-$(CONFIG_PPC64) := machine_kexec_64.o
|
||||
@ -72,8 +71,12 @@ obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o $(kexec-y)
|
||||
obj-$(CONFIG_AUDIT) += audit.o
|
||||
obj64-$(CONFIG_AUDIT) += compat_audit.o
|
||||
|
||||
ifneq ($(CONFIG_PPC_INDIRECT_IO),y)
|
||||
obj-y += iomap.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PPC_ISERIES),y)
|
||||
$(obj)/head_64.o: $(obj)/lparmap.s
|
||||
extra-y += lparmap.s
|
||||
AFLAGS_head_64.o += -I$(obj)
|
||||
endif
|
||||
|
||||
|
@ -118,7 +118,8 @@ int main(void)
|
||||
DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr));
|
||||
DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1));
|
||||
DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc));
|
||||
DEFINE(PACAPROCENABLED, offsetof(struct paca_struct, proc_enabled));
|
||||
DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
|
||||
DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled));
|
||||
DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache));
|
||||
DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
|
||||
DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
|
||||
|
@ -83,6 +83,22 @@ _GLOBAL(__setup_cpu_ppc970)
|
||||
rldimi r0,r11,52,8 /* set NAP and DPM */
|
||||
li r11,0
|
||||
rldimi r0,r11,32,31 /* clear EN_ATTN */
|
||||
b load_hids /* Jump to shared code */
|
||||
|
||||
|
||||
_GLOBAL(__setup_cpu_ppc970MP)
|
||||
/* Do nothing if not running in HV mode */
|
||||
mfmsr r0
|
||||
rldicl. r0,r0,4,63
|
||||
beqlr
|
||||
|
||||
mfspr r0,SPRN_HID0
|
||||
li r11,0x15 /* clear DOZE and SLEEP */
|
||||
rldimi r0,r11,52,6 /* set DEEPNAP, NAP and DPM */
|
||||
li r11,0
|
||||
rldimi r0,r11,32,31 /* clear EN_ATTN */
|
||||
|
||||
load_hids:
|
||||
mtspr SPRN_HID0,r0
|
||||
mfspr r0,SPRN_HID0
|
||||
mfspr r0,SPRN_HID0
|
||||
|
@ -42,6 +42,7 @@ extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec);
|
||||
#endif /* CONFIG_PPC32 */
|
||||
#ifdef CONFIG_PPC64
|
||||
extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
|
||||
extern void __setup_cpu_ppc970MP(unsigned long offset, struct cpu_spec* spec);
|
||||
extern void __restore_cpu_ppc970(void);
|
||||
#endif /* CONFIG_PPC64 */
|
||||
|
||||
@ -222,9 +223,9 @@ static struct cpu_spec cpu_specs[] = {
|
||||
.icache_bsize = 128,
|
||||
.dcache_bsize = 128,
|
||||
.num_pmcs = 8,
|
||||
.cpu_setup = __setup_cpu_ppc970,
|
||||
.cpu_setup = __setup_cpu_ppc970MP,
|
||||
.cpu_restore = __restore_cpu_ppc970,
|
||||
.oprofile_cpu_type = "ppc64/970",
|
||||
.oprofile_cpu_type = "ppc64/970MP",
|
||||
.oprofile_type = PPC_OPROFILE_POWER4,
|
||||
.platform = "ppc970",
|
||||
},
|
||||
@ -276,10 +277,45 @@ static struct cpu_spec cpu_specs[] = {
|
||||
.oprofile_mmcra_sipr = MMCRA_SIPR,
|
||||
.platform = "power5+",
|
||||
},
|
||||
{ /* POWER6 in P5+ mode; 2.04-compliant processor */
|
||||
.pvr_mask = 0xffffffff,
|
||||
.pvr_value = 0x0f000001,
|
||||
.cpu_name = "POWER5+",
|
||||
.cpu_features = CPU_FTRS_POWER5,
|
||||
.cpu_user_features = COMMON_USER_POWER5_PLUS,
|
||||
.icache_bsize = 128,
|
||||
.dcache_bsize = 128,
|
||||
.num_pmcs = 6,
|
||||
.oprofile_cpu_type = "ppc64/power6",
|
||||
.oprofile_type = PPC_OPROFILE_POWER4,
|
||||
.oprofile_mmcra_sihv = POWER6_MMCRA_SIHV,
|
||||
.oprofile_mmcra_sipr = POWER6_MMCRA_SIPR,
|
||||
.oprofile_mmcra_clear = POWER6_MMCRA_THRM |
|
||||
POWER6_MMCRA_OTHER,
|
||||
.platform = "power5+",
|
||||
},
|
||||
{ /* Power6 */
|
||||
.pvr_mask = 0xffff0000,
|
||||
.pvr_value = 0x003e0000,
|
||||
.cpu_name = "POWER6",
|
||||
.cpu_name = "POWER6 (raw)",
|
||||
.cpu_features = CPU_FTRS_POWER6,
|
||||
.cpu_user_features = COMMON_USER_POWER6 |
|
||||
PPC_FEATURE_POWER6_EXT,
|
||||
.icache_bsize = 128,
|
||||
.dcache_bsize = 128,
|
||||
.num_pmcs = 6,
|
||||
.oprofile_cpu_type = "ppc64/power6",
|
||||
.oprofile_type = PPC_OPROFILE_POWER4,
|
||||
.oprofile_mmcra_sihv = POWER6_MMCRA_SIHV,
|
||||
.oprofile_mmcra_sipr = POWER6_MMCRA_SIPR,
|
||||
.oprofile_mmcra_clear = POWER6_MMCRA_THRM |
|
||||
POWER6_MMCRA_OTHER,
|
||||
.platform = "power6x",
|
||||
},
|
||||
{ /* 2.05-compliant processor, i.e. Power6 "architected" mode */
|
||||
.pvr_mask = 0xffffffff,
|
||||
.pvr_value = 0x0f000002,
|
||||
.cpu_name = "POWER6 (architected)",
|
||||
.cpu_features = CPU_FTRS_POWER6,
|
||||
.cpu_user_features = COMMON_USER_POWER6,
|
||||
.icache_bsize = 128,
|
||||
@ -303,6 +339,9 @@ static struct cpu_spec cpu_specs[] = {
|
||||
PPC_FEATURE_SMT,
|
||||
.icache_bsize = 128,
|
||||
.dcache_bsize = 128,
|
||||
.num_pmcs = 4,
|
||||
.oprofile_cpu_type = "ppc64/cell-be",
|
||||
.oprofile_type = PPC_OPROFILE_CELL,
|
||||
.platform = "ppc-cell-be",
|
||||
},
|
||||
{ /* PA Semi PA6T */
|
||||
@ -801,6 +840,17 @@ static struct cpu_spec cpu_specs[] = {
|
||||
.cpu_setup = __setup_cpu_603,
|
||||
.platform = "ppc603",
|
||||
},
|
||||
{ /* e300c3 on 83xx */
|
||||
.pvr_mask = 0x7fff0000,
|
||||
.pvr_value = 0x00850000,
|
||||
.cpu_name = "e300c3",
|
||||
.cpu_features = CPU_FTRS_E300,
|
||||
.cpu_user_features = COMMON_USER,
|
||||
.icache_bsize = 32,
|
||||
.dcache_bsize = 32,
|
||||
.cpu_setup = __setup_cpu_603,
|
||||
.platform = "ppc603",
|
||||
},
|
||||
{ /* default match, we assume split I/D cache & TB (non-601)... */
|
||||
.pvr_mask = 0x00000000,
|
||||
.pvr_value = 0x00000000,
|
||||
@ -1169,19 +1219,15 @@ static struct cpu_spec cpu_specs[] = {
|
||||
#endif /* CONFIG_PPC32 */
|
||||
};
|
||||
|
||||
struct cpu_spec *identify_cpu(unsigned long offset)
|
||||
struct cpu_spec *identify_cpu(unsigned long offset, unsigned int pvr)
|
||||
{
|
||||
struct cpu_spec *s = cpu_specs;
|
||||
struct cpu_spec **cur = &cur_cpu_spec;
|
||||
unsigned int pvr = mfspr(SPRN_PVR);
|
||||
int i;
|
||||
|
||||
s = PTRRELOC(s);
|
||||
cur = PTRRELOC(cur);
|
||||
|
||||
if (*cur != NULL)
|
||||
return PTRRELOC(*cur);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++)
|
||||
if ((pvr & s->pvr_mask) == s->pvr_value) {
|
||||
*cur = cpu_specs + i;
|
||||
|
@ -111,7 +111,7 @@ void crash_ipi_callback(struct pt_regs *regs)
|
||||
if (!cpu_online(cpu))
|
||||
return;
|
||||
|
||||
local_irq_disable();
|
||||
hard_irq_disable();
|
||||
if (!cpu_isset(cpu, cpus_in_crash))
|
||||
crash_save_this_cpu(regs, cpu);
|
||||
cpu_set(cpu, cpus_in_crash);
|
||||
@ -289,7 +289,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
|
||||
* an SMP system.
|
||||
* The kernel is broken so disable interrupts.
|
||||
*/
|
||||
local_irq_disable();
|
||||
hard_irq_disable();
|
||||
|
||||
for_each_irq(irq) {
|
||||
struct irq_desc *desc = irq_desc + irq;
|
||||
|
@ -1,151 +1,194 @@
|
||||
/*
|
||||
* Copyright (C) 2004 IBM Corporation
|
||||
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corporation
|
||||
*
|
||||
* Implements the generic device dma API for ppc64. Handles
|
||||
* the pci and vio busses
|
||||
* Provide default implementations of the DMA mapping callbacks for
|
||||
* directly mapped busses and busses using the iommu infrastructure
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
/* Include the busses we support */
|
||||
#include <linux/pci.h>
|
||||
#include <asm/vio.h>
|
||||
#include <asm/ibmebus.h>
|
||||
#include <asm/scatterlist.h>
|
||||
#include <asm/bug.h>
|
||||
#include <asm/iommu.h>
|
||||
#include <asm/abs_addr.h>
|
||||
|
||||
static struct dma_mapping_ops *get_dma_ops(struct device *dev)
|
||||
/*
|
||||
* Generic iommu implementation
|
||||
*/
|
||||
|
||||
static inline unsigned long device_to_mask(struct device *dev)
|
||||
{
|
||||
#ifdef CONFIG_PCI
|
||||
if (dev->bus == &pci_bus_type)
|
||||
return &pci_dma_ops;
|
||||
#endif
|
||||
#ifdef CONFIG_IBMVIO
|
||||
if (dev->bus == &vio_bus_type)
|
||||
return &vio_dma_ops;
|
||||
#endif
|
||||
#ifdef CONFIG_IBMEBUS
|
||||
if (dev->bus == &ibmebus_bus_type)
|
||||
return &ibmebus_dma_ops;
|
||||
#endif
|
||||
return NULL;
|
||||
if (dev->dma_mask && *dev->dma_mask)
|
||||
return *dev->dma_mask;
|
||||
/* Assume devices without mask can take 32 bit addresses */
|
||||
return 0xfffffffful;
|
||||
}
|
||||
|
||||
int dma_supported(struct device *dev, u64 mask)
|
||||
|
||||
/* Allocates a contiguous real buffer and creates mappings over it.
|
||||
* Returns the virtual address of the buffer and sets dma_handle
|
||||
* to the dma address (mapping) of the first page.
|
||||
*/
|
||||
static void *dma_iommu_alloc_coherent(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t flag)
|
||||
{
|
||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||
|
||||
BUG_ON(!dma_ops);
|
||||
|
||||
return dma_ops->dma_supported(dev, mask);
|
||||
return iommu_alloc_coherent(dev->archdata.dma_data, size, dma_handle,
|
||||
device_to_mask(dev), flag,
|
||||
dev->archdata.numa_node);
|
||||
}
|
||||
EXPORT_SYMBOL(dma_supported);
|
||||
|
||||
int dma_set_mask(struct device *dev, u64 dma_mask)
|
||||
static void dma_iommu_free_coherent(struct device *dev, size_t size,
|
||||
void *vaddr, dma_addr_t dma_handle)
|
||||
{
|
||||
#ifdef CONFIG_PCI
|
||||
if (dev->bus == &pci_bus_type)
|
||||
return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
|
||||
#endif
|
||||
#ifdef CONFIG_IBMVIO
|
||||
if (dev->bus == &vio_bus_type)
|
||||
return -EIO;
|
||||
#endif /* CONFIG_IBMVIO */
|
||||
#ifdef CONFIG_IBMEBUS
|
||||
if (dev->bus == &ibmebus_bus_type)
|
||||
return -EIO;
|
||||
#endif
|
||||
BUG();
|
||||
return 0;
|
||||
iommu_free_coherent(dev->archdata.dma_data, size, vaddr, dma_handle);
|
||||
}
|
||||
EXPORT_SYMBOL(dma_set_mask);
|
||||
|
||||
void *dma_alloc_coherent(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t flag)
|
||||
/* Creates TCEs for a user provided buffer. The user buffer must be
|
||||
* contiguous real kernel storage (not vmalloc). The address of the buffer
|
||||
* passed here is the kernel (virtual) address of the buffer. The buffer
|
||||
* need not be page aligned, the dma_addr_t returned will point to the same
|
||||
* byte within the page as vaddr.
|
||||
*/
|
||||
static dma_addr_t dma_iommu_map_single(struct device *dev, void *vaddr,
|
||||
size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||
|
||||
BUG_ON(!dma_ops);
|
||||
|
||||
return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
|
||||
return iommu_map_single(dev->archdata.dma_data, vaddr, size,
|
||||
device_to_mask(dev), direction);
|
||||
}
|
||||
EXPORT_SYMBOL(dma_alloc_coherent);
|
||||
|
||||
void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
|
||||
dma_addr_t dma_handle)
|
||||
|
||||
static void dma_iommu_unmap_single(struct device *dev, dma_addr_t dma_handle,
|
||||
size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||
|
||||
BUG_ON(!dma_ops);
|
||||
|
||||
dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
|
||||
iommu_unmap_single(dev->archdata.dma_data, dma_handle, size, direction);
|
||||
}
|
||||
EXPORT_SYMBOL(dma_free_coherent);
|
||||
|
||||
dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
|
||||
static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
|
||||
int nelems, enum dma_data_direction direction)
|
||||
{
|
||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||
|
||||
BUG_ON(!dma_ops);
|
||||
|
||||
return dma_ops->map_single(dev, cpu_addr, size, direction);
|
||||
return iommu_map_sg(dev->archdata.dma_data, sglist, nelems,
|
||||
device_to_mask(dev), direction);
|
||||
}
|
||||
EXPORT_SYMBOL(dma_map_single);
|
||||
|
||||
void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist,
|
||||
int nelems, enum dma_data_direction direction)
|
||||
{
|
||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||
|
||||
BUG_ON(!dma_ops);
|
||||
|
||||
dma_ops->unmap_single(dev, dma_addr, size, direction);
|
||||
iommu_unmap_sg(dev->archdata.dma_data, sglist, nelems, direction);
|
||||
}
|
||||
EXPORT_SYMBOL(dma_unmap_single);
|
||||
|
||||
dma_addr_t dma_map_page(struct device *dev, struct page *page,
|
||||
unsigned long offset, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
/* We support DMA to/from any memory page via the iommu */
|
||||
static int dma_iommu_dma_supported(struct device *dev, u64 mask)
|
||||
{
|
||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||
struct iommu_table *tbl = dev->archdata.dma_data;
|
||||
|
||||
BUG_ON(!dma_ops);
|
||||
|
||||
return dma_ops->map_single(dev, page_address(page) + offset, size,
|
||||
direction);
|
||||
if (!tbl || tbl->it_offset > mask) {
|
||||
printk(KERN_INFO
|
||||
"Warning: IOMMU offset too big for device mask\n");
|
||||
if (tbl)
|
||||
printk(KERN_INFO
|
||||
"mask: 0x%08lx, table offset: 0x%08lx\n",
|
||||
mask, tbl->it_offset);
|
||||
else
|
||||
printk(KERN_INFO "mask: 0x%08lx, table unavailable\n",
|
||||
mask);
|
||||
return 0;
|
||||
} else
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL(dma_map_page);
|
||||
|
||||
void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
struct dma_mapping_ops dma_iommu_ops = {
|
||||
.alloc_coherent = dma_iommu_alloc_coherent,
|
||||
.free_coherent = dma_iommu_free_coherent,
|
||||
.map_single = dma_iommu_map_single,
|
||||
.unmap_single = dma_iommu_unmap_single,
|
||||
.map_sg = dma_iommu_map_sg,
|
||||
.unmap_sg = dma_iommu_unmap_sg,
|
||||
.dma_supported = dma_iommu_dma_supported,
|
||||
};
|
||||
EXPORT_SYMBOL(dma_iommu_ops);
|
||||
|
||||
/*
|
||||
* Generic direct DMA implementation
|
||||
*
|
||||
* This implementation supports a global offset that can be applied if
|
||||
* the address at which memory is visible to devices is not 0.
|
||||
*/
|
||||
unsigned long dma_direct_offset;
|
||||
|
||||
static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t flag)
|
||||
{
|
||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||
struct page *page;
|
||||
void *ret;
|
||||
int node = dev->archdata.numa_node;
|
||||
|
||||
BUG_ON(!dma_ops);
|
||||
/* TODO: Maybe use the numa node here too ? */
|
||||
page = alloc_pages_node(node, flag, get_order(size));
|
||||
if (page == NULL)
|
||||
return NULL;
|
||||
ret = page_address(page);
|
||||
memset(ret, 0, size);
|
||||
*dma_handle = virt_to_abs(ret) | dma_direct_offset;
|
||||
|
||||
dma_ops->unmap_single(dev, dma_address, size, direction);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(dma_unmap_page);
|
||||
|
||||
int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
|
||||
enum dma_data_direction direction)
|
||||
static void dma_direct_free_coherent(struct device *dev, size_t size,
|
||||
void *vaddr, dma_addr_t dma_handle)
|
||||
{
|
||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||
|
||||
BUG_ON(!dma_ops);
|
||||
|
||||
return dma_ops->map_sg(dev, sg, nents, direction);
|
||||
free_pages((unsigned long)vaddr, get_order(size));
|
||||
}
|
||||
EXPORT_SYMBOL(dma_map_sg);
|
||||
|
||||
void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
|
||||
enum dma_data_direction direction)
|
||||
static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr,
|
||||
size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||
|
||||
BUG_ON(!dma_ops);
|
||||
|
||||
dma_ops->unmap_sg(dev, sg, nhwentries, direction);
|
||||
return virt_to_abs(ptr) | dma_direct_offset;
|
||||
}
|
||||
EXPORT_SYMBOL(dma_unmap_sg);
|
||||
|
||||
static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr,
|
||||
size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
}
|
||||
|
||||
static int dma_direct_map_sg(struct device *dev, struct scatterlist *sg,
|
||||
int nents, enum dma_data_direction direction)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nents; i++, sg++) {
|
||||
sg->dma_address = (page_to_phys(sg->page) + sg->offset) |
|
||||
dma_direct_offset;
|
||||
sg->dma_length = sg->length;
|
||||
}
|
||||
|
||||
return nents;
|
||||
}
|
||||
|
||||
static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg,
|
||||
int nents, enum dma_data_direction direction)
|
||||
{
|
||||
}
|
||||
|
||||
static int dma_direct_dma_supported(struct device *dev, u64 mask)
|
||||
{
|
||||
/* Could be improved to check for memory though it better be
|
||||
* done via some global so platforms can set the limit in case
|
||||
* they have limited DMA windows
|
||||
*/
|
||||
return mask >= DMA_32BIT_MASK;
|
||||
}
|
||||
|
||||
struct dma_mapping_ops dma_direct_ops = {
|
||||
.alloc_coherent = dma_direct_alloc_coherent,
|
||||
.free_coherent = dma_direct_free_coherent,
|
||||
.map_single = dma_direct_map_single,
|
||||
.unmap_single = dma_direct_unmap_single,
|
||||
.map_sg = dma_direct_map_sg,
|
||||
.unmap_sg = dma_direct_unmap_sg,
|
||||
.dma_supported = dma_direct_dma_supported,
|
||||
};
|
||||
EXPORT_SYMBOL(dma_direct_ops);
|
||||
|
@ -87,15 +87,19 @@ system_call_common:
|
||||
addi r9,r1,STACK_FRAME_OVERHEAD
|
||||
ld r11,exception_marker@toc(r2)
|
||||
std r11,-16(r9) /* "regshere" marker */
|
||||
li r10,1
|
||||
stb r10,PACASOFTIRQEN(r13)
|
||||
stb r10,PACAHARDIRQEN(r13)
|
||||
std r10,SOFTE(r1)
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
BEGIN_FW_FTR_SECTION
|
||||
/* Hack for handling interrupts when soft-enabling on iSeries */
|
||||
cmpdi cr1,r0,0x5555 /* syscall 0x5555 */
|
||||
andi. r10,r12,MSR_PR /* from kernel */
|
||||
crand 4*cr0+eq,4*cr1+eq,4*cr0+eq
|
||||
beq hardware_interrupt_entry
|
||||
lbz r10,PACAPROCENABLED(r13)
|
||||
std r10,SOFTE(r1)
|
||||
bne 2f
|
||||
b hardware_interrupt_entry
|
||||
2:
|
||||
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
|
||||
#endif
|
||||
mfmsr r11
|
||||
@ -460,9 +464,9 @@ _GLOBAL(ret_from_except_lite)
|
||||
#endif
|
||||
|
||||
restore:
|
||||
ld r5,SOFTE(r1)
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
BEGIN_FW_FTR_SECTION
|
||||
ld r5,SOFTE(r1)
|
||||
cmpdi 0,r5,0
|
||||
beq 4f
|
||||
/* Check for pending interrupts (iSeries) */
|
||||
@ -472,21 +476,25 @@ BEGIN_FW_FTR_SECTION
|
||||
beq+ 4f /* skip do_IRQ if no interrupts */
|
||||
|
||||
li r3,0
|
||||
stb r3,PACAPROCENABLED(r13) /* ensure we are soft-disabled */
|
||||
stb r3,PACASOFTIRQEN(r13) /* ensure we are soft-disabled */
|
||||
ori r10,r10,MSR_EE
|
||||
mtmsrd r10 /* hard-enable again */
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl .do_IRQ
|
||||
b .ret_from_except_lite /* loop back and handle more */
|
||||
|
||||
4: stb r5,PACAPROCENABLED(r13)
|
||||
4:
|
||||
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
|
||||
#endif
|
||||
stb r5,PACASOFTIRQEN(r13)
|
||||
|
||||
ld r3,_MSR(r1)
|
||||
andi. r0,r3,MSR_RI
|
||||
beq- unrecov_restore
|
||||
|
||||
/* extract EE bit and use it to restore paca->hard_enabled */
|
||||
rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */
|
||||
stb r4,PACAHARDIRQEN(r13)
|
||||
|
||||
andi. r0,r3,MSR_PR
|
||||
|
||||
/*
|
||||
@ -538,25 +546,15 @@ do_work:
|
||||
/* Check that preempt_count() == 0 and interrupts are enabled */
|
||||
lwz r8,TI_PREEMPT(r9)
|
||||
cmpwi cr1,r8,0
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
BEGIN_FW_FTR_SECTION
|
||||
ld r0,SOFTE(r1)
|
||||
cmpdi r0,0
|
||||
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
|
||||
#endif
|
||||
BEGIN_FW_FTR_SECTION
|
||||
andi. r0,r3,MSR_EE
|
||||
END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
|
||||
crandc eq,cr1*4+eq,eq
|
||||
bne restore
|
||||
/* here we are preempting the current task */
|
||||
1:
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
BEGIN_FW_FTR_SECTION
|
||||
li r0,1
|
||||
stb r0,PACAPROCENABLED(r13)
|
||||
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
|
||||
#endif
|
||||
stb r0,PACASOFTIRQEN(r13)
|
||||
stb r0,PACAHARDIRQEN(r13)
|
||||
ori r10,r10,MSR_EE
|
||||
mtmsrd r10,1 /* reenable interrupts */
|
||||
bl .preempt_schedule
|
||||
@ -639,8 +637,7 @@ _GLOBAL(enter_rtas)
|
||||
/* There is no way it is acceptable to get here with interrupts enabled,
|
||||
* check it with the asm equivalent of WARN_ON
|
||||
*/
|
||||
mfmsr r6
|
||||
andi. r0,r6,MSR_EE
|
||||
lbz r0,PACASOFTIRQEN(r13)
|
||||
1: tdnei r0,0
|
||||
.section __bug_table,"a"
|
||||
.llong 1b,__LINE__ + 0x1000000, 1f, 2f
|
||||
@ -649,7 +646,13 @@ _GLOBAL(enter_rtas)
|
||||
1: .asciz __FILE__
|
||||
2: .asciz "enter_rtas"
|
||||
.previous
|
||||
|
||||
|
||||
/* Hard-disable interrupts */
|
||||
mfmsr r6
|
||||
rldicl r7,r6,48,1
|
||||
rotldi r7,r7,16
|
||||
mtmsrd r7,1
|
||||
|
||||
/* Unfortunately, the stack pointer and the MSR are also clobbered,
|
||||
* so they are saved in the PACA which allows us to restore
|
||||
* our original state after RTAS returns.
|
||||
@ -735,8 +738,6 @@ _STATIC(rtas_restore_regs)
|
||||
|
||||
#endif /* CONFIG_PPC_RTAS */
|
||||
|
||||
#ifdef CONFIG_PPC_MULTIPLATFORM
|
||||
|
||||
_GLOBAL(enter_prom)
|
||||
mflr r0
|
||||
std r0,16(r1)
|
||||
@ -821,5 +822,3 @@ _GLOBAL(enter_prom)
|
||||
ld r0,16(r1)
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
#endif /* CONFIG_PPC_MULTIPLATFORM */
|
||||
|
@ -35,9 +35,7 @@
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/firmware.h>
|
||||
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
#define DO_SOFT_DISABLE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We layout physical memory as follows:
|
||||
@ -74,13 +72,11 @@
|
||||
.text
|
||||
.globl _stext
|
||||
_stext:
|
||||
#ifdef CONFIG_PPC_MULTIPLATFORM
|
||||
_GLOBAL(__start)
|
||||
/* NOP this out unconditionally */
|
||||
BEGIN_FTR_SECTION
|
||||
b .__start_initialization_multiplatform
|
||||
END_FTR_SECTION(0, 1)
|
||||
#endif /* CONFIG_PPC_MULTIPLATFORM */
|
||||
|
||||
/* Catch branch to 0 in real mode */
|
||||
trap
|
||||
@ -308,7 +304,9 @@ exception_marker:
|
||||
std r9,_LINK(r1); \
|
||||
mfctr r10; /* save CTR in stackframe */ \
|
||||
std r10,_CTR(r1); \
|
||||
lbz r10,PACASOFTIRQEN(r13); \
|
||||
mfspr r11,SPRN_XER; /* save XER in stackframe */ \
|
||||
std r10,SOFTE(r1); \
|
||||
std r11,_XER(r1); \
|
||||
li r9,(n)+1; \
|
||||
std r9,_TRAP(r1); /* set trap number */ \
|
||||
@ -343,6 +341,34 @@ label##_pSeries: \
|
||||
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
|
||||
|
||||
|
||||
#define MASKABLE_EXCEPTION_PSERIES(n, label) \
|
||||
. = n; \
|
||||
.globl label##_pSeries; \
|
||||
label##_pSeries: \
|
||||
HMT_MEDIUM; \
|
||||
mtspr SPRN_SPRG1,r13; /* save r13 */ \
|
||||
mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
|
||||
std r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \
|
||||
std r10,PACA_EXGEN+EX_R10(r13); \
|
||||
lbz r10,PACASOFTIRQEN(r13); \
|
||||
mfcr r9; \
|
||||
cmpwi r10,0; \
|
||||
beq masked_interrupt; \
|
||||
mfspr r10,SPRN_SPRG1; \
|
||||
std r10,PACA_EXGEN+EX_R13(r13); \
|
||||
std r11,PACA_EXGEN+EX_R11(r13); \
|
||||
std r12,PACA_EXGEN+EX_R12(r13); \
|
||||
clrrdi r12,r13,32; /* get high part of &label */ \
|
||||
mfmsr r10; \
|
||||
mfspr r11,SPRN_SRR0; /* save SRR0 */ \
|
||||
LOAD_HANDLER(r12,label##_common) \
|
||||
ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
|
||||
mtspr SPRN_SRR0,r12; \
|
||||
mfspr r12,SPRN_SRR1; /* and SRR1 */ \
|
||||
mtspr SPRN_SRR1,r10; \
|
||||
rfid; \
|
||||
b . /* prevent speculative execution */
|
||||
|
||||
#define STD_EXCEPTION_ISERIES(n, label, area) \
|
||||
.globl label##_iSeries; \
|
||||
label##_iSeries: \
|
||||
@ -358,40 +384,32 @@ label##_iSeries: \
|
||||
HMT_MEDIUM; \
|
||||
mtspr SPRN_SPRG1,r13; /* save r13 */ \
|
||||
EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \
|
||||
lbz r10,PACAPROCENABLED(r13); \
|
||||
lbz r10,PACASOFTIRQEN(r13); \
|
||||
cmpwi 0,r10,0; \
|
||||
beq- label##_iSeries_masked; \
|
||||
EXCEPTION_PROLOG_ISERIES_2; \
|
||||
b label##_common; \
|
||||
|
||||
#ifdef DO_SOFT_DISABLE
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
#define DISABLE_INTS \
|
||||
BEGIN_FW_FTR_SECTION; \
|
||||
lbz r10,PACAPROCENABLED(r13); \
|
||||
li r11,0; \
|
||||
std r10,SOFTE(r1); \
|
||||
stb r11,PACASOFTIRQEN(r13); \
|
||||
BEGIN_FW_FTR_SECTION; \
|
||||
stb r11,PACAHARDIRQEN(r13); \
|
||||
END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \
|
||||
BEGIN_FW_FTR_SECTION; \
|
||||
mfmsr r10; \
|
||||
stb r11,PACAPROCENABLED(r13); \
|
||||
ori r10,r10,MSR_EE; \
|
||||
mtmsrd r10,1; \
|
||||
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
|
||||
|
||||
#define ENABLE_INTS \
|
||||
BEGIN_FW_FTR_SECTION; \
|
||||
lbz r10,PACAPROCENABLED(r13); \
|
||||
mfmsr r11; \
|
||||
std r10,SOFTE(r1); \
|
||||
ori r11,r11,MSR_EE; \
|
||||
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES); \
|
||||
BEGIN_FW_FTR_SECTION; \
|
||||
ld r12,_MSR(r1); \
|
||||
mfmsr r11; \
|
||||
rlwimi r11,r12,0,MSR_EE; \
|
||||
END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \
|
||||
mtmsrd r11,1
|
||||
#else
|
||||
#define DISABLE_INTS \
|
||||
li r11,0; \
|
||||
stb r11,PACASOFTIRQEN(r13); \
|
||||
stb r11,PACAHARDIRQEN(r13)
|
||||
|
||||
#else /* hard enable/disable interrupts */
|
||||
#define DISABLE_INTS
|
||||
#endif /* CONFIG_PPC_ISERIES */
|
||||
|
||||
#define ENABLE_INTS \
|
||||
ld r12,_MSR(r1); \
|
||||
@ -399,8 +417,6 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \
|
||||
rlwimi r11,r12,0,MSR_EE; \
|
||||
mtmsrd r11,1
|
||||
|
||||
#endif
|
||||
|
||||
#define STD_EXCEPTION_COMMON(trap, label, hdlr) \
|
||||
.align 7; \
|
||||
.globl label##_common; \
|
||||
@ -541,11 +557,11 @@ instruction_access_slb_pSeries:
|
||||
mfspr r12,SPRN_SRR1 /* and SRR1 */
|
||||
b .slb_miss_realmode /* Rel. branch works in real mode */
|
||||
|
||||
STD_EXCEPTION_PSERIES(0x500, hardware_interrupt)
|
||||
MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt)
|
||||
STD_EXCEPTION_PSERIES(0x600, alignment)
|
||||
STD_EXCEPTION_PSERIES(0x700, program_check)
|
||||
STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
|
||||
STD_EXCEPTION_PSERIES(0x900, decrementer)
|
||||
MASKABLE_EXCEPTION_PSERIES(0x900, decrementer)
|
||||
STD_EXCEPTION_PSERIES(0xa00, trap_0a)
|
||||
STD_EXCEPTION_PSERIES(0xb00, trap_0b)
|
||||
|
||||
@ -597,7 +613,24 @@ system_call_pSeries:
|
||||
/*** pSeries interrupt support ***/
|
||||
|
||||
/* moved from 0xf00 */
|
||||
STD_EXCEPTION_PSERIES(., performance_monitor)
|
||||
MASKABLE_EXCEPTION_PSERIES(., performance_monitor)
|
||||
|
||||
/*
|
||||
* An interrupt came in while soft-disabled; clear EE in SRR1,
|
||||
* clear paca->hard_enabled and return.
|
||||
*/
|
||||
masked_interrupt:
|
||||
stb r10,PACAHARDIRQEN(r13)
|
||||
mtcrf 0x80,r9
|
||||
ld r9,PACA_EXGEN+EX_R9(r13)
|
||||
mfspr r10,SPRN_SRR1
|
||||
rldicl r10,r10,48,1 /* clear MSR_EE */
|
||||
rotldi r10,r10,16
|
||||
mtspr SPRN_SRR1,r10
|
||||
ld r10,PACA_EXGEN+EX_R10(r13)
|
||||
mfspr r13,SPRN_SPRG1
|
||||
rfid
|
||||
b .
|
||||
|
||||
.align 7
|
||||
do_stab_bolted_pSeries:
|
||||
@ -792,7 +825,7 @@ system_reset_iSeries:
|
||||
|
||||
cmpwi 0,r23,0
|
||||
beq iSeries_secondary_smp_loop /* Loop until told to go */
|
||||
bne .__secondary_start /* Loop until told to go */
|
||||
bne __secondary_start /* Loop until told to go */
|
||||
iSeries_secondary_smp_loop:
|
||||
/* Let the Hypervisor know we are alive */
|
||||
/* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
|
||||
@ -813,7 +846,6 @@ iSeries_secondary_smp_loop:
|
||||
b 1b /* If SMP not configured, secondaries
|
||||
* loop forever */
|
||||
|
||||
.globl decrementer_iSeries_masked
|
||||
decrementer_iSeries_masked:
|
||||
/* We may not have a valid TOC pointer in here. */
|
||||
li r11,1
|
||||
@ -824,7 +856,6 @@ decrementer_iSeries_masked:
|
||||
mtspr SPRN_DEC,r12
|
||||
/* fall through */
|
||||
|
||||
.globl hardware_interrupt_iSeries_masked
|
||||
hardware_interrupt_iSeries_masked:
|
||||
mtcrf 0x80,r9 /* Restore regs */
|
||||
ld r12,PACALPPACAPTR(r13)
|
||||
@ -926,10 +957,18 @@ bad_stack:
|
||||
* any task or sent any task a signal, you should use
|
||||
* ret_from_except or ret_from_except_lite instead of this.
|
||||
*/
|
||||
fast_exc_return_irq: /* restores irq state too */
|
||||
ld r3,SOFTE(r1)
|
||||
ld r12,_MSR(r1)
|
||||
stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */
|
||||
rldicl r4,r12,49,63 /* get MSR_EE to LSB */
|
||||
stb r4,PACAHARDIRQEN(r13) /* restore paca->hard_enabled */
|
||||
b 1f
|
||||
|
||||
.globl fast_exception_return
|
||||
fast_exception_return:
|
||||
ld r12,_MSR(r1)
|
||||
ld r11,_NIP(r1)
|
||||
1: ld r11,_NIP(r1)
|
||||
andi. r3,r12,MSR_RI /* check if RI is set */
|
||||
beq- unrecov_fer
|
||||
|
||||
@ -952,7 +991,8 @@ fast_exception_return:
|
||||
REST_8GPRS(2, r1)
|
||||
|
||||
mfmsr r10
|
||||
clrrdi r10,r10,2 /* clear RI (LE is 0 already) */
|
||||
rldicl r10,r10,48,1 /* clear EE */
|
||||
rldicr r10,r10,16,61 /* clear RI (LE is 0 already) */
|
||||
mtmsrd r10,1
|
||||
|
||||
mtspr SPRN_SRR1,r12
|
||||
@ -1326,6 +1366,16 @@ BEGIN_FW_FTR_SECTION
|
||||
* interrupts if necessary.
|
||||
*/
|
||||
beq 13f
|
||||
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
|
||||
#endif
|
||||
BEGIN_FW_FTR_SECTION
|
||||
/*
|
||||
* Here we have interrupts hard-disabled, so it is sufficient
|
||||
* to restore paca->{soft,hard}_enable and get out.
|
||||
*/
|
||||
beq fast_exc_return_irq /* Return from exception on success */
|
||||
END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
|
||||
|
||||
/* For a hash failure, we don't bother re-enabling interrupts */
|
||||
ble- 12f
|
||||
|
||||
@ -1337,14 +1387,6 @@ BEGIN_FW_FTR_SECTION
|
||||
ld r3,SOFTE(r1)
|
||||
bl .local_irq_restore
|
||||
b 11f
|
||||
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
|
||||
#endif
|
||||
BEGIN_FW_FTR_SECTION
|
||||
beq fast_exception_return /* Return from exception on success */
|
||||
ble- 12f /* Failure return from hash_page */
|
||||
|
||||
/* fall through */
|
||||
END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
|
||||
|
||||
/* Here we have a page fault that hash_page can't handle. */
|
||||
handle_page_fault:
|
||||
@ -1362,6 +1404,8 @@ handle_page_fault:
|
||||
bl .bad_page_fault
|
||||
b .ret_from_except
|
||||
|
||||
13: b .ret_from_except_lite
|
||||
|
||||
/* We have a page fault that hash_page could handle but HV refused
|
||||
* the PTE insertion
|
||||
*/
|
||||
@ -1371,8 +1415,6 @@ handle_page_fault:
|
||||
bl .low_hash_fault
|
||||
b .ret_from_except
|
||||
|
||||
13: b .ret_from_except_lite
|
||||
|
||||
/* here we have a segment miss */
|
||||
do_ste_alloc:
|
||||
bl .ste_allocate /* try to insert stab entry */
|
||||
@ -1560,7 +1602,7 @@ _GLOBAL(generic_secondary_smp_init)
|
||||
ld r1,PACAEMERGSP(r13)
|
||||
subi r1,r1,STACK_FRAME_OVERHEAD
|
||||
|
||||
b .__secondary_start
|
||||
b __secondary_start
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
@ -1595,7 +1637,6 @@ _STATIC(__start_initialization_iSeries)
|
||||
b .start_here_common
|
||||
#endif /* CONFIG_PPC_ISERIES */
|
||||
|
||||
#ifdef CONFIG_PPC_MULTIPLATFORM
|
||||
|
||||
_STATIC(__mmu_off)
|
||||
mfmsr r3
|
||||
@ -1621,13 +1662,11 @@ _STATIC(__mmu_off)
|
||||
*
|
||||
*/
|
||||
_GLOBAL(__start_initialization_multiplatform)
|
||||
#ifdef CONFIG_PPC_MULTIPLATFORM
|
||||
/*
|
||||
* Are we booted from a PROM Of-type client-interface ?
|
||||
*/
|
||||
cmpldi cr0,r5,0
|
||||
bne .__boot_from_prom /* yes -> prom */
|
||||
#endif
|
||||
|
||||
/* Save parameters */
|
||||
mr r31,r3
|
||||
@ -1656,7 +1695,6 @@ _GLOBAL(__start_initialization_multiplatform)
|
||||
bl .__mmu_off
|
||||
b .__after_prom_start
|
||||
|
||||
#ifdef CONFIG_PPC_MULTIPLATFORM
|
||||
_STATIC(__boot_from_prom)
|
||||
/* Save parameters */
|
||||
mr r31,r3
|
||||
@ -1696,7 +1734,6 @@ _STATIC(__boot_from_prom)
|
||||
bl .prom_init
|
||||
/* We never return */
|
||||
trap
|
||||
#endif
|
||||
|
||||
/*
|
||||
* At this point, r3 contains the physical address we are running at,
|
||||
@ -1752,8 +1789,6 @@ _STATIC(__after_prom_start)
|
||||
bl .copy_and_flush /* copy the rest */
|
||||
b .start_here_multiplatform
|
||||
|
||||
#endif /* CONFIG_PPC_MULTIPLATFORM */
|
||||
|
||||
/*
|
||||
* Copy routine used to copy the kernel to start at physical address 0
|
||||
* and flush and invalidate the caches as needed.
|
||||
@ -1836,7 +1871,7 @@ _GLOBAL(pmac_secondary_start)
|
||||
ld r1,PACAEMERGSP(r13)
|
||||
subi r1,r1,STACK_FRAME_OVERHEAD
|
||||
|
||||
b .__secondary_start
|
||||
b __secondary_start
|
||||
|
||||
#endif /* CONFIG_PPC_PMAC */
|
||||
|
||||
@ -1853,7 +1888,7 @@ _GLOBAL(pmac_secondary_start)
|
||||
* r13 = paca virtual address
|
||||
* SPRG3 = paca virtual address
|
||||
*/
|
||||
_GLOBAL(__secondary_start)
|
||||
__secondary_start:
|
||||
/* Set thread priority to MEDIUM */
|
||||
HMT_MEDIUM
|
||||
|
||||
@ -1877,11 +1912,16 @@ _GLOBAL(__secondary_start)
|
||||
/* enable MMU and jump to start_secondary */
|
||||
LOAD_REG_ADDR(r3, .start_secondary_prolog)
|
||||
LOAD_REG_IMMEDIATE(r4, MSR_KERNEL)
|
||||
#ifdef DO_SOFT_DISABLE
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
BEGIN_FW_FTR_SECTION
|
||||
ori r4,r4,MSR_EE
|
||||
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
|
||||
#endif
|
||||
BEGIN_FW_FTR_SECTION
|
||||
stb r7,PACASOFTIRQEN(r13)
|
||||
stb r7,PACAHARDIRQEN(r13)
|
||||
END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
|
||||
|
||||
mtspr SPRN_SRR0,r3
|
||||
mtspr SPRN_SRR1,r4
|
||||
rfid
|
||||
@ -1913,7 +1953,6 @@ _GLOBAL(enable_64b_mode)
|
||||
isync
|
||||
blr
|
||||
|
||||
#ifdef CONFIG_PPC_MULTIPLATFORM
|
||||
/*
|
||||
* This is where the main kernel code starts.
|
||||
*/
|
||||
@ -1977,7 +2016,6 @@ _STATIC(start_here_multiplatform)
|
||||
mtspr SPRN_SRR1,r4
|
||||
rfid
|
||||
b . /* prevent speculative execution */
|
||||
#endif /* CONFIG_PPC_MULTIPLATFORM */
|
||||
|
||||
/* This is where all platforms converge execution */
|
||||
_STATIC(start_here_common)
|
||||
@ -2005,15 +2043,18 @@ _STATIC(start_here_common)
|
||||
|
||||
/* Load up the kernel context */
|
||||
5:
|
||||
#ifdef DO_SOFT_DISABLE
|
||||
BEGIN_FW_FTR_SECTION
|
||||
li r5,0
|
||||
stb r5,PACAPROCENABLED(r13) /* Soft Disabled */
|
||||
stb r5,PACASOFTIRQEN(r13) /* Soft Disabled */
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
BEGIN_FW_FTR_SECTION
|
||||
mfmsr r5
|
||||
ori r5,r5,MSR_EE /* Hard Enabled */
|
||||
mtmsrd r5
|
||||
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
|
||||
#endif
|
||||
BEGIN_FW_FTR_SECTION
|
||||
stb r5,PACAHARDIRQEN(r13)
|
||||
END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
|
||||
|
||||
bl .start_kernel
|
||||
|
||||
|
@ -112,7 +112,7 @@ static int ibmebus_dma_supported(struct device *dev, u64 mask)
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct dma_mapping_ops ibmebus_dma_ops = {
|
||||
static struct dma_mapping_ops ibmebus_dma_ops = {
|
||||
.alloc_coherent = ibmebus_alloc_coherent,
|
||||
.free_coherent = ibmebus_free_coherent,
|
||||
.map_single = ibmebus_map_single,
|
||||
@ -176,6 +176,10 @@ static struct ibmebus_dev* __devinit ibmebus_register_device_common(
|
||||
dev->ofdev.dev.bus = &ibmebus_bus_type;
|
||||
dev->ofdev.dev.release = ibmebus_dev_release;
|
||||
|
||||
dev->ofdev.dev.archdata.of_node = dev->ofdev.node;
|
||||
dev->ofdev.dev.archdata.dma_ops = &ibmebus_dma_ops;
|
||||
dev->ofdev.dev.archdata.numa_node = of_node_to_nid(dev->ofdev.node);
|
||||
|
||||
/* An ibmebusdev is based on a of_device. We have to change the
|
||||
* bus type to use our own DMA mapping operations.
|
||||
*/
|
||||
@ -210,11 +214,10 @@ static struct ibmebus_dev* __devinit ibmebus_register_device_node(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dev = kmalloc(sizeof(struct ibmebus_dev), GFP_KERNEL);
|
||||
dev = kzalloc(sizeof(struct ibmebus_dev), GFP_KERNEL);
|
||||
if (!dev) {
|
||||
return NULL;
|
||||
}
|
||||
memset(dev, 0, sizeof(struct ibmebus_dev));
|
||||
|
||||
dev->ofdev.node = of_node_get(dn);
|
||||
|
||||
|
@ -39,6 +39,13 @@
|
||||
#define cpu_should_die() 0
|
||||
#endif
|
||||
|
||||
static int __init powersave_off(char *arg)
|
||||
{
|
||||
ppc_md.power_save = NULL;
|
||||
return 0;
|
||||
}
|
||||
__setup("powersave=off", powersave_off);
|
||||
|
||||
/*
|
||||
* The body of the idle task.
|
||||
*/
|
||||
|
@ -30,6 +30,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
|
||||
beqlr
|
||||
|
||||
/* Go to NAP now */
|
||||
mfmsr r7
|
||||
rldicl r0,r7,48,1
|
||||
rotldi r0,r0,16
|
||||
mtmsrd r0,1 /* hard-disable interrupts */
|
||||
li r0,1
|
||||
stb r0,PACASOFTIRQEN(r13) /* we'll hard-enable shortly */
|
||||
stb r0,PACAHARDIRQEN(r13)
|
||||
BEGIN_FTR_SECTION
|
||||
DSSALL
|
||||
sync
|
||||
@ -38,7 +45,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
|
||||
ld r8,TI_LOCAL_FLAGS(r9) /* set napping bit */
|
||||
ori r8,r8,_TLF_NAPPING /* so when we take an exception */
|
||||
std r8,TI_LOCAL_FLAGS(r9) /* it will return to our caller */
|
||||
mfmsr r7
|
||||
ori r7,r7,MSR_EE
|
||||
oris r7,r7,MSR_POW@h
|
||||
1: sync
|
||||
|
@ -25,13 +25,11 @@
|
||||
#include <asm/firmware.h>
|
||||
#include <asm/bug.h>
|
||||
|
||||
void _insb(volatile u8 __iomem *port, void *buf, long count)
|
||||
void _insb(const volatile u8 __iomem *port, void *buf, long count)
|
||||
{
|
||||
u8 *tbuf = buf;
|
||||
u8 tmp;
|
||||
|
||||
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||
|
||||
if (unlikely(count <= 0))
|
||||
return;
|
||||
asm volatile("sync");
|
||||
@ -48,8 +46,6 @@ void _outsb(volatile u8 __iomem *port, const void *buf, long count)
|
||||
{
|
||||
const u8 *tbuf = buf;
|
||||
|
||||
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||
|
||||
if (unlikely(count <= 0))
|
||||
return;
|
||||
asm volatile("sync");
|
||||
@ -60,13 +56,11 @@ void _outsb(volatile u8 __iomem *port, const void *buf, long count)
|
||||
}
|
||||
EXPORT_SYMBOL(_outsb);
|
||||
|
||||
void _insw_ns(volatile u16 __iomem *port, void *buf, long count)
|
||||
void _insw_ns(const volatile u16 __iomem *port, void *buf, long count)
|
||||
{
|
||||
u16 *tbuf = buf;
|
||||
u16 tmp;
|
||||
|
||||
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||
|
||||
if (unlikely(count <= 0))
|
||||
return;
|
||||
asm volatile("sync");
|
||||
@ -83,8 +77,6 @@ void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count)
|
||||
{
|
||||
const u16 *tbuf = buf;
|
||||
|
||||
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||
|
||||
if (unlikely(count <= 0))
|
||||
return;
|
||||
asm volatile("sync");
|
||||
@ -95,13 +87,11 @@ void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count)
|
||||
}
|
||||
EXPORT_SYMBOL(_outsw_ns);
|
||||
|
||||
void _insl_ns(volatile u32 __iomem *port, void *buf, long count)
|
||||
void _insl_ns(const volatile u32 __iomem *port, void *buf, long count)
|
||||
{
|
||||
u32 *tbuf = buf;
|
||||
u32 tmp;
|
||||
|
||||
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||
|
||||
if (unlikely(count <= 0))
|
||||
return;
|
||||
asm volatile("sync");
|
||||
@ -118,8 +108,6 @@ void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count)
|
||||
{
|
||||
const u32 *tbuf = buf;
|
||||
|
||||
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||
|
||||
if (unlikely(count <= 0))
|
||||
return;
|
||||
asm volatile("sync");
|
||||
@ -129,3 +117,90 @@ void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count)
|
||||
asm volatile("sync");
|
||||
}
|
||||
EXPORT_SYMBOL(_outsl_ns);
|
||||
|
||||
#define IO_CHECK_ALIGN(v,a) ((((unsigned long)(v)) & ((a) - 1)) == 0)
|
||||
|
||||
void _memset_io(volatile void __iomem *addr, int c, unsigned long n)
|
||||
{
|
||||
void *p = (void __force *)addr;
|
||||
u32 lc = c;
|
||||
lc |= lc << 8;
|
||||
lc |= lc << 16;
|
||||
|
||||
__asm__ __volatile__ ("sync" : : : "memory");
|
||||
while(n && !IO_CHECK_ALIGN(p, 4)) {
|
||||
*((volatile u8 *)p) = c;
|
||||
p++;
|
||||
n--;
|
||||
}
|
||||
while(n >= 4) {
|
||||
*((volatile u32 *)p) = lc;
|
||||
p += 4;
|
||||
n -= 4;
|
||||
}
|
||||
while(n) {
|
||||
*((volatile u8 *)p) = c;
|
||||
p++;
|
||||
n--;
|
||||
}
|
||||
__asm__ __volatile__ ("sync" : : : "memory");
|
||||
}
|
||||
EXPORT_SYMBOL(_memset_io);
|
||||
|
||||
void _memcpy_fromio(void *dest, const volatile void __iomem *src,
|
||||
unsigned long n)
|
||||
{
|
||||
void *vsrc = (void __force *) src;
|
||||
|
||||
__asm__ __volatile__ ("sync" : : : "memory");
|
||||
while(n && (!IO_CHECK_ALIGN(vsrc, 4) || !IO_CHECK_ALIGN(dest, 4))) {
|
||||
*((u8 *)dest) = *((volatile u8 *)vsrc);
|
||||
__asm__ __volatile__ ("eieio" : : : "memory");
|
||||
vsrc++;
|
||||
dest++;
|
||||
n--;
|
||||
}
|
||||
while(n > 4) {
|
||||
*((u32 *)dest) = *((volatile u32 *)vsrc);
|
||||
__asm__ __volatile__ ("eieio" : : : "memory");
|
||||
vsrc += 4;
|
||||
dest += 4;
|
||||
n -= 4;
|
||||
}
|
||||
while(n) {
|
||||
*((u8 *)dest) = *((volatile u8 *)vsrc);
|
||||
__asm__ __volatile__ ("eieio" : : : "memory");
|
||||
vsrc++;
|
||||
dest++;
|
||||
n--;
|
||||
}
|
||||
__asm__ __volatile__ ("sync" : : : "memory");
|
||||
}
|
||||
EXPORT_SYMBOL(_memcpy_fromio);
|
||||
|
||||
void _memcpy_toio(volatile void __iomem *dest, const void *src, unsigned long n)
|
||||
{
|
||||
void *vdest = (void __force *) dest;
|
||||
|
||||
__asm__ __volatile__ ("sync" : : : "memory");
|
||||
while(n && (!IO_CHECK_ALIGN(vdest, 4) || !IO_CHECK_ALIGN(src, 4))) {
|
||||
*((volatile u8 *)vdest) = *((u8 *)src);
|
||||
src++;
|
||||
vdest++;
|
||||
n--;
|
||||
}
|
||||
while(n > 4) {
|
||||
*((volatile u32 *)vdest) = *((volatile u32 *)src);
|
||||
src += 4;
|
||||
vdest += 4;
|
||||
n-=4;
|
||||
}
|
||||
while(n) {
|
||||
*((volatile u8 *)vdest) = *((u8 *)src);
|
||||
src++;
|
||||
vdest++;
|
||||
n--;
|
||||
}
|
||||
__asm__ __volatile__ ("sync" : : : "memory");
|
||||
}
|
||||
EXPORT_SYMBOL(_memcpy_toio);
|
||||
|
@ -106,7 +106,7 @@ EXPORT_SYMBOL(iowrite32_rep);
|
||||
|
||||
void __iomem *ioport_map(unsigned long port, unsigned int len)
|
||||
{
|
||||
return (void __iomem *) (port+pci_io_base);
|
||||
return (void __iomem *) (port + _IO_BASE);
|
||||
}
|
||||
|
||||
void ioport_unmap(void __iomem *addr)
|
||||
|
@ -258,9 +258,9 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
|
||||
spin_unlock_irqrestore(&(tbl->it_lock), flags);
|
||||
}
|
||||
|
||||
int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
|
||||
struct scatterlist *sglist, int nelems,
|
||||
unsigned long mask, enum dma_data_direction direction)
|
||||
int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
|
||||
int nelems, unsigned long mask,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
dma_addr_t dma_next = 0, dma_addr;
|
||||
unsigned long flags;
|
||||
|
@ -64,8 +64,9 @@
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/udbg.h>
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
#ifdef CONFIG_PPC64
|
||||
#include <asm/paca.h>
|
||||
#include <asm/firmware.h>
|
||||
#endif
|
||||
|
||||
int __irq_offset_value;
|
||||
@ -95,6 +96,74 @@ extern atomic_t ipi_sent;
|
||||
EXPORT_SYMBOL(irq_desc);
|
||||
|
||||
int distribute_irqs = 1;
|
||||
|
||||
static inline unsigned long get_hard_enabled(void)
|
||||
{
|
||||
unsigned long enabled;
|
||||
|
||||
__asm__ __volatile__("lbz %0,%1(13)"
|
||||
: "=r" (enabled) : "i" (offsetof(struct paca_struct, hard_enabled)));
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
static inline void set_soft_enabled(unsigned long enable)
|
||||
{
|
||||
__asm__ __volatile__("stb %0,%1(13)"
|
||||
: : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled)));
|
||||
}
|
||||
|
||||
void local_irq_restore(unsigned long en)
|
||||
{
|
||||
/*
|
||||
* get_paca()->soft_enabled = en;
|
||||
* Is it ever valid to use local_irq_restore(0) when soft_enabled is 1?
|
||||
* That was allowed before, and in such a case we do need to take care
|
||||
* that gcc will set soft_enabled directly via r13, not choose to use
|
||||
* an intermediate register, lest we're preempted to a different cpu.
|
||||
*/
|
||||
set_soft_enabled(en);
|
||||
if (!en)
|
||||
return;
|
||||
|
||||
if (firmware_has_feature(FW_FEATURE_ISERIES)) {
|
||||
/*
|
||||
* Do we need to disable preemption here? Not really: in the
|
||||
* unlikely event that we're preempted to a different cpu in
|
||||
* between getting r13, loading its lppaca_ptr, and loading
|
||||
* its any_int, we might call iseries_handle_interrupts without
|
||||
* an interrupt pending on the new cpu, but that's no disaster,
|
||||
* is it? And the business of preempting us off the old cpu
|
||||
* would itself involve a local_irq_restore which handles the
|
||||
* interrupt to that cpu.
|
||||
*
|
||||
* But use "local_paca->lppaca_ptr" instead of "get_lppaca()"
|
||||
* to avoid any preemption checking added into get_paca().
|
||||
*/
|
||||
if (local_paca->lppaca_ptr->int_dword.any_int)
|
||||
iseries_handle_interrupts();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* if (get_paca()->hard_enabled) return;
|
||||
* But again we need to take care that gcc gets hard_enabled directly
|
||||
* via r13, not choose to use an intermediate register, lest we're
|
||||
* preempted to a different cpu in between the two instructions.
|
||||
*/
|
||||
if (get_hard_enabled())
|
||||
return;
|
||||
|
||||
/*
|
||||
* Need to hard-enable interrupts here. Since currently disabled,
|
||||
* no need to take further asm precautions against preemption; but
|
||||
* use local_paca instead of get_paca() to avoid preemption checking.
|
||||
*/
|
||||
local_paca->hard_enabled = en;
|
||||
if ((int)mfspr(SPRN_DEC) < 0)
|
||||
mtspr(SPRN_DEC, 1);
|
||||
hard_irq_enable();
|
||||
}
|
||||
#endif /* CONFIG_PPC64 */
|
||||
|
||||
int show_interrupts(struct seq_file *p, void *v)
|
||||
@ -246,7 +315,8 @@ void do_IRQ(struct pt_regs *regs)
|
||||
set_irq_regs(old_regs);
|
||||
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
if (get_lppaca()->int_dword.fields.decr_int) {
|
||||
if (firmware_has_feature(FW_FEATURE_ISERIES) &&
|
||||
get_lppaca()->int_dword.fields.decr_int) {
|
||||
get_lppaca()->int_dword.fields.decr_int = 0;
|
||||
/* Signal a fake decrementer interrupt */
|
||||
timer_interrupt(regs);
|
||||
@ -626,10 +696,14 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
|
||||
|
||||
void irq_dispose_mapping(unsigned int virq)
|
||||
{
|
||||
struct irq_host *host = irq_map[virq].host;
|
||||
struct irq_host *host;
|
||||
irq_hw_number_t hwirq;
|
||||
unsigned long flags;
|
||||
|
||||
if (virq == NO_IRQ)
|
||||
return;
|
||||
|
||||
host = irq_map[virq].host;
|
||||
WARN_ON (host == NULL);
|
||||
if (host == NULL)
|
||||
return;
|
||||
|
@ -8,6 +8,34 @@
|
||||
#include <asm/errno.h>
|
||||
#include <asm/of_device.h>
|
||||
|
||||
/**
|
||||
* of_match_node - Tell if an device_node has a matching of_match structure
|
||||
* @ids: array of of device match structures to search in
|
||||
* @node: the of device structure to match against
|
||||
*
|
||||
* Low level utility function used by device matching.
|
||||
*/
|
||||
const struct of_device_id *of_match_node(const struct of_device_id *matches,
|
||||
const struct device_node *node)
|
||||
{
|
||||
while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
|
||||
int match = 1;
|
||||
if (matches->name[0])
|
||||
match &= node->name
|
||||
&& !strcmp(matches->name, node->name);
|
||||
if (matches->type[0])
|
||||
match &= node->type
|
||||
&& !strcmp(matches->type, node->type);
|
||||
if (matches->compatible[0])
|
||||
match &= device_is_compatible(node,
|
||||
matches->compatible);
|
||||
if (match)
|
||||
return matches;
|
||||
matches++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* of_match_device - Tell if an of_device structure has a matching
|
||||
* of_match structure
|
||||
@ -22,34 +50,7 @@ const struct of_device_id *of_match_device(const struct of_device_id *matches,
|
||||
{
|
||||
if (!dev->node)
|
||||
return NULL;
|
||||
while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
|
||||
int match = 1;
|
||||
if (matches->name[0])
|
||||
match &= dev->node->name
|
||||
&& !strcmp(matches->name, dev->node->name);
|
||||
if (matches->type[0])
|
||||
match &= dev->node->type
|
||||
&& !strcmp(matches->type, dev->node->type);
|
||||
if (matches->compatible[0])
|
||||
match &= device_is_compatible(dev->node,
|
||||
matches->compatible);
|
||||
if (match)
|
||||
return matches;
|
||||
matches++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * of_drv = to_of_platform_driver(drv);
|
||||
const struct of_device_id * matches = of_drv->match_table;
|
||||
|
||||
if (!matches)
|
||||
return 0;
|
||||
|
||||
return of_match_device(matches, of_dev) != NULL;
|
||||
return of_match_node(matches, dev->node);
|
||||
}
|
||||
|
||||
struct of_device *of_dev_get(struct of_device *dev)
|
||||
@ -71,96 +72,8 @@ void of_dev_put(struct of_device *dev)
|
||||
put_device(&dev->dev);
|
||||
}
|
||||
|
||||
|
||||
static int of_device_probe(struct device *dev)
|
||||
{
|
||||
int error = -ENODEV;
|
||||
struct of_platform_driver *drv;
|
||||
struct of_device *of_dev;
|
||||
const struct of_device_id *match;
|
||||
|
||||
drv = to_of_platform_driver(dev->driver);
|
||||
of_dev = to_of_device(dev);
|
||||
|
||||
if (!drv->probe)
|
||||
return error;
|
||||
|
||||
of_dev_get(of_dev);
|
||||
|
||||
match = of_match_device(drv->match_table, of_dev);
|
||||
if (match)
|
||||
error = drv->probe(of_dev, match);
|
||||
if (error)
|
||||
of_dev_put(of_dev);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int of_device_remove(struct device *dev)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
|
||||
if (dev->driver && drv->remove)
|
||||
drv->remove(of_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int of_device_suspend(struct device *dev, pm_message_t state)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
int error = 0;
|
||||
|
||||
if (dev->driver && drv->suspend)
|
||||
error = drv->suspend(of_dev, state);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int of_device_resume(struct device * dev)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
int error = 0;
|
||||
|
||||
if (dev->driver && drv->resume)
|
||||
error = drv->resume(of_dev);
|
||||
return error;
|
||||
}
|
||||
|
||||
struct bus_type of_platform_bus_type = {
|
||||
.name = "of_platform",
|
||||
.match = of_platform_bus_match,
|
||||
.probe = of_device_probe,
|
||||
.remove = of_device_remove,
|
||||
.suspend = of_device_suspend,
|
||||
.resume = of_device_resume,
|
||||
};
|
||||
|
||||
static int __init of_bus_driver_init(void)
|
||||
{
|
||||
return bus_register(&of_platform_bus_type);
|
||||
}
|
||||
|
||||
postcore_initcall(of_bus_driver_init);
|
||||
|
||||
int of_register_driver(struct of_platform_driver *drv)
|
||||
{
|
||||
/* initialize common driver fields */
|
||||
drv->driver.name = drv->name;
|
||||
drv->driver.bus = &of_platform_bus_type;
|
||||
|
||||
/* register with core */
|
||||
return driver_register(&drv->driver);
|
||||
}
|
||||
|
||||
void of_unregister_driver(struct of_platform_driver *drv)
|
||||
{
|
||||
driver_unregister(&drv->driver);
|
||||
}
|
||||
|
||||
|
||||
static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
static ssize_t dev_show_devspec(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct of_device *ofdev;
|
||||
|
||||
@ -208,41 +121,11 @@ void of_device_unregister(struct of_device *ofdev)
|
||||
device_unregister(&ofdev->dev);
|
||||
}
|
||||
|
||||
struct of_device* of_platform_device_create(struct device_node *np,
|
||||
const char *bus_id,
|
||||
struct device *parent)
|
||||
{
|
||||
struct of_device *dev;
|
||||
|
||||
dev = kmalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
memset(dev, 0, sizeof(*dev));
|
||||
|
||||
dev->node = of_node_get(np);
|
||||
dev->dma_mask = 0xffffffffUL;
|
||||
dev->dev.dma_mask = &dev->dma_mask;
|
||||
dev->dev.parent = parent;
|
||||
dev->dev.bus = &of_platform_bus_type;
|
||||
dev->dev.release = of_release_dev;
|
||||
|
||||
strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
|
||||
|
||||
if (of_device_register(dev) != 0) {
|
||||
kfree(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(of_match_node);
|
||||
EXPORT_SYMBOL(of_match_device);
|
||||
EXPORT_SYMBOL(of_platform_bus_type);
|
||||
EXPORT_SYMBOL(of_register_driver);
|
||||
EXPORT_SYMBOL(of_unregister_driver);
|
||||
EXPORT_SYMBOL(of_device_register);
|
||||
EXPORT_SYMBOL(of_device_unregister);
|
||||
EXPORT_SYMBOL(of_dev_get);
|
||||
EXPORT_SYMBOL(of_dev_put);
|
||||
EXPORT_SYMBOL(of_platform_device_create);
|
||||
EXPORT_SYMBOL(of_release_dev);
|
||||
|
489
arch/powerpc/kernel/of_platform.c
Normal file
489
arch/powerpc/kernel/of_platform.c
Normal file
@ -0,0 +1,489 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||
* <benh@kernel.crashing.org>
|
||||
* and Arnd Bergmann, IBM Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <asm/errno.h>
|
||||
#include <asm/dcr.h>
|
||||
#include <asm/of_device.h>
|
||||
#include <asm/of_platform.h>
|
||||
#include <asm/topology.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/ppc-pci.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
|
||||
/*
|
||||
* The list of OF IDs below is used for matching bus types in the
|
||||
* system whose devices are to be exposed as of_platform_devices.
|
||||
*
|
||||
* This is the default list valid for most platforms. This file provides
|
||||
* functions who can take an explicit list if necessary though
|
||||
*
|
||||
* The search is always performed recursively looking for children of
|
||||
* the provided device_node and recursively if such a children matches
|
||||
* a bus type in the list
|
||||
*/
|
||||
|
||||
static struct of_device_id of_default_bus_ids[] = {
|
||||
{ .type = "soc", },
|
||||
{ .compatible = "soc", },
|
||||
{ .type = "spider", },
|
||||
{ .type = "axon", },
|
||||
{ .type = "plb5", },
|
||||
{ .type = "plb4", },
|
||||
{ .type = "opb", },
|
||||
{},
|
||||
};
|
||||
|
||||
static atomic_t bus_no_reg_magic;
|
||||
|
||||
/*
|
||||
*
|
||||
* OF platform device type definition & base infrastructure
|
||||
*
|
||||
*/
|
||||
|
||||
static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * of_drv = to_of_platform_driver(drv);
|
||||
const struct of_device_id * matches = of_drv->match_table;
|
||||
|
||||
if (!matches)
|
||||
return 0;
|
||||
|
||||
return of_match_device(matches, of_dev) != NULL;
|
||||
}
|
||||
|
||||
static int of_platform_device_probe(struct device *dev)
|
||||
{
|
||||
int error = -ENODEV;
|
||||
struct of_platform_driver *drv;
|
||||
struct of_device *of_dev;
|
||||
const struct of_device_id *match;
|
||||
|
||||
drv = to_of_platform_driver(dev->driver);
|
||||
of_dev = to_of_device(dev);
|
||||
|
||||
if (!drv->probe)
|
||||
return error;
|
||||
|
||||
of_dev_get(of_dev);
|
||||
|
||||
match = of_match_device(drv->match_table, of_dev);
|
||||
if (match)
|
||||
error = drv->probe(of_dev, match);
|
||||
if (error)
|
||||
of_dev_put(of_dev);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int of_platform_device_remove(struct device *dev)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
|
||||
if (dev->driver && drv->remove)
|
||||
drv->remove(of_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int of_platform_device_suspend(struct device *dev, pm_message_t state)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
int error = 0;
|
||||
|
||||
if (dev->driver && drv->suspend)
|
||||
error = drv->suspend(of_dev, state);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int of_platform_device_resume(struct device * dev)
|
||||
{
|
||||
struct of_device * of_dev = to_of_device(dev);
|
||||
struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
|
||||
int error = 0;
|
||||
|
||||
if (dev->driver && drv->resume)
|
||||
error = drv->resume(of_dev);
|
||||
return error;
|
||||
}
|
||||
|
||||
struct bus_type of_platform_bus_type = {
|
||||
.name = "of_platform",
|
||||
.match = of_platform_bus_match,
|
||||
.probe = of_platform_device_probe,
|
||||
.remove = of_platform_device_remove,
|
||||
.suspend = of_platform_device_suspend,
|
||||
.resume = of_platform_device_resume,
|
||||
};
|
||||
EXPORT_SYMBOL(of_platform_bus_type);
|
||||
|
||||
static int __init of_bus_driver_init(void)
|
||||
{
|
||||
return bus_register(&of_platform_bus_type);
|
||||
}
|
||||
|
||||
postcore_initcall(of_bus_driver_init);
|
||||
|
||||
int of_register_platform_driver(struct of_platform_driver *drv)
|
||||
{
|
||||
/* initialize common driver fields */
|
||||
drv->driver.name = drv->name;
|
||||
drv->driver.bus = &of_platform_bus_type;
|
||||
|
||||
/* register with core */
|
||||
return driver_register(&drv->driver);
|
||||
}
|
||||
EXPORT_SYMBOL(of_register_platform_driver);
|
||||
|
||||
void of_unregister_platform_driver(struct of_platform_driver *drv)
|
||||
{
|
||||
driver_unregister(&drv->driver);
|
||||
}
|
||||
EXPORT_SYMBOL(of_unregister_platform_driver);
|
||||
|
||||
static void of_platform_make_bus_id(struct of_device *dev)
|
||||
{
|
||||
struct device_node *node = dev->node;
|
||||
char *name = dev->dev.bus_id;
|
||||
const u32 *reg;
|
||||
u64 addr;
|
||||
long magic;
|
||||
|
||||
/*
|
||||
* If it's a DCR based device, use 'd' for native DCRs
|
||||
* and 'D' for MMIO DCRs.
|
||||
*/
|
||||
#ifdef CONFIG_PPC_DCR
|
||||
reg = get_property(node, "dcr-reg", NULL);
|
||||
if (reg) {
|
||||
#ifdef CONFIG_PPC_DCR_NATIVE
|
||||
snprintf(name, BUS_ID_SIZE, "d%x.%s",
|
||||
*reg, node->name);
|
||||
#else /* CONFIG_PPC_DCR_NATIVE */
|
||||
addr = of_translate_dcr_address(node, *reg, NULL);
|
||||
if (addr != OF_BAD_ADDR) {
|
||||
snprintf(name, BUS_ID_SIZE,
|
||||
"D%llx.%s", (unsigned long long)addr,
|
||||
node->name);
|
||||
return;
|
||||
}
|
||||
#endif /* !CONFIG_PPC_DCR_NATIVE */
|
||||
}
|
||||
#endif /* CONFIG_PPC_DCR */
|
||||
|
||||
/*
|
||||
* For MMIO, get the physical address
|
||||
*/
|
||||
reg = get_property(node, "reg", NULL);
|
||||
if (reg) {
|
||||
addr = of_translate_address(node, reg);
|
||||
if (addr != OF_BAD_ADDR) {
|
||||
snprintf(name, BUS_ID_SIZE,
|
||||
"%llx.%s", (unsigned long long)addr,
|
||||
node->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* No BusID, use the node name and add a globally incremented
|
||||
* counter (and pray...)
|
||||
*/
|
||||
magic = atomic_add_return(1, &bus_no_reg_magic);
|
||||
snprintf(name, BUS_ID_SIZE, "%s.%d", node->name, magic - 1);
|
||||
}
|
||||
|
||||
struct of_device* of_platform_device_create(struct device_node *np,
|
||||
const char *bus_id,
|
||||
struct device *parent)
|
||||
{
|
||||
struct of_device *dev;
|
||||
|
||||
dev = kmalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
memset(dev, 0, sizeof(*dev));
|
||||
|
||||
dev->node = of_node_get(np);
|
||||
dev->dma_mask = 0xffffffffUL;
|
||||
dev->dev.dma_mask = &dev->dma_mask;
|
||||
dev->dev.parent = parent;
|
||||
dev->dev.bus = &of_platform_bus_type;
|
||||
dev->dev.release = of_release_dev;
|
||||
dev->dev.archdata.of_node = np;
|
||||
dev->dev.archdata.numa_node = of_node_to_nid(np);
|
||||
|
||||
/* We do not fill the DMA ops for platform devices by default.
|
||||
* This is currently the responsibility of the platform code
|
||||
* to do such, possibly using a device notifier
|
||||
*/
|
||||
|
||||
if (bus_id)
|
||||
strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
|
||||
else
|
||||
of_platform_make_bus_id(dev);
|
||||
|
||||
if (of_device_register(dev) != 0) {
|
||||
kfree(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
EXPORT_SYMBOL(of_platform_device_create);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* of_platform_bus_create - Create an OF device for a bus node and all its
|
||||
* children. Optionally recursively instanciate matching busses.
|
||||
* @bus: device node of the bus to instanciate
|
||||
* @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
|
||||
* disallow recursive creation of child busses
|
||||
*/
|
||||
static int of_platform_bus_create(struct device_node *bus,
|
||||
struct of_device_id *matches,
|
||||
struct device *parent)
|
||||
{
|
||||
struct device_node *child;
|
||||
struct of_device *dev;
|
||||
int rc = 0;
|
||||
|
||||
for (child = NULL; (child = of_get_next_child(bus, child)); ) {
|
||||
pr_debug(" create child: %s\n", child->full_name);
|
||||
dev = of_platform_device_create(child, NULL, parent);
|
||||
if (dev == NULL)
|
||||
rc = -ENOMEM;
|
||||
else if (!of_match_node(matches, child))
|
||||
continue;
|
||||
if (rc == 0) {
|
||||
pr_debug(" and sub busses\n");
|
||||
rc = of_platform_bus_create(child, matches, &dev->dev);
|
||||
} if (rc) {
|
||||
of_node_put(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* of_platform_bus_probe - Probe the device-tree for platform busses
|
||||
* @root: parent of the first level to probe or NULL for the root of the tree
|
||||
* @matches: match table, NULL to use the default
|
||||
* @parent: parent to hook devices from, NULL for toplevel
|
||||
*
|
||||
* Note that children of the provided root are not instanciated as devices
|
||||
* unless the specified root itself matches the bus list and is not NULL.
|
||||
*/
|
||||
|
||||
int of_platform_bus_probe(struct device_node *root,
|
||||
struct of_device_id *matches,
|
||||
struct device *parent)
|
||||
{
|
||||
struct device_node *child;
|
||||
struct of_device *dev;
|
||||
int rc = 0;
|
||||
|
||||
if (matches == NULL)
|
||||
matches = of_default_bus_ids;
|
||||
if (matches == OF_NO_DEEP_PROBE)
|
||||
return -EINVAL;
|
||||
if (root == NULL)
|
||||
root = of_find_node_by_path("/");
|
||||
else
|
||||
of_node_get(root);
|
||||
|
||||
pr_debug("of_platform_bus_probe()\n");
|
||||
pr_debug(" starting at: %s\n", root->full_name);
|
||||
|
||||
/* Do a self check of bus type, if there's a match, create
|
||||
* children
|
||||
*/
|
||||
if (of_match_node(matches, root)) {
|
||||
pr_debug(" root match, create all sub devices\n");
|
||||
dev = of_platform_device_create(root, NULL, parent);
|
||||
if (dev == NULL) {
|
||||
rc = -ENOMEM;
|
||||
goto bail;
|
||||
}
|
||||
pr_debug(" create all sub busses\n");
|
||||
rc = of_platform_bus_create(root, matches, &dev->dev);
|
||||
goto bail;
|
||||
}
|
||||
for (child = NULL; (child = of_get_next_child(root, child)); ) {
|
||||
if (!of_match_node(matches, child))
|
||||
continue;
|
||||
|
||||
pr_debug(" match: %s\n", child->full_name);
|
||||
dev = of_platform_device_create(child, NULL, parent);
|
||||
if (dev == NULL)
|
||||
rc = -ENOMEM;
|
||||
else
|
||||
rc = of_platform_bus_create(child, matches, &dev->dev);
|
||||
if (rc) {
|
||||
of_node_put(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
bail:
|
||||
of_node_put(root);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(of_platform_bus_probe);
|
||||
|
||||
static int of_dev_node_match(struct device *dev, void *data)
|
||||
{
|
||||
return to_of_device(dev)->node == data;
|
||||
}
|
||||
|
||||
struct of_device *of_find_device_by_node(struct device_node *np)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
dev = bus_find_device(&of_platform_bus_type,
|
||||
NULL, np, of_dev_node_match);
|
||||
if (dev)
|
||||
return to_of_device(dev);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_device_by_node);
|
||||
|
||||
static int of_dev_phandle_match(struct device *dev, void *data)
|
||||
{
|
||||
phandle *ph = data;
|
||||
return to_of_device(dev)->node->linux_phandle == *ph;
|
||||
}
|
||||
|
||||
struct of_device *of_find_device_by_phandle(phandle ph)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
dev = bus_find_device(&of_platform_bus_type,
|
||||
NULL, &ph, of_dev_phandle_match);
|
||||
if (dev)
|
||||
return to_of_device(dev);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_device_by_phandle);
|
||||
|
||||
|
||||
#ifdef CONFIG_PPC_OF_PLATFORM_PCI
|
||||
|
||||
/* The probing of PCI controllers from of_platform is currently
|
||||
* 64 bits only, mostly due to gratuitous differences between
|
||||
* the 32 and 64 bits PCI code on PowerPC and the 32 bits one
|
||||
* lacking some bits needed here.
|
||||
*/
|
||||
|
||||
static int __devinit of_pci_phb_probe(struct of_device *dev,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
struct pci_controller *phb;
|
||||
|
||||
/* Check if we can do that ... */
|
||||
if (ppc_md.pci_setup_phb == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
printk(KERN_INFO "Setting up PCI bus %s\n", dev->node->full_name);
|
||||
|
||||
/* Alloc and setup PHB data structure */
|
||||
phb = pcibios_alloc_controller(dev->node);
|
||||
if (!phb)
|
||||
return -ENODEV;
|
||||
|
||||
/* Setup parent in sysfs */
|
||||
phb->parent = &dev->dev;
|
||||
|
||||
/* Setup the PHB using arch provided callback */
|
||||
if (ppc_md.pci_setup_phb(phb)) {
|
||||
pcibios_free_controller(phb);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Process "ranges" property */
|
||||
pci_process_bridge_OF_ranges(phb, dev->node, 0);
|
||||
|
||||
/* Setup IO space.
|
||||
* This will not work properly for ISA IOs, something needs to be done
|
||||
* about it if we ever generalize that way of probing PCI brigdes
|
||||
*/
|
||||
pci_setup_phb_io_dynamic(phb, 0);
|
||||
|
||||
/* Init pci_dn data structures */
|
||||
pci_devs_phb_init_dynamic(phb);
|
||||
|
||||
/* Register devices with EEH */
|
||||
#ifdef CONFIG_EEH
|
||||
if (dev->node->child)
|
||||
eeh_add_device_tree_early(dev->node);
|
||||
#endif /* CONFIG_EEH */
|
||||
|
||||
/* Scan the bus */
|
||||
scan_phb(phb);
|
||||
|
||||
/* Claim resources. This might need some rework as well depending
|
||||
* wether we are doing probe-only or not, like assigning unassigned
|
||||
* resources etc...
|
||||
*/
|
||||
pcibios_claim_one_bus(phb->bus);
|
||||
|
||||
/* Finish EEH setup */
|
||||
#ifdef CONFIG_EEH
|
||||
eeh_add_device_tree_late(phb->bus);
|
||||
#endif
|
||||
|
||||
/* Add probed PCI devices to the device model */
|
||||
pci_bus_add_devices(phb->bus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id of_pci_phb_ids[] = {
|
||||
{ .type = "pci", },
|
||||
{ .type = "pcix", },
|
||||
{ .type = "pcie", },
|
||||
{ .type = "pciex", },
|
||||
{ .type = "ht", },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct of_platform_driver of_pci_phb_driver = {
|
||||
.name = "of-pci",
|
||||
.match_table = of_pci_phb_ids,
|
||||
.probe = of_pci_phb_probe,
|
||||
.driver = {
|
||||
.multithread_probe = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static __init int of_pci_phb_init(void)
|
||||
{
|
||||
return of_register_platform_driver(&of_pci_phb_driver);
|
||||
}
|
||||
|
||||
device_initcall(of_pci_phb_init);
|
||||
|
||||
#endif /* CONFIG_PPC_OF_PLATFORM_PCI */
|
@ -12,6 +12,7 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#include <asm/processor.h>
|
||||
#include <asm/io.h>
|
||||
@ -99,7 +100,7 @@ pcibios_fixup_resources(struct pci_dev *dev)
|
||||
continue;
|
||||
if (res->end == 0xffffffff) {
|
||||
DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n",
|
||||
pci_name(dev), i, res->start, res->end);
|
||||
pci_name(dev), i, (u64)res->start, (u64)res->end);
|
||||
res->end -= res->start;
|
||||
res->start = 0;
|
||||
res->flags |= IORESOURCE_UNSET;
|
||||
@ -115,11 +116,9 @@ pcibios_fixup_resources(struct pci_dev *dev)
|
||||
if (offset != 0) {
|
||||
res->start += offset;
|
||||
res->end += offset;
|
||||
#ifdef DEBUG
|
||||
printk("Fixup res %d (%lx) of dev %s: %llx -> %llx\n",
|
||||
i, res->flags, pci_name(dev),
|
||||
res->start - offset, res->start);
|
||||
#endif
|
||||
DBG("Fixup res %d (%lx) of dev %s: %llx -> %llx\n",
|
||||
i, res->flags, pci_name(dev),
|
||||
(u64)res->start - offset, (u64)res->start);
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,7 +254,7 @@ pcibios_allocate_bus_resources(struct list_head *bus_list)
|
||||
}
|
||||
|
||||
DBG("PCI: bridge rsrc %llx..%llx (%lx), parent %p\n",
|
||||
res->start, res->end, res->flags, pr);
|
||||
(u64)res->start, (u64)res->end, res->flags, pr);
|
||||
if (pr) {
|
||||
if (request_resource(pr, res) == 0)
|
||||
continue;
|
||||
@ -306,7 +305,7 @@ reparent_resources(struct resource *parent, struct resource *res)
|
||||
for (p = res->child; p != NULL; p = p->sibling) {
|
||||
p->parent = res;
|
||||
DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n",
|
||||
p->name, p->start, p->end, res->name);
|
||||
p->name, (u64)p->start, (u64)p->end, res->name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -362,7 +361,7 @@ pci_relocate_bridge_resource(struct pci_bus *bus, int i)
|
||||
}
|
||||
if (request_resource(pr, res)) {
|
||||
DBG(KERN_ERR "PCI: huh? couldn't move to %llx..%llx\n",
|
||||
res->start, res->end);
|
||||
(u64)res->start, (u64)res->end);
|
||||
return -1; /* "can't happen" */
|
||||
}
|
||||
update_bridge_base(bus, i);
|
||||
@ -480,14 +479,14 @@ static inline void alloc_resource(struct pci_dev *dev, int idx)
|
||||
struct resource *pr, *r = &dev->resource[idx];
|
||||
|
||||
DBG("PCI:%s: Resource %d: %016llx-%016llx (f=%lx)\n",
|
||||
pci_name(dev), idx, r->start, r->end, r->flags);
|
||||
pci_name(dev), idx, (u64)r->start, (u64)r->end, r->flags);
|
||||
pr = pci_find_parent_resource(dev, r);
|
||||
if (!pr || request_resource(pr, r) < 0) {
|
||||
printk(KERN_ERR "PCI: Cannot allocate resource region %d"
|
||||
" of device %s\n", idx, pci_name(dev));
|
||||
if (pr)
|
||||
DBG("PCI: parent is %p: %016llx-%016llx (f=%lx)\n",
|
||||
pr, pr->start, pr->end, pr->flags);
|
||||
pr, (u64)pr->start, (u64)pr->end, pr->flags);
|
||||
/* We'll assign a new address later */
|
||||
r->flags |= IORESOURCE_UNSET;
|
||||
r->end -= r->start;
|
||||
@ -960,7 +959,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose,
|
||||
res->flags = IORESOURCE_IO;
|
||||
res->start = ranges[2];
|
||||
DBG("PCI: IO 0x%llx -> 0x%llx\n",
|
||||
res->start, res->start + size - 1);
|
||||
(u64)res->start, (u64)res->start + size - 1);
|
||||
break;
|
||||
case 2: /* memory space */
|
||||
memno = 0;
|
||||
@ -982,7 +981,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose,
|
||||
res->flags |= IORESOURCE_PREFETCH;
|
||||
res->start = ranges[na+2];
|
||||
DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno,
|
||||
res->start, res->start + size - 1);
|
||||
(u64)res->start, (u64)res->start + size - 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1268,7 +1267,10 @@ pcibios_init(void)
|
||||
if (pci_assign_all_buses)
|
||||
hose->first_busno = next_busno;
|
||||
hose->last_busno = 0xff;
|
||||
bus = pci_scan_bus(hose->first_busno, hose->ops, hose);
|
||||
bus = pci_scan_bus_parented(hose->parent, hose->first_busno,
|
||||
hose->ops, hose);
|
||||
if (bus)
|
||||
pci_bus_add_devices(bus);
|
||||
hose->last_busno = bus->subordinate;
|
||||
if (pci_assign_all_buses || next_busno <= hose->last_busno)
|
||||
next_busno = hose->last_busno + pcibios_assign_bus_offset;
|
||||
@ -1282,10 +1284,6 @@ pcibios_init(void)
|
||||
if (pci_assign_all_buses && have_of)
|
||||
pcibios_make_OF_bus_map();
|
||||
|
||||
/* Do machine dependent PCI interrupt routing */
|
||||
if (ppc_md.pci_swizzle && ppc_md.pci_map_irq)
|
||||
pci_fixup_irqs(ppc_md.pci_swizzle, ppc_md.pci_map_irq);
|
||||
|
||||
/* Call machine dependent fixup */
|
||||
if (ppc_md.pcibios_fixup)
|
||||
ppc_md.pcibios_fixup();
|
||||
@ -1308,25 +1306,6 @@ pcibios_init(void)
|
||||
|
||||
subsys_initcall(pcibios_init);
|
||||
|
||||
unsigned char __init
|
||||
common_swizzle(struct pci_dev *dev, unsigned char *pinp)
|
||||
{
|
||||
struct pci_controller *hose = dev->sysdata;
|
||||
|
||||
if (dev->bus->number != hose->first_busno) {
|
||||
u8 pin = *pinp;
|
||||
do {
|
||||
pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
|
||||
/* Move up the chain of bridges. */
|
||||
dev = dev->bus->self;
|
||||
} while (dev->bus->self);
|
||||
*pinp = pin;
|
||||
|
||||
/* The slot is the idsel of the last bridge. */
|
||||
}
|
||||
return PCI_SLOT(dev->devfn);
|
||||
}
|
||||
|
||||
unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
|
||||
unsigned long start, unsigned long size)
|
||||
{
|
||||
@ -1338,6 +1317,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
|
||||
struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
|
||||
unsigned long io_offset;
|
||||
struct resource *res;
|
||||
struct pci_dev *dev;
|
||||
int i;
|
||||
|
||||
io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
|
||||
@ -1390,8 +1370,16 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
|
||||
}
|
||||
}
|
||||
|
||||
/* Platform specific bus fixups */
|
||||
if (ppc_md.pcibios_fixup_bus)
|
||||
ppc_md.pcibios_fixup_bus(bus);
|
||||
|
||||
/* Read default IRQs and fixup if necessary */
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
pci_read_irq_line(dev);
|
||||
if (ppc_md.pci_irq_fixup)
|
||||
ppc_md.pci_irq_fixup(dev);
|
||||
}
|
||||
}
|
||||
|
||||
char __init *pcibios_setup(char *str)
|
||||
@ -1571,7 +1559,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
|
||||
*offset += hose->pci_mem_offset;
|
||||
res_bit = IORESOURCE_MEM;
|
||||
} else {
|
||||
io_offset = hose->io_base_virt - ___IO_BASE;
|
||||
io_offset = hose->io_base_virt - (void __iomem *)_IO_BASE;
|
||||
*offset += io_offset;
|
||||
res_bit = IORESOURCE_IO;
|
||||
}
|
||||
@ -1826,7 +1814,8 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,
|
||||
return;
|
||||
|
||||
if (rsrc->flags & IORESOURCE_IO)
|
||||
offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys;
|
||||
offset = (void __iomem *)_IO_BASE - hose->io_base_virt
|
||||
+ hose->io_base_phys;
|
||||
|
||||
*start = rsrc->start + offset;
|
||||
*end = rsrc->end + offset;
|
||||
@ -1845,35 +1834,6 @@ pci_init_resource(struct resource *res, unsigned long start, unsigned long end,
|
||||
res->child = NULL;
|
||||
}
|
||||
|
||||
void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
|
||||
{
|
||||
unsigned long start = pci_resource_start(dev, bar);
|
||||
unsigned long len = pci_resource_len(dev, bar);
|
||||
unsigned long flags = pci_resource_flags(dev, bar);
|
||||
|
||||
if (!len)
|
||||
return NULL;
|
||||
if (max && len > max)
|
||||
len = max;
|
||||
if (flags & IORESOURCE_IO)
|
||||
return ioport_map(start, len);
|
||||
if (flags & IORESOURCE_MEM)
|
||||
/* Not checking IORESOURCE_CACHEABLE because PPC does
|
||||
* not currently distinguish between ioremap and
|
||||
* ioremap_nocache.
|
||||
*/
|
||||
return ioremap(start, len);
|
||||
/* What? */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
EXPORT_SYMBOL(pci_iomap);
|
||||
EXPORT_SYMBOL(pci_iounmap);
|
||||
|
||||
unsigned long pci_address_to_pio(phys_addr_t address)
|
||||
{
|
||||
struct pci_controller* hose = hose_head;
|
||||
|
@ -42,11 +42,9 @@
|
||||
unsigned long pci_probe_only = 1;
|
||||
int pci_assign_all_buses = 0;
|
||||
|
||||
#ifdef CONFIG_PPC_MULTIPLATFORM
|
||||
static void fixup_resource(struct resource *res, struct pci_dev *dev);
|
||||
static void do_bus_setup(struct pci_bus *bus);
|
||||
static void phbs_remap_io(void);
|
||||
#endif
|
||||
|
||||
/* pci_io_base -- the base address from which io bars are offsets.
|
||||
* This is the lowest I/O base address (so bar values are always positive),
|
||||
@ -63,7 +61,7 @@ void iSeries_pcibios_init(void);
|
||||
|
||||
LIST_HEAD(hose_list);
|
||||
|
||||
struct dma_mapping_ops pci_dma_ops;
|
||||
struct dma_mapping_ops *pci_dma_ops;
|
||||
EXPORT_SYMBOL(pci_dma_ops);
|
||||
|
||||
int global_phb_number; /* Global phb counter */
|
||||
@ -212,6 +210,10 @@ struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
|
||||
|
||||
void pcibios_free_controller(struct pci_controller *phb)
|
||||
{
|
||||
spin_lock(&hose_spinlock);
|
||||
list_del(&phb->list_node);
|
||||
spin_unlock(&hose_spinlock);
|
||||
|
||||
if (phb->is_dynamic)
|
||||
kfree(phb);
|
||||
}
|
||||
@ -251,7 +253,6 @@ static void __init pcibios_claim_of_setup(void)
|
||||
pcibios_claim_one_bus(b);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC_MULTIPLATFORM
|
||||
static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
|
||||
{
|
||||
const u32 *prop;
|
||||
@ -329,7 +330,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
|
||||
struct pci_dev *dev;
|
||||
const char *type;
|
||||
|
||||
dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
|
||||
dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
type = get_property(node, "device_type", NULL);
|
||||
@ -338,7 +339,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
|
||||
|
||||
DBG(" create device, devfn: %x, type: %s\n", devfn, type);
|
||||
|
||||
memset(dev, 0, sizeof(struct pci_dev));
|
||||
dev->bus = bus;
|
||||
dev->sysdata = node;
|
||||
dev->dev.parent = bus->bridge;
|
||||
@ -506,7 +506,6 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
|
||||
pci_scan_child_bus(bus);
|
||||
}
|
||||
EXPORT_SYMBOL(of_scan_pci_bridge);
|
||||
#endif /* CONFIG_PPC_MULTIPLATFORM */
|
||||
|
||||
void __devinit scan_phb(struct pci_controller *hose)
|
||||
{
|
||||
@ -517,7 +516,7 @@ void __devinit scan_phb(struct pci_controller *hose)
|
||||
|
||||
DBG("Scanning PHB %s\n", node ? node->full_name : "<NO NAME>");
|
||||
|
||||
bus = pci_create_bus(NULL, hose->first_busno, hose->ops, node);
|
||||
bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node);
|
||||
if (bus == NULL) {
|
||||
printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
|
||||
hose->global_number);
|
||||
@ -540,7 +539,7 @@ void __devinit scan_phb(struct pci_controller *hose)
|
||||
}
|
||||
|
||||
mode = PCI_PROBE_NORMAL;
|
||||
#ifdef CONFIG_PPC_MULTIPLATFORM
|
||||
|
||||
if (node && ppc_md.pci_probe_mode)
|
||||
mode = ppc_md.pci_probe_mode(bus);
|
||||
DBG(" probe mode: %d\n", mode);
|
||||
@ -548,7 +547,7 @@ void __devinit scan_phb(struct pci_controller *hose)
|
||||
bus->subordinate = hose->last_busno;
|
||||
of_scan_bus(node, bus);
|
||||
}
|
||||
#endif /* CONFIG_PPC_MULTIPLATFORM */
|
||||
|
||||
if (mode == PCI_PROBE_NORMAL)
|
||||
hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
|
||||
}
|
||||
@ -592,11 +591,9 @@ static int __init pcibios_init(void)
|
||||
if (ppc64_isabridge_dev != NULL)
|
||||
printk(KERN_DEBUG "ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
|
||||
|
||||
#ifdef CONFIG_PPC_MULTIPLATFORM
|
||||
if (!firmware_has_feature(FW_FEATURE_ISERIES))
|
||||
/* map in PCI I/O space */
|
||||
phbs_remap_io();
|
||||
#endif
|
||||
|
||||
printk(KERN_DEBUG "PCI: Probing PCI hardware done\n");
|
||||
|
||||
@ -873,8 +870,6 @@ void pcibios_add_platform_entries(struct pci_dev *pdev)
|
||||
device_create_file(&pdev->dev, &dev_attr_devspec);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC_MULTIPLATFORM
|
||||
|
||||
#define ISA_SPACE_MASK 0x1
|
||||
#define ISA_SPACE_IO 0x1
|
||||
|
||||
@ -975,11 +970,7 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
|
||||
res = NULL;
|
||||
pci_space = ranges[0];
|
||||
pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2];
|
||||
|
||||
cpu_phys_addr = ranges[3];
|
||||
if (na >= 2)
|
||||
cpu_phys_addr = (cpu_phys_addr << 32) | ranges[4];
|
||||
|
||||
cpu_phys_addr = of_translate_address(dev, &ranges[3]);
|
||||
size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4];
|
||||
ranges += np;
|
||||
if (size == 0)
|
||||
@ -1145,7 +1136,7 @@ int unmap_bus_range(struct pci_bus *bus)
|
||||
|
||||
if (get_bus_io_range(bus, &start_phys, &start_virt, &size))
|
||||
return 1;
|
||||
if (iounmap_explicit((void __iomem *) start_virt, size))
|
||||
if (__iounmap_explicit((void __iomem *) start_virt, size))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
@ -1213,23 +1204,52 @@ void __devinit pcibios_fixup_device_resources(struct pci_dev *dev,
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_fixup_device_resources);
|
||||
|
||||
void __devinit pcibios_setup_new_device(struct pci_dev *dev)
|
||||
{
|
||||
struct dev_archdata *sd = &dev->dev.archdata;
|
||||
|
||||
sd->of_node = pci_device_to_OF_node(dev);
|
||||
|
||||
DBG("PCI device %s OF node: %s\n", pci_name(dev),
|
||||
sd->of_node ? sd->of_node->full_name : "<none>");
|
||||
|
||||
sd->dma_ops = pci_dma_ops;
|
||||
#ifdef CONFIG_NUMA
|
||||
sd->numa_node = pcibus_to_node(dev->bus);
|
||||
#else
|
||||
sd->numa_node = -1;
|
||||
#endif
|
||||
if (ppc_md.pci_dma_dev_setup)
|
||||
ppc_md.pci_dma_dev_setup(dev);
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_setup_new_device);
|
||||
|
||||
static void __devinit do_bus_setup(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
|
||||
ppc_md.iommu_bus_setup(bus);
|
||||
if (ppc_md.pci_dma_bus_setup)
|
||||
ppc_md.pci_dma_bus_setup(bus);
|
||||
|
||||
list_for_each_entry(dev, &bus->devices, bus_list)
|
||||
ppc_md.iommu_dev_setup(dev);
|
||||
pcibios_setup_new_device(dev);
|
||||
|
||||
if (ppc_md.irq_bus_setup)
|
||||
ppc_md.irq_bus_setup(bus);
|
||||
/* Read default IRQs and fixup if necessary */
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
pci_read_irq_line(dev);
|
||||
if (ppc_md.pci_irq_fixup)
|
||||
ppc_md.pci_irq_fixup(dev);
|
||||
}
|
||||
}
|
||||
|
||||
void __devinit pcibios_fixup_bus(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_dev *dev = bus->self;
|
||||
struct device_node *np;
|
||||
|
||||
np = pci_bus_to_OF_node(bus);
|
||||
|
||||
DBG("pcibios_fixup_bus(%s)\n", np ? np->full_name : "<???>");
|
||||
|
||||
if (dev && pci_probe_only &&
|
||||
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
|
||||
@ -1343,8 +1363,6 @@ struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PPC_MULTIPLATFORM */
|
||||
|
||||
unsigned long pci_address_to_pio(phys_addr_t address)
|
||||
{
|
||||
struct pci_controller *hose, *tmp;
|
||||
|
@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Support for DMA from PCI devices to main memory on
|
||||
* machines without an iommu or with directly addressable
|
||||
* RAM (typically a pmac with 2Gb of RAM or less)
|
||||
*
|
||||
* Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include <asm/sections.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pmac_feature.h>
|
||||
#include <asm/abs_addr.h>
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t flag)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
ret = (void *)__get_free_pages(flag, get_order(size));
|
||||
if (ret != NULL) {
|
||||
memset(ret, 0, size);
|
||||
*dma_handle = virt_to_abs(ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pci_direct_free_coherent(struct device *hwdev, size_t size,
|
||||
void *vaddr, dma_addr_t dma_handle)
|
||||
{
|
||||
free_pages((unsigned long)vaddr, get_order(size));
|
||||
}
|
||||
|
||||
static dma_addr_t pci_direct_map_single(struct device *hwdev, void *ptr,
|
||||
size_t size, enum dma_data_direction direction)
|
||||
{
|
||||
return virt_to_abs(ptr);
|
||||
}
|
||||
|
||||
static void pci_direct_unmap_single(struct device *hwdev, dma_addr_t dma_addr,
|
||||
size_t size, enum dma_data_direction direction)
|
||||
{
|
||||
}
|
||||
|
||||
static int pci_direct_map_sg(struct device *hwdev, struct scatterlist *sg,
|
||||
int nents, enum dma_data_direction direction)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nents; i++, sg++) {
|
||||
sg->dma_address = page_to_phys(sg->page) + sg->offset;
|
||||
sg->dma_length = sg->length;
|
||||
}
|
||||
|
||||
return nents;
|
||||
}
|
||||
|
||||
static void pci_direct_unmap_sg(struct device *hwdev, struct scatterlist *sg,
|
||||
int nents, enum dma_data_direction direction)
|
||||
{
|
||||
}
|
||||
|
||||
static int pci_direct_dma_supported(struct device *dev, u64 mask)
|
||||
{
|
||||
return mask < 0x100000000ull;
|
||||
}
|
||||
|
||||
static struct dma_mapping_ops pci_direct_ops = {
|
||||
.alloc_coherent = pci_direct_alloc_coherent,
|
||||
.free_coherent = pci_direct_free_coherent,
|
||||
.map_single = pci_direct_map_single,
|
||||
.unmap_single = pci_direct_unmap_single,
|
||||
.map_sg = pci_direct_map_sg,
|
||||
.unmap_sg = pci_direct_unmap_sg,
|
||||
.dma_supported = pci_direct_dma_supported,
|
||||
};
|
||||
|
||||
void __init pci_direct_iommu_init(void)
|
||||
{
|
||||
pci_dma_ops = pci_direct_ops;
|
||||
}
|
@ -1,164 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
|
||||
*
|
||||
* Rewrite, cleanup, new allocation schemes:
|
||||
* Copyright (C) 2004 Olof Johansson, IBM Corporation
|
||||
*
|
||||
* Dynamic DMA mapping support, platform-independent parts.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/iommu.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
/*
|
||||
* We can use ->sysdata directly and avoid the extra work in
|
||||
* pci_device_to_OF_node since ->sysdata will have been initialised
|
||||
* in the iommu init code for all devices.
|
||||
*/
|
||||
#define PCI_GET_DN(dev) ((struct device_node *)((dev)->sysdata))
|
||||
|
||||
static inline struct iommu_table *device_to_table(struct device *hwdev)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
|
||||
if (!hwdev) {
|
||||
pdev = ppc64_isabridge_dev;
|
||||
if (!pdev)
|
||||
return NULL;
|
||||
} else
|
||||
pdev = to_pci_dev(hwdev);
|
||||
|
||||
return PCI_DN(PCI_GET_DN(pdev))->iommu_table;
|
||||
}
|
||||
|
||||
|
||||
static inline unsigned long device_to_mask(struct device *hwdev)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
|
||||
if (!hwdev) {
|
||||
pdev = ppc64_isabridge_dev;
|
||||
if (!pdev) /* This is the best guess we can do */
|
||||
return 0xfffffffful;
|
||||
} else
|
||||
pdev = to_pci_dev(hwdev);
|
||||
|
||||
if (pdev->dma_mask)
|
||||
return pdev->dma_mask;
|
||||
|
||||
/* Assume devices without mask can take 32 bit addresses */
|
||||
return 0xfffffffful;
|
||||
}
|
||||
|
||||
|
||||
/* Allocates a contiguous real buffer and creates mappings over it.
|
||||
* Returns the virtual address of the buffer and sets dma_handle
|
||||
* to the dma address (mapping) of the first page.
|
||||
*/
|
||||
static void *pci_iommu_alloc_coherent(struct device *hwdev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t flag)
|
||||
{
|
||||
return iommu_alloc_coherent(device_to_table(hwdev), size, dma_handle,
|
||||
device_to_mask(hwdev), flag,
|
||||
pcibus_to_node(to_pci_dev(hwdev)->bus));
|
||||
}
|
||||
|
||||
static void pci_iommu_free_coherent(struct device *hwdev, size_t size,
|
||||
void *vaddr, dma_addr_t dma_handle)
|
||||
{
|
||||
iommu_free_coherent(device_to_table(hwdev), size, vaddr, dma_handle);
|
||||
}
|
||||
|
||||
/* Creates TCEs for a user provided buffer. The user buffer must be
|
||||
* contiguous real kernel storage (not vmalloc). The address of the buffer
|
||||
* passed here is the kernel (virtual) address of the buffer. The buffer
|
||||
* need not be page aligned, the dma_addr_t returned will point to the same
|
||||
* byte within the page as vaddr.
|
||||
*/
|
||||
static dma_addr_t pci_iommu_map_single(struct device *hwdev, void *vaddr,
|
||||
size_t size, enum dma_data_direction direction)
|
||||
{
|
||||
return iommu_map_single(device_to_table(hwdev), vaddr, size,
|
||||
device_to_mask(hwdev), direction);
|
||||
}
|
||||
|
||||
|
||||
static void pci_iommu_unmap_single(struct device *hwdev, dma_addr_t dma_handle,
|
||||
size_t size, enum dma_data_direction direction)
|
||||
{
|
||||
iommu_unmap_single(device_to_table(hwdev), dma_handle, size, direction);
|
||||
}
|
||||
|
||||
|
||||
static int pci_iommu_map_sg(struct device *pdev, struct scatterlist *sglist,
|
||||
int nelems, enum dma_data_direction direction)
|
||||
{
|
||||
return iommu_map_sg(pdev, device_to_table(pdev), sglist,
|
||||
nelems, device_to_mask(pdev), direction);
|
||||
}
|
||||
|
||||
static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist,
|
||||
int nelems, enum dma_data_direction direction)
|
||||
{
|
||||
iommu_unmap_sg(device_to_table(pdev), sglist, nelems, direction);
|
||||
}
|
||||
|
||||
/* We support DMA to/from any memory page via the iommu */
|
||||
static int pci_iommu_dma_supported(struct device *dev, u64 mask)
|
||||
{
|
||||
struct iommu_table *tbl = device_to_table(dev);
|
||||
|
||||
if (!tbl || tbl->it_offset > mask) {
|
||||
printk(KERN_INFO "Warning: IOMMU table offset too big for device mask\n");
|
||||
if (tbl)
|
||||
printk(KERN_INFO "mask: 0x%08lx, table offset: 0x%08lx\n",
|
||||
mask, tbl->it_offset);
|
||||
else
|
||||
printk(KERN_INFO "mask: 0x%08lx, table unavailable\n",
|
||||
mask);
|
||||
return 0;
|
||||
} else
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct dma_mapping_ops pci_iommu_ops = {
|
||||
.alloc_coherent = pci_iommu_alloc_coherent,
|
||||
.free_coherent = pci_iommu_free_coherent,
|
||||
.map_single = pci_iommu_map_single,
|
||||
.unmap_single = pci_iommu_unmap_single,
|
||||
.map_sg = pci_iommu_map_sg,
|
||||
.unmap_sg = pci_iommu_unmap_sg,
|
||||
.dma_supported = pci_iommu_dma_supported,
|
||||
};
|
||||
|
||||
void pci_iommu_init(void)
|
||||
{
|
||||
pci_dma_ops = pci_iommu_ops;
|
||||
}
|
@ -49,6 +49,10 @@
|
||||
#include <asm/commproc.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
EXPORT_SYMBOL(local_irq_restore);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC32
|
||||
extern void transfer_to_handler(void);
|
||||
extern void do_IRQ(struct pt_regs *regs);
|
||||
|
@ -538,35 +538,31 @@ static struct ibm_pa_feature {
|
||||
{CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0},
|
||||
};
|
||||
|
||||
static void __init check_cpu_pa_features(unsigned long node)
|
||||
static void __init scan_features(unsigned long node, unsigned char *ftrs,
|
||||
unsigned long tablelen,
|
||||
struct ibm_pa_feature *fp,
|
||||
unsigned long ft_size)
|
||||
{
|
||||
unsigned char *pa_ftrs;
|
||||
unsigned long len, tablelen, i, bit;
|
||||
|
||||
pa_ftrs = of_get_flat_dt_prop(node, "ibm,pa-features", &tablelen);
|
||||
if (pa_ftrs == NULL)
|
||||
return;
|
||||
unsigned long i, len, bit;
|
||||
|
||||
/* find descriptor with type == 0 */
|
||||
for (;;) {
|
||||
if (tablelen < 3)
|
||||
return;
|
||||
len = 2 + pa_ftrs[0];
|
||||
len = 2 + ftrs[0];
|
||||
if (tablelen < len)
|
||||
return; /* descriptor 0 not found */
|
||||
if (pa_ftrs[1] == 0)
|
||||
if (ftrs[1] == 0)
|
||||
break;
|
||||
tablelen -= len;
|
||||
pa_ftrs += len;
|
||||
ftrs += len;
|
||||
}
|
||||
|
||||
/* loop over bits we know about */
|
||||
for (i = 0; i < ARRAY_SIZE(ibm_pa_features); ++i) {
|
||||
struct ibm_pa_feature *fp = &ibm_pa_features[i];
|
||||
|
||||
if (fp->pabyte >= pa_ftrs[0])
|
||||
for (i = 0; i < ft_size; ++i, ++fp) {
|
||||
if (fp->pabyte >= ftrs[0])
|
||||
continue;
|
||||
bit = (pa_ftrs[2 + fp->pabyte] >> (7 - fp->pabit)) & 1;
|
||||
bit = (ftrs[2 + fp->pabyte] >> (7 - fp->pabit)) & 1;
|
||||
if (bit ^ fp->invert) {
|
||||
cur_cpu_spec->cpu_features |= fp->cpu_features;
|
||||
cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs;
|
||||
@ -577,16 +573,59 @@ static void __init check_cpu_pa_features(unsigned long node)
|
||||
}
|
||||
}
|
||||
|
||||
static void __init check_cpu_pa_features(unsigned long node)
|
||||
{
|
||||
unsigned char *pa_ftrs;
|
||||
unsigned long tablelen;
|
||||
|
||||
pa_ftrs = of_get_flat_dt_prop(node, "ibm,pa-features", &tablelen);
|
||||
if (pa_ftrs == NULL)
|
||||
return;
|
||||
|
||||
scan_features(node, pa_ftrs, tablelen,
|
||||
ibm_pa_features, ARRAY_SIZE(ibm_pa_features));
|
||||
}
|
||||
|
||||
static struct feature_property {
|
||||
const char *name;
|
||||
u32 min_value;
|
||||
unsigned long cpu_feature;
|
||||
unsigned long cpu_user_ftr;
|
||||
} feature_properties[] __initdata = {
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
{"altivec", 0, CPU_FTR_ALTIVEC, PPC_FEATURE_HAS_ALTIVEC},
|
||||
{"ibm,vmx", 1, CPU_FTR_ALTIVEC, PPC_FEATURE_HAS_ALTIVEC},
|
||||
#endif /* CONFIG_ALTIVEC */
|
||||
#ifdef CONFIG_PPC64
|
||||
{"ibm,dfp", 1, 0, PPC_FEATURE_HAS_DFP},
|
||||
{"ibm,purr", 1, CPU_FTR_PURR, 0},
|
||||
{"ibm,spurr", 1, CPU_FTR_SPURR, 0},
|
||||
#endif /* CONFIG_PPC64 */
|
||||
};
|
||||
|
||||
static void __init check_cpu_feature_properties(unsigned long node)
|
||||
{
|
||||
unsigned long i;
|
||||
struct feature_property *fp = feature_properties;
|
||||
const u32 *prop;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(feature_properties); ++i, ++fp) {
|
||||
prop = of_get_flat_dt_prop(node, fp->name, NULL);
|
||||
if (prop && *prop >= fp->min_value) {
|
||||
cur_cpu_spec->cpu_features |= fp->cpu_feature;
|
||||
cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int __init early_init_dt_scan_cpus(unsigned long node,
|
||||
const char *uname, int depth,
|
||||
void *data)
|
||||
{
|
||||
static int logical_cpuid = 0;
|
||||
char *type = of_get_flat_dt_prop(node, "device_type", NULL);
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
u32 *prop;
|
||||
#endif
|
||||
u32 *intserv;
|
||||
const u32 *prop;
|
||||
const u32 *intserv;
|
||||
int i, nthreads;
|
||||
unsigned long len;
|
||||
int found = 0;
|
||||
@ -643,24 +682,27 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
|
||||
intserv[i]);
|
||||
boot_cpuid = logical_cpuid;
|
||||
set_hard_smp_processor_id(boot_cpuid, intserv[i]);
|
||||
|
||||
/*
|
||||
* PAPR defines "logical" PVR values for cpus that
|
||||
* meet various levels of the architecture:
|
||||
* 0x0f000001 Architecture version 2.04
|
||||
* 0x0f000002 Architecture version 2.05
|
||||
* If the cpu-version property in the cpu node contains
|
||||
* such a value, we call identify_cpu again with the
|
||||
* logical PVR value in order to use the cpu feature
|
||||
* bits appropriate for the architecture level.
|
||||
*
|
||||
* A POWER6 partition in "POWER6 architected" mode
|
||||
* uses the 0x0f000002 PVR value; in POWER5+ mode
|
||||
* it uses 0x0f000001.
|
||||
*/
|
||||
prop = of_get_flat_dt_prop(node, "cpu-version", NULL);
|
||||
if (prop && (*prop & 0xff000000) == 0x0f000000)
|
||||
identify_cpu(0, *prop);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
/* Check if we have a VMX and eventually update CPU features */
|
||||
prop = (u32 *)of_get_flat_dt_prop(node, "ibm,vmx", NULL);
|
||||
if (prop && (*prop) > 0) {
|
||||
cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
|
||||
cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
|
||||
}
|
||||
|
||||
/* Same goes for Apple's "altivec" property */
|
||||
prop = (u32 *)of_get_flat_dt_prop(node, "altivec", NULL);
|
||||
if (prop) {
|
||||
cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
|
||||
cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
|
||||
}
|
||||
#endif /* CONFIG_ALTIVEC */
|
||||
|
||||
check_cpu_feature_properties(node);
|
||||
check_cpu_pa_features(node);
|
||||
|
||||
#ifdef CONFIG_PPC_PSERIES
|
||||
@ -1674,6 +1716,7 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_cpu_node);
|
||||
|
||||
#ifdef DEBUG
|
||||
static struct debugfs_blob_wrapper flat_dt_blob;
|
||||
|
@ -173,8 +173,8 @@ static unsigned long __initdata dt_string_start, dt_string_end;
|
||||
static unsigned long __initdata prom_initrd_start, prom_initrd_end;
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
static int __initdata iommu_force_on;
|
||||
static int __initdata ppc64_iommu_off;
|
||||
static int __initdata prom_iommu_force_on;
|
||||
static int __initdata prom_iommu_off;
|
||||
static unsigned long __initdata prom_tce_alloc_start;
|
||||
static unsigned long __initdata prom_tce_alloc_end;
|
||||
#endif
|
||||
@ -582,9 +582,9 @@ static void __init early_cmdline_parse(void)
|
||||
while (*opt && *opt == ' ')
|
||||
opt++;
|
||||
if (!strncmp(opt, RELOC("off"), 3))
|
||||
RELOC(ppc64_iommu_off) = 1;
|
||||
RELOC(prom_iommu_off) = 1;
|
||||
else if (!strncmp(opt, RELOC("force"), 5))
|
||||
RELOC(iommu_force_on) = 1;
|
||||
RELOC(prom_iommu_force_on) = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -627,6 +627,7 @@ static void __init early_cmdline_parse(void)
|
||||
/* Option vector 3: processor options supported */
|
||||
#define OV3_FP 0x80 /* floating point */
|
||||
#define OV3_VMX 0x40 /* VMX/Altivec */
|
||||
#define OV3_DFP 0x20 /* decimal FP */
|
||||
|
||||
/* Option vector 5: PAPR/OF options supported */
|
||||
#define OV5_LPAR 0x80 /* logical partitioning supported */
|
||||
@ -642,6 +643,7 @@ static void __init early_cmdline_parse(void)
|
||||
static unsigned char ibm_architecture_vec[] = {
|
||||
W(0xfffe0000), W(0x003a0000), /* POWER5/POWER5+ */
|
||||
W(0xffff0000), W(0x003e0000), /* POWER6 */
|
||||
W(0xffffffff), W(0x0f000002), /* all 2.05-compliant */
|
||||
W(0xfffffffe), W(0x0f000001), /* all 2.04-compliant and earlier */
|
||||
5 - 1, /* 5 option vectors */
|
||||
|
||||
@ -668,7 +670,7 @@ static unsigned char ibm_architecture_vec[] = {
|
||||
/* option vector 3: processor options supported */
|
||||
3 - 2, /* length */
|
||||
0, /* don't ignore, don't halt */
|
||||
OV3_FP | OV3_VMX,
|
||||
OV3_FP | OV3_VMX | OV3_DFP,
|
||||
|
||||
/* option vector 4: IBM PAPR implementation */
|
||||
2 - 2, /* length */
|
||||
@ -1167,7 +1169,7 @@ static void __init prom_initialize_tce_table(void)
|
||||
u64 local_alloc_top, local_alloc_bottom;
|
||||
u64 i;
|
||||
|
||||
if (RELOC(ppc64_iommu_off))
|
||||
if (RELOC(prom_iommu_off))
|
||||
return;
|
||||
|
||||
prom_debug("starting prom_initialize_tce_table\n");
|
||||
@ -2283,11 +2285,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
|
||||
* Fill in some infos for use by the kernel later on
|
||||
*/
|
||||
#ifdef CONFIG_PPC64
|
||||
if (RELOC(ppc64_iommu_off))
|
||||
if (RELOC(prom_iommu_off))
|
||||
prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off",
|
||||
NULL, 0);
|
||||
|
||||
if (RELOC(iommu_force_on))
|
||||
if (RELOC(prom_iommu_force_on))
|
||||
prom_setprop(_prom->chosen, "/chosen", "linux,iommu-force-on",
|
||||
NULL, 0);
|
||||
|
||||
|
@ -25,6 +25,12 @@
|
||||
#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
|
||||
(ns) > 0)
|
||||
|
||||
static struct of_bus *of_match_bus(struct device_node *np);
|
||||
static int __of_address_to_resource(struct device_node *dev,
|
||||
const u32 *addrp, u64 size, unsigned int flags,
|
||||
struct resource *r);
|
||||
|
||||
|
||||
/* Debug utility */
|
||||
#ifdef DEBUG
|
||||
static void of_dump_addr(const char *s, const u32 *addr, int na)
|
||||
@ -101,6 +107,7 @@ static unsigned int of_bus_default_get_flags(const u32 *addr)
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
/*
|
||||
* PCI bus specific translator
|
||||
*/
|
||||
@ -153,15 +160,156 @@ static unsigned int of_bus_pci_get_flags(const u32 *addr)
|
||||
switch((w >> 24) & 0x03) {
|
||||
case 0x01:
|
||||
flags |= IORESOURCE_IO;
|
||||
break;
|
||||
case 0x02: /* 32 bits */
|
||||
case 0x03: /* 64 bits */
|
||||
flags |= IORESOURCE_MEM;
|
||||
break;
|
||||
}
|
||||
if (w & 0x40000000)
|
||||
flags |= IORESOURCE_PREFETCH;
|
||||
return flags;
|
||||
}
|
||||
|
||||
const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
|
||||
unsigned int *flags)
|
||||
{
|
||||
const u32 *prop;
|
||||
unsigned int psize;
|
||||
struct device_node *parent;
|
||||
struct of_bus *bus;
|
||||
int onesize, i, na, ns;
|
||||
|
||||
/* Get parent & match bus type */
|
||||
parent = of_get_parent(dev);
|
||||
if (parent == NULL)
|
||||
return NULL;
|
||||
bus = of_match_bus(parent);
|
||||
if (strcmp(bus->name, "pci")) {
|
||||
of_node_put(parent);
|
||||
return NULL;
|
||||
}
|
||||
bus->count_cells(dev, &na, &ns);
|
||||
of_node_put(parent);
|
||||
if (!OF_CHECK_COUNTS(na, ns))
|
||||
return NULL;
|
||||
|
||||
/* Get "reg" or "assigned-addresses" property */
|
||||
prop = get_property(dev, bus->addresses, &psize);
|
||||
if (prop == NULL)
|
||||
return NULL;
|
||||
psize /= 4;
|
||||
|
||||
onesize = na + ns;
|
||||
for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
|
||||
if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
|
||||
if (size)
|
||||
*size = of_read_number(prop + na, ns);
|
||||
if (flags)
|
||||
*flags = bus->get_flags(prop);
|
||||
return prop;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_pci_address);
|
||||
|
||||
int of_pci_address_to_resource(struct device_node *dev, int bar,
|
||||
struct resource *r)
|
||||
{
|
||||
const u32 *addrp;
|
||||
u64 size;
|
||||
unsigned int flags;
|
||||
|
||||
addrp = of_get_pci_address(dev, bar, &size, &flags);
|
||||
if (addrp == NULL)
|
||||
return -EINVAL;
|
||||
return __of_address_to_resource(dev, addrp, size, flags, r);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
|
||||
|
||||
static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
|
||||
{
|
||||
return (((pin - 1) + slot) % 4) + 1;
|
||||
}
|
||||
|
||||
int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
|
||||
{
|
||||
struct device_node *dn, *ppnode;
|
||||
struct pci_dev *ppdev;
|
||||
u32 lspec;
|
||||
u32 laddr[3];
|
||||
u8 pin;
|
||||
int rc;
|
||||
|
||||
/* Check if we have a device node, if yes, fallback to standard OF
|
||||
* parsing
|
||||
*/
|
||||
dn = pci_device_to_OF_node(pdev);
|
||||
if (dn)
|
||||
return of_irq_map_one(dn, 0, out_irq);
|
||||
|
||||
/* Ok, we don't, time to have fun. Let's start by building up an
|
||||
* interrupt spec. we assume #interrupt-cells is 1, which is standard
|
||||
* for PCI. If you do different, then don't use that routine.
|
||||
*/
|
||||
rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
/* No pin, exit */
|
||||
if (pin == 0)
|
||||
return -ENODEV;
|
||||
|
||||
/* Now we walk up the PCI tree */
|
||||
lspec = pin;
|
||||
for (;;) {
|
||||
/* Get the pci_dev of our parent */
|
||||
ppdev = pdev->bus->self;
|
||||
|
||||
/* Ouch, it's a host bridge... */
|
||||
if (ppdev == NULL) {
|
||||
#ifdef CONFIG_PPC64
|
||||
ppnode = pci_bus_to_OF_node(pdev->bus);
|
||||
#else
|
||||
struct pci_controller *host;
|
||||
host = pci_bus_to_host(pdev->bus);
|
||||
ppnode = host ? host->arch_data : NULL;
|
||||
#endif
|
||||
/* No node for host bridge ? give up */
|
||||
if (ppnode == NULL)
|
||||
return -EINVAL;
|
||||
} else
|
||||
/* We found a P2P bridge, check if it has a node */
|
||||
ppnode = pci_device_to_OF_node(ppdev);
|
||||
|
||||
/* Ok, we have found a parent with a device-node, hand over to
|
||||
* the OF parsing code.
|
||||
* We build a unit address from the linux device to be used for
|
||||
* resolution. Note that we use the linux bus number which may
|
||||
* not match your firmware bus numbering.
|
||||
* Fortunately, in most cases, interrupt-map-mask doesn't include
|
||||
* the bus number as part of the matching.
|
||||
* You should still be careful about that though if you intend
|
||||
* to rely on this function (you ship a firmware that doesn't
|
||||
* create device nodes for all PCI devices).
|
||||
*/
|
||||
if (ppnode)
|
||||
break;
|
||||
|
||||
/* We can only get here if we hit a P2P bridge with no node,
|
||||
* let's do standard swizzling and try again
|
||||
*/
|
||||
lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec);
|
||||
pdev = ppdev;
|
||||
}
|
||||
|
||||
laddr[0] = (pdev->bus->number << 16)
|
||||
| (pdev->devfn << 8);
|
||||
laddr[1] = laddr[2] = 0;
|
||||
return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_irq_map_pci);
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
/*
|
||||
* ISA bus specific translator
|
||||
*/
|
||||
@ -223,6 +371,7 @@ static unsigned int of_bus_isa_get_flags(const u32 *addr)
|
||||
*/
|
||||
|
||||
static struct of_bus of_busses[] = {
|
||||
#ifdef CONFIG_PCI
|
||||
/* PCI */
|
||||
{
|
||||
.name = "pci",
|
||||
@ -233,6 +382,7 @@ static struct of_bus of_busses[] = {
|
||||
.translate = of_bus_pci_translate,
|
||||
.get_flags = of_bus_pci_get_flags,
|
||||
},
|
||||
#endif /* CONFIG_PCI */
|
||||
/* ISA */
|
||||
{
|
||||
.name = "isa",
|
||||
@ -445,48 +595,6 @@ const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_address);
|
||||
|
||||
const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
|
||||
unsigned int *flags)
|
||||
{
|
||||
const u32 *prop;
|
||||
unsigned int psize;
|
||||
struct device_node *parent;
|
||||
struct of_bus *bus;
|
||||
int onesize, i, na, ns;
|
||||
|
||||
/* Get parent & match bus type */
|
||||
parent = of_get_parent(dev);
|
||||
if (parent == NULL)
|
||||
return NULL;
|
||||
bus = of_match_bus(parent);
|
||||
if (strcmp(bus->name, "pci")) {
|
||||
of_node_put(parent);
|
||||
return NULL;
|
||||
}
|
||||
bus->count_cells(dev, &na, &ns);
|
||||
of_node_put(parent);
|
||||
if (!OF_CHECK_COUNTS(na, ns))
|
||||
return NULL;
|
||||
|
||||
/* Get "reg" or "assigned-addresses" property */
|
||||
prop = get_property(dev, bus->addresses, &psize);
|
||||
if (prop == NULL)
|
||||
return NULL;
|
||||
psize /= 4;
|
||||
|
||||
onesize = na + ns;
|
||||
for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
|
||||
if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
|
||||
if (size)
|
||||
*size = of_read_number(prop + na, ns);
|
||||
if (flags)
|
||||
*flags = bus->get_flags(prop);
|
||||
return prop;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_pci_address);
|
||||
|
||||
static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
|
||||
u64 size, unsigned int flags,
|
||||
struct resource *r)
|
||||
@ -529,20 +637,6 @@ int of_address_to_resource(struct device_node *dev, int index,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_address_to_resource);
|
||||
|
||||
int of_pci_address_to_resource(struct device_node *dev, int bar,
|
||||
struct resource *r)
|
||||
{
|
||||
const u32 *addrp;
|
||||
u64 size;
|
||||
unsigned int flags;
|
||||
|
||||
addrp = of_get_pci_address(dev, bar, &size, &flags);
|
||||
if (addrp == NULL)
|
||||
return -EINVAL;
|
||||
return __of_address_to_resource(dev, addrp, size, flags, r);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
|
||||
|
||||
void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
|
||||
unsigned long *busno, unsigned long *phys, unsigned long *size)
|
||||
{
|
||||
@ -898,87 +992,3 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_irq_map_one);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
|
||||
{
|
||||
return (((pin - 1) + slot) % 4) + 1;
|
||||
}
|
||||
|
||||
int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
|
||||
{
|
||||
struct device_node *dn, *ppnode;
|
||||
struct pci_dev *ppdev;
|
||||
u32 lspec;
|
||||
u32 laddr[3];
|
||||
u8 pin;
|
||||
int rc;
|
||||
|
||||
/* Check if we have a device node, if yes, fallback to standard OF
|
||||
* parsing
|
||||
*/
|
||||
dn = pci_device_to_OF_node(pdev);
|
||||
if (dn)
|
||||
return of_irq_map_one(dn, 0, out_irq);
|
||||
|
||||
/* Ok, we don't, time to have fun. Let's start by building up an
|
||||
* interrupt spec. we assume #interrupt-cells is 1, which is standard
|
||||
* for PCI. If you do different, then don't use that routine.
|
||||
*/
|
||||
rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
/* No pin, exit */
|
||||
if (pin == 0)
|
||||
return -ENODEV;
|
||||
|
||||
/* Now we walk up the PCI tree */
|
||||
lspec = pin;
|
||||
for (;;) {
|
||||
/* Get the pci_dev of our parent */
|
||||
ppdev = pdev->bus->self;
|
||||
|
||||
/* Ouch, it's a host bridge... */
|
||||
if (ppdev == NULL) {
|
||||
#ifdef CONFIG_PPC64
|
||||
ppnode = pci_bus_to_OF_node(pdev->bus);
|
||||
#else
|
||||
struct pci_controller *host;
|
||||
host = pci_bus_to_host(pdev->bus);
|
||||
ppnode = host ? host->arch_data : NULL;
|
||||
#endif
|
||||
/* No node for host bridge ? give up */
|
||||
if (ppnode == NULL)
|
||||
return -EINVAL;
|
||||
} else
|
||||
/* We found a P2P bridge, check if it has a node */
|
||||
ppnode = pci_device_to_OF_node(ppdev);
|
||||
|
||||
/* Ok, we have found a parent with a device-node, hand over to
|
||||
* the OF parsing code.
|
||||
* We build a unit address from the linux device to be used for
|
||||
* resolution. Note that we use the linux bus number which may
|
||||
* not match your firmware bus numbering.
|
||||
* Fortunately, in most cases, interrupt-map-mask doesn't include
|
||||
* the bus number as part of the matching.
|
||||
* You should still be careful about that though if you intend
|
||||
* to rely on this function (you ship a firmware that doesn't
|
||||
* create device nodes for all PCI devices).
|
||||
*/
|
||||
if (ppnode)
|
||||
break;
|
||||
|
||||
/* We can only get here if we hit a P2P bridge with no node,
|
||||
* let's do standard swizzling and try again
|
||||
*/
|
||||
lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec);
|
||||
pdev = ppdev;
|
||||
}
|
||||
|
||||
laddr[0] = (pdev->bus->number << 16)
|
||||
| (pdev->devfn << 8);
|
||||
laddr[1] = laddr[2] = 0;
|
||||
return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_irq_map_pci);
|
||||
#endif /* CONFIG_PCI */
|
||||
|
@ -810,9 +810,9 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
/* This version can't take the spinlock, because it never returns */
|
||||
|
||||
struct rtas_args rtas_stop_self_args = {
|
||||
static struct rtas_args rtas_stop_self_args = {
|
||||
/* The token is initialized for real in setup_system() */
|
||||
.token = RTAS_UNKNOWN_SERVICE,
|
||||
.nargs = 0,
|
||||
@ -834,6 +834,7 @@ void rtas_stop_self(void)
|
||||
|
||||
panic("Alas, I survived.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Call early during boot, before mem init or bootmem, to retrieve the RTAS
|
||||
|
@ -681,14 +681,12 @@ static int initialize_flash_pde_data(const char *rtas_call_name,
|
||||
int *status;
|
||||
int token;
|
||||
|
||||
dp->data = kmalloc(buf_size, GFP_KERNEL);
|
||||
dp->data = kzalloc(buf_size, GFP_KERNEL);
|
||||
if (dp->data == NULL) {
|
||||
remove_flash_pde(dp);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(dp->data, 0, buf_size);
|
||||
|
||||
/*
|
||||
* This code assumes that the status int is the first member of the
|
||||
* struct
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <asm/rtas.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <asm/ppc-pci.h>
|
||||
#include <asm/eeh.h>
|
||||
|
||||
/* RTAS tokens */
|
||||
static int read_pci_config;
|
||||
@ -231,32 +232,13 @@ void __init init_pci_config_tokens (void)
|
||||
|
||||
unsigned long __devinit get_phb_buid (struct device_node *phb)
|
||||
{
|
||||
int addr_cells;
|
||||
const unsigned int *buid_vals;
|
||||
unsigned int len;
|
||||
unsigned long buid;
|
||||
struct resource r;
|
||||
|
||||
if (ibm_read_pci_config == -1) return 0;
|
||||
|
||||
/* PHB's will always be children of the root node,
|
||||
* or so it is promised by the current firmware. */
|
||||
if (phb->parent == NULL)
|
||||
if (ibm_read_pci_config == -1)
|
||||
return 0;
|
||||
if (phb->parent->parent)
|
||||
if (of_address_to_resource(phb, 0, &r))
|
||||
return 0;
|
||||
|
||||
buid_vals = get_property(phb, "reg", &len);
|
||||
if (buid_vals == NULL)
|
||||
return 0;
|
||||
|
||||
addr_cells = prom_n_addr_cells(phb);
|
||||
if (addr_cells == 1) {
|
||||
buid = (unsigned long) buid_vals[0];
|
||||
} else {
|
||||
buid = (((unsigned long)buid_vals[0]) << 32UL) |
|
||||
(((unsigned long)buid_vals[1]) & 0xffffffff);
|
||||
}
|
||||
return buid;
|
||||
return r.start;
|
||||
}
|
||||
|
||||
static int phb_set_bus_ranges(struct device_node *dev,
|
||||
@ -276,8 +258,10 @@ static int phb_set_bus_ranges(struct device_node *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __devinit setup_phb(struct device_node *dev, struct pci_controller *phb)
|
||||
int __devinit rtas_setup_phb(struct pci_controller *phb)
|
||||
{
|
||||
struct device_node *dev = phb->arch_data;
|
||||
|
||||
if (is_python(dev))
|
||||
python_countermeasures(dev);
|
||||
|
||||
@ -309,7 +293,7 @@ unsigned long __init find_and_init_phbs(void)
|
||||
phb = pcibios_alloc_controller(node);
|
||||
if (!phb)
|
||||
continue;
|
||||
setup_phb(node, phb);
|
||||
rtas_setup_phb(phb);
|
||||
pci_process_bridge_OF_ranges(phb, node, 0);
|
||||
pci_setup_phb_io(phb, index == 0);
|
||||
index++;
|
||||
@ -381,7 +365,6 @@ int pcibios_remove_root_bus(struct pci_controller *phb)
|
||||
}
|
||||
}
|
||||
|
||||
list_del(&phb->list_node);
|
||||
pcibios_free_controller(phb);
|
||||
|
||||
return 0;
|
||||
|
@ -63,10 +63,6 @@ unsigned int DMA_MODE_WRITE;
|
||||
|
||||
int have_of = 1;
|
||||
|
||||
#ifdef CONFIG_PPC_MULTIPLATFORM
|
||||
dev_t boot_dev;
|
||||
#endif /* CONFIG_PPC_MULTIPLATFORM */
|
||||
|
||||
#ifdef CONFIG_VGA_CONSOLE
|
||||
unsigned long vgacon_remap_base;
|
||||
#endif
|
||||
@ -101,7 +97,7 @@ unsigned long __init early_init(unsigned long dt_ptr)
|
||||
* Identify the CPU type and fix up code sections
|
||||
* that depend on which cpu we have.
|
||||
*/
|
||||
spec = identify_cpu(offset);
|
||||
spec = identify_cpu(offset, mfspr(SPRN_PVR));
|
||||
|
||||
do_feature_fixups(spec->cpu_features,
|
||||
PTRRELOC(&__start___ftr_fixup),
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/pci.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/kdump.h>
|
||||
#include <asm/prom.h>
|
||||
@ -71,7 +72,6 @@
|
||||
|
||||
int have_of = 1;
|
||||
int boot_cpuid = 0;
|
||||
dev_t boot_dev;
|
||||
u64 ppc64_pft_size;
|
||||
|
||||
/* Pick defaults since we might want to patch instructions
|
||||
@ -171,7 +171,7 @@ void __init setup_paca(int cpu)
|
||||
void __init early_setup(unsigned long dt_ptr)
|
||||
{
|
||||
/* Identify CPU type */
|
||||
identify_cpu(0);
|
||||
identify_cpu(0, mfspr(SPRN_PVR));
|
||||
|
||||
/* Assume we're on cpu 0 for now. Don't write to the paca yet! */
|
||||
setup_paca(0);
|
||||
@ -226,8 +226,8 @@ void early_setup_secondary(void)
|
||||
{
|
||||
struct paca_struct *lpaca = get_paca();
|
||||
|
||||
/* Mark enabled in PACA */
|
||||
lpaca->proc_enabled = 0;
|
||||
/* Mark interrupts enabled in PACA */
|
||||
lpaca->soft_enabled = 0;
|
||||
|
||||
/* Initialize hash table for that CPU */
|
||||
htab_initialize_secondary();
|
||||
@ -392,7 +392,8 @@ void __init setup_system(void)
|
||||
* setting up the hash table pointers. It also sets up some interrupt-mapping
|
||||
* related options that will be used by finish_device_tree()
|
||||
*/
|
||||
ppc_md.init_early();
|
||||
if (ppc_md.init_early)
|
||||
ppc_md.init_early();
|
||||
|
||||
/*
|
||||
* We can discover serial ports now since the above did setup the
|
||||
@ -598,3 +599,10 @@ void __init setup_per_cpu_areas(void)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_PPC_INDIRECT_IO
|
||||
struct ppc_pci_io ppc_pci_io;
|
||||
EXPORT_SYMBOL(ppc_pci_io);
|
||||
#endif /* CONFIG_PPC_INDIRECT_IO */
|
||||
|
||||
|
@ -78,7 +78,7 @@ static int __devinit start_contest(int cmd, long offset, int num)
|
||||
{
|
||||
int i, score=0;
|
||||
u64 tb;
|
||||
long mark;
|
||||
u64 mark;
|
||||
|
||||
tbsync->cmd = cmd;
|
||||
|
||||
@ -116,8 +116,7 @@ void __devinit smp_generic_give_timebase(void)
|
||||
printk("Synchronizing timebase\n");
|
||||
|
||||
/* if this fails then this kernel won't work anyway... */
|
||||
tbsync = kmalloc( sizeof(*tbsync), GFP_KERNEL );
|
||||
memset( tbsync, 0, sizeof(*tbsync) );
|
||||
tbsync = kzalloc( sizeof(*tbsync), GFP_KERNEL );
|
||||
mb();
|
||||
running = 1;
|
||||
|
||||
|
@ -65,6 +65,7 @@ cpumask_t cpu_sibling_map[NR_CPUS] = { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
|
||||
|
||||
EXPORT_SYMBOL(cpu_online_map);
|
||||
EXPORT_SYMBOL(cpu_possible_map);
|
||||
EXPORT_SYMBOL(cpu_sibling_map);
|
||||
|
||||
/* SMP operations for this machine */
|
||||
struct smp_ops_t *smp_ops;
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include <asm/time.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/ppc-pci.h>
|
||||
#include <asm/syscalls.h>
|
||||
|
||||
/* readdir & getdents */
|
||||
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
|
||||
|
@ -200,10 +200,9 @@ static void register_cpu_online(unsigned int cpu)
|
||||
struct cpu *c = &per_cpu(cpu_devices, cpu);
|
||||
struct sys_device *s = &c->sysdev;
|
||||
|
||||
#ifndef CONFIG_PPC_ISERIES
|
||||
if (cpu_has_feature(CPU_FTR_SMT))
|
||||
if (!firmware_has_feature(FW_FEATURE_ISERIES) &&
|
||||
cpu_has_feature(CPU_FTR_SMT))
|
||||
sysdev_create_file(s, &attr_smt_snooze_delay);
|
||||
#endif
|
||||
|
||||
/* PMC stuff */
|
||||
|
||||
@ -242,10 +241,9 @@ static void unregister_cpu_online(unsigned int cpu)
|
||||
|
||||
BUG_ON(c->no_control);
|
||||
|
||||
#ifndef CONFIG_PPC_ISERIES
|
||||
if (cpu_has_feature(CPU_FTR_SMT))
|
||||
if (!firmware_has_feature(FW_FEATURE_ISERIES) &&
|
||||
cpu_has_feature(CPU_FTR_SMT))
|
||||
sysdev_remove_file(s, &attr_smt_snooze_delay);
|
||||
#endif
|
||||
|
||||
/* PMC stuff */
|
||||
|
||||
@ -299,6 +297,72 @@ static struct notifier_block __cpuinitdata sysfs_cpu_nb = {
|
||||
.notifier_call = sysfs_cpu_notify,
|
||||
};
|
||||
|
||||
static DEFINE_MUTEX(cpu_mutex);
|
||||
|
||||
int cpu_add_sysdev_attr(struct sysdev_attribute *attr)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
mutex_lock(&cpu_mutex);
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
sysdev_create_file(get_cpu_sysdev(cpu), attr);
|
||||
}
|
||||
|
||||
mutex_unlock(&cpu_mutex);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpu_add_sysdev_attr);
|
||||
|
||||
int cpu_add_sysdev_attr_group(struct attribute_group *attrs)
|
||||
{
|
||||
int cpu;
|
||||
struct sys_device *sysdev;
|
||||
|
||||
mutex_lock(&cpu_mutex);
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
sysdev = get_cpu_sysdev(cpu);
|
||||
sysfs_create_group(&sysdev->kobj, attrs);
|
||||
}
|
||||
|
||||
mutex_unlock(&cpu_mutex);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpu_add_sysdev_attr_group);
|
||||
|
||||
|
||||
void cpu_remove_sysdev_attr(struct sysdev_attribute *attr)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
mutex_lock(&cpu_mutex);
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
sysdev_remove_file(get_cpu_sysdev(cpu), attr);
|
||||
}
|
||||
|
||||
mutex_unlock(&cpu_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpu_remove_sysdev_attr);
|
||||
|
||||
void cpu_remove_sysdev_attr_group(struct attribute_group *attrs)
|
||||
{
|
||||
int cpu;
|
||||
struct sys_device *sysdev;
|
||||
|
||||
mutex_lock(&cpu_mutex);
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
sysdev = get_cpu_sysdev(cpu);
|
||||
sysfs_remove_group(&sysdev->kobj, attrs);
|
||||
}
|
||||
|
||||
mutex_unlock(&cpu_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpu_remove_sysdev_attr_group);
|
||||
|
||||
|
||||
/* NUMA stuff */
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
|
@ -631,7 +631,8 @@ void timer_interrupt(struct pt_regs * regs)
|
||||
calculate_steal_time();
|
||||
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
get_lppaca()->int_dword.fields.decr_int = 0;
|
||||
if (firmware_has_feature(FW_FEATURE_ISERIES))
|
||||
get_lppaca()->int_dword.fields.decr_int = 0;
|
||||
#endif
|
||||
|
||||
while ((ticks = tb_ticks_since(per_cpu(last_jiffy, cpu)))
|
||||
@ -674,7 +675,7 @@ void timer_interrupt(struct pt_regs * regs)
|
||||
set_dec(next_dec);
|
||||
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
if (hvlpevent_is_pending())
|
||||
if (firmware_has_feature(FW_FEATURE_ISERIES) && hvlpevent_is_pending())
|
||||
process_hvlpevents();
|
||||
#endif
|
||||
|
||||
@ -774,7 +775,7 @@ int do_settimeofday(struct timespec *tv)
|
||||
* settimeofday to perform this operation.
|
||||
*/
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
if (first_settimeofday) {
|
||||
if (firmware_has_feature(FW_FEATURE_ISERIES) && first_settimeofday) {
|
||||
iSeries_tb_recal();
|
||||
first_settimeofday = 0;
|
||||
}
|
||||
|
@ -53,10 +53,6 @@
|
||||
#endif
|
||||
#include <asm/kexec.h>
|
||||
|
||||
#ifdef CONFIG_PPC64 /* XXX */
|
||||
#define _IO_BASE pci_io_base
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUGGER
|
||||
int (*__debugger)(struct pt_regs *regs);
|
||||
int (*__debugger_ipi)(struct pt_regs *regs);
|
||||
@ -241,7 +237,7 @@ void system_reset_exception(struct pt_regs *regs)
|
||||
*/
|
||||
static inline int check_io_access(struct pt_regs *regs)
|
||||
{
|
||||
#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
|
||||
#ifdef CONFIG_PPC32
|
||||
unsigned long msr = regs->msr;
|
||||
const struct exception_table_entry *entry;
|
||||
unsigned int *nip = (unsigned int *)regs->nip;
|
||||
@ -274,7 +270,7 @@ static inline int check_io_access(struct pt_regs *regs)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_PPC_PMAC && CONFIG_PPC32 */
|
||||
#endif /* CONFIG_PPC32 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -81,15 +81,15 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
|
||||
struct iommu_table *tbl;
|
||||
unsigned long offset, size;
|
||||
|
||||
dma_window = get_property(dev->dev.platform_data,
|
||||
"ibm,my-dma-window", NULL);
|
||||
dma_window = get_property(dev->dev.archdata.of_node,
|
||||
"ibm,my-dma-window", NULL);
|
||||
if (!dma_window)
|
||||
return NULL;
|
||||
|
||||
tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
|
||||
|
||||
of_parse_dma_window(dev->dev.platform_data, dma_window,
|
||||
&tbl->it_index, &offset, &size);
|
||||
of_parse_dma_window(dev->dev.archdata.of_node, dma_window,
|
||||
&tbl->it_index, &offset, &size);
|
||||
|
||||
/* TCE table size - measured in tce entries */
|
||||
tbl->it_size = size >> IOMMU_PAGE_SHIFT;
|
||||
@ -117,7 +117,8 @@ static const struct vio_device_id *vio_match_device(
|
||||
{
|
||||
while (ids->type[0] != '\0') {
|
||||
if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) &&
|
||||
device_is_compatible(dev->dev.platform_data, ids->compat))
|
||||
device_is_compatible(dev->dev.archdata.of_node,
|
||||
ids->compat))
|
||||
return ids;
|
||||
ids++;
|
||||
}
|
||||
@ -198,9 +199,9 @@ EXPORT_SYMBOL(vio_unregister_driver);
|
||||
/* vio_dev refcount hit 0 */
|
||||
static void __devinit vio_dev_release(struct device *dev)
|
||||
{
|
||||
if (dev->platform_data) {
|
||||
/* XXX free TCE table */
|
||||
of_node_put(dev->platform_data);
|
||||
if (dev->archdata.of_node) {
|
||||
/* XXX should free TCE table */
|
||||
of_node_put(dev->archdata.of_node);
|
||||
}
|
||||
kfree(to_vio_dev(dev));
|
||||
}
|
||||
@ -210,7 +211,7 @@ static void __devinit vio_dev_release(struct device *dev)
|
||||
* @of_node: The OF node for this device.
|
||||
*
|
||||
* Creates and initializes a vio_dev structure from the data in
|
||||
* of_node (dev.platform_data) and adds it to the list of virtual devices.
|
||||
* of_node and adds it to the list of virtual devices.
|
||||
* Returns a pointer to the created vio_dev or NULL if node has
|
||||
* NULL device_type or compatible fields.
|
||||
*/
|
||||
@ -240,8 +241,6 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
|
||||
if (viodev == NULL)
|
||||
return NULL;
|
||||
|
||||
viodev->dev.platform_data = of_node_get(of_node);
|
||||
|
||||
viodev->irq = irq_of_parse_and_map(of_node, 0);
|
||||
|
||||
snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address);
|
||||
@ -254,7 +253,10 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
|
||||
if (unit_address != NULL)
|
||||
viodev->unit_address = *unit_address;
|
||||
}
|
||||
viodev->iommu_table = vio_build_iommu_table(viodev);
|
||||
viodev->dev.archdata.of_node = of_node_get(of_node);
|
||||
viodev->dev.archdata.dma_ops = &dma_iommu_ops;
|
||||
viodev->dev.archdata.dma_data = vio_build_iommu_table(viodev);
|
||||
viodev->dev.archdata.numa_node = of_node_to_nid(of_node);
|
||||
|
||||
/* init generic 'struct device' fields: */
|
||||
viodev->dev.parent = &vio_bus_device.dev;
|
||||
@ -285,10 +287,11 @@ static int __init vio_bus_init(void)
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
if (firmware_has_feature(FW_FEATURE_ISERIES)) {
|
||||
iommu_vio_init();
|
||||
vio_bus_device.iommu_table = &vio_iommu_table;
|
||||
vio_bus_device.dev.archdata.dma_ops = &dma_iommu_ops;
|
||||
vio_bus_device.dev.archdata.dma_data = &vio_iommu_table;
|
||||
iSeries_vio_dev = &vio_bus_device.dev;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_PPC_ISERIES */
|
||||
|
||||
err = bus_register(&vio_bus_type);
|
||||
if (err) {
|
||||
@ -336,7 +339,7 @@ static ssize_t name_show(struct device *dev,
|
||||
static ssize_t devspec_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct device_node *of_node = dev->platform_data;
|
||||
struct device_node *of_node = dev->archdata.of_node;
|
||||
|
||||
return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none");
|
||||
}
|
||||
@ -353,62 +356,6 @@ void __devinit vio_unregister_device(struct vio_dev *viodev)
|
||||
}
|
||||
EXPORT_SYMBOL(vio_unregister_device);
|
||||
|
||||
static dma_addr_t vio_map_single(struct device *dev, void *vaddr,
|
||||
size_t size, enum dma_data_direction direction)
|
||||
{
|
||||
return iommu_map_single(to_vio_dev(dev)->iommu_table, vaddr, size,
|
||||
~0ul, direction);
|
||||
}
|
||||
|
||||
static void vio_unmap_single(struct device *dev, dma_addr_t dma_handle,
|
||||
size_t size, enum dma_data_direction direction)
|
||||
{
|
||||
iommu_unmap_single(to_vio_dev(dev)->iommu_table, dma_handle, size,
|
||||
direction);
|
||||
}
|
||||
|
||||
static int vio_map_sg(struct device *dev, struct scatterlist *sglist,
|
||||
int nelems, enum dma_data_direction direction)
|
||||
{
|
||||
return iommu_map_sg(dev, to_vio_dev(dev)->iommu_table, sglist,
|
||||
nelems, ~0ul, direction);
|
||||
}
|
||||
|
||||
static void vio_unmap_sg(struct device *dev, struct scatterlist *sglist,
|
||||
int nelems, enum dma_data_direction direction)
|
||||
{
|
||||
iommu_unmap_sg(to_vio_dev(dev)->iommu_table, sglist, nelems, direction);
|
||||
}
|
||||
|
||||
static void *vio_alloc_coherent(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t flag)
|
||||
{
|
||||
return iommu_alloc_coherent(to_vio_dev(dev)->iommu_table, size,
|
||||
dma_handle, ~0ul, flag, -1);
|
||||
}
|
||||
|
||||
static void vio_free_coherent(struct device *dev, size_t size,
|
||||
void *vaddr, dma_addr_t dma_handle)
|
||||
{
|
||||
iommu_free_coherent(to_vio_dev(dev)->iommu_table, size, vaddr,
|
||||
dma_handle);
|
||||
}
|
||||
|
||||
static int vio_dma_supported(struct device *dev, u64 mask)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct dma_mapping_ops vio_dma_ops = {
|
||||
.alloc_coherent = vio_alloc_coherent,
|
||||
.free_coherent = vio_free_coherent,
|
||||
.map_single = vio_map_single,
|
||||
.unmap_single = vio_unmap_single,
|
||||
.map_sg = vio_map_sg,
|
||||
.unmap_sg = vio_unmap_sg,
|
||||
.dma_supported = vio_dma_supported,
|
||||
};
|
||||
|
||||
static int vio_bus_match(struct device *dev, struct device_driver *drv)
|
||||
{
|
||||
const struct vio_dev *vio_dev = to_vio_dev(dev);
|
||||
@ -422,13 +369,14 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
{
|
||||
const struct vio_dev *vio_dev = to_vio_dev(dev);
|
||||
struct device_node *dn = dev->platform_data;
|
||||
struct device_node *dn;
|
||||
const char *cp;
|
||||
int length;
|
||||
|
||||
if (!num_envp)
|
||||
return -ENOMEM;
|
||||
|
||||
dn = dev->archdata.of_node;
|
||||
if (!dn)
|
||||
return -ENODEV;
|
||||
cp = get_property(dn, "compatible", &length);
|
||||
@ -465,7 +413,7 @@ struct bus_type vio_bus_type = {
|
||||
*/
|
||||
const void *vio_get_attribute(struct vio_dev *vdev, char *which, int *length)
|
||||
{
|
||||
return get_property(vdev->dev.platform_data, which, length);
|
||||
return get_property(vdev->dev.archdata.of_node, which, length);
|
||||
}
|
||||
EXPORT_SYMBOL(vio_get_attribute);
|
||||
|
||||
|
@ -8,7 +8,7 @@ endif
|
||||
|
||||
obj-y := fault.o mem.o lmb.o
|
||||
obj-$(CONFIG_PPC32) += init_32.o pgtable_32.o mmu_context_32.o
|
||||
hash-$(CONFIG_PPC_MULTIPLATFORM) := hash_native_64.o
|
||||
hash-$(CONFIG_PPC_NATIVE) := hash_native_64.o
|
||||
obj-$(CONFIG_PPC64) += init_64.o pgtable_64.o mmu_context_64.o \
|
||||
hash_utils_64.o hash_low_64.o tlb_64.o \
|
||||
slb_low.o slb.o stab.o mmap.o imalloc.o \
|
||||
|
@ -426,18 +426,21 @@ void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
|
||||
|
||||
/* kernel has accessed a bad area */
|
||||
|
||||
printk(KERN_ALERT "Unable to handle kernel paging request for ");
|
||||
switch (regs->trap) {
|
||||
case 0x300:
|
||||
case 0x380:
|
||||
printk("data at address 0x%08lx\n", regs->dar);
|
||||
break;
|
||||
case 0x400:
|
||||
case 0x480:
|
||||
printk("instruction fetch\n");
|
||||
break;
|
||||
default:
|
||||
printk("unknown fault\n");
|
||||
case 0x300:
|
||||
case 0x380:
|
||||
printk(KERN_ALERT "Unable to handle kernel paging request for "
|
||||
"data at address 0x%08lx\n", regs->dar);
|
||||
break;
|
||||
case 0x400:
|
||||
case 0x480:
|
||||
printk(KERN_ALERT "Unable to handle kernel paging request for "
|
||||
"instruction fetch\n");
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ALERT "Unable to handle kernel paging request for "
|
||||
"unknown fault\n");
|
||||
break;
|
||||
}
|
||||
printk(KERN_ALERT "Faulting instruction address: 0x%08lx\n",
|
||||
regs->nip);
|
||||
|
@ -123,7 +123,7 @@ static inline void native_unlock_hpte(hpte_t *hptep)
|
||||
clear_bit(HPTE_LOCK_BIT, word);
|
||||
}
|
||||
|
||||
long native_hpte_insert(unsigned long hpte_group, unsigned long va,
|
||||
static long native_hpte_insert(unsigned long hpte_group, unsigned long va,
|
||||
unsigned long pa, unsigned long rflags,
|
||||
unsigned long vflags, int psize)
|
||||
{
|
||||
|
@ -277,7 +277,7 @@ static void __init htab_init_page_sizes(void)
|
||||
* Not in the device-tree, let's fallback on known size
|
||||
* list for 16M capable GP & GR
|
||||
*/
|
||||
if (cpu_has_feature(CPU_FTR_16M_PAGE) && !machine_is(iseries))
|
||||
if (cpu_has_feature(CPU_FTR_16M_PAGE))
|
||||
memcpy(mmu_psize_defs, mmu_psize_defaults_gp,
|
||||
sizeof(mmu_psize_defaults_gp));
|
||||
found:
|
||||
|
@ -130,7 +130,7 @@ static int __init setup_kcore(void)
|
||||
/* GFP_ATOMIC to avoid might_sleep warnings during boot */
|
||||
kcore_mem = kmalloc(sizeof(struct kcore_list), GFP_ATOMIC);
|
||||
if (!kcore_mem)
|
||||
panic("mem_init: kmalloc failed\n");
|
||||
panic("%s: kmalloc failed\n", __FUNCTION__);
|
||||
|
||||
kclist_add(kcore_mem, __va(base), size);
|
||||
}
|
||||
|
@ -141,30 +141,20 @@ void pte_free(struct page *ptepage)
|
||||
__free_page(ptepage);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_PHYS_64BIT
|
||||
void __iomem *
|
||||
ioremap(phys_addr_t addr, unsigned long size)
|
||||
{
|
||||
return __ioremap(addr, size, _PAGE_NO_CACHE);
|
||||
}
|
||||
#else /* CONFIG_PHYS_64BIT */
|
||||
void __iomem *
|
||||
ioremap64(unsigned long long addr, unsigned long size)
|
||||
{
|
||||
return __ioremap(addr, size, _PAGE_NO_CACHE);
|
||||
}
|
||||
EXPORT_SYMBOL(ioremap64);
|
||||
|
||||
void __iomem *
|
||||
ioremap(phys_addr_t addr, unsigned long size)
|
||||
{
|
||||
phys_addr_t addr64 = fixup_bigphys_addr(addr, size);
|
||||
|
||||
return ioremap64(addr64, size);
|
||||
}
|
||||
#endif /* CONFIG_PHYS_64BIT */
|
||||
EXPORT_SYMBOL(ioremap);
|
||||
|
||||
void __iomem *
|
||||
ioremap_flags(phys_addr_t addr, unsigned long size, unsigned long flags)
|
||||
{
|
||||
return __ioremap(addr, size, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(ioremap_flags);
|
||||
|
||||
void __iomem *
|
||||
__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
|
||||
{
|
||||
@ -264,20 +254,7 @@ void iounmap(volatile void __iomem *addr)
|
||||
}
|
||||
EXPORT_SYMBOL(iounmap);
|
||||
|
||||
void __iomem *ioport_map(unsigned long port, unsigned int len)
|
||||
{
|
||||
return (void __iomem *) (port + _IO_BASE);
|
||||
}
|
||||
|
||||
void ioport_unmap(void __iomem *addr)
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
EXPORT_SYMBOL(ioport_map);
|
||||
EXPORT_SYMBOL(ioport_unmap);
|
||||
|
||||
int
|
||||
map_page(unsigned long va, phys_addr_t pa, int flags)
|
||||
int map_page(unsigned long va, phys_addr_t pa, int flags)
|
||||
{
|
||||
pmd_t *pd;
|
||||
pte_t *pg;
|
||||
|
@ -113,7 +113,7 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags)
|
||||
}
|
||||
|
||||
|
||||
static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa,
|
||||
static void __iomem * __ioremap_com(phys_addr_t addr, unsigned long pa,
|
||||
unsigned long ea, unsigned long size,
|
||||
unsigned long flags)
|
||||
{
|
||||
@ -129,22 +129,12 @@ static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa,
|
||||
return (void __iomem *) (ea + (addr & ~PAGE_MASK));
|
||||
}
|
||||
|
||||
|
||||
void __iomem *
|
||||
ioremap(unsigned long addr, unsigned long size)
|
||||
{
|
||||
return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED);
|
||||
}
|
||||
|
||||
void __iomem * __ioremap(unsigned long addr, unsigned long size,
|
||||
void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
|
||||
unsigned long flags)
|
||||
{
|
||||
unsigned long pa, ea;
|
||||
void __iomem *ret;
|
||||
|
||||
if (firmware_has_feature(FW_FEATURE_ISERIES))
|
||||
return (void __iomem *)addr;
|
||||
|
||||
/*
|
||||
* Choose an address to map it to.
|
||||
* Once the imalloc system is running, we use it.
|
||||
@ -178,9 +168,28 @@ void __iomem * __ioremap(unsigned long addr, unsigned long size,
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void __iomem * ioremap(phys_addr_t addr, unsigned long size)
|
||||
{
|
||||
unsigned long flags = _PAGE_NO_CACHE | _PAGE_GUARDED;
|
||||
|
||||
if (ppc_md.ioremap)
|
||||
return ppc_md.ioremap(addr, size, flags);
|
||||
return __ioremap(addr, size, flags);
|
||||
}
|
||||
|
||||
void __iomem * ioremap_flags(phys_addr_t addr, unsigned long size,
|
||||
unsigned long flags)
|
||||
{
|
||||
if (ppc_md.ioremap)
|
||||
return ppc_md.ioremap(addr, size, flags);
|
||||
return __ioremap(addr, size, flags);
|
||||
}
|
||||
|
||||
|
||||
#define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK))
|
||||
|
||||
int __ioremap_explicit(unsigned long pa, unsigned long ea,
|
||||
int __ioremap_explicit(phys_addr_t pa, unsigned long ea,
|
||||
unsigned long size, unsigned long flags)
|
||||
{
|
||||
struct vm_struct *area;
|
||||
@ -235,13 +244,10 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea,
|
||||
*
|
||||
* XXX what about calls before mem_init_done (ie python_countermeasures())
|
||||
*/
|
||||
void iounmap(volatile void __iomem *token)
|
||||
void __iounmap(volatile void __iomem *token)
|
||||
{
|
||||
void *addr;
|
||||
|
||||
if (firmware_has_feature(FW_FEATURE_ISERIES))
|
||||
return;
|
||||
|
||||
if (!mem_init_done)
|
||||
return;
|
||||
|
||||
@ -250,6 +256,14 @@ void iounmap(volatile void __iomem *token)
|
||||
im_free(addr);
|
||||
}
|
||||
|
||||
void iounmap(volatile void __iomem *token)
|
||||
{
|
||||
if (ppc_md.iounmap)
|
||||
ppc_md.iounmap(token);
|
||||
else
|
||||
__iounmap(token);
|
||||
}
|
||||
|
||||
static int iounmap_subset_regions(unsigned long addr, unsigned long size)
|
||||
{
|
||||
struct vm_struct *area;
|
||||
@ -268,7 +282,7 @@ static int iounmap_subset_regions(unsigned long addr, unsigned long size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iounmap_explicit(volatile void __iomem *start, unsigned long size)
|
||||
int __iounmap_explicit(volatile void __iomem *start, unsigned long size)
|
||||
{
|
||||
struct vm_struct *area;
|
||||
unsigned long addr;
|
||||
@ -303,8 +317,10 @@ int iounmap_explicit(volatile void __iomem *start, unsigned long size)
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(ioremap);
|
||||
EXPORT_SYMBOL(ioremap_flags);
|
||||
EXPORT_SYMBOL(__ioremap);
|
||||
EXPORT_SYMBOL(iounmap);
|
||||
EXPORT_SYMBOL(__iounmap);
|
||||
|
||||
void __iomem * reserve_phb_iospace(unsigned long size)
|
||||
{
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <asm/cputable.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/firmware.h>
|
||||
#include <linux/compiler.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -193,6 +194,7 @@ static inline void patch_slb_encoding(unsigned int *insn_addr,
|
||||
void slb_initialize(void)
|
||||
{
|
||||
unsigned long linear_llp, vmalloc_llp, io_llp;
|
||||
unsigned long lflags, vflags;
|
||||
static int slb_encoding_inited;
|
||||
extern unsigned int *slb_miss_kernel_load_linear;
|
||||
extern unsigned int *slb_miss_kernel_load_io;
|
||||
@ -225,11 +227,12 @@ void slb_initialize(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
get_paca()->stab_rr = SLB_NUM_BOLTED;
|
||||
|
||||
/* On iSeries the bolted entries have already been set up by
|
||||
* the hypervisor from the lparMap data in head.S */
|
||||
#ifndef CONFIG_PPC_ISERIES
|
||||
{
|
||||
unsigned long lflags, vflags;
|
||||
if (firmware_has_feature(FW_FEATURE_ISERIES))
|
||||
return;
|
||||
|
||||
lflags = SLB_VSID_KERNEL | linear_llp;
|
||||
vflags = SLB_VSID_KERNEL | vmalloc_llp;
|
||||
@ -247,8 +250,4 @@ void slb_initialize(void)
|
||||
* elsewhere, we'll call _switch() which will bolt in the new
|
||||
* one. */
|
||||
asm volatile("isync":::"memory");
|
||||
}
|
||||
#endif /* CONFIG_PPC_ISERIES */
|
||||
|
||||
get_paca()->stab_rr = SLB_NUM_BOLTED;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
|
||||
timer_int.o )
|
||||
|
||||
oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
|
||||
oprofile-$(CONFIG_PPC_CELL_NATIVE) += op_model_cell.o
|
||||
oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o
|
||||
oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
|
||||
oprofile-$(CONFIG_6xx) += op_model_7450.o
|
||||
|
@ -69,7 +69,10 @@ static void op_powerpc_cpu_start(void *dummy)
|
||||
|
||||
static int op_powerpc_start(void)
|
||||
{
|
||||
on_each_cpu(op_powerpc_cpu_start, NULL, 0, 1);
|
||||
if (model->global_start)
|
||||
model->global_start(ctr);
|
||||
if (model->start)
|
||||
on_each_cpu(op_powerpc_cpu_start, NULL, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -80,7 +83,10 @@ static inline void op_powerpc_cpu_stop(void *dummy)
|
||||
|
||||
static void op_powerpc_stop(void)
|
||||
{
|
||||
on_each_cpu(op_powerpc_cpu_stop, NULL, 0, 1);
|
||||
if (model->stop)
|
||||
on_each_cpu(op_powerpc_cpu_stop, NULL, 0, 1);
|
||||
if (model->global_stop)
|
||||
model->global_stop();
|
||||
}
|
||||
|
||||
static int op_powerpc_create_files(struct super_block *sb, struct dentry *root)
|
||||
@ -141,6 +147,11 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
|
||||
|
||||
switch (cur_cpu_spec->oprofile_type) {
|
||||
#ifdef CONFIG_PPC64
|
||||
#ifdef CONFIG_PPC_CELL_NATIVE
|
||||
case PPC_OPROFILE_CELL:
|
||||
model = &op_model_cell;
|
||||
break;
|
||||
#endif
|
||||
case PPC_OPROFILE_RS64:
|
||||
model = &op_model_rs64;
|
||||
break;
|
||||
|
724
arch/powerpc/oprofile/op_model_cell.c
Normal file
724
arch/powerpc/oprofile/op_model_cell.c
Normal file
@ -0,0 +1,724 @@
|
||||
/*
|
||||
* Cell Broadband Engine OProfile Support
|
||||
*
|
||||
* (C) Copyright IBM Corporation 2006
|
||||
*
|
||||
* Author: David Erb (djerb@us.ibm.com)
|
||||
* Modifications:
|
||||
* Carl Love <carll@us.ibm.com>
|
||||
* Maynard Johnson <maynardj@us.ibm.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/oprofile.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/timer.h>
|
||||
#include <asm/cell-pmu.h>
|
||||
#include <asm/cputable.h>
|
||||
#include <asm/firmware.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/oprofile_impl.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/reg.h>
|
||||
#include <asm/rtas.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#include "../platforms/cell/interrupt.h"
|
||||
|
||||
#define PPU_CYCLES_EVENT_NUM 1 /* event number for CYCLES */
|
||||
#define CBE_COUNT_ALL_CYCLES 0x42800000 /* PPU cycle event specifier */
|
||||
|
||||
#define NUM_THREADS 2
|
||||
#define VIRT_CNTR_SW_TIME_NS 100000000 // 0.5 seconds
|
||||
|
||||
struct pmc_cntrl_data {
|
||||
unsigned long vcntr;
|
||||
unsigned long evnts;
|
||||
unsigned long masks;
|
||||
unsigned long enabled;
|
||||
};
|
||||
|
||||
/*
|
||||
* ibm,cbe-perftools rtas parameters
|
||||
*/
|
||||
|
||||
struct pm_signal {
|
||||
u16 cpu; /* Processor to modify */
|
||||
u16 sub_unit; /* hw subunit this applies to (if applicable) */
|
||||
u16 signal_group; /* Signal Group to Enable/Disable */
|
||||
u8 bus_word; /* Enable/Disable on this Trace/Trigger/Event
|
||||
* Bus Word(s) (bitmask)
|
||||
*/
|
||||
u8 bit; /* Trigger/Event bit (if applicable) */
|
||||
};
|
||||
|
||||
/*
|
||||
* rtas call arguments
|
||||
*/
|
||||
enum {
|
||||
SUBFUNC_RESET = 1,
|
||||
SUBFUNC_ACTIVATE = 2,
|
||||
SUBFUNC_DEACTIVATE = 3,
|
||||
|
||||
PASSTHRU_IGNORE = 0,
|
||||
PASSTHRU_ENABLE = 1,
|
||||
PASSTHRU_DISABLE = 2,
|
||||
};
|
||||
|
||||
struct pm_cntrl {
|
||||
u16 enable;
|
||||
u16 stop_at_max;
|
||||
u16 trace_mode;
|
||||
u16 freeze;
|
||||
u16 count_mode;
|
||||
};
|
||||
|
||||
static struct {
|
||||
u32 group_control;
|
||||
u32 debug_bus_control;
|
||||
struct pm_cntrl pm_cntrl;
|
||||
u32 pm07_cntrl[NR_PHYS_CTRS];
|
||||
} pm_regs;
|
||||
|
||||
|
||||
#define GET_SUB_UNIT(x) ((x & 0x0000f000) >> 12)
|
||||
#define GET_BUS_WORD(x) ((x & 0x000000f0) >> 4)
|
||||
#define GET_BUS_TYPE(x) ((x & 0x00000300) >> 8)
|
||||
#define GET_POLARITY(x) ((x & 0x00000002) >> 1)
|
||||
#define GET_COUNT_CYCLES(x) (x & 0x00000001)
|
||||
#define GET_INPUT_CONTROL(x) ((x & 0x00000004) >> 2)
|
||||
|
||||
|
||||
static DEFINE_PER_CPU(unsigned long[NR_PHYS_CTRS], pmc_values);
|
||||
|
||||
static struct pmc_cntrl_data pmc_cntrl[NUM_THREADS][NR_PHYS_CTRS];
|
||||
|
||||
/* Interpetation of hdw_thread:
|
||||
* 0 - even virtual cpus 0, 2, 4,...
|
||||
* 1 - odd virtual cpus 1, 3, 5, ...
|
||||
*/
|
||||
static u32 hdw_thread;
|
||||
|
||||
static u32 virt_cntr_inter_mask;
|
||||
static struct timer_list timer_virt_cntr;
|
||||
|
||||
/* pm_signal needs to be global since it is initialized in
|
||||
* cell_reg_setup at the time when the necessary information
|
||||
* is available.
|
||||
*/
|
||||
static struct pm_signal pm_signal[NR_PHYS_CTRS];
|
||||
static int pm_rtas_token;
|
||||
|
||||
static u32 reset_value[NR_PHYS_CTRS];
|
||||
static int num_counters;
|
||||
static int oprofile_running;
|
||||
static spinlock_t virt_cntr_lock = SPIN_LOCK_UNLOCKED;
|
||||
|
||||
static u32 ctr_enabled;
|
||||
|
||||
static unsigned char trace_bus[4];
|
||||
static unsigned char input_bus[2];
|
||||
|
||||
/*
|
||||
* Firmware interface functions
|
||||
*/
|
||||
static int
|
||||
rtas_ibm_cbe_perftools(int subfunc, int passthru,
|
||||
void *address, unsigned long length)
|
||||
{
|
||||
u64 paddr = __pa(address);
|
||||
|
||||
return rtas_call(pm_rtas_token, 5, 1, NULL, subfunc, passthru,
|
||||
paddr >> 32, paddr & 0xffffffff, length);
|
||||
}
|
||||
|
||||
static void pm_rtas_reset_signals(u32 node)
|
||||
{
|
||||
int ret;
|
||||
struct pm_signal pm_signal_local;
|
||||
|
||||
/* The debug bus is being set to the passthru disable state.
|
||||
* However, the FW still expects atleast one legal signal routing
|
||||
* entry or it will return an error on the arguments. If we don't
|
||||
* supply a valid entry, we must ignore all return values. Ignoring
|
||||
* all return values means we might miss an error we should be
|
||||
* concerned about.
|
||||
*/
|
||||
|
||||
/* fw expects physical cpu #. */
|
||||
pm_signal_local.cpu = node;
|
||||
pm_signal_local.signal_group = 21;
|
||||
pm_signal_local.bus_word = 1;
|
||||
pm_signal_local.sub_unit = 0;
|
||||
pm_signal_local.bit = 0;
|
||||
|
||||
ret = rtas_ibm_cbe_perftools(SUBFUNC_RESET, PASSTHRU_DISABLE,
|
||||
&pm_signal_local,
|
||||
sizeof(struct pm_signal));
|
||||
|
||||
if (ret)
|
||||
printk(KERN_WARNING "%s: rtas returned: %d\n",
|
||||
__FUNCTION__, ret);
|
||||
}
|
||||
|
||||
static void pm_rtas_activate_signals(u32 node, u32 count)
|
||||
{
|
||||
int ret;
|
||||
int j;
|
||||
struct pm_signal pm_signal_local[NR_PHYS_CTRS];
|
||||
|
||||
for (j = 0; j < count; j++) {
|
||||
/* fw expects physical cpu # */
|
||||
pm_signal_local[j].cpu = node;
|
||||
pm_signal_local[j].signal_group = pm_signal[j].signal_group;
|
||||
pm_signal_local[j].bus_word = pm_signal[j].bus_word;
|
||||
pm_signal_local[j].sub_unit = pm_signal[j].sub_unit;
|
||||
pm_signal_local[j].bit = pm_signal[j].bit;
|
||||
}
|
||||
|
||||
ret = rtas_ibm_cbe_perftools(SUBFUNC_ACTIVATE, PASSTHRU_ENABLE,
|
||||
pm_signal_local,
|
||||
count * sizeof(struct pm_signal));
|
||||
|
||||
if (ret)
|
||||
printk(KERN_WARNING "%s: rtas returned: %d\n",
|
||||
__FUNCTION__, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* PM Signal functions
|
||||
*/
|
||||
static void set_pm_event(u32 ctr, int event, u32 unit_mask)
|
||||
{
|
||||
struct pm_signal *p;
|
||||
u32 signal_bit;
|
||||
u32 bus_word, bus_type, count_cycles, polarity, input_control;
|
||||
int j, i;
|
||||
|
||||
if (event == PPU_CYCLES_EVENT_NUM) {
|
||||
/* Special Event: Count all cpu cycles */
|
||||
pm_regs.pm07_cntrl[ctr] = CBE_COUNT_ALL_CYCLES;
|
||||
p = &(pm_signal[ctr]);
|
||||
p->signal_group = 21;
|
||||
p->bus_word = 1;
|
||||
p->sub_unit = 0;
|
||||
p->bit = 0;
|
||||
goto out;
|
||||
} else {
|
||||
pm_regs.pm07_cntrl[ctr] = 0;
|
||||
}
|
||||
|
||||
bus_word = GET_BUS_WORD(unit_mask);
|
||||
bus_type = GET_BUS_TYPE(unit_mask);
|
||||
count_cycles = GET_COUNT_CYCLES(unit_mask);
|
||||
polarity = GET_POLARITY(unit_mask);
|
||||
input_control = GET_INPUT_CONTROL(unit_mask);
|
||||
signal_bit = (event % 100);
|
||||
|
||||
p = &(pm_signal[ctr]);
|
||||
|
||||
p->signal_group = event / 100;
|
||||
p->bus_word = bus_word;
|
||||
p->sub_unit = unit_mask & 0x0000f000;
|
||||
|
||||
pm_regs.pm07_cntrl[ctr] = 0;
|
||||
pm_regs.pm07_cntrl[ctr] |= PM07_CTR_COUNT_CYCLES(count_cycles);
|
||||
pm_regs.pm07_cntrl[ctr] |= PM07_CTR_POLARITY(polarity);
|
||||
pm_regs.pm07_cntrl[ctr] |= PM07_CTR_INPUT_CONTROL(input_control);
|
||||
|
||||
if (input_control == 0) {
|
||||
if (signal_bit > 31) {
|
||||
signal_bit -= 32;
|
||||
if (bus_word == 0x3)
|
||||
bus_word = 0x2;
|
||||
else if (bus_word == 0xc)
|
||||
bus_word = 0x8;
|
||||
}
|
||||
|
||||
if ((bus_type == 0) && p->signal_group >= 60)
|
||||
bus_type = 2;
|
||||
if ((bus_type == 1) && p->signal_group >= 50)
|
||||
bus_type = 0;
|
||||
|
||||
pm_regs.pm07_cntrl[ctr] |= PM07_CTR_INPUT_MUX(signal_bit);
|
||||
} else {
|
||||
pm_regs.pm07_cntrl[ctr] = 0;
|
||||
p->bit = signal_bit;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (bus_word & (1 << i)) {
|
||||
pm_regs.debug_bus_control |=
|
||||
(bus_type << (31 - (2 * i) + 1));
|
||||
|
||||
for (j = 0; j < 2; j++) {
|
||||
if (input_bus[j] == 0xff) {
|
||||
input_bus[j] = i;
|
||||
pm_regs.group_control |=
|
||||
(i << (31 - i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
out:
|
||||
;
|
||||
}
|
||||
|
||||
static void write_pm_cntrl(int cpu, struct pm_cntrl *pm_cntrl)
|
||||
{
|
||||
/* Oprofile will use 32 bit counters, set bits 7:10 to 0 */
|
||||
u32 val = 0;
|
||||
if (pm_cntrl->enable == 1)
|
||||
val |= CBE_PM_ENABLE_PERF_MON;
|
||||
|
||||
if (pm_cntrl->stop_at_max == 1)
|
||||
val |= CBE_PM_STOP_AT_MAX;
|
||||
|
||||
if (pm_cntrl->trace_mode == 1)
|
||||
val |= CBE_PM_TRACE_MODE_SET(pm_cntrl->trace_mode);
|
||||
|
||||
if (pm_cntrl->freeze == 1)
|
||||
val |= CBE_PM_FREEZE_ALL_CTRS;
|
||||
|
||||
/* Routine set_count_mode must be called previously to set
|
||||
* the count mode based on the user selection of user and kernel.
|
||||
*/
|
||||
val |= CBE_PM_COUNT_MODE_SET(pm_cntrl->count_mode);
|
||||
cbe_write_pm(cpu, pm_control, val);
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_count_mode(u32 kernel, u32 user, struct pm_cntrl *pm_cntrl)
|
||||
{
|
||||
/* The user must specify user and kernel if they want them. If
|
||||
* neither is specified, OProfile will count in hypervisor mode
|
||||
*/
|
||||
if (kernel) {
|
||||
if (user)
|
||||
pm_cntrl->count_mode = CBE_COUNT_ALL_MODES;
|
||||
else
|
||||
pm_cntrl->count_mode = CBE_COUNT_SUPERVISOR_MODE;
|
||||
} else {
|
||||
if (user)
|
||||
pm_cntrl->count_mode = CBE_COUNT_PROBLEM_MODE;
|
||||
else
|
||||
pm_cntrl->count_mode = CBE_COUNT_HYPERVISOR_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void enable_ctr(u32 cpu, u32 ctr, u32 * pm07_cntrl)
|
||||
{
|
||||
|
||||
pm07_cntrl[ctr] |= PM07_CTR_ENABLE(1);
|
||||
cbe_write_pm07_control(cpu, ctr, pm07_cntrl[ctr]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Oprofile is expected to collect data on all CPUs simultaneously.
|
||||
* However, there is one set of performance counters per node. There are
|
||||
* two hardware threads or virtual CPUs on each node. Hence, OProfile must
|
||||
* multiplex in time the performance counter collection on the two virtual
|
||||
* CPUs. The multiplexing of the performance counters is done by this
|
||||
* virtual counter routine.
|
||||
*
|
||||
* The pmc_values used below is defined as 'per-cpu' but its use is
|
||||
* more akin to 'per-node'. We need to store two sets of counter
|
||||
* values per node -- one for the previous run and one for the next.
|
||||
* The per-cpu[NR_PHYS_CTRS] gives us the storage we need. Each odd/even
|
||||
* pair of per-cpu arrays is used for storing the previous and next
|
||||
* pmc values for a given node.
|
||||
* NOTE: We use the per-cpu variable to improve cache performance.
|
||||
*/
|
||||
static void cell_virtual_cntr(unsigned long data)
|
||||
{
|
||||
/* This routine will alternate loading the virtual counters for
|
||||
* virtual CPUs
|
||||
*/
|
||||
int i, prev_hdw_thread, next_hdw_thread;
|
||||
u32 cpu;
|
||||
unsigned long flags;
|
||||
|
||||
/* Make sure that the interrupt_hander and
|
||||
* the virt counter are not both playing with
|
||||
* the counters on the same node.
|
||||
*/
|
||||
|
||||
spin_lock_irqsave(&virt_cntr_lock, flags);
|
||||
|
||||
prev_hdw_thread = hdw_thread;
|
||||
|
||||
/* switch the cpu handling the interrupts */
|
||||
hdw_thread = 1 ^ hdw_thread;
|
||||
next_hdw_thread = hdw_thread;
|
||||
|
||||
/* The following is done only once per each node, but
|
||||
* we need cpu #, not node #, to pass to the cbe_xxx functions.
|
||||
*/
|
||||
for_each_online_cpu(cpu) {
|
||||
if (cbe_get_hw_thread_id(cpu))
|
||||
continue;
|
||||
|
||||
/* stop counters, save counter values, restore counts
|
||||
* for previous thread
|
||||
*/
|
||||
cbe_disable_pm(cpu);
|
||||
cbe_disable_pm_interrupts(cpu);
|
||||
for (i = 0; i < num_counters; i++) {
|
||||
per_cpu(pmc_values, cpu + prev_hdw_thread)[i]
|
||||
= cbe_read_ctr(cpu, i);
|
||||
|
||||
if (per_cpu(pmc_values, cpu + next_hdw_thread)[i]
|
||||
== 0xFFFFFFFF)
|
||||
/* If the cntr value is 0xffffffff, we must
|
||||
* reset that to 0xfffffff0 when the current
|
||||
* thread is restarted. This will generate a new
|
||||
* interrupt and make sure that we never restore
|
||||
* the counters to the max value. If the counters
|
||||
* were restored to the max value, they do not
|
||||
* increment and no interrupts are generated. Hence
|
||||
* no more samples will be collected on that cpu.
|
||||
*/
|
||||
cbe_write_ctr(cpu, i, 0xFFFFFFF0);
|
||||
else
|
||||
cbe_write_ctr(cpu, i,
|
||||
per_cpu(pmc_values,
|
||||
cpu +
|
||||
next_hdw_thread)[i]);
|
||||
}
|
||||
|
||||
/* Switch to the other thread. Change the interrupt
|
||||
* and control regs to be scheduled on the CPU
|
||||
* corresponding to the thread to execute.
|
||||
*/
|
||||
for (i = 0; i < num_counters; i++) {
|
||||
if (pmc_cntrl[next_hdw_thread][i].enabled) {
|
||||
/* There are some per thread events.
|
||||
* Must do the set event, enable_cntr
|
||||
* for each cpu.
|
||||
*/
|
||||
set_pm_event(i,
|
||||
pmc_cntrl[next_hdw_thread][i].evnts,
|
||||
pmc_cntrl[next_hdw_thread][i].masks);
|
||||
enable_ctr(cpu, i,
|
||||
pm_regs.pm07_cntrl);
|
||||
} else {
|
||||
cbe_write_pm07_control(cpu, i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable interrupts on the CPU thread that is starting */
|
||||
cbe_enable_pm_interrupts(cpu, next_hdw_thread,
|
||||
virt_cntr_inter_mask);
|
||||
cbe_enable_pm(cpu);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&virt_cntr_lock, flags);
|
||||
|
||||
mod_timer(&timer_virt_cntr, jiffies + HZ / 10);
|
||||
}
|
||||
|
||||
static void start_virt_cntrs(void)
|
||||
{
|
||||
init_timer(&timer_virt_cntr);
|
||||
timer_virt_cntr.function = cell_virtual_cntr;
|
||||
timer_virt_cntr.data = 0UL;
|
||||
timer_virt_cntr.expires = jiffies + HZ / 10;
|
||||
add_timer(&timer_virt_cntr);
|
||||
}
|
||||
|
||||
/* This function is called once for all cpus combined */
|
||||
static void
|
||||
cell_reg_setup(struct op_counter_config *ctr,
|
||||
struct op_system_config *sys, int num_ctrs)
|
||||
{
|
||||
int i, j, cpu;
|
||||
|
||||
pm_rtas_token = rtas_token("ibm,cbe-perftools");
|
||||
if (pm_rtas_token == RTAS_UNKNOWN_SERVICE) {
|
||||
printk(KERN_WARNING "%s: RTAS_UNKNOWN_SERVICE\n",
|
||||
__FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
num_counters = num_ctrs;
|
||||
|
||||
pm_regs.group_control = 0;
|
||||
pm_regs.debug_bus_control = 0;
|
||||
|
||||
/* setup the pm_control register */
|
||||
memset(&pm_regs.pm_cntrl, 0, sizeof(struct pm_cntrl));
|
||||
pm_regs.pm_cntrl.stop_at_max = 1;
|
||||
pm_regs.pm_cntrl.trace_mode = 0;
|
||||
pm_regs.pm_cntrl.freeze = 1;
|
||||
|
||||
set_count_mode(sys->enable_kernel, sys->enable_user,
|
||||
&pm_regs.pm_cntrl);
|
||||
|
||||
/* Setup the thread 0 events */
|
||||
for (i = 0; i < num_ctrs; ++i) {
|
||||
|
||||
pmc_cntrl[0][i].evnts = ctr[i].event;
|
||||
pmc_cntrl[0][i].masks = ctr[i].unit_mask;
|
||||
pmc_cntrl[0][i].enabled = ctr[i].enabled;
|
||||
pmc_cntrl[0][i].vcntr = i;
|
||||
|
||||
for_each_possible_cpu(j)
|
||||
per_cpu(pmc_values, j)[i] = 0;
|
||||
}
|
||||
|
||||
/* Setup the thread 1 events, map the thread 0 event to the
|
||||
* equivalent thread 1 event.
|
||||
*/
|
||||
for (i = 0; i < num_ctrs; ++i) {
|
||||
if ((ctr[i].event >= 2100) && (ctr[i].event <= 2111))
|
||||
pmc_cntrl[1][i].evnts = ctr[i].event + 19;
|
||||
else if (ctr[i].event == 2203)
|
||||
pmc_cntrl[1][i].evnts = ctr[i].event;
|
||||
else if ((ctr[i].event >= 2200) && (ctr[i].event <= 2215))
|
||||
pmc_cntrl[1][i].evnts = ctr[i].event + 16;
|
||||
else
|
||||
pmc_cntrl[1][i].evnts = ctr[i].event;
|
||||
|
||||
pmc_cntrl[1][i].masks = ctr[i].unit_mask;
|
||||
pmc_cntrl[1][i].enabled = ctr[i].enabled;
|
||||
pmc_cntrl[1][i].vcntr = i;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
trace_bus[i] = 0xff;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
input_bus[i] = 0xff;
|
||||
|
||||
/* Our counters count up, and "count" refers to
|
||||
* how much before the next interrupt, and we interrupt
|
||||
* on overflow. So we calculate the starting value
|
||||
* which will give us "count" until overflow.
|
||||
* Then we set the events on the enabled counters.
|
||||
*/
|
||||
for (i = 0; i < num_counters; ++i) {
|
||||
/* start with virtual counter set 0 */
|
||||
if (pmc_cntrl[0][i].enabled) {
|
||||
/* Using 32bit counters, reset max - count */
|
||||
reset_value[i] = 0xFFFFFFFF - ctr[i].count;
|
||||
set_pm_event(i,
|
||||
pmc_cntrl[0][i].evnts,
|
||||
pmc_cntrl[0][i].masks);
|
||||
|
||||
/* global, used by cell_cpu_setup */
|
||||
ctr_enabled |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize the previous counts for the virtual cntrs */
|
||||
for_each_online_cpu(cpu)
|
||||
for (i = 0; i < num_counters; ++i) {
|
||||
per_cpu(pmc_values, cpu)[i] = reset_value[i];
|
||||
}
|
||||
out:
|
||||
;
|
||||
}
|
||||
|
||||
/* This function is called once for each cpu */
|
||||
static void cell_cpu_setup(struct op_counter_config *cntr)
|
||||
{
|
||||
u32 cpu = smp_processor_id();
|
||||
u32 num_enabled = 0;
|
||||
int i;
|
||||
|
||||
/* There is one performance monitor per processor chip (i.e. node),
|
||||
* so we only need to perform this function once per node.
|
||||
*/
|
||||
if (cbe_get_hw_thread_id(cpu))
|
||||
goto out;
|
||||
|
||||
if (pm_rtas_token == RTAS_UNKNOWN_SERVICE) {
|
||||
printk(KERN_WARNING "%s: RTAS_UNKNOWN_SERVICE\n",
|
||||
__FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Stop all counters */
|
||||
cbe_disable_pm(cpu);
|
||||
cbe_disable_pm_interrupts(cpu);
|
||||
|
||||
cbe_write_pm(cpu, pm_interval, 0);
|
||||
cbe_write_pm(cpu, pm_start_stop, 0);
|
||||
cbe_write_pm(cpu, group_control, pm_regs.group_control);
|
||||
cbe_write_pm(cpu, debug_bus_control, pm_regs.debug_bus_control);
|
||||
write_pm_cntrl(cpu, &pm_regs.pm_cntrl);
|
||||
|
||||
for (i = 0; i < num_counters; ++i) {
|
||||
if (ctr_enabled & (1 << i)) {
|
||||
pm_signal[num_enabled].cpu = cbe_cpu_to_node(cpu);
|
||||
num_enabled++;
|
||||
}
|
||||
}
|
||||
|
||||
pm_rtas_activate_signals(cbe_cpu_to_node(cpu), num_enabled);
|
||||
out:
|
||||
;
|
||||
}
|
||||
|
||||
static void cell_global_start(struct op_counter_config *ctr)
|
||||
{
|
||||
u32 cpu;
|
||||
u32 interrupt_mask = 0;
|
||||
u32 i;
|
||||
|
||||
/* This routine gets called once for the system.
|
||||
* There is one performance monitor per node, so we
|
||||
* only need to perform this function once per node.
|
||||
*/
|
||||
for_each_online_cpu(cpu) {
|
||||
if (cbe_get_hw_thread_id(cpu))
|
||||
continue;
|
||||
|
||||
interrupt_mask = 0;
|
||||
|
||||
for (i = 0; i < num_counters; ++i) {
|
||||
if (ctr_enabled & (1 << i)) {
|
||||
cbe_write_ctr(cpu, i, reset_value[i]);
|
||||
enable_ctr(cpu, i, pm_regs.pm07_cntrl);
|
||||
interrupt_mask |=
|
||||
CBE_PM_CTR_OVERFLOW_INTR(i);
|
||||
} else {
|
||||
/* Disable counter */
|
||||
cbe_write_pm07_control(cpu, i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
cbe_clear_pm_interrupts(cpu);
|
||||
cbe_enable_pm_interrupts(cpu, hdw_thread, interrupt_mask);
|
||||
cbe_enable_pm(cpu);
|
||||
}
|
||||
|
||||
virt_cntr_inter_mask = interrupt_mask;
|
||||
oprofile_running = 1;
|
||||
smp_wmb();
|
||||
|
||||
/* NOTE: start_virt_cntrs will result in cell_virtual_cntr() being
|
||||
* executed which manipulates the PMU. We start the "virtual counter"
|
||||
* here so that we do not need to synchronize access to the PMU in
|
||||
* the above for-loop.
|
||||
*/
|
||||
start_virt_cntrs();
|
||||
}
|
||||
|
||||
static void cell_global_stop(void)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
/* This routine will be called once for the system.
|
||||
* There is one performance monitor per node, so we
|
||||
* only need to perform this function once per node.
|
||||
*/
|
||||
del_timer_sync(&timer_virt_cntr);
|
||||
oprofile_running = 0;
|
||||
smp_wmb();
|
||||
|
||||
for_each_online_cpu(cpu) {
|
||||
if (cbe_get_hw_thread_id(cpu))
|
||||
continue;
|
||||
|
||||
cbe_sync_irq(cbe_cpu_to_node(cpu));
|
||||
/* Stop the counters */
|
||||
cbe_disable_pm(cpu);
|
||||
|
||||
/* Deactivate the signals */
|
||||
pm_rtas_reset_signals(cbe_cpu_to_node(cpu));
|
||||
|
||||
/* Deactivate interrupts */
|
||||
cbe_disable_pm_interrupts(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cell_handle_interrupt(struct pt_regs *regs, struct op_counter_config *ctr)
|
||||
{
|
||||
u32 cpu;
|
||||
u64 pc;
|
||||
int is_kernel;
|
||||
unsigned long flags = 0;
|
||||
u32 interrupt_mask;
|
||||
int i;
|
||||
|
||||
cpu = smp_processor_id();
|
||||
|
||||
/* Need to make sure the interrupt handler and the virt counter
|
||||
* routine are not running at the same time. See the
|
||||
* cell_virtual_cntr() routine for additional comments.
|
||||
*/
|
||||
spin_lock_irqsave(&virt_cntr_lock, flags);
|
||||
|
||||
/* Need to disable and reenable the performance counters
|
||||
* to get the desired behavior from the hardware. This
|
||||
* is hardware specific.
|
||||
*/
|
||||
|
||||
cbe_disable_pm(cpu);
|
||||
|
||||
interrupt_mask = cbe_clear_pm_interrupts(cpu);
|
||||
|
||||
/* If the interrupt mask has been cleared, then the virt cntr
|
||||
* has cleared the interrupt. When the thread that generated
|
||||
* the interrupt is restored, the data count will be restored to
|
||||
* 0xffffff0 to cause the interrupt to be regenerated.
|
||||
*/
|
||||
|
||||
if ((oprofile_running == 1) && (interrupt_mask != 0)) {
|
||||
pc = regs->nip;
|
||||
is_kernel = is_kernel_addr(pc);
|
||||
|
||||
for (i = 0; i < num_counters; ++i) {
|
||||
if ((interrupt_mask & CBE_PM_CTR_OVERFLOW_INTR(i))
|
||||
&& ctr[i].enabled) {
|
||||
oprofile_add_pc(pc, is_kernel, i);
|
||||
cbe_write_ctr(cpu, i, reset_value[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* The counters were frozen by the interrupt.
|
||||
* Reenable the interrupt and restart the counters.
|
||||
* If there was a race between the interrupt handler and
|
||||
* the virtual counter routine. The virutal counter
|
||||
* routine may have cleared the interrupts. Hence must
|
||||
* use the virt_cntr_inter_mask to re-enable the interrupts.
|
||||
*/
|
||||
cbe_enable_pm_interrupts(cpu, hdw_thread,
|
||||
virt_cntr_inter_mask);
|
||||
|
||||
/* The writes to the various performance counters only writes
|
||||
* to a latch. The new values (interrupt setting bits, reset
|
||||
* counter value etc.) are not copied to the actual registers
|
||||
* until the performance monitor is enabled. In order to get
|
||||
* this to work as desired, the permormance monitor needs to
|
||||
* be disabled while writting to the latches. This is a
|
||||
* HW design issue.
|
||||
*/
|
||||
cbe_enable_pm(cpu);
|
||||
}
|
||||
spin_unlock_irqrestore(&virt_cntr_lock, flags);
|
||||
}
|
||||
|
||||
struct op_powerpc_model op_model_cell = {
|
||||
.reg_setup = cell_reg_setup,
|
||||
.cpu_setup = cell_cpu_setup,
|
||||
.global_start = cell_global_start,
|
||||
.global_stop = cell_global_stop,
|
||||
.handle_interrupt = cell_handle_interrupt,
|
||||
};
|
9
arch/powerpc/platforms/52xx/Makefile
Normal file
9
arch/powerpc/platforms/52xx/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
#
|
||||
# Makefile for 52xx based boards
|
||||
#
|
||||
ifeq ($(CONFIG_PPC_MERGE),y)
|
||||
obj-y += mpc52xx_pic.o mpc52xx_common.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_PPC_EFIKA) += efika-setup.o efika-pci.o
|
||||
obj-$(CONFIG_PPC_LITE5200) += lite5200.o
|
119
arch/powerpc/platforms/52xx/efika-pci.c
Normal file
119
arch/powerpc/platforms/52xx/efika-pci.c
Normal file
@ -0,0 +1,119 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/rtas.h>
|
||||
|
||||
#include "efika.h"
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
/*
|
||||
* Access functions for PCI config space using RTAS calls.
|
||||
*/
|
||||
static int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
|
||||
int len, u32 * val)
|
||||
{
|
||||
struct pci_controller *hose = bus->sysdata;
|
||||
unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
|
||||
| (((bus->number - hose->first_busno) & 0xff) << 16)
|
||||
| (hose->index << 24);
|
||||
int ret = -1;
|
||||
int rval;
|
||||
|
||||
rval = rtas_call(rtas_token("read-pci-config"), 2, 2, &ret, addr, len);
|
||||
*val = ret;
|
||||
return rval ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int rtas_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int offset, int len, u32 val)
|
||||
{
|
||||
struct pci_controller *hose = bus->sysdata;
|
||||
unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
|
||||
| (((bus->number - hose->first_busno) & 0xff) << 16)
|
||||
| (hose->index << 24);
|
||||
int rval;
|
||||
|
||||
rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL,
|
||||
addr, len, val);
|
||||
return rval ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static struct pci_ops rtas_pci_ops = {
|
||||
rtas_read_config,
|
||||
rtas_write_config
|
||||
};
|
||||
|
||||
void __init efika_pcisetup(void)
|
||||
{
|
||||
const int *bus_range;
|
||||
int len;
|
||||
struct pci_controller *hose;
|
||||
struct device_node *root;
|
||||
struct device_node *pcictrl;
|
||||
|
||||
root = of_find_node_by_path("/");
|
||||
if (root == NULL) {
|
||||
printk(KERN_WARNING EFIKA_PLATFORM_NAME
|
||||
": Unable to find the root node\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (pcictrl = NULL;;) {
|
||||
pcictrl = of_get_next_child(root, pcictrl);
|
||||
if ((pcictrl == NULL) || (strcmp(pcictrl->name, "pci") == 0))
|
||||
break;
|
||||
}
|
||||
|
||||
of_node_put(root);
|
||||
|
||||
if (pcictrl == NULL) {
|
||||
printk(KERN_WARNING EFIKA_PLATFORM_NAME
|
||||
": Unable to find the PCI bridge node\n");
|
||||
return;
|
||||
}
|
||||
|
||||
bus_range = get_property(pcictrl, "bus-range", &len);
|
||||
if (bus_range == NULL || len < 2 * sizeof(int)) {
|
||||
printk(KERN_WARNING EFIKA_PLATFORM_NAME
|
||||
": Can't get bus-range for %s\n", pcictrl->full_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bus_range[1] == bus_range[0])
|
||||
printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI bus %d",
|
||||
bus_range[0]);
|
||||
else
|
||||
printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI buses %d..%d",
|
||||
bus_range[0], bus_range[1]);
|
||||
printk(" controlled by %s\n", pcictrl->full_name);
|
||||
printk("\n");
|
||||
|
||||
hose = pcibios_alloc_controller();
|
||||
if (!hose) {
|
||||
printk(KERN_WARNING EFIKA_PLATFORM_NAME
|
||||
": Can't allocate PCI controller structure for %s\n",
|
||||
pcictrl->full_name);
|
||||
return;
|
||||
}
|
||||
|
||||
hose->arch_data = of_node_get(pcictrl);
|
||||
hose->first_busno = bus_range[0];
|
||||
hose->last_busno = bus_range[1];
|
||||
hose->ops = &rtas_pci_ops;
|
||||
|
||||
pci_process_bridge_OF_ranges(hose, pcictrl, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
void __init efika_pcisetup(void)
|
||||
{}
|
||||
#endif
|
150
arch/powerpc/platforms/52xx/efika-setup.c
Normal file
150
arch/powerpc/platforms/52xx/efika-setup.c
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
*
|
||||
* Efika 5K2 platform setup
|
||||
* Some code really inspired from the lite5200b platform.
|
||||
*
|
||||
* Copyright (C) 2006 bplan GmbH
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/utsrelease.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/root_dev.h>
|
||||
#include <linux/initrd.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/rtas.h>
|
||||
#include <asm/of_device.h>
|
||||
#include <asm/of_platform.h>
|
||||
#include <asm/mpc52xx.h>
|
||||
|
||||
#include "efika.h"
|
||||
|
||||
static void efika_show_cpuinfo(struct seq_file *m)
|
||||
{
|
||||
struct device_node *root;
|
||||
const char *revision = NULL;
|
||||
const char *codegendescription = NULL;
|
||||
const char *codegenvendor = NULL;
|
||||
|
||||
root = of_find_node_by_path("/");
|
||||
if (root) {
|
||||
revision = get_property(root, "revision", NULL);
|
||||
codegendescription =
|
||||
get_property(root, "CODEGEN,description", NULL);
|
||||
codegenvendor = get_property(root, "CODEGEN,vendor", NULL);
|
||||
|
||||
of_node_put(root);
|
||||
}
|
||||
|
||||
if (codegendescription)
|
||||
seq_printf(m, "machine\t\t: %s\n", codegendescription);
|
||||
else
|
||||
seq_printf(m, "machine\t\t: Efika\n");
|
||||
|
||||
if (revision)
|
||||
seq_printf(m, "revision\t: %s\n", revision);
|
||||
|
||||
if (codegenvendor)
|
||||
seq_printf(m, "vendor\t\t: %s\n", codegenvendor);
|
||||
|
||||
of_node_put(root);
|
||||
}
|
||||
|
||||
static void __init efika_setup_arch(void)
|
||||
{
|
||||
rtas_initialize();
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
initrd_below_start_ok = 1;
|
||||
|
||||
if (initrd_start)
|
||||
ROOT_DEV = Root_RAM0;
|
||||
else
|
||||
#endif
|
||||
ROOT_DEV = Root_SDA2; /* sda2 (sda1 is for the kernel) */
|
||||
|
||||
efika_pcisetup();
|
||||
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("Linux/PPC " UTS_RELEASE " runnung on Efika ;-)\n", 0x0);
|
||||
}
|
||||
|
||||
static void __init efika_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
struct device_node *cnp = NULL;
|
||||
const u32 *base;
|
||||
|
||||
/* Find every child of the SOC node and add it to of_platform */
|
||||
np = of_find_node_by_name(NULL, "builtin");
|
||||
if (np) {
|
||||
char name[BUS_ID_SIZE];
|
||||
while ((cnp = of_get_next_child(np, cnp))) {
|
||||
strcpy(name, cnp->name);
|
||||
|
||||
base = get_property(cnp, "reg", NULL);
|
||||
if (base == NULL)
|
||||
continue;
|
||||
|
||||
snprintf(name+strlen(name), BUS_ID_SIZE, "@%x", *base);
|
||||
of_platform_device_create(cnp, name, NULL);
|
||||
|
||||
printk(KERN_INFO EFIKA_PLATFORM_NAME" : Added %s (type '%s' at '%s') to the known devices\n", name, cnp->type, cnp->full_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress(" Have fun with your Efika! ", 0x7777);
|
||||
}
|
||||
|
||||
static int __init efika_probe(void)
|
||||
{
|
||||
char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
|
||||
"model", NULL);
|
||||
|
||||
if (model == NULL)
|
||||
return 0;
|
||||
if (strcmp(model, "EFIKA5K2"))
|
||||
return 0;
|
||||
|
||||
ISA_DMA_THRESHOLD = ~0L;
|
||||
DMA_MODE_READ = 0x44;
|
||||
DMA_MODE_WRITE = 0x48;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
define_machine(efika)
|
||||
{
|
||||
.name = EFIKA_PLATFORM_NAME,
|
||||
.probe = efika_probe,
|
||||
.setup_arch = efika_setup_arch,
|
||||
.init = efika_init,
|
||||
.show_cpuinfo = efika_show_cpuinfo,
|
||||
.init_IRQ = mpc52xx_init_irq,
|
||||
.get_irq = mpc52xx_get_irq,
|
||||
.restart = rtas_restart,
|
||||
.power_off = rtas_power_off,
|
||||
.halt = rtas_halt,
|
||||
.set_rtc_time = rtas_set_rtc_time,
|
||||
.get_rtc_time = rtas_get_rtc_time,
|
||||
.progress = rtas_progress,
|
||||
.get_boot_time = rtas_get_boot_time,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.phys_mem_access_prot = pci_phys_mem_access_prot,
|
||||
};
|
19
arch/powerpc/platforms/52xx/efika.h
Normal file
19
arch/powerpc/platforms/52xx/efika.h
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Efika 5K2 platform setup - Header file
|
||||
*
|
||||
* Copyright (C) 2006 bplan GmbH
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_POWERPC_EFIKA__
|
||||
#define __ARCH_POWERPC_EFIKA__
|
||||
|
||||
#define EFIKA_PLATFORM_NAME "Efika"
|
||||
|
||||
extern void __init efika_pcisetup(void);
|
||||
|
||||
#endif
|
162
arch/powerpc/platforms/52xx/lite5200.c
Normal file
162
arch/powerpc/platforms/52xx/lite5200.c
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Freescale Lite5200 board support
|
||||
*
|
||||
* Written by: Grant Likely <grant.likely@secretlab.ca>
|
||||
*
|
||||
* Copyright (C) Secret Lab Technologies Ltd. 2006. All rights reserved.
|
||||
* Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
|
||||
*
|
||||
* Description:
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/root_dev.h>
|
||||
#include <linux/initrd.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/ipic.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <asm/qe.h>
|
||||
#include <asm/qe_ic.h>
|
||||
#include <asm/of_platform.h>
|
||||
|
||||
#include <asm/mpc52xx.h>
|
||||
|
||||
/* ************************************************************************
|
||||
*
|
||||
* Setup the architecture
|
||||
*
|
||||
*/
|
||||
|
||||
static void __init
|
||||
lite52xx_setup_cpu(void)
|
||||
{
|
||||
struct mpc52xx_gpio __iomem *gpio;
|
||||
u32 port_config;
|
||||
|
||||
/* Map zones */
|
||||
gpio = mpc52xx_find_and_map("mpc52xx-gpio");
|
||||
if (!gpio) {
|
||||
printk(KERN_ERR __FILE__ ": "
|
||||
"Error while mapping GPIO register for port config. "
|
||||
"Expect some abnormal behavior\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Set port config */
|
||||
port_config = in_be32(&gpio->port_config);
|
||||
|
||||
port_config &= ~0x00800000; /* 48Mhz internal, pin is GPIO */
|
||||
|
||||
port_config &= ~0x00007000; /* USB port : Differential mode */
|
||||
port_config |= 0x00001000; /* USB 1 only */
|
||||
|
||||
port_config &= ~0x03000000; /* ATA CS is on csb_4/5 */
|
||||
port_config |= 0x01000000;
|
||||
|
||||
pr_debug("port_config: old:%x new:%x\n",
|
||||
in_be32(&gpio->port_config), port_config);
|
||||
out_be32(&gpio->port_config, port_config);
|
||||
|
||||
/* Unmap zone */
|
||||
error:
|
||||
iounmap(gpio);
|
||||
}
|
||||
|
||||
static void __init lite52xx_setup_arch(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("lite52xx_setup_arch()", 0);
|
||||
|
||||
np = of_find_node_by_type(NULL, "cpu");
|
||||
if (np) {
|
||||
unsigned int *fp =
|
||||
(int *)get_property(np, "clock-frequency", NULL);
|
||||
if (fp != 0)
|
||||
loops_per_jiffy = *fp / HZ;
|
||||
else
|
||||
loops_per_jiffy = 50000000 / HZ;
|
||||
of_node_put(np);
|
||||
}
|
||||
|
||||
/* CPU & Port mux setup */
|
||||
mpc52xx_setup_cpu(); /* Generic */
|
||||
lite52xx_setup_cpu(); /* Platorm specific */
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
if (initrd_start)
|
||||
ROOT_DEV = Root_RAM0;
|
||||
else
|
||||
#endif
|
||||
#ifdef CONFIG_ROOT_NFS
|
||||
ROOT_DEV = Root_NFS;
|
||||
#else
|
||||
ROOT_DEV = Root_HDA1;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void lite52xx_show_cpuinfo(struct seq_file *m)
|
||||
{
|
||||
struct device_node* np = of_find_all_nodes(NULL);
|
||||
const char *model = NULL;
|
||||
|
||||
if (np)
|
||||
model = get_property(np, "model", NULL);
|
||||
|
||||
seq_printf(m, "vendor\t\t: Freescale Semiconductor\n");
|
||||
seq_printf(m, "machine\t\t: %s\n", model ? model : "unknown");
|
||||
|
||||
of_node_put(np);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called very early, MMU is off, device-tree isn't unflattened
|
||||
*/
|
||||
static int __init lite52xx_probe(void)
|
||||
{
|
||||
unsigned long node = of_get_flat_dt_root();
|
||||
const char *model = of_get_flat_dt_prop(node, "model", NULL);
|
||||
|
||||
if (!of_flat_dt_is_compatible(node, "lite52xx"))
|
||||
return 0;
|
||||
pr_debug("%s board w/ mpc52xx found\n", model ? model : "unknown");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
define_machine(lite52xx) {
|
||||
.name = "lite52xx",
|
||||
.probe = lite52xx_probe,
|
||||
.setup_arch = lite52xx_setup_arch,
|
||||
.init_IRQ = mpc52xx_init_irq,
|
||||
.get_irq = mpc52xx_get_irq,
|
||||
.show_cpuinfo = lite52xx_show_cpuinfo,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
};
|
126
arch/powerpc/platforms/52xx/mpc52xx_common.c
Normal file
126
arch/powerpc/platforms/52xx/mpc52xx_common.c
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
*
|
||||
* Utility functions for the Freescale MPC52xx.
|
||||
*
|
||||
* Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/of_platform.h>
|
||||
#include <asm/mpc52xx.h>
|
||||
|
||||
|
||||
void __iomem *
|
||||
mpc52xx_find_and_map(const char *compatible)
|
||||
{
|
||||
struct device_node *ofn;
|
||||
const u32 *regaddr_p;
|
||||
u64 regaddr64, size64;
|
||||
|
||||
ofn = of_find_compatible_node(NULL, NULL, compatible);
|
||||
if (!ofn)
|
||||
return NULL;
|
||||
|
||||
regaddr_p = of_get_address(ofn, 0, &size64, NULL);
|
||||
if (!regaddr_p) {
|
||||
of_node_put(ofn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
regaddr64 = of_translate_address(ofn, regaddr_p);
|
||||
|
||||
of_node_put(ofn);
|
||||
|
||||
return ioremap((u32)regaddr64, (u32)size64);
|
||||
}
|
||||
EXPORT_SYMBOL(mpc52xx_find_and_map);
|
||||
|
||||
|
||||
/**
|
||||
* mpc52xx_find_ipb_freq - Find the IPB bus frequency for a device
|
||||
* @node: device node
|
||||
*
|
||||
* Returns IPB bus frequency, or 0 if the bus frequency cannot be found.
|
||||
*/
|
||||
unsigned int
|
||||
mpc52xx_find_ipb_freq(struct device_node *node)
|
||||
{
|
||||
struct device_node *np;
|
||||
const unsigned int *p_ipb_freq = NULL;
|
||||
|
||||
of_node_get(node);
|
||||
while (node) {
|
||||
p_ipb_freq = get_property(node, "bus-frequency", NULL);
|
||||
if (p_ipb_freq)
|
||||
break;
|
||||
|
||||
np = of_get_parent(node);
|
||||
of_node_put(node);
|
||||
node = np;
|
||||
}
|
||||
if (node)
|
||||
of_node_put(node);
|
||||
|
||||
return p_ipb_freq ? *p_ipb_freq : 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mpc52xx_find_ipb_freq);
|
||||
|
||||
|
||||
void __init
|
||||
mpc52xx_setup_cpu(void)
|
||||
{
|
||||
struct mpc52xx_cdm __iomem *cdm;
|
||||
struct mpc52xx_xlb __iomem *xlb;
|
||||
|
||||
/* Map zones */
|
||||
cdm = mpc52xx_find_and_map("mpc52xx-cdm");
|
||||
xlb = mpc52xx_find_and_map("mpc52xx-xlb");
|
||||
|
||||
if (!cdm || !xlb) {
|
||||
printk(KERN_ERR __FILE__ ": "
|
||||
"Error while mapping CDM/XLB during mpc52xx_setup_cpu. "
|
||||
"Expect some abnormal behavior\n");
|
||||
goto unmap_regs;
|
||||
}
|
||||
|
||||
/* Use internal 48 Mhz */
|
||||
out_8(&cdm->ext_48mhz_en, 0x00);
|
||||
out_8(&cdm->fd_enable, 0x01);
|
||||
if (in_be32(&cdm->rstcfg) & 0x40) /* Assumes 33Mhz clock */
|
||||
out_be16(&cdm->fd_counters, 0x0001);
|
||||
else
|
||||
out_be16(&cdm->fd_counters, 0x5555);
|
||||
|
||||
/* Configure the XLB Arbiter priorities */
|
||||
out_be32(&xlb->master_pri_enable, 0xff);
|
||||
out_be32(&xlb->master_priority, 0x11111111);
|
||||
|
||||
/* Disable XLB pipelining */
|
||||
/* (cfr errate 292. We could do this only just before ATA PIO
|
||||
transaction and re-enable it afterwards ...) */
|
||||
out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS);
|
||||
|
||||
/* Unmap zones */
|
||||
unmap_regs:
|
||||
if (cdm) iounmap(cdm);
|
||||
if (xlb) iounmap(xlb);
|
||||
}
|
||||
|
||||
static int __init
|
||||
mpc52xx_declare_of_platform_devices(void)
|
||||
{
|
||||
/* Find every child of the SOC node and add it to of_platform */
|
||||
return of_platform_bus_probe(NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
device_initcall(mpc52xx_declare_of_platform_devices);
|
473
arch/powerpc/platforms/52xx/mpc52xx_pic.c
Normal file
473
arch/powerpc/platforms/52xx/mpc52xx_pic.c
Normal file
@ -0,0 +1,473 @@
|
||||
/*
|
||||
*
|
||||
* Programmable Interrupt Controller functions for the Freescale MPC52xx.
|
||||
*
|
||||
* Copyright (C) 2006 bplan GmbH
|
||||
*
|
||||
* Based on the code from the 2.4 kernel by
|
||||
* Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg.
|
||||
*
|
||||
* Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
|
||||
* Copyright (C) 2003 Montavista Software, Inc
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/hardirq.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/mpc52xx.h>
|
||||
#include "mpc52xx_pic.h"
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static struct mpc52xx_intr __iomem *intr;
|
||||
static struct mpc52xx_sdma __iomem *sdma;
|
||||
static struct irq_host *mpc52xx_irqhost = NULL;
|
||||
|
||||
static unsigned char mpc52xx_map_senses[4] = {
|
||||
IRQ_TYPE_LEVEL_HIGH,
|
||||
IRQ_TYPE_EDGE_RISING,
|
||||
IRQ_TYPE_EDGE_FALLING,
|
||||
IRQ_TYPE_LEVEL_LOW,
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static inline void io_be_setbit(u32 __iomem *addr, int bitno)
|
||||
{
|
||||
out_be32(addr, in_be32(addr) | (1 << bitno));
|
||||
}
|
||||
|
||||
static inline void io_be_clrbit(u32 __iomem *addr, int bitno)
|
||||
{
|
||||
out_be32(addr, in_be32(addr) & ~(1 << bitno));
|
||||
}
|
||||
|
||||
/*
|
||||
* IRQ[0-3] interrupt irq_chip
|
||||
*/
|
||||
|
||||
static void mpc52xx_extirq_mask(unsigned int virq)
|
||||
{
|
||||
int irq;
|
||||
int l2irq;
|
||||
|
||||
irq = irq_map[virq].hwirq;
|
||||
l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
|
||||
pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
|
||||
io_be_clrbit(&intr->ctrl, 11 - l2irq);
|
||||
}
|
||||
|
||||
static void mpc52xx_extirq_unmask(unsigned int virq)
|
||||
{
|
||||
int irq;
|
||||
int l2irq;
|
||||
|
||||
irq = irq_map[virq].hwirq;
|
||||
l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
|
||||
pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
|
||||
io_be_setbit(&intr->ctrl, 11 - l2irq);
|
||||
}
|
||||
|
||||
static void mpc52xx_extirq_ack(unsigned int virq)
|
||||
{
|
||||
int irq;
|
||||
int l2irq;
|
||||
|
||||
irq = irq_map[virq].hwirq;
|
||||
l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
|
||||
pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
|
||||
io_be_setbit(&intr->ctrl, 27-l2irq);
|
||||
}
|
||||
|
||||
static struct irq_chip mpc52xx_extirq_irqchip = {
|
||||
.typename = " MPC52xx IRQ[0-3] ",
|
||||
.mask = mpc52xx_extirq_mask,
|
||||
.unmask = mpc52xx_extirq_unmask,
|
||||
.ack = mpc52xx_extirq_ack,
|
||||
};
|
||||
|
||||
/*
|
||||
* Main interrupt irq_chip
|
||||
*/
|
||||
|
||||
static void mpc52xx_main_mask(unsigned int virq)
|
||||
{
|
||||
int irq;
|
||||
int l2irq;
|
||||
|
||||
irq = irq_map[virq].hwirq;
|
||||
l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
|
||||
pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
|
||||
io_be_setbit(&intr->main_mask, 15 - l2irq);
|
||||
}
|
||||
|
||||
static void mpc52xx_main_unmask(unsigned int virq)
|
||||
{
|
||||
int irq;
|
||||
int l2irq;
|
||||
|
||||
irq = irq_map[virq].hwirq;
|
||||
l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
|
||||
pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
|
||||
io_be_clrbit(&intr->main_mask, 15 - l2irq);
|
||||
}
|
||||
|
||||
static struct irq_chip mpc52xx_main_irqchip = {
|
||||
.typename = "MPC52xx Main",
|
||||
.mask = mpc52xx_main_mask,
|
||||
.mask_ack = mpc52xx_main_mask,
|
||||
.unmask = mpc52xx_main_unmask,
|
||||
};
|
||||
|
||||
/*
|
||||
* Peripherals interrupt irq_chip
|
||||
*/
|
||||
|
||||
static void mpc52xx_periph_mask(unsigned int virq)
|
||||
{
|
||||
int irq;
|
||||
int l2irq;
|
||||
|
||||
irq = irq_map[virq].hwirq;
|
||||
l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
|
||||
pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
|
||||
io_be_setbit(&intr->per_mask, 31 - l2irq);
|
||||
}
|
||||
|
||||
static void mpc52xx_periph_unmask(unsigned int virq)
|
||||
{
|
||||
int irq;
|
||||
int l2irq;
|
||||
|
||||
irq = irq_map[virq].hwirq;
|
||||
l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
|
||||
pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
|
||||
io_be_clrbit(&intr->per_mask, 31 - l2irq);
|
||||
}
|
||||
|
||||
static struct irq_chip mpc52xx_periph_irqchip = {
|
||||
.typename = "MPC52xx Peripherals",
|
||||
.mask = mpc52xx_periph_mask,
|
||||
.mask_ack = mpc52xx_periph_mask,
|
||||
.unmask = mpc52xx_periph_unmask,
|
||||
};
|
||||
|
||||
/*
|
||||
* SDMA interrupt irq_chip
|
||||
*/
|
||||
|
||||
static void mpc52xx_sdma_mask(unsigned int virq)
|
||||
{
|
||||
int irq;
|
||||
int l2irq;
|
||||
|
||||
irq = irq_map[virq].hwirq;
|
||||
l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
|
||||
pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
|
||||
io_be_setbit(&sdma->IntMask, l2irq);
|
||||
}
|
||||
|
||||
static void mpc52xx_sdma_unmask(unsigned int virq)
|
||||
{
|
||||
int irq;
|
||||
int l2irq;
|
||||
|
||||
irq = irq_map[virq].hwirq;
|
||||
l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
|
||||
pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
|
||||
io_be_clrbit(&sdma->IntMask, l2irq);
|
||||
}
|
||||
|
||||
static void mpc52xx_sdma_ack(unsigned int virq)
|
||||
{
|
||||
int irq;
|
||||
int l2irq;
|
||||
|
||||
irq = irq_map[virq].hwirq;
|
||||
l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
|
||||
pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
|
||||
|
||||
out_be32(&sdma->IntPend, 1 << l2irq);
|
||||
}
|
||||
|
||||
static struct irq_chip mpc52xx_sdma_irqchip = {
|
||||
.typename = "MPC52xx SDMA",
|
||||
.mask = mpc52xx_sdma_mask,
|
||||
.unmask = mpc52xx_sdma_unmask,
|
||||
.ack = mpc52xx_sdma_ack,
|
||||
};
|
||||
|
||||
/*
|
||||
* irq_host
|
||||
*/
|
||||
|
||||
static int mpc52xx_irqhost_match(struct irq_host *h, struct device_node *node)
|
||||
{
|
||||
pr_debug("%s: node=%p\n", __func__, node);
|
||||
return mpc52xx_irqhost->host_data == node;
|
||||
}
|
||||
|
||||
static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
|
||||
u32 * intspec, unsigned int intsize,
|
||||
irq_hw_number_t * out_hwirq,
|
||||
unsigned int *out_flags)
|
||||
{
|
||||
int intrvect_l1;
|
||||
int intrvect_l2;
|
||||
int intrvect_type;
|
||||
int intrvect_linux;
|
||||
|
||||
if (intsize != 3)
|
||||
return -1;
|
||||
|
||||
intrvect_l1 = (int)intspec[0];
|
||||
intrvect_l2 = (int)intspec[1];
|
||||
intrvect_type = (int)intspec[2];
|
||||
|
||||
intrvect_linux =
|
||||
(intrvect_l1 << MPC52xx_IRQ_L1_OFFSET) & MPC52xx_IRQ_L1_MASK;
|
||||
intrvect_linux |=
|
||||
(intrvect_l2 << MPC52xx_IRQ_L2_OFFSET) & MPC52xx_IRQ_L2_MASK;
|
||||
|
||||
pr_debug("return %x, l1=%d, l2=%d\n", intrvect_linux, intrvect_l1,
|
||||
intrvect_l2);
|
||||
|
||||
*out_hwirq = intrvect_linux;
|
||||
*out_flags = mpc52xx_map_senses[intrvect_type];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* this function retrieves the correct IRQ type out
|
||||
* of the MPC regs
|
||||
* Only externals IRQs needs this
|
||||
*/
|
||||
static int mpc52xx_irqx_gettype(int irq)
|
||||
{
|
||||
int type;
|
||||
u32 ctrl_reg;
|
||||
|
||||
ctrl_reg = in_be32(&intr->ctrl);
|
||||
type = (ctrl_reg >> (22 - irq * 2)) & 0x3;
|
||||
|
||||
return mpc52xx_map_senses[type];
|
||||
}
|
||||
|
||||
static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
|
||||
irq_hw_number_t irq)
|
||||
{
|
||||
int l1irq;
|
||||
int l2irq;
|
||||
struct irq_chip *good_irqchip;
|
||||
void *good_handle;
|
||||
int type;
|
||||
|
||||
l1irq = (irq & MPC52xx_IRQ_L1_MASK) >> MPC52xx_IRQ_L1_OFFSET;
|
||||
l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
|
||||
|
||||
/*
|
||||
* Most of ours IRQs will be level low
|
||||
* Only external IRQs on some platform may be others
|
||||
*/
|
||||
type = IRQ_TYPE_LEVEL_LOW;
|
||||
|
||||
switch (l1irq) {
|
||||
case MPC52xx_IRQ_L1_CRIT:
|
||||
pr_debug("%s: Critical. l2=%x\n", __func__, l2irq);
|
||||
|
||||
BUG_ON(l2irq != 0);
|
||||
|
||||
type = mpc52xx_irqx_gettype(l2irq);
|
||||
good_irqchip = &mpc52xx_extirq_irqchip;
|
||||
break;
|
||||
|
||||
case MPC52xx_IRQ_L1_MAIN:
|
||||
pr_debug("%s: Main IRQ[1-3] l2=%x\n", __func__, l2irq);
|
||||
|
||||
if ((l2irq >= 1) && (l2irq <= 3)) {
|
||||
type = mpc52xx_irqx_gettype(l2irq);
|
||||
good_irqchip = &mpc52xx_extirq_irqchip;
|
||||
} else {
|
||||
good_irqchip = &mpc52xx_main_irqchip;
|
||||
}
|
||||
break;
|
||||
|
||||
case MPC52xx_IRQ_L1_PERP:
|
||||
pr_debug("%s: Peripherals. l2=%x\n", __func__, l2irq);
|
||||
good_irqchip = &mpc52xx_periph_irqchip;
|
||||
break;
|
||||
|
||||
case MPC52xx_IRQ_L1_SDMA:
|
||||
pr_debug("%s: SDMA. l2=%x\n", __func__, l2irq);
|
||||
good_irqchip = &mpc52xx_sdma_irqchip;
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_debug("%s: Error, unknown L1 IRQ (0x%x)\n", __func__, l1irq);
|
||||
printk(KERN_ERR "Unknow IRQ!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
good_handle = handle_edge_irq;
|
||||
break;
|
||||
default:
|
||||
good_handle = handle_level_irq;
|
||||
}
|
||||
|
||||
set_irq_chip_and_handler(virq, good_irqchip, good_handle);
|
||||
|
||||
pr_debug("%s: virq=%x, hw=%x. type=%x\n", __func__, virq,
|
||||
(int)irq, type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_host_ops mpc52xx_irqhost_ops = {
|
||||
.match = mpc52xx_irqhost_match,
|
||||
.xlate = mpc52xx_irqhost_xlate,
|
||||
.map = mpc52xx_irqhost_map,
|
||||
};
|
||||
|
||||
/*
|
||||
* init (public)
|
||||
*/
|
||||
|
||||
void __init mpc52xx_init_irq(void)
|
||||
{
|
||||
u32 intr_ctrl;
|
||||
struct device_node *picnode;
|
||||
|
||||
/* Remap the necessary zones */
|
||||
picnode = of_find_compatible_node(NULL, NULL, "mpc52xx-pic");
|
||||
|
||||
intr = mpc52xx_find_and_map("mpc52xx-pic");
|
||||
if (!intr)
|
||||
panic(__FILE__ ": find_and_map failed on 'mpc52xx-pic'. "
|
||||
"Check node !");
|
||||
|
||||
sdma = mpc52xx_find_and_map("mpc52xx-bestcomm");
|
||||
if (!sdma)
|
||||
panic(__FILE__ ": find_and_map failed on 'mpc52xx-bestcomm'. "
|
||||
"Check node !");
|
||||
|
||||
/* Disable all interrupt sources. */
|
||||
out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */
|
||||
out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */
|
||||
out_be32(&intr->per_mask, 0x7ffffc00); /* 1 means disabled */
|
||||
out_be32(&intr->main_mask, 0x00010fff); /* 1 means disabled */
|
||||
intr_ctrl = in_be32(&intr->ctrl);
|
||||
intr_ctrl &= 0x00ff0000; /* Keeps IRQ[0-3] config */
|
||||
intr_ctrl |= 0x0f000000 | /* clear IRQ 0-3 */
|
||||
0x00001000 | /* MEE master external enable */
|
||||
0x00000000 | /* 0 means disable IRQ 0-3 */
|
||||
0x00000001; /* CEb route critical normally */
|
||||
out_be32(&intr->ctrl, intr_ctrl);
|
||||
|
||||
/* Zero a bunch of the priority settings. */
|
||||
out_be32(&intr->per_pri1, 0);
|
||||
out_be32(&intr->per_pri2, 0);
|
||||
out_be32(&intr->per_pri3, 0);
|
||||
out_be32(&intr->main_pri1, 0);
|
||||
out_be32(&intr->main_pri2, 0);
|
||||
|
||||
/*
|
||||
* As last step, add an irq host to translate the real
|
||||
* hw irq information provided by the ofw to linux virq
|
||||
*/
|
||||
|
||||
mpc52xx_irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
|
||||
MPC52xx_IRQ_HIGHTESTHWIRQ,
|
||||
&mpc52xx_irqhost_ops, -1);
|
||||
|
||||
if (!mpc52xx_irqhost)
|
||||
panic(__FILE__ ": Cannot allocate the IRQ host\n");
|
||||
|
||||
mpc52xx_irqhost->host_data = picnode;
|
||||
printk(KERN_INFO "MPC52xx PIC is up and running!\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* get_irq (public)
|
||||
*/
|
||||
unsigned int mpc52xx_get_irq(void)
|
||||
{
|
||||
u32 status;
|
||||
int irq = NO_IRQ_IGNORE;
|
||||
|
||||
status = in_be32(&intr->enc_status);
|
||||
if (status & 0x00000400) { /* critical */
|
||||
irq = (status >> 8) & 0x3;
|
||||
if (irq == 2) /* high priority peripheral */
|
||||
goto peripheral;
|
||||
irq |= (MPC52xx_IRQ_L1_CRIT << MPC52xx_IRQ_L1_OFFSET) &
|
||||
MPC52xx_IRQ_L1_MASK;
|
||||
} else if (status & 0x00200000) { /* main */
|
||||
irq = (status >> 16) & 0x1f;
|
||||
if (irq == 4) /* low priority peripheral */
|
||||
goto peripheral;
|
||||
irq |= (MPC52xx_IRQ_L1_MAIN << MPC52xx_IRQ_L1_OFFSET) &
|
||||
MPC52xx_IRQ_L1_MASK;
|
||||
} else if (status & 0x20000000) { /* peripheral */
|
||||
peripheral:
|
||||
irq = (status >> 24) & 0x1f;
|
||||
if (irq == 0) { /* bestcomm */
|
||||
status = in_be32(&sdma->IntPend);
|
||||
irq = ffs(status) - 1;
|
||||
irq |= (MPC52xx_IRQ_L1_SDMA << MPC52xx_IRQ_L1_OFFSET) &
|
||||
MPC52xx_IRQ_L1_MASK;
|
||||
} else {
|
||||
irq |= (MPC52xx_IRQ_L1_PERP << MPC52xx_IRQ_L1_OFFSET) &
|
||||
MPC52xx_IRQ_L1_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
pr_debug("%s: irq=%x. virq=%d\n", __func__, irq,
|
||||
irq_linear_revmap(mpc52xx_irqhost, irq));
|
||||
|
||||
return irq_linear_revmap(mpc52xx_irqhost, irq);
|
||||
}
|
53
arch/powerpc/platforms/52xx/mpc52xx_pic.h
Normal file
53
arch/powerpc/platforms/52xx/mpc52xx_pic.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Header file for Freescale MPC52xx Interrupt controller
|
||||
*
|
||||
* Copyright (C) 2004-2005 Sylvain Munaut <tnt@246tNt.com>
|
||||
* Copyright (C) 2003 MontaVista, Software, Inc.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#ifndef __POWERPC_SYSDEV_MPC52xx_PIC_H__
|
||||
#define __POWERPC_SYSDEV_MPC52xx_PIC_H__
|
||||
|
||||
#include <asm/types.h>
|
||||
|
||||
|
||||
/* HW IRQ mapping */
|
||||
#define MPC52xx_IRQ_L1_CRIT (0)
|
||||
#define MPC52xx_IRQ_L1_MAIN (1)
|
||||
#define MPC52xx_IRQ_L1_PERP (2)
|
||||
#define MPC52xx_IRQ_L1_SDMA (3)
|
||||
|
||||
#define MPC52xx_IRQ_L1_OFFSET (6)
|
||||
#define MPC52xx_IRQ_L1_MASK (0x00c0)
|
||||
|
||||
#define MPC52xx_IRQ_L2_OFFSET (0)
|
||||
#define MPC52xx_IRQ_L2_MASK (0x003f)
|
||||
|
||||
#define MPC52xx_IRQ_HIGHTESTHWIRQ (0xd0)
|
||||
|
||||
|
||||
/* Interrupt controller Register set */
|
||||
struct mpc52xx_intr {
|
||||
u32 per_mask; /* INTR + 0x00 */
|
||||
u32 per_pri1; /* INTR + 0x04 */
|
||||
u32 per_pri2; /* INTR + 0x08 */
|
||||
u32 per_pri3; /* INTR + 0x0c */
|
||||
u32 ctrl; /* INTR + 0x10 */
|
||||
u32 main_mask; /* INTR + 0x14 */
|
||||
u32 main_pri1; /* INTR + 0x18 */
|
||||
u32 main_pri2; /* INTR + 0x1c */
|
||||
u32 reserved1; /* INTR + 0x20 */
|
||||
u32 enc_status; /* INTR + 0x24 */
|
||||
u32 crit_status; /* INTR + 0x28 */
|
||||
u32 main_status; /* INTR + 0x2c */
|
||||
u32 per_status; /* INTR + 0x30 */
|
||||
u32 reserved2; /* INTR + 0x34 */
|
||||
u32 per_error; /* INTR + 0x38 */
|
||||
};
|
||||
|
||||
#endif /* __POWERPC_SYSDEV_MPC52xx_PIC_H__ */
|
||||
|
@ -515,16 +515,6 @@ static int m82xx_pci_exclude_device(u_char bus, u_char devfn)
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static void
|
||||
__init mpc82xx_pcibios_fixup(void)
|
||||
{
|
||||
struct pci_dev *dev = NULL;
|
||||
|
||||
for_each_pci_dev(dev) {
|
||||
pci_read_irq_line(dev);
|
||||
}
|
||||
}
|
||||
|
||||
void __init add_bridge(struct device_node *np)
|
||||
{
|
||||
int len;
|
||||
@ -597,9 +587,6 @@ static void __init mpc82xx_ads_setup_arch(void)
|
||||
add_bridge(np);
|
||||
|
||||
of_node_put(np);
|
||||
ppc_md.pci_map_irq = NULL;
|
||||
ppc_md.pcibios_fixup = mpc82xx_pcibios_fixup;
|
||||
ppc_md.pcibios_fixup_bus = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROOT_NFS
|
||||
|
@ -97,8 +97,6 @@ static void __init mpc832x_sys_setup_arch(void)
|
||||
#ifdef CONFIG_PCI
|
||||
for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
|
||||
add_bridge(np);
|
||||
|
||||
ppc_md.pci_swizzle = common_swizzle;
|
||||
ppc_md.pci_exclude_device = mpc83xx_exclude_device;
|
||||
#endif
|
||||
|
||||
|
@ -118,7 +118,4 @@ define_machine(mpc834x_itx) {
|
||||
.time_init = mpc83xx_time_init,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup = mpc83xx_pcibios_fixup,
|
||||
#endif
|
||||
};
|
||||
|
@ -137,7 +137,4 @@ define_machine(mpc834x_sys) {
|
||||
.time_init = mpc83xx_time_init,
|
||||
.calibrate_decr = generic_calibrate_decr,
|
||||
.progress = udbg_progress,
|
||||
#ifdef CONFIG_PCI
|
||||
.pcibios_fixup = mpc83xx_pcibios_fixup,
|
||||
#endif
|
||||
};
|
||||
|
@ -102,8 +102,6 @@ static void __init mpc8360_sys_setup_arch(void)
|
||||
#ifdef CONFIG_PCI
|
||||
for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
|
||||
add_bridge(np);
|
||||
|
||||
ppc_md.pci_swizzle = common_swizzle;
|
||||
ppc_md.pci_exclude_device = mpc83xx_exclude_device;
|
||||
#endif
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
extern int add_bridge(struct device_node *dev);
|
||||
extern int mpc83xx_exclude_device(u_char bus, u_char devfn);
|
||||
extern void mpc83xx_pcibios_fixup(void);
|
||||
extern void mpc83xx_restart(char *cmd);
|
||||
extern long mpc83xx_time_init(void);
|
||||
|
||||
|
@ -45,15 +45,6 @@ int mpc83xx_exclude_device(u_char bus, u_char devfn)
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
void __init mpc83xx_pcibios_fixup(void)
|
||||
{
|
||||
struct pci_dev *dev = NULL;
|
||||
|
||||
/* map all the PCI irqs */
|
||||
for_each_pci_dev(dev)
|
||||
pci_read_irq_line(dev);
|
||||
}
|
||||
|
||||
int __init add_bridge(struct device_node *dev)
|
||||
{
|
||||
int len;
|
||||
|
@ -21,11 +21,3 @@ void mpc85xx_restart(char *cmd)
|
||||
local_irq_disable();
|
||||
abort();
|
||||
}
|
||||
|
||||
/* For now this is a pass through */
|
||||
phys_addr_t fixup_bigphys_addr(phys_addr_t addr, phys_addr_t size)
|
||||
{
|
||||
return addr;
|
||||
};
|
||||
|
||||
EXPORT_SYMBOL(fixup_bigphys_addr);
|
||||
|
@ -53,15 +53,6 @@ mpc85xx_exclude_device(u_char bus, u_char devfn)
|
||||
else
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
void __init
|
||||
mpc85xx_pcibios_fixup(void)
|
||||
{
|
||||
struct pci_dev *dev = NULL;
|
||||
|
||||
for_each_pci_dev(dev)
|
||||
pci_read_irq_line(dev);
|
||||
}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
#ifdef CONFIG_CPM2
|
||||
@ -253,8 +244,6 @@ static void __init mpc85xx_ads_setup_arch(void)
|
||||
#ifdef CONFIG_PCI
|
||||
for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
|
||||
add_bridge(np);
|
||||
|
||||
ppc_md.pcibios_fixup = mpc85xx_pcibios_fixup;
|
||||
ppc_md.pci_exclude_device = mpc85xx_exclude_device;
|
||||
#endif
|
||||
|
||||
|
@ -398,15 +398,6 @@ mpc86xx_hpcn_show_cpuinfo(struct seq_file *m)
|
||||
}
|
||||
|
||||
|
||||
void __init mpc86xx_hpcn_pcibios_fixup(void)
|
||||
{
|
||||
struct pci_dev *dev = NULL;
|
||||
|
||||
for_each_pci_dev(dev)
|
||||
pci_read_irq_line(dev);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
*/
|
||||
@ -461,7 +452,6 @@ define_machine(mpc86xx_hpcn) {
|
||||
.setup_arch = mpc86xx_hpcn_setup_arch,
|
||||
.init_IRQ = mpc86xx_hpcn_init_irq,
|
||||
.show_cpuinfo = mpc86xx_hpcn_show_cpuinfo,
|
||||
.pcibios_fixup = mpc86xx_hpcn_pcibios_fixup,
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = mpc86xx_restart,
|
||||
.time_init = mpc86xx_time_init,
|
||||
|
@ -7,12 +7,14 @@ endif
|
||||
endif
|
||||
obj-$(CONFIG_PPC_CHRP) += chrp/
|
||||
obj-$(CONFIG_4xx) += 4xx/
|
||||
obj-$(CONFIG_PPC_MPC52xx) += 52xx/
|
||||
obj-$(CONFIG_PPC_83xx) += 83xx/
|
||||
obj-$(CONFIG_PPC_85xx) += 85xx/
|
||||
obj-$(CONFIG_PPC_86xx) += 86xx/
|
||||
obj-$(CONFIG_PPC_PSERIES) += pseries/
|
||||
obj-$(CONFIG_PPC_ISERIES) += iseries/
|
||||
obj-$(CONFIG_PPC_MAPLE) += maple/
|
||||
obj-$(CONFIG_PPC_PASEMI) += pasemi/
|
||||
obj-$(CONFIG_PPC_PASEMI) += pasemi/
|
||||
obj-$(CONFIG_PPC_CELL) += cell/
|
||||
obj-$(CONFIG_PPC_PS3) += ps3/
|
||||
obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user