Merge branch 'for-2.6.24' of master.kernel.org:/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx into merge
This commit is contained in:
Коммит
688016f4e2
|
@ -52,6 +52,7 @@ Table of Contents
|
||||||
i) Freescale QUICC Engine module (QE)
|
i) Freescale QUICC Engine module (QE)
|
||||||
j) CFI or JEDEC memory-mapped NOR flash
|
j) CFI or JEDEC memory-mapped NOR flash
|
||||||
k) Global Utilities Block
|
k) Global Utilities Block
|
||||||
|
l) Xilinx IP cores
|
||||||
|
|
||||||
VII - Specifying interrupt information for devices
|
VII - Specifying interrupt information for devices
|
||||||
1) interrupts property
|
1) interrupts property
|
||||||
|
@ -2252,6 +2253,266 @@ platforms are moved over to use the flattened-device-tree model.
|
||||||
available.
|
available.
|
||||||
For Axon: 0x0000012a
|
For Axon: 0x0000012a
|
||||||
|
|
||||||
|
l) Xilinx IP cores
|
||||||
|
|
||||||
|
The Xilinx EDK toolchain ships with a set of IP cores (devices) for use
|
||||||
|
in Xilinx Spartan and Virtex FPGAs. The devices cover the whole range
|
||||||
|
of standard device types (network, serial, etc.) and miscellanious
|
||||||
|
devices (gpio, LCD, spi, etc). Also, since these devices are
|
||||||
|
implemented within the fpga fabric every instance of the device can be
|
||||||
|
synthesised with different options that change the behaviour.
|
||||||
|
|
||||||
|
Each IP-core has a set of parameters which the FPGA designer can use to
|
||||||
|
control how the core is synthesized. Historically, the EDK tool would
|
||||||
|
extract the device parameters relevant to device drivers and copy them
|
||||||
|
into an 'xparameters.h' in the form of #define symbols. This tells the
|
||||||
|
device drivers how the IP cores are configured, but it requres the kernel
|
||||||
|
to be recompiled every time the FPGA bitstream is resynthesized.
|
||||||
|
|
||||||
|
The new approach is to export the parameters into the device tree and
|
||||||
|
generate a new device tree each time the FPGA bitstream changes. The
|
||||||
|
parameters which used to be exported as #defines will now become
|
||||||
|
properties of the device node. In general, device nodes for IP-cores
|
||||||
|
will take the following form:
|
||||||
|
|
||||||
|
(name)@(base-address) {
|
||||||
|
compatible = "xlnx,(ip-core-name)-(HW_VER)"
|
||||||
|
[, (list of compatible devices), ...];
|
||||||
|
reg = <(baseaddr) (size)>;
|
||||||
|
interrupt-parent = <&interrupt-controller-phandle>;
|
||||||
|
interrupts = < ... >;
|
||||||
|
xlnx,(parameter1) = "(string-value)";
|
||||||
|
xlnx,(parameter2) = <(int-value)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
(ip-core-name): the name of the ip block (given after the BEGIN
|
||||||
|
directive in system.mhs). Should be in lowercase
|
||||||
|
and all underscores '_' converted to dashes '-'.
|
||||||
|
(name): is derived from the "PARAMETER INSTANCE" value.
|
||||||
|
(parameter#): C_* parameters from system.mhs. The C_ prefix is
|
||||||
|
dropped from the parameter name, the name is converted
|
||||||
|
to lowercase and all underscore '_' characters are
|
||||||
|
converted to dashes '-'.
|
||||||
|
(baseaddr): the C_BASEADDR parameter.
|
||||||
|
(HW_VER): from the HW_VER parameter.
|
||||||
|
(size): equals C_HIGHADDR - C_BASEADDR + 1
|
||||||
|
|
||||||
|
Typically, the compatible list will include the exact IP core version
|
||||||
|
followed by an older IP core version which implements the same
|
||||||
|
interface or any other device with the same interface.
|
||||||
|
|
||||||
|
'reg', 'interrupt-parent' and 'interrupts' are all optional properties.
|
||||||
|
|
||||||
|
For example, the following block from system.mhs:
|
||||||
|
|
||||||
|
BEGIN opb_uartlite
|
||||||
|
PARAMETER INSTANCE = opb_uartlite_0
|
||||||
|
PARAMETER HW_VER = 1.00.b
|
||||||
|
PARAMETER C_BAUDRATE = 115200
|
||||||
|
PARAMETER C_DATA_BITS = 8
|
||||||
|
PARAMETER C_ODD_PARITY = 0
|
||||||
|
PARAMETER C_USE_PARITY = 0
|
||||||
|
PARAMETER C_CLK_FREQ = 50000000
|
||||||
|
PARAMETER C_BASEADDR = 0xEC100000
|
||||||
|
PARAMETER C_HIGHADDR = 0xEC10FFFF
|
||||||
|
BUS_INTERFACE SOPB = opb_7
|
||||||
|
PORT OPB_Clk = CLK_50MHz
|
||||||
|
PORT Interrupt = opb_uartlite_0_Interrupt
|
||||||
|
PORT RX = opb_uartlite_0_RX
|
||||||
|
PORT TX = opb_uartlite_0_TX
|
||||||
|
PORT OPB_Rst = sys_bus_reset_0
|
||||||
|
END
|
||||||
|
|
||||||
|
becomes the following device tree node:
|
||||||
|
|
||||||
|
opb-uartlite-0@ec100000 {
|
||||||
|
device_type = "serial";
|
||||||
|
compatible = "xlnx,opb-uartlite-1.00.b";
|
||||||
|
reg = <ec100000 10000>;
|
||||||
|
interrupt-parent = <&opb-intc>;
|
||||||
|
interrupts = <1 0>; // got this from the opb_intc parameters
|
||||||
|
current-speed = <d#115200>; // standard serial device prop
|
||||||
|
clock-frequency = <d#50000000>; // standard serial device prop
|
||||||
|
xlnx,data-bits = <8>;
|
||||||
|
xlnx,odd-parity = <0>;
|
||||||
|
xlnx,use-parity = <0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
Some IP cores actually implement 2 or more logical devices. In this case,
|
||||||
|
the device should still describe the whole IP core with a single node
|
||||||
|
and add a child node for each logical device. The ranges property can
|
||||||
|
be used to translate from parent IP-core to the registers of each device.
|
||||||
|
(Note: this makes the assumption that both logical devices have the same
|
||||||
|
bus binding. If this is not true, then separate nodes should be used for
|
||||||
|
each logical device). The 'cell-index' property can be used to enumerate
|
||||||
|
logical devices within an IP core. For example, the following is the
|
||||||
|
system.mhs entry for the dual ps2 controller found on the ml403 reference
|
||||||
|
design.
|
||||||
|
|
||||||
|
BEGIN opb_ps2_dual_ref
|
||||||
|
PARAMETER INSTANCE = opb_ps2_dual_ref_0
|
||||||
|
PARAMETER HW_VER = 1.00.a
|
||||||
|
PARAMETER C_BASEADDR = 0xA9000000
|
||||||
|
PARAMETER C_HIGHADDR = 0xA9001FFF
|
||||||
|
BUS_INTERFACE SOPB = opb_v20_0
|
||||||
|
PORT Sys_Intr1 = ps2_1_intr
|
||||||
|
PORT Sys_Intr2 = ps2_2_intr
|
||||||
|
PORT Clkin1 = ps2_clk_rx_1
|
||||||
|
PORT Clkin2 = ps2_clk_rx_2
|
||||||
|
PORT Clkpd1 = ps2_clk_tx_1
|
||||||
|
PORT Clkpd2 = ps2_clk_tx_2
|
||||||
|
PORT Rx1 = ps2_d_rx_1
|
||||||
|
PORT Rx2 = ps2_d_rx_2
|
||||||
|
PORT Txpd1 = ps2_d_tx_1
|
||||||
|
PORT Txpd2 = ps2_d_tx_2
|
||||||
|
END
|
||||||
|
|
||||||
|
It would result in the following device tree nodes:
|
||||||
|
|
||||||
|
opb_ps2_dual_ref_0@a9000000 {
|
||||||
|
ranges = <0 a9000000 2000>;
|
||||||
|
// If this device had extra parameters, then they would
|
||||||
|
// go here.
|
||||||
|
ps2@0 {
|
||||||
|
compatible = "xlnx,opb-ps2-dual-ref-1.00.a";
|
||||||
|
reg = <0 40>;
|
||||||
|
interrupt-parent = <&opb-intc>;
|
||||||
|
interrupts = <3 0>;
|
||||||
|
cell-index = <0>;
|
||||||
|
};
|
||||||
|
ps2@1000 {
|
||||||
|
compatible = "xlnx,opb-ps2-dual-ref-1.00.a";
|
||||||
|
reg = <1000 40>;
|
||||||
|
interrupt-parent = <&opb-intc>;
|
||||||
|
interrupts = <3 0>;
|
||||||
|
cell-index = <0>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Also, the system.mhs file defines bus attachments from the processor
|
||||||
|
to the devices. The device tree structure should reflect the bus
|
||||||
|
attachments. Again an example; this system.mhs fragment:
|
||||||
|
|
||||||
|
BEGIN ppc405_virtex4
|
||||||
|
PARAMETER INSTANCE = ppc405_0
|
||||||
|
PARAMETER HW_VER = 1.01.a
|
||||||
|
BUS_INTERFACE DPLB = plb_v34_0
|
||||||
|
BUS_INTERFACE IPLB = plb_v34_0
|
||||||
|
END
|
||||||
|
|
||||||
|
BEGIN opb_intc
|
||||||
|
PARAMETER INSTANCE = opb_intc_0
|
||||||
|
PARAMETER HW_VER = 1.00.c
|
||||||
|
PARAMETER C_BASEADDR = 0xD1000FC0
|
||||||
|
PARAMETER C_HIGHADDR = 0xD1000FDF
|
||||||
|
BUS_INTERFACE SOPB = opb_v20_0
|
||||||
|
END
|
||||||
|
|
||||||
|
BEGIN opb_uart16550
|
||||||
|
PARAMETER INSTANCE = opb_uart16550_0
|
||||||
|
PARAMETER HW_VER = 1.00.d
|
||||||
|
PARAMETER C_BASEADDR = 0xa0000000
|
||||||
|
PARAMETER C_HIGHADDR = 0xa0001FFF
|
||||||
|
BUS_INTERFACE SOPB = opb_v20_0
|
||||||
|
END
|
||||||
|
|
||||||
|
BEGIN plb_v34
|
||||||
|
PARAMETER INSTANCE = plb_v34_0
|
||||||
|
PARAMETER HW_VER = 1.02.a
|
||||||
|
END
|
||||||
|
|
||||||
|
BEGIN plb_bram_if_cntlr
|
||||||
|
PARAMETER INSTANCE = plb_bram_if_cntlr_0
|
||||||
|
PARAMETER HW_VER = 1.00.b
|
||||||
|
PARAMETER C_BASEADDR = 0xFFFF0000
|
||||||
|
PARAMETER C_HIGHADDR = 0xFFFFFFFF
|
||||||
|
BUS_INTERFACE SPLB = plb_v34_0
|
||||||
|
END
|
||||||
|
|
||||||
|
BEGIN plb2opb_bridge
|
||||||
|
PARAMETER INSTANCE = plb2opb_bridge_0
|
||||||
|
PARAMETER HW_VER = 1.01.a
|
||||||
|
PARAMETER C_RNG0_BASEADDR = 0x20000000
|
||||||
|
PARAMETER C_RNG0_HIGHADDR = 0x3FFFFFFF
|
||||||
|
PARAMETER C_RNG1_BASEADDR = 0x60000000
|
||||||
|
PARAMETER C_RNG1_HIGHADDR = 0x7FFFFFFF
|
||||||
|
PARAMETER C_RNG2_BASEADDR = 0x80000000
|
||||||
|
PARAMETER C_RNG2_HIGHADDR = 0xBFFFFFFF
|
||||||
|
PARAMETER C_RNG3_BASEADDR = 0xC0000000
|
||||||
|
PARAMETER C_RNG3_HIGHADDR = 0xDFFFFFFF
|
||||||
|
BUS_INTERFACE SPLB = plb_v34_0
|
||||||
|
BUS_INTERFACE MOPB = opb_v20_0
|
||||||
|
END
|
||||||
|
|
||||||
|
Gives this device tree (some properties removed for clarity):
|
||||||
|
|
||||||
|
plb-v34-0 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
device_type = "ibm,plb";
|
||||||
|
ranges; // 1:1 translation
|
||||||
|
|
||||||
|
plb-bram-if-cntrl-0@ffff0000 {
|
||||||
|
reg = <ffff0000 10000>;
|
||||||
|
}
|
||||||
|
|
||||||
|
opb-v20-0 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
ranges = <20000000 20000000 20000000
|
||||||
|
60000000 60000000 20000000
|
||||||
|
80000000 80000000 40000000
|
||||||
|
c0000000 c0000000 20000000>;
|
||||||
|
|
||||||
|
opb-uart16550-0@a0000000 {
|
||||||
|
reg = <a00000000 2000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
opb-intc-0@d1000fc0 {
|
||||||
|
reg = <d1000fc0 20>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
That covers the general approach to binding xilinx IP cores into the
|
||||||
|
device tree. The following are bindings for specific devices:
|
||||||
|
|
||||||
|
i) Xilinx ML300 Framebuffer
|
||||||
|
|
||||||
|
Simple framebuffer device from the ML300 reference design (also on the
|
||||||
|
ML403 reference design as well as others).
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
- resolution = <xres yres> : pixel resolution of framebuffer. Some
|
||||||
|
implementations use a different resolution.
|
||||||
|
Default is <d#640 d#480>
|
||||||
|
- virt-resolution = <xvirt yvirt> : Size of framebuffer in memory.
|
||||||
|
Default is <d#1024 d#480>.
|
||||||
|
- rotate-display (empty) : rotate display 180 degrees.
|
||||||
|
|
||||||
|
ii) Xilinx SystemACE
|
||||||
|
|
||||||
|
The Xilinx SystemACE device is used to program FPGAs from an FPGA
|
||||||
|
bitstream stored on a CF card. It can also be used as a generic CF
|
||||||
|
interface device.
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
- 8-bit (empty) : Set this property for SystemACE in 8 bit mode
|
||||||
|
|
||||||
|
iii) Xilinx EMAC and Xilinx TEMAC
|
||||||
|
|
||||||
|
Xilinx Ethernet devices. In addition to general xilinx properties
|
||||||
|
listed above, nodes for these devices should include a phy-handle
|
||||||
|
property, and may include other common network device properties
|
||||||
|
like local-mac-address.
|
||||||
|
|
||||||
|
iv) Xilinx Uartlite
|
||||||
|
|
||||||
|
Xilinx uartlite devices are simple fixed speed serial ports.
|
||||||
|
|
||||||
|
Requred properties:
|
||||||
|
- current-speed : Baud rate of uartlite
|
||||||
|
|
||||||
More devices will be defined as this spec matures.
|
More devices will be defined as this spec matures.
|
||||||
|
|
||||||
VII - Specifying interrupt information for devices
|
VII - Specifying interrupt information for devices
|
||||||
|
|
|
@ -122,7 +122,9 @@
|
||||||
device_type = "network";
|
device_type = "network";
|
||||||
compatible = "ibm,emac-405gp", "ibm,emac";
|
compatible = "ibm,emac-405gp", "ibm,emac";
|
||||||
interrupt-parent = <&UIC0>;
|
interrupt-parent = <&UIC0>;
|
||||||
interrupts = <9 4 f 4>;
|
interrupts = <
|
||||||
|
f 4 /* Ethernet */
|
||||||
|
9 4 /* Ethernet Wake Up */>;
|
||||||
local-mac-address = [000000000000]; /* Filled in by zImage */
|
local-mac-address = [000000000000]; /* Filled in by zImage */
|
||||||
reg = <ef600800 70>;
|
reg = <ef600800 70>;
|
||||||
mal-device = <&MAL>;
|
mal-device = <&MAL>;
|
||||||
|
|
|
@ -21,6 +21,14 @@
|
||||||
# (default ./arch/powerpc/boot)
|
# (default ./arch/powerpc/boot)
|
||||||
# -W dir specify working directory for temporary files (default .)
|
# -W dir specify working directory for temporary files (default .)
|
||||||
|
|
||||||
|
# Stop execution if any command fails
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Allow for verbose output
|
||||||
|
if [ "$V" = 1 ]; then
|
||||||
|
set -x
|
||||||
|
fi
|
||||||
|
|
||||||
# defaults
|
# defaults
|
||||||
kernel=
|
kernel=
|
||||||
ofile=zImage
|
ofile=zImage
|
||||||
|
@ -111,7 +119,7 @@ if [ -n "$dts" ]; then
|
||||||
if [ -z "$dtb" ]; then
|
if [ -z "$dtb" ]; then
|
||||||
dtb="$platform.dtb"
|
dtb="$platform.dtb"
|
||||||
fi
|
fi
|
||||||
dtc -O dtb -o "$dtb" -b 0 -V 16 "$dts" || exit 1
|
dtc -O dtb -o "$dtb" -b 0 -V 16 "$dts"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$kernel" ]; then
|
if [ -z "$kernel" ]; then
|
||||||
|
@ -283,23 +291,13 @@ ps3)
|
||||||
|
|
||||||
${CROSS}objcopy -O binary "$ofile" "$ofile.bin"
|
${CROSS}objcopy -O binary "$ofile" "$ofile.bin"
|
||||||
|
|
||||||
msg=$(dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
|
dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
|
||||||
skip=$overlay_dest seek=$system_reset_kernel \
|
skip=$overlay_dest seek=$system_reset_kernel \
|
||||||
count=$overlay_size bs=1 2>&1)
|
count=$overlay_size bs=1
|
||||||
|
|
||||||
if [ $? -ne "0" ]; then
|
dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
|
||||||
echo $msg
|
skip=$system_reset_overlay seek=$overlay_dest \
|
||||||
exit 1
|
count=$overlay_size bs=1
|
||||||
fi
|
|
||||||
|
|
||||||
msg=$(dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
|
|
||||||
skip=$system_reset_overlay seek=$overlay_dest \
|
|
||||||
count=$overlay_size bs=1 2>&1)
|
|
||||||
|
|
||||||
if [ $? -ne "0" ]; then
|
|
||||||
echo $msg
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
gzip --force -9 --stdout "$ofile.bin" > "$object/otheros.bld"
|
gzip --force -9 --stdout "$ofile.bin" > "$object/otheros.bld"
|
||||||
;;
|
;;
|
||||||
|
|
|
@ -1104,6 +1104,16 @@ static struct cpu_spec __initdata cpu_specs[] = {
|
||||||
{
|
{
|
||||||
.pvr_mask = 0xf0000fff,
|
.pvr_mask = 0xf0000fff,
|
||||||
.pvr_value = 0x40000850,
|
.pvr_value = 0x40000850,
|
||||||
|
.cpu_name = "440GR Rev. A",
|
||||||
|
.cpu_features = CPU_FTRS_44X,
|
||||||
|
.cpu_user_features = COMMON_USER_BOOKE,
|
||||||
|
.icache_bsize = 32,
|
||||||
|
.dcache_bsize = 32,
|
||||||
|
.platform = "ppc440",
|
||||||
|
},
|
||||||
|
{ /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */
|
||||||
|
.pvr_mask = 0xf0000fff,
|
||||||
|
.pvr_value = 0x40000858,
|
||||||
.cpu_name = "440EP Rev. A",
|
.cpu_name = "440EP Rev. A",
|
||||||
.cpu_features = CPU_FTRS_44X,
|
.cpu_features = CPU_FTRS_44X,
|
||||||
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
|
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
|
||||||
|
@ -1115,6 +1125,16 @@ static struct cpu_spec __initdata cpu_specs[] = {
|
||||||
{
|
{
|
||||||
.pvr_mask = 0xf0000fff,
|
.pvr_mask = 0xf0000fff,
|
||||||
.pvr_value = 0x400008d3,
|
.pvr_value = 0x400008d3,
|
||||||
|
.cpu_name = "440GR Rev. B",
|
||||||
|
.cpu_features = CPU_FTRS_44X,
|
||||||
|
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
|
||||||
|
.icache_bsize = 32,
|
||||||
|
.dcache_bsize = 32,
|
||||||
|
.platform = "ppc440",
|
||||||
|
},
|
||||||
|
{ /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */
|
||||||
|
.pvr_mask = 0xf0000fff,
|
||||||
|
.pvr_value = 0x400008db,
|
||||||
.cpu_name = "440EP Rev. B",
|
.cpu_name = "440EP Rev. B",
|
||||||
.cpu_features = CPU_FTRS_44X,
|
.cpu_features = CPU_FTRS_44X,
|
||||||
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
|
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
|
||||||
|
@ -1123,20 +1143,9 @@ static struct cpu_spec __initdata cpu_specs[] = {
|
||||||
.cpu_setup = __setup_cpu_440ep,
|
.cpu_setup = __setup_cpu_440ep,
|
||||||
.platform = "ppc440",
|
.platform = "ppc440",
|
||||||
},
|
},
|
||||||
{ /* 440EPX */
|
|
||||||
.pvr_mask = 0xf0000ffb,
|
|
||||||
.pvr_value = 0x200008D0,
|
|
||||||
.cpu_name = "440EPX",
|
|
||||||
.cpu_features = CPU_FTRS_44X,
|
|
||||||
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
|
|
||||||
.icache_bsize = 32,
|
|
||||||
.dcache_bsize = 32,
|
|
||||||
.cpu_setup = __setup_cpu_440epx,
|
|
||||||
.platform = "ppc440",
|
|
||||||
},
|
|
||||||
{ /* 440GRX */
|
{ /* 440GRX */
|
||||||
.pvr_mask = 0xf0000ffb,
|
.pvr_mask = 0xf0000ffb,
|
||||||
.pvr_value = 0x200008D8,
|
.pvr_value = 0x200008D0,
|
||||||
.cpu_name = "440GRX",
|
.cpu_name = "440GRX",
|
||||||
.cpu_features = CPU_FTRS_44X,
|
.cpu_features = CPU_FTRS_44X,
|
||||||
.cpu_user_features = COMMON_USER_BOOKE,
|
.cpu_user_features = COMMON_USER_BOOKE,
|
||||||
|
@ -1145,6 +1154,17 @@ static struct cpu_spec __initdata cpu_specs[] = {
|
||||||
.cpu_setup = __setup_cpu_440grx,
|
.cpu_setup = __setup_cpu_440grx,
|
||||||
.platform = "ppc440",
|
.platform = "ppc440",
|
||||||
},
|
},
|
||||||
|
{ /* Use logical PVR for 440EPx (logical pvr = pvr | 0x8) */
|
||||||
|
.pvr_mask = 0xf0000ffb,
|
||||||
|
.pvr_value = 0x200008D8,
|
||||||
|
.cpu_name = "440EPX",
|
||||||
|
.cpu_features = CPU_FTRS_44X,
|
||||||
|
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
|
||||||
|
.icache_bsize = 32,
|
||||||
|
.dcache_bsize = 32,
|
||||||
|
.cpu_setup = __setup_cpu_440epx,
|
||||||
|
.platform = "ppc440",
|
||||||
|
},
|
||||||
{ /* 440GP Rev. B */
|
{ /* 440GP Rev. B */
|
||||||
.pvr_mask = 0xf0000fff,
|
.pvr_mask = 0xf0000fff,
|
||||||
.pvr_value = 0x40000440,
|
.pvr_value = 0x40000440,
|
||||||
|
|
|
@ -244,6 +244,13 @@ syscall_exit_cont:
|
||||||
andis. r10,r0,DBCR0_IC@h
|
andis. r10,r0,DBCR0_IC@h
|
||||||
bnel- load_dbcr0
|
bnel- load_dbcr0
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_44x
|
||||||
|
lis r4,icache_44x_need_flush@ha
|
||||||
|
lwz r5,icache_44x_need_flush@l(r4)
|
||||||
|
cmplwi cr0,r5,0
|
||||||
|
bne- 2f
|
||||||
|
1:
|
||||||
|
#endif /* CONFIG_44x */
|
||||||
stwcx. r0,0,r1 /* to clear the reservation */
|
stwcx. r0,0,r1 /* to clear the reservation */
|
||||||
lwz r4,_LINK(r1)
|
lwz r4,_LINK(r1)
|
||||||
lwz r5,_CCR(r1)
|
lwz r5,_CCR(r1)
|
||||||
|
@ -258,6 +265,12 @@ syscall_exit_cont:
|
||||||
mtspr SPRN_SRR1,r8
|
mtspr SPRN_SRR1,r8
|
||||||
SYNC
|
SYNC
|
||||||
RFI
|
RFI
|
||||||
|
#ifdef CONFIG_44x
|
||||||
|
2: li r7,0
|
||||||
|
iccci r0,r0
|
||||||
|
stw r7,icache_44x_need_flush@l(r4)
|
||||||
|
b 1b
|
||||||
|
#endif /* CONFIG_44x */
|
||||||
|
|
||||||
66: li r3,-ENOSYS
|
66: li r3,-ENOSYS
|
||||||
b ret_from_syscall
|
b ret_from_syscall
|
||||||
|
@ -683,6 +696,16 @@ resume_kernel:
|
||||||
|
|
||||||
/* interrupts are hard-disabled at this point */
|
/* interrupts are hard-disabled at this point */
|
||||||
restore:
|
restore:
|
||||||
|
#ifdef CONFIG_44x
|
||||||
|
lis r4,icache_44x_need_flush@ha
|
||||||
|
lwz r5,icache_44x_need_flush@l(r4)
|
||||||
|
cmplwi cr0,r5,0
|
||||||
|
beq+ 1f
|
||||||
|
li r6,0
|
||||||
|
iccci r0,r0
|
||||||
|
stw r6,icache_44x_need_flush@l(r4)
|
||||||
|
1:
|
||||||
|
#endif /* CONFIG_44x */
|
||||||
lwz r0,GPR0(r1)
|
lwz r0,GPR0(r1)
|
||||||
lwz r2,GPR2(r1)
|
lwz r2,GPR2(r1)
|
||||||
REST_4GPRS(3, r1)
|
REST_4GPRS(3, r1)
|
||||||
|
|
|
@ -288,7 +288,16 @@ _GLOBAL(_tlbia)
|
||||||
*/
|
*/
|
||||||
_GLOBAL(_tlbie)
|
_GLOBAL(_tlbie)
|
||||||
#if defined(CONFIG_40x)
|
#if defined(CONFIG_40x)
|
||||||
|
/* We run the search with interrupts disabled because we have to change
|
||||||
|
* the PID and I don't want to preempt when that happens.
|
||||||
|
*/
|
||||||
|
mfmsr r5
|
||||||
|
mfspr r6,SPRN_PID
|
||||||
|
wrteei 0
|
||||||
|
mtspr SPRN_PID,r4
|
||||||
tlbsx. r3, 0, r3
|
tlbsx. r3, 0, r3
|
||||||
|
mtspr SPRN_PID,r6
|
||||||
|
wrtee r5
|
||||||
bne 10f
|
bne 10f
|
||||||
sync
|
sync
|
||||||
/* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
|
/* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
|
||||||
|
@ -297,23 +306,23 @@ _GLOBAL(_tlbie)
|
||||||
tlbwe r3, r3, TLB_TAG
|
tlbwe r3, r3, TLB_TAG
|
||||||
isync
|
isync
|
||||||
10:
|
10:
|
||||||
|
|
||||||
#elif defined(CONFIG_44x)
|
#elif defined(CONFIG_44x)
|
||||||
mfspr r4,SPRN_MMUCR
|
mfspr r5,SPRN_MMUCR
|
||||||
mfspr r5,SPRN_PID /* Get PID */
|
rlwimi r5,r4,0,24,31 /* Set TID */
|
||||||
rlwimi r4,r5,0,24,31 /* Set TID */
|
|
||||||
|
|
||||||
/* We have to run the search with interrupts disabled, even critical
|
/* We have to run the search with interrupts disabled, even critical
|
||||||
* and debug interrupts (in fact the only critical exceptions we have
|
* and debug interrupts (in fact the only critical exceptions we have
|
||||||
* are debug and machine check). Otherwise an interrupt which causes
|
* are debug and machine check). Otherwise an interrupt which causes
|
||||||
* a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */
|
* a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */
|
||||||
mfmsr r5
|
mfmsr r4
|
||||||
lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha
|
lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha
|
||||||
addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
|
addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
|
||||||
andc r6,r5,r6
|
andc r6,r4,r6
|
||||||
mtmsr r6
|
mtmsr r6
|
||||||
mtspr SPRN_MMUCR,r4
|
mtspr SPRN_MMUCR,r5
|
||||||
tlbsx. r3, 0, r3
|
tlbsx. r3, 0, r3
|
||||||
mtmsr r5
|
mtmsr r4
|
||||||
bne 10f
|
bne 10f
|
||||||
sync
|
sync
|
||||||
/* There are only 64 TLB entries, so r3 < 64,
|
/* There are only 64 TLB entries, so r3 < 64,
|
||||||
|
@ -534,12 +543,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
|
||||||
addi r3,r3,L1_CACHE_BYTES
|
addi r3,r3,L1_CACHE_BYTES
|
||||||
bdnz 0b
|
bdnz 0b
|
||||||
sync
|
sync
|
||||||
|
#ifndef CONFIG_44x
|
||||||
|
/* We don't flush the icache on 44x. Those have a virtual icache
|
||||||
|
* and we don't have access to the virtual address here (it's
|
||||||
|
* not the page vaddr but where it's mapped in user space). The
|
||||||
|
* flushing of the icache on these is handled elsewhere, when
|
||||||
|
* a change in the address space occurs, before returning to
|
||||||
|
* user space
|
||||||
|
*/
|
||||||
mtctr r4
|
mtctr r4
|
||||||
1: icbi 0,r6
|
1: icbi 0,r6
|
||||||
addi r6,r6,L1_CACHE_BYTES
|
addi r6,r6,L1_CACHE_BYTES
|
||||||
bdnz 1b
|
bdnz 1b
|
||||||
sync
|
sync
|
||||||
isync
|
isync
|
||||||
|
#endif /* CONFIG_44x */
|
||||||
blr
|
blr
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -697,6 +697,18 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
|
||||||
prop = of_get_flat_dt_prop(node, "cpu-version", NULL);
|
prop = of_get_flat_dt_prop(node, "cpu-version", NULL);
|
||||||
if (prop && (*prop & 0xff000000) == 0x0f000000)
|
if (prop && (*prop & 0xff000000) == 0x0f000000)
|
||||||
identify_cpu(0, *prop);
|
identify_cpu(0, *prop);
|
||||||
|
#if defined(CONFIG_44x) && defined(CONFIG_PPC_FPU)
|
||||||
|
/*
|
||||||
|
* Since 440GR(x)/440EP(x) processors have the same pvr,
|
||||||
|
* we check the node path and set bit 28 in the cur_cpu_spec
|
||||||
|
* pvr for EP(x) processor version. This bit is always 0 in
|
||||||
|
* the "real" pvr. Then we call identify_cpu again with
|
||||||
|
* the new logical pvr to enable FPU support.
|
||||||
|
*/
|
||||||
|
if (strstr(uname, "440EP")) {
|
||||||
|
identify_cpu(0, cur_cpu_spec->pvr_value | 0x8);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
check_cpu_feature_properties(node);
|
check_cpu_feature_properties(node);
|
||||||
|
|
|
@ -98,13 +98,12 @@ unsigned long __init mmu_mapin_ram(void)
|
||||||
|
|
||||||
v = KERNELBASE;
|
v = KERNELBASE;
|
||||||
p = PPC_MEMSTART;
|
p = PPC_MEMSTART;
|
||||||
s = 0;
|
s = total_lowmem;
|
||||||
|
|
||||||
if (__map_without_ltlbs) {
|
if (__map_without_ltlbs)
|
||||||
return s;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
while (s <= (total_lowmem - LARGE_PAGE_SIZE_16M)) {
|
while (s >= LARGE_PAGE_SIZE_16M) {
|
||||||
pmd_t *pmdp;
|
pmd_t *pmdp;
|
||||||
unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
|
unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
|
||||||
|
|
||||||
|
@ -116,10 +115,10 @@ unsigned long __init mmu_mapin_ram(void)
|
||||||
|
|
||||||
v += LARGE_PAGE_SIZE_16M;
|
v += LARGE_PAGE_SIZE_16M;
|
||||||
p += LARGE_PAGE_SIZE_16M;
|
p += LARGE_PAGE_SIZE_16M;
|
||||||
s += LARGE_PAGE_SIZE_16M;
|
s -= LARGE_PAGE_SIZE_16M;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (s <= (total_lowmem - LARGE_PAGE_SIZE_4M)) {
|
while (s >= LARGE_PAGE_SIZE_4M) {
|
||||||
pmd_t *pmdp;
|
pmd_t *pmdp;
|
||||||
unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
|
unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
|
||||||
|
|
||||||
|
@ -128,8 +127,8 @@ unsigned long __init mmu_mapin_ram(void)
|
||||||
|
|
||||||
v += LARGE_PAGE_SIZE_4M;
|
v += LARGE_PAGE_SIZE_4M;
|
||||||
p += LARGE_PAGE_SIZE_4M;
|
p += LARGE_PAGE_SIZE_4M;
|
||||||
s += LARGE_PAGE_SIZE_4M;
|
s -= LARGE_PAGE_SIZE_4M;
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return total_lowmem - s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
*/
|
*/
|
||||||
unsigned int tlb_44x_index; /* = 0 */
|
unsigned int tlb_44x_index; /* = 0 */
|
||||||
unsigned int tlb_44x_hwater = PPC44x_TLB_SIZE - 1 - PPC44x_EARLY_TLBS;
|
unsigned int tlb_44x_hwater = PPC44x_TLB_SIZE - 1 - PPC44x_EARLY_TLBS;
|
||||||
|
int icache_44x_need_flush;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "Pins" a 256MB TLB entry in AS0 for kernel lowmem
|
* "Pins" a 256MB TLB entry in AS0 for kernel lowmem
|
||||||
|
|
|
@ -309,7 +309,7 @@ good_area:
|
||||||
set_bit(PG_arch_1, &page->flags);
|
set_bit(PG_arch_1, &page->flags);
|
||||||
}
|
}
|
||||||
pte_update(ptep, 0, _PAGE_HWEXEC);
|
pte_update(ptep, 0, _PAGE_HWEXEC);
|
||||||
_tlbie(address);
|
_tlbie(address, mm->context.id);
|
||||||
pte_unmap_unlock(ptep, ptl);
|
pte_unmap_unlock(ptep, ptl);
|
||||||
up_read(&mm->mmap_sem);
|
up_read(&mm->mmap_sem);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -61,12 +61,12 @@ extern unsigned long total_lowmem;
|
||||||
#define mmu_mapin_ram() (0UL)
|
#define mmu_mapin_ram() (0UL)
|
||||||
|
|
||||||
#elif defined(CONFIG_4xx)
|
#elif defined(CONFIG_4xx)
|
||||||
#define flush_HPTE(X, va, pg) _tlbie(va)
|
#define flush_HPTE(pid, va, pg) _tlbie(va, pid)
|
||||||
extern void MMU_init_hw(void);
|
extern void MMU_init_hw(void);
|
||||||
extern unsigned long mmu_mapin_ram(void);
|
extern unsigned long mmu_mapin_ram(void);
|
||||||
|
|
||||||
#elif defined(CONFIG_FSL_BOOKE)
|
#elif defined(CONFIG_FSL_BOOKE)
|
||||||
#define flush_HPTE(X, va, pg) _tlbie(va)
|
#define flush_HPTE(pid, va, pg) _tlbie(va, pid)
|
||||||
extern void MMU_init_hw(void);
|
extern void MMU_init_hw(void);
|
||||||
extern unsigned long mmu_mapin_ram(void);
|
extern unsigned long mmu_mapin_ram(void);
|
||||||
extern void adjust_total_lowmem(void);
|
extern void adjust_total_lowmem(void);
|
||||||
|
|
|
@ -244,6 +244,13 @@ syscall_exit_cont:
|
||||||
andis. r10,r0,DBCR0_IC@h
|
andis. r10,r0,DBCR0_IC@h
|
||||||
bnel- load_dbcr0
|
bnel- load_dbcr0
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_44x
|
||||||
|
lis r4,icache_44x_need_flush@ha
|
||||||
|
lwz r5,icache_44x_need_flush@l(r4)
|
||||||
|
cmplwi cr0,r5,0
|
||||||
|
bne- 2f
|
||||||
|
1:
|
||||||
|
#endif /* CONFIG_44x */
|
||||||
stwcx. r0,0,r1 /* to clear the reservation */
|
stwcx. r0,0,r1 /* to clear the reservation */
|
||||||
lwz r4,_LINK(r1)
|
lwz r4,_LINK(r1)
|
||||||
lwz r5,_CCR(r1)
|
lwz r5,_CCR(r1)
|
||||||
|
@ -258,6 +265,12 @@ syscall_exit_cont:
|
||||||
mtspr SPRN_SRR1,r8
|
mtspr SPRN_SRR1,r8
|
||||||
SYNC
|
SYNC
|
||||||
RFI
|
RFI
|
||||||
|
#ifdef CONFIG_44x
|
||||||
|
2: li r7,0
|
||||||
|
iccci r0,r0
|
||||||
|
stw r7,icache_44x_need_flush@l(r4)
|
||||||
|
b 1b
|
||||||
|
#endif /* CONFIG_44x */
|
||||||
|
|
||||||
66: li r3,-ENOSYS
|
66: li r3,-ENOSYS
|
||||||
b ret_from_syscall
|
b ret_from_syscall
|
||||||
|
@ -679,6 +692,16 @@ resume_kernel:
|
||||||
|
|
||||||
/* interrupts are hard-disabled at this point */
|
/* interrupts are hard-disabled at this point */
|
||||||
restore:
|
restore:
|
||||||
|
#ifdef CONFIG_44x
|
||||||
|
lis r4,icache_44x_need_flush@ha
|
||||||
|
lwz r5,icache_44x_need_flush@l(r4)
|
||||||
|
cmplwi cr0,r5,0
|
||||||
|
beq+ 1f
|
||||||
|
li r6,0
|
||||||
|
iccci r0,r0
|
||||||
|
stw r6,icache_44x_need_flush@l(r4)
|
||||||
|
1:
|
||||||
|
#endif /* CONFIG_44x */
|
||||||
lwz r0,GPR0(r1)
|
lwz r0,GPR0(r1)
|
||||||
lwz r2,GPR2(r1)
|
lwz r2,GPR2(r1)
|
||||||
REST_4GPRS(3, r1)
|
REST_4GPRS(3, r1)
|
||||||
|
|
|
@ -224,7 +224,16 @@ _GLOBAL(_tlbia)
|
||||||
*/
|
*/
|
||||||
_GLOBAL(_tlbie)
|
_GLOBAL(_tlbie)
|
||||||
#if defined(CONFIG_40x)
|
#if defined(CONFIG_40x)
|
||||||
|
/* We run the search with interrupts disabled because we have to change
|
||||||
|
* the PID and I don't want to preempt when that happens.
|
||||||
|
*/
|
||||||
|
mfmsr r5
|
||||||
|
mfspr r6,SPRN_PID
|
||||||
|
wrteei 0
|
||||||
|
mtspr SPRN_PID,r4
|
||||||
tlbsx. r3, 0, r3
|
tlbsx. r3, 0, r3
|
||||||
|
mtspr SPRN_PID,r6
|
||||||
|
wrtee r5
|
||||||
bne 10f
|
bne 10f
|
||||||
sync
|
sync
|
||||||
/* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
|
/* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
|
||||||
|
@ -234,22 +243,21 @@ _GLOBAL(_tlbie)
|
||||||
isync
|
isync
|
||||||
10:
|
10:
|
||||||
#elif defined(CONFIG_44x)
|
#elif defined(CONFIG_44x)
|
||||||
mfspr r4,SPRN_MMUCR
|
mfspr r5,SPRN_MMUCR
|
||||||
mfspr r5,SPRN_PID /* Get PID */
|
rlwimi r5,r4,0,24,31 /* Set TID */
|
||||||
rlwimi r4,r5,0,24,31 /* Set TID */
|
|
||||||
|
|
||||||
/* We have to run the search with interrupts disabled, even critical
|
/* We have to run the search with interrupts disabled, even critical
|
||||||
* and debug interrupts (in fact the only critical exceptions we have
|
* and debug interrupts (in fact the only critical exceptions we have
|
||||||
* are debug and machine check). Otherwise an interrupt which causes
|
* are debug and machine check). Otherwise an interrupt which causes
|
||||||
* a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */
|
* a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */
|
||||||
mfmsr r5
|
mfmsr r4
|
||||||
lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha
|
lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha
|
||||||
addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
|
addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
|
||||||
andc r6,r5,r6
|
andc r6,r4,r6
|
||||||
mtmsr r6
|
mtmsr r6
|
||||||
mtspr SPRN_MMUCR,r4
|
mtspr SPRN_MMUCR,r5
|
||||||
tlbsx. r3, 0, r3
|
tlbsx. r3, 0, r3
|
||||||
mtmsr r5
|
mtmsr r4
|
||||||
bne 10f
|
bne 10f
|
||||||
sync
|
sync
|
||||||
/* There are only 64 TLB entries, so r3 < 64,
|
/* There are only 64 TLB entries, so r3 < 64,
|
||||||
|
@ -491,12 +499,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
|
||||||
addi r3,r3,L1_CACHE_BYTES
|
addi r3,r3,L1_CACHE_BYTES
|
||||||
bdnz 0b
|
bdnz 0b
|
||||||
sync
|
sync
|
||||||
|
#ifndef CONFIG_44x
|
||||||
|
/* We don't flush the icache on 44x. Those have a virtual icache
|
||||||
|
* and we don't have access to the virtual address here (it's
|
||||||
|
* not the page vaddr but where it's mapped in user space). The
|
||||||
|
* flushing of the icache on these is handled elsewhere, when
|
||||||
|
* a change in the address space occurs, before returning to
|
||||||
|
* user space
|
||||||
|
*/
|
||||||
mtctr r4
|
mtctr r4
|
||||||
1: icbi 0,r6
|
1: icbi 0,r6
|
||||||
addi r6,r6,L1_CACHE_BYTES
|
addi r6,r6,L1_CACHE_BYTES
|
||||||
bdnz 1b
|
bdnz 1b
|
||||||
sync
|
sync
|
||||||
isync
|
isync
|
||||||
|
#endif /* CONFIG_44x */
|
||||||
blr
|
blr
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -61,6 +61,7 @@ extern char etext[], _stext[];
|
||||||
*/
|
*/
|
||||||
unsigned int tlb_44x_index = 0;
|
unsigned int tlb_44x_index = 0;
|
||||||
unsigned int tlb_44x_hwater = 62;
|
unsigned int tlb_44x_hwater = 62;
|
||||||
|
int icache_44x_need_flush;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "Pins" a 256MB TLB entry in AS0 for kernel lowmem
|
* "Pins" a 256MB TLB entry in AS0 for kernel lowmem
|
||||||
|
|
|
@ -99,13 +99,12 @@ unsigned long __init mmu_mapin_ram(void)
|
||||||
|
|
||||||
v = KERNELBASE;
|
v = KERNELBASE;
|
||||||
p = PPC_MEMSTART;
|
p = PPC_MEMSTART;
|
||||||
s = 0;
|
s = total_lowmem;
|
||||||
|
|
||||||
if (__map_without_ltlbs) {
|
if (__map_without_ltlbs)
|
||||||
return s;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
while (s <= (total_lowmem - LARGE_PAGE_SIZE_16M)) {
|
while (s >= LARGE_PAGE_SIZE_16M) {
|
||||||
pmd_t *pmdp;
|
pmd_t *pmdp;
|
||||||
unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
|
unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
|
||||||
|
|
||||||
|
@ -117,10 +116,10 @@ unsigned long __init mmu_mapin_ram(void)
|
||||||
|
|
||||||
v += LARGE_PAGE_SIZE_16M;
|
v += LARGE_PAGE_SIZE_16M;
|
||||||
p += LARGE_PAGE_SIZE_16M;
|
p += LARGE_PAGE_SIZE_16M;
|
||||||
s += LARGE_PAGE_SIZE_16M;
|
s -= LARGE_PAGE_SIZE_16M;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (s <= (total_lowmem - LARGE_PAGE_SIZE_4M)) {
|
while (s >= LARGE_PAGE_SIZE_4M) {
|
||||||
pmd_t *pmdp;
|
pmd_t *pmdp;
|
||||||
unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
|
unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
|
||||||
|
|
||||||
|
@ -129,8 +128,8 @@ unsigned long __init mmu_mapin_ram(void)
|
||||||
|
|
||||||
v += LARGE_PAGE_SIZE_4M;
|
v += LARGE_PAGE_SIZE_4M;
|
||||||
p += LARGE_PAGE_SIZE_4M;
|
p += LARGE_PAGE_SIZE_4M;
|
||||||
s += LARGE_PAGE_SIZE_4M;
|
s -= LARGE_PAGE_SIZE_4M;
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return total_lowmem - s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,7 +227,7 @@ good_area:
|
||||||
set_bit(PG_arch_1, &page->flags);
|
set_bit(PG_arch_1, &page->flags);
|
||||||
}
|
}
|
||||||
pte_update(ptep, 0, _PAGE_HWEXEC);
|
pte_update(ptep, 0, _PAGE_HWEXEC);
|
||||||
_tlbie(address);
|
_tlbie(address, mm->context.id);
|
||||||
pte_unmap_unlock(ptep, ptl);
|
pte_unmap_unlock(ptep, ptl);
|
||||||
up_read(&mm->mmap_sem);
|
up_read(&mm->mmap_sem);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -54,12 +54,12 @@ extern unsigned int num_tlbcam_entries;
|
||||||
#define mmu_mapin_ram() (0UL)
|
#define mmu_mapin_ram() (0UL)
|
||||||
|
|
||||||
#elif defined(CONFIG_4xx)
|
#elif defined(CONFIG_4xx)
|
||||||
#define flush_HPTE(X, va, pg) _tlbie(va)
|
#define flush_HPTE(pid, va, pg) _tlbie(va, pid)
|
||||||
extern void MMU_init_hw(void);
|
extern void MMU_init_hw(void);
|
||||||
extern unsigned long mmu_mapin_ram(void);
|
extern unsigned long mmu_mapin_ram(void);
|
||||||
|
|
||||||
#elif defined(CONFIG_FSL_BOOKE)
|
#elif defined(CONFIG_FSL_BOOKE)
|
||||||
#define flush_HPTE(X, va, pg) _tlbie(va)
|
#define flush_HPTE(pid, va, pg) _tlbie(va, pid)
|
||||||
extern void MMU_init_hw(void);
|
extern void MMU_init_hw(void);
|
||||||
extern unsigned long mmu_mapin_ram(void);
|
extern unsigned long mmu_mapin_ram(void);
|
||||||
extern void adjust_total_lowmem(void);
|
extern void adjust_total_lowmem(void);
|
||||||
|
|
|
@ -236,7 +236,7 @@ ebony_early_serial_map(void)
|
||||||
gen550_init(0, &port);
|
gen550_init(0, &port);
|
||||||
|
|
||||||
/* Purge TLB entry added in head_44x.S for early serial access */
|
/* Purge TLB entry added in head_44x.S for early serial access */
|
||||||
_tlbie(UART0_IO_BASE);
|
_tlbie(UART0_IO_BASE, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
port.membase = ioremap64(PPC440GP_UART1_ADDR, 8);
|
port.membase = ioremap64(PPC440GP_UART1_ADDR, 8);
|
||||||
|
|
|
@ -230,10 +230,15 @@ luan_setup_hoses(void)
|
||||||
|
|
||||||
/* Allocate hoses for PCIX1 and PCIX2 */
|
/* Allocate hoses for PCIX1 and PCIX2 */
|
||||||
hose1 = pcibios_alloc_controller();
|
hose1 = pcibios_alloc_controller();
|
||||||
hose2 = pcibios_alloc_controller();
|
if (!hose1)
|
||||||
if (!hose1 || !hose2)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
hose2 = pcibios_alloc_controller();
|
||||||
|
if (!hose2) {
|
||||||
|
pcibios_free_controller(hose1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup PCIX1 */
|
/* Setup PCIX1 */
|
||||||
hose1->first_busno = 0;
|
hose1->first_busno = 0;
|
||||||
hose1->last_busno = 0xff;
|
hose1->last_busno = 0xff;
|
||||||
|
|
|
@ -259,7 +259,7 @@ ocotea_early_serial_map(void)
|
||||||
gen550_init(0, &port);
|
gen550_init(0, &port);
|
||||||
|
|
||||||
/* Purge TLB entry added in head_44x.S for early serial access */
|
/* Purge TLB entry added in head_44x.S for early serial access */
|
||||||
_tlbie(UART0_IO_BASE);
|
_tlbie(UART0_IO_BASE, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);
|
port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);
|
||||||
|
|
|
@ -316,7 +316,7 @@ taishan_early_serial_map(void)
|
||||||
gen550_init(0, &port);
|
gen550_init(0, &port);
|
||||||
|
|
||||||
/* Purge TLB entry added in head_44x.S for early serial access */
|
/* Purge TLB entry added in head_44x.S for early serial access */
|
||||||
_tlbie(UART0_IO_BASE);
|
_tlbie(UART0_IO_BASE, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);
|
port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);
|
||||||
|
|
|
@ -329,12 +329,14 @@ static struct uart_ops ulite_ops = {
|
||||||
static void ulite_console_wait_tx(struct uart_port *port)
|
static void ulite_console_wait_tx(struct uart_port *port)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
u8 val;
|
||||||
|
|
||||||
/* wait up to 10ms for the character(s) to be sent */
|
/* Spin waiting for TX fifo to have space available */
|
||||||
for (i = 0; i < 10000; i++) {
|
for (i = 0; i < 100000; i++) {
|
||||||
if (readb(port->membase + ULITE_STATUS) & ULITE_STATUS_TXEMPTY)
|
val = readb(port->membase + ULITE_STATUS);
|
||||||
|
if ((val & ULITE_STATUS_TXFULL) == 0)
|
||||||
break;
|
break;
|
||||||
udelay(1);
|
cpu_relax();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,11 @@
|
||||||
extern unsigned long va_to_phys(unsigned long address);
|
extern unsigned long va_to_phys(unsigned long address);
|
||||||
extern pte_t *va_to_pte(unsigned long address);
|
extern pte_t *va_to_pte(unsigned long address);
|
||||||
extern unsigned long ioremap_bot, ioremap_base;
|
extern unsigned long ioremap_bot, ioremap_base;
|
||||||
|
|
||||||
|
#ifdef CONFIG_44x
|
||||||
|
extern int icache_44x_need_flush;
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -562,6 +567,10 @@ static inline unsigned long pte_update(pte_t *p, unsigned long clr,
|
||||||
: "=&r" (old), "=&r" (tmp), "=m" (*p)
|
: "=&r" (old), "=&r" (tmp), "=m" (*p)
|
||||||
: "r" (p), "r" (clr), "r" (set), "m" (*p)
|
: "r" (p), "r" (clr), "r" (set), "m" (*p)
|
||||||
: "cc" );
|
: "cc" );
|
||||||
|
#ifdef CONFIG_44x
|
||||||
|
if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
|
||||||
|
icache_44x_need_flush = 1;
|
||||||
|
#endif
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -582,6 +591,10 @@ static inline unsigned long long pte_update(pte_t *p, unsigned long clr,
|
||||||
: "=&r" (old), "=&r" (tmp), "=m" (*p)
|
: "=&r" (old), "=&r" (tmp), "=m" (*p)
|
||||||
: "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p)
|
: "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p)
|
||||||
: "cc" );
|
: "cc" );
|
||||||
|
#ifdef CONFIG_44x
|
||||||
|
if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
|
||||||
|
icache_44x_need_flush = 1;
|
||||||
|
#endif
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#ifndef _ASM_POWERPC_TLBFLUSH_H
|
#ifndef _ASM_POWERPC_TLBFLUSH_H
|
||||||
#define _ASM_POWERPC_TLBFLUSH_H
|
#define _ASM_POWERPC_TLBFLUSH_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TLB flushing:
|
* TLB flushing:
|
||||||
*
|
*
|
||||||
|
@ -16,9 +17,6 @@
|
||||||
*/
|
*/
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
struct mm_struct;
|
|
||||||
struct vm_area_struct;
|
|
||||||
|
|
||||||
#if defined(CONFIG_4xx) || defined(CONFIG_8xx) || defined(CONFIG_FSL_BOOKE)
|
#if defined(CONFIG_4xx) || defined(CONFIG_8xx) || defined(CONFIG_FSL_BOOKE)
|
||||||
/*
|
/*
|
||||||
* TLB flushing for software loaded TLB chips
|
* TLB flushing for software loaded TLB chips
|
||||||
|
@ -28,7 +26,9 @@ struct vm_area_struct;
|
||||||
* specific tlbie's
|
* specific tlbie's
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern void _tlbie(unsigned long address);
|
#include <linux/mm.h>
|
||||||
|
|
||||||
|
extern void _tlbie(unsigned long address, unsigned int pid);
|
||||||
|
|
||||||
#if defined(CONFIG_40x) || defined(CONFIG_8xx)
|
#if defined(CONFIG_40x) || defined(CONFIG_8xx)
|
||||||
#define _tlbia() asm volatile ("tlbia; sync" : : : "memory")
|
#define _tlbia() asm volatile ("tlbia; sync" : : : "memory")
|
||||||
|
@ -44,13 +44,13 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
|
||||||
static inline void flush_tlb_page(struct vm_area_struct *vma,
|
static inline void flush_tlb_page(struct vm_area_struct *vma,
|
||||||
unsigned long vmaddr)
|
unsigned long vmaddr)
|
||||||
{
|
{
|
||||||
_tlbie(vmaddr);
|
_tlbie(vmaddr, vma->vm_mm->context.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
|
static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
|
||||||
unsigned long vmaddr)
|
unsigned long vmaddr)
|
||||||
{
|
{
|
||||||
_tlbie(vmaddr);
|
_tlbie(vmaddr, vma->vm_mm->context.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void flush_tlb_range(struct vm_area_struct *vma,
|
static inline void flush_tlb_range(struct vm_area_struct *vma,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче