Merge with rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git

This commit is contained in:
Jaroslav Kysela 2005-11-07 11:02:51 +01:00
commit 1d4ae4a119
492 changed files with 46640 additions and 44600 deletions

View File

@ -239,9 +239,9 @@ X!Ilib/string.c
<title>Network device support</title>
<sect1><title>Driver Support</title>
!Enet/core/dev.c
</sect1>
<sect1><title>8390 Based Network Cards</title>
!Edrivers/net/8390.c
!Enet/ethernet/eth.c
!Einclude/linux/etherdevice.h
!Enet/core/wireless.c
</sect1>
<sect1><title>Synchronous PPP</title>
!Edrivers/net/wan/syncppp.c

View File

@ -8,10 +8,9 @@ Compilation of kernel
---------------------
In order to compile ARM Linux, you will need a compiler capable of
generating ARM ELF code with GNU extensions. GCC 2.95.1, EGCS
1.1.2, and GCC 3.3 are known to be good compilers. Fortunately, you
needn't guess. The kernel will report an error if your compiler is
a recognized offender.
generating ARM ELF code with GNU extensions. GCC 3.3 is known to be
a good compiler. Fortunately, you needn't guess. The kernel will report
an error if your compiler is a recognized offender.
To build ARM Linux natively, you shouldn't have to alter the ARCH = line
in the top level Makefile. However, if you don't have the ARM Linux ELF

View File

@ -1,48 +1,153 @@
S2IO Technologies XFrame 10 Gig adapter.
-------------------------------------------
Release notes for Neterion's (Formerly S2io) Xframe I/II PCI-X 10GbE driver.
I. Module loadable parameters.
When loaded as a module, the driver provides a host of Module loadable
parameters, so the device can be tuned as per the users needs.
A list of the Module params is given below.
(i) ring_num: This can be used to program the number of
receive rings used in the driver.
(ii) ring_len: This defines the number of descriptors each ring
can have. There can be a maximum of 8 rings.
(iii) frame_len: This is an array of size 8. Using this we can
set the maximum size of the received frame that can
be steered into the corrsponding receive ring.
(iv) fifo_num: This defines the number of Tx FIFOs thats used in
the driver.
(v) fifo_len: Each element defines the number of
Tx descriptors that can be associated with each
corresponding FIFO. There are a maximum of 8 FIFOs.
(vi) tx_prio: This is a bool, if module is loaded with a non-zero
value for tx_prio multi FIFO scheme is activated.
(vii) rx_prio: This is a bool, if module is loaded with a non-zero
value for tx_prio multi RING scheme is activated.
(viii) latency_timer: The value given against this param will be
loaded into the latency timer register in PCI Config
space, else the register is left with its reset value.
Contents
=======
- 1. Introduction
- 2. Identifying the adapter/interface
- 3. Features supported
- 4. Command line parameters
- 5. Performance suggestions
- 6. Available Downloads
II. Performance tuning.
By changing a few sysctl parameters.
Copy the following lines into a file and run the following command,
"sysctl -p <file_name>"
### IPV4 specific settings
net.ipv4.tcp_timestamps = 0 # turns TCP timestamp support off, default 1, reduces CPU use
net.ipv4.tcp_sack = 0 # turn SACK support off, default on
# on systems with a VERY fast bus -> memory interface this is the big gainer
net.ipv4.tcp_rmem = 10000000 10000000 10000000 # sets min/default/max TCP read buffer, default 4096 87380 174760
net.ipv4.tcp_wmem = 10000000 10000000 10000000 # sets min/pressure/max TCP write buffer, default 4096 16384 131072
net.ipv4.tcp_mem = 10000000 10000000 10000000 # sets min/pressure/max TCP buffer space, default 31744 32256 32768
### CORE settings (mostly for socket and UDP effect)
net.core.rmem_max = 524287 # maximum receive socket buffer size, default 131071
net.core.wmem_max = 524287 # maximum send socket buffer size, default 131071
net.core.rmem_default = 524287 # default receive socket buffer size, default 65535
net.core.wmem_default = 524287 # default send socket buffer size, default 65535
net.core.optmem_max = 524287 # maximum amount of option memory buffers, default 10240
net.core.netdev_max_backlog = 300000 # number of unprocessed input packets before kernel starts dropping them, default 300
---End of performance tuning file---
1. Introduction:
This Linux driver supports Neterion's Xframe I PCI-X 1.0 and
Xframe II PCI-X 2.0 adapters. It supports several features
such as jumbo frames, MSI/MSI-X, checksum offloads, TSO, UFO and so on.
See below for complete list of features.
All features are supported for both IPv4 and IPv6.
2. Identifying the adapter/interface:
a. Insert the adapter(s) in your system.
b. Build and load driver
# insmod s2io.ko
c. View log messages
# dmesg | tail -40
You will see messages similar to:
eth3: Neterion Xframe I 10GbE adapter (rev 3), Version 2.0.9.1, Intr type INTA
eth4: Neterion Xframe II 10GbE adapter (rev 2), Version 2.0.9.1, Intr type INTA
eth4: Device is on 64 bit 133MHz PCIX(M1) bus
The above messages identify the adapter type(Xframe I/II), adapter revision,
driver version, interface name(eth3, eth4), Interrupt type(INTA, MSI, MSI-X).
In case of Xframe II, the PCI/PCI-X bus width and frequency are displayed
as well.
To associate an interface with a physical adapter use "ethtool -p <ethX>".
The corresponding adapter's LED will blink multiple times.
3. Features supported:
a. Jumbo frames. Xframe I/II supports MTU upto 9600 bytes,
modifiable using ifconfig command.
b. Offloads. Supports checksum offload(TCP/UDP/IP) on transmit
and receive, TSO.
c. Multi-buffer receive mode. Scattering of packet across multiple
buffers. Currently driver supports 2-buffer mode which yields
significant performance improvement on certain platforms(SGI Altix,
IBM xSeries).
d. MSI/MSI-X. Can be enabled on platforms which support this feature
(IA64, Xeon) resulting in noticeable performance improvement(upto 7%
on certain platforms).
e. NAPI. Compile-time option(CONFIG_S2IO_NAPI) for better Rx interrupt
moderation.
f. Statistics. Comprehensive MAC-level and software statistics displayed
using "ethtool -S" option.
g. Multi-FIFO/Ring. Supports up to 8 transmit queues and receive rings,
with multiple steering options.
4. Command line parameters
a. tx_fifo_num
Number of transmit queues
Valid range: 1-8
Default: 1
b. rx_ring_num
Number of receive rings
Valid range: 1-8
Default: 1
c. tx_fifo_len
Size of each transmit queue
Valid range: Total length of all queues should not exceed 8192
Default: 4096
d. rx_ring_sz
Size of each receive ring(in 4K blocks)
Valid range: Limited by memory on system
Default: 30
e. intr_type
Specifies interrupt type. Possible values 1(INTA), 2(MSI), 3(MSI-X)
Valid range: 1-3
Default: 1
5. Performance suggestions
General:
a. Set MTU to maximum(9000 for switch setup, 9600 in back-to-back configuration)
b. Set TCP windows size to optimal value.
For instance, for MTU=1500 a value of 210K has been observed to result in
good performance.
# sysctl -w net.ipv4.tcp_rmem="210000 210000 210000"
# sysctl -w net.ipv4.tcp_wmem="210000 210000 210000"
For MTU=9000, TCP window size of 10 MB is recommended.
# sysctl -w net.ipv4.tcp_rmem="10000000 10000000 10000000"
# sysctl -w net.ipv4.tcp_wmem="10000000 10000000 10000000"
Transmit performance:
a. By default, the driver respects BIOS settings for PCI bus parameters.
However, you may want to experiment with PCI bus parameters
max-split-transactions(MOST) and MMRBC (use setpci command).
A MOST value of 2 has been found optimal for Opterons and 3 for Itanium.
It could be different for your hardware.
Set MMRBC to 4K**.
For example you can set
For opteron
#setpci -d 17d5:* 62=1d
For Itanium
#setpci -d 17d5:* 62=3d
For detailed description of the PCI registers, please see Xframe User Guide.
b. Ensure Transmit Checksum offload is enabled. Use ethtool to set/verify this
parameter.
c. Turn on TSO(using "ethtool -K")
# ethtool -K <ethX> tso on
Receive performance:
a. By default, the driver respects BIOS settings for PCI bus parameters.
However, you may want to set PCI latency timer to 248.
#setpci -d 17d5:* LATENCY_TIMER=f8
For detailed description of the PCI registers, please see Xframe User Guide.
b. Use 2-buffer mode. This results in large performance boost on
on certain platforms(eg. SGI Altix, IBM xSeries).
c. Ensure Receive Checksum offload is enabled. Use "ethtool -K ethX" command to
set/verify this option.
d. Enable NAPI feature(in kernel configuration Device Drivers ---> Network
device support ---> Ethernet (10000 Mbit) ---> S2IO 10Gbe Xframe NIC) to
bring down CPU utilization.
** For AMD opteron platforms with 8131 chipset, MMRBC=1 and MOST=1 are
recommended as safe parameters.
For more information, please review the AMD8131 errata at
http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/26310.pdf
6. Available Downloads
Neterion "s2io" driver in Red Hat and Suse 2.6-based distributions is kept up
to date, also the latest "s2io" code (including support for 2.4 kernels) is
available via "Support" link on the Neterion site: http://www.neterion.com.
For Xframe User Guide (Programming manual), visit ftp site ns1.s2io.com,
user: linuxdocs password: HALdocs
7. Support
For further support please contact either your 10GbE Xframe NIC vendor (IBM,
HP, SGI etc.) or click on the "Support" link on the Neterion site:
http://www.neterion.com.

View File

@ -0,0 +1,45 @@
Copyright (c) 2003-2005 QLogic Corporation
QLogic Linux Fibre Channel HBA Driver
This program includes a device driver for Linux 2.6 that may be
distributed with QLogic hardware specific firmware binary file.
You may modify and redistribute the device driver code under the
GNU General Public License as published by the Free Software
Foundation (version 2 or a later version).
You may redistribute the hardware specific firmware binary file
under the following terms:
1. Redistribution of source code (only if applicable),
must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistribution in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
3. The name of QLogic Corporation may not be used to
endorse or promote products derived from this software
without specific prior written permission
REGARDLESS OF WHAT LICENSING MECHANISM IS USED OR APPLICABLE,
THIS PROGRAM IS PROVIDED BY QLOGIC CORPORATION "AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
USER ACKNOWLEDGES AND AGREES THAT USE OF THIS PROGRAM WILL NOT
CREATE OR GIVE GROUNDS FOR A LICENSE BY IMPLICATION, ESTOPPEL, OR
OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS (PATENT, COPYRIGHT,
TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT) EMBODIED IN
ANY OTHER QLOGIC HARDWARE OR SOFTWARE EITHER SOLELY OR IN
COMBINATION WITH THIS PROGRAM.

View File

@ -297,6 +297,11 @@ P: Richard Purdie
M: rpurdie@rpsys.net
S: Maintained
ARM/TOSA MACHINE SUPPORT
P: Dirk Opfer
M: dirk@opfer-online.de
S: Maintained
ARM/PLEB SUPPORT
P: Peter Chubb
M: pleb@gelato.unsw.edu.au
@ -910,6 +915,15 @@ L: linux-fbdev-devel@lists.sourceforge.net
W: http://linux-fbdev.sourceforge.net/
S: Maintained
FREESCALE SOC FS_ENET DRIVER
P: Pantelis Antoniou
M: pantelis.antoniou@gmail.com
P: Vitaly Bordug
M: vbordug@ru.mvista.com
L: linuxppc-embedded@ozlabs.org
L: netdev@vger.kernel.org
S: Maintained
FILE LOCKING (flock() and fcntl()/lockf())
P: Matthew Wilcox
M: matthew@wil.cx

View File

@ -346,7 +346,8 @@ AFLAGS_KERNEL =
# Use LINUXINCLUDE when you must reference the include/ directory.
# Needed to be compatible with the O= option
LINUXINCLUDE := -Iinclude \
$(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include)
$(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \
-imacros include/linux/autoconf.h
CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
@ -1249,11 +1250,6 @@ tags: FORCE
# Scripts to check various things for consistency
# ---------------------------------------------------------------------------
configcheck:
find * $(RCS_FIND_IGNORE) \
-name '*.[hcS]' -type f -print | sort \
| xargs $(PERL) -w scripts/checkconfig.pl
includecheck:
find * $(RCS_FIND_IGNORE) \
-name '*.[hcS]' -type f -print | sort \

View File

@ -704,8 +704,7 @@ source "drivers/acorn/block/Kconfig"
if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \
|| ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
|| ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
|| MACH_MP1000
|| ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE
source "drivers/ide/Kconfig"
endif

View File

@ -38,6 +38,7 @@ comma = ,
# macro, but instead defines a whole series of macros which makes
# testing for a specific architecture or later rather impossible.
arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
arch-$(CONFIG_CPU_32v6K) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k)
arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4)
arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4
arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3
@ -143,7 +144,7 @@ drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
drivers-$(CONFIG_ARCH_CLPS7500) += drivers/acorn/char/
drivers-$(CONFIG_ARCH_L7200) += drivers/acorn/char/
libs-y += arch/arm/lib/
libs-y := arch/arm/lib/ $(libs-y)
# Default target when executing plain make
ifeq ($(CONFIG_XIP_KERNEL),y)

View File

@ -39,8 +39,7 @@
defined(CONFIG_ARCH_IXP4XX) || \
defined(CONFIG_ARCH_IXP2000) || \
defined(CONFIG_ARCH_LH7A40X) || \
defined(CONFIG_ARCH_OMAP) || \
defined(CONFIG_MACH_MP1000)
defined(CONFIG_ARCH_OMAP)
.macro loadsp, rb
addruart \rb
.endm

View File

@ -152,7 +152,7 @@ CONFIG_ALIGNMENT_TRAP=y
#
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware"
CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware"
# CONFIG_XIP_KERNEL is not set
#
@ -560,7 +560,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=2
CONFIG_SERIAL_8250_NR_UARTS=3
# CONFIG_SERIAL_8250_EXTENDED is not set
#

View File

@ -560,7 +560,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=2
CONFIG_SERIAL_8250_NR_UARTS=3
# CONFIG_SERIAL_8250_EXTENDED is not set
#

View File

@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.14-rc1
# Fri Sep 16 15:48:13 2005
# Linux kernel version: 2.6.14-rc2
# Thu Sep 29 14:50:10 2005
#
CONFIG_ARM=y
CONFIG_MMU=y
@ -12,11 +12,9 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
# CONFIG_CLEAN_COMPILE is not set
CONFIG_BROKEN=y
# CONFIG_EXPERIMENTAL is not set
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
#
@ -24,18 +22,16 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
#
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
# CONFIG_HOTPLUG is not set
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_IKCONFIG is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@ -58,17 +54,15 @@ CONFIG_BASE_SMALL=0
#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
# CONFIG_KMOD is not set
#
# System Type
#
# CONFIG_ARCH_CLPS7500 is not set
CONFIG_ARCH_CLPS711X=y
# CONFIG_ARCH_CLPS711X is not set
# CONFIG_ARCH_CO285 is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_CAMELOT is not set
@ -86,43 +80,43 @@ CONFIG_ARCH_CLPS711X=y
# CONFIG_ARCH_LH7A40X is not set
# CONFIG_ARCH_OMAP is not set
# CONFIG_ARCH_VERSATILE is not set
CONFIG_ARCH_REALVIEW=y
# CONFIG_ARCH_IMX is not set
# CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_AAEC2000 is not set
#
# CLPS711X/EP721X Implementations
# RealView platform type
#
# CONFIG_ARCH_AUTCPU12 is not set
# CONFIG_ARCH_CDB89712 is not set
# CONFIG_ARCH_CEIVA is not set
# CONFIG_ARCH_CLEP7312 is not set
# CONFIG_ARCH_EDB7211 is not set
# CONFIG_ARCH_P720T is not set
# CONFIG_ARCH_FORTUNET is not set
CONFIG_MACH_MP1000=y
CONFIG_MP1000_90MHZ=y
CONFIG_MACH_REALVIEW_EB=y
#
# Processor Type
#
CONFIG_CPU_32=y
CONFIG_CPU_ARM720T=y
CONFIG_CPU_32v4=y
CONFIG_CPU_ABRT_LV4T=y
CONFIG_CPU_CACHE_V4=y
CONFIG_CPU_ARM926T=y
# CONFIG_CPU_V6 is not set
CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5TJ=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_COPY_V4WT=y
CONFIG_CPU_TLB_V4WT=y
CONFIG_CPU_COPY_V4WB=y
CONFIG_CPU_TLB_V4WBI=y
#
# Processor Features
#
CONFIG_ARM_THUMB=y
# CONFIG_CPU_ICACHE_DISABLE is not set
# CONFIG_CPU_DCACHE_DISABLE is not set
# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
CONFIG_ARM_GIC=y
CONFIG_ICST307=y
#
# Bus support
#
CONFIG_ARM_AMBA=y
CONFIG_ISA_DMA_API=y
#
@ -133,14 +127,8 @@ CONFIG_ISA_DMA_API=y
#
# Kernel Features
#
# CONFIG_SMP is not set
CONFIG_PREEMPT=y
# CONFIG_NO_IDLE_HZ is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
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
@ -151,7 +139,7 @@ CONFIG_ALIGNMENT_TRAP=y
#
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="console=ttyCL,38400 root=/dev/discs/disc0/part1 ip=any cs89x0_media=rj45"
CONFIG_CMDLINE="root=/dev/nfs nfsroot=10.1.69.3:/work/nfsroot ip=dhcp console=ttyAMA0 mem=128M"
# CONFIG_XIP_KERNEL is not set
#
@ -163,14 +151,14 @@ CONFIG_CMDLINE="console=ttyCL,38400 root=/dev/discs/disc0/part1 ip=any cs89x0_me
#
CONFIG_FPE_NWFPE=y
# CONFIG_FPE_NWFPE_XP is not set
# CONFIG_FPE_FASTFPE is not set
# CONFIG_VFP is not set
#
# Userspace binary formats
#
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_AOUT is not set
CONFIG_BINFMT_MISC=y
# CONFIG_BINFMT_MISC is not set
# CONFIG_ARTHUR is not set
#
@ -197,10 +185,9 @@ CONFIG_IP_FIB_HASH=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
# 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
@ -210,36 +197,14 @@ CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
CONFIG_IPV6=y
# CONFIG_IPV6_PRIVACY is not set
# CONFIG_INET6_AH is not set
# CONFIG_INET6_ESP is not set
# CONFIG_INET6_IPCOMP is not set
# CONFIG_INET6_TUNNEL is not set
# CONFIG_IPV6_TUNNEL is not set
# CONFIG_IPV6 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
# 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_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_SCHED is not set
# CONFIG_NET_CLS_ROUTE is not set
@ -247,7 +212,6 @@ CONFIG_IPV6=y
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_NETFILTER_NETLINK is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
@ -269,14 +233,10 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
CONFIG_MTD_DEBUG=y
CONFIG_MTD_DEBUG_VERBOSE=3
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_REDBOOT_PARTS=m
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-2
CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
@ -292,45 +252,36 @@ CONFIG_MTD_BLOCK=y
#
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=m
CONFIG_MTD_CFI=y
# CONFIG_MTD_JEDECPROBE is not set
CONFIG_MTD_GEN_PROBE=m
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_NOSWAP=y
# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
CONFIG_MTD_CFI_GEOMETRY=y
# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set
CONFIG_MTD_GEN_PROBE=y
# CONFIG_MTD_CFI_ADV_OPTIONS is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
# CONFIG_MTD_CFI_I1 is not set
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_OTP is not set
CONFIG_MTD_CFI_INTELEXT=m
# CONFIG_MTD_CFI_AMDSTD is not set
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_CFI_AMDSTD_RETRY=0
# CONFIG_MTD_CFI_STAA is not set
CONFIG_MTD_CFI_UTIL=m
CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
# CONFIG_MTD_OBSOLETE_CHIPS is not set
# CONFIG_MTD_XIP is not set
#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=m
CONFIG_MTD_PHYSMAP_START=0x0000000
CONFIG_MTD_PHYSMAP_LEN=0x4000000
CONFIG_MTD_PHYSMAP_BANKWIDTH=2
# CONFIG_MTD_ARM_INTEGRATOR is not set
CONFIG_MTD_EDB7312=m
# CONFIG_MTD_PHYSMAP is not set
CONFIG_MTD_ARM_INTEGRATOR=y
# CONFIG_MTD_EDB7312 is not set
# CONFIG_MTD_PLATRAM is not set
#
@ -340,7 +291,6 @@ CONFIG_MTD_EDB7312=m
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
# CONFIG_MTD_BLKMTD is not set
# CONFIG_MTD_BLOCK2MTD is not set
#
# Disk-On-Chip Device Drivers
@ -352,12 +302,7 @@ CONFIG_MTD_EDB7312=m
#
# NAND Flash Device Drivers
#
CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_VERIFY_WRITE is not set
CONFIG_MTD_NAND_MP1000=y
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_NANDSIM is not set
# CONFIG_MTD_NAND is not set
#
# Parallel port support
@ -372,52 +317,21 @@ CONFIG_MTD_NAND_IDS=y
# Block devices
#
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=m
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=2
CONFIG_BLK_DEV_RAM_SIZE=16384
CONFIG_BLK_DEV_INITRD=y
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
# CONFIG_CDROM_PKTCDVD is not set
#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
# CONFIG_IOSCHED_AS is not set
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
# CONFIG_IOSCHED_CFQ is not set
# CONFIG_ATA_OVER_ETH is not set
#
# ATA/ATAPI/MFM/RLL support
#
CONFIG_IDE=y
CONFIG_BLK_DEV_IDE=y
#
# Please see Documentation/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_IDE_SATA is not set
# CONFIG_BLK_DEV_HD_IDE is not set
CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set
# CONFIG_BLK_DEV_IDECD is not set
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_IDE_TASK_IOCTL is not set
#
# IDE chipset support/bugfixes
#
# CONFIG_IDE_GENERIC is not set
CONFIG_IDE_ARM=y
CONFIG_BLK_DEV_IDE_MP1000=y
# CONFIG_BLK_DEV_IDEDMA is not set
# CONFIG_IDEDMA_AUTO is not set
# CONFIG_BLK_DEV_HD is not set
#
# SCSI device support
#
@ -427,14 +341,7 @@ CONFIG_BLK_DEV_IDE_MP1000=y
#
# Multi-device support (RAID and LVM)
#
CONFIG_MD=y
# CONFIG_BLK_DEV_MD is not set
CONFIG_BLK_DEV_DM=y
# CONFIG_DM_CRYPT is not set
# CONFIG_DM_SNAPSHOT is not set
# CONFIG_DM_MIRROR is not set
# CONFIG_DM_ZERO is not set
# CONFIG_DM_MULTIPATH is not set
# CONFIG_MD is not set
#
# Fusion MPT device support
@ -444,7 +351,6 @@ CONFIG_BLK_DEV_DM=y
#
# IEEE 1394 (FireWire) support
#
# CONFIG_IEEE1394 is not set
#
# I2O device support
@ -468,10 +374,9 @@ CONFIG_NETDEVICES=y
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
# CONFIG_SMC91X is not set
CONFIG_MII=y
CONFIG_SMC91X=y
# CONFIG_DM9000 is not set
CONFIG_CS89x0=y
#
# Ethernet (1000 Mbit)
@ -496,8 +401,6 @@ CONFIG_CS89x0=y
# 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
@ -514,17 +417,28 @@ CONFIG_INPUT=y
#
# Userland interfaces
#
# CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
CONFIG_INPUT_EVBUG=y
# CONFIG_INPUT_EVBUG is not set
#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
# CONFIG_MOUSE_SERIAL is not set
# CONFIG_MOUSE_VSXXXAA is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
@ -533,8 +447,9 @@ CONFIG_INPUT_EVBUG=y
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_LIBPS2 is not set
# CONFIG_SERIO_SERPORT is not set
CONFIG_SERIO_AMBAKMI=y
CONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set
# CONFIG_GAMEPORT is not set
@ -549,21 +464,19 @@ CONFIG_HW_CONSOLE=y
#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=2
# CONFIG_SERIAL_8250_EXTENDED is not set
# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CLPS711X=y
CONFIG_SERIAL_CLPS711X_CONSOLE=y
# CONFIG_SERIAL_AMBA_PL010 is not set
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_LEGACY_PTY_COUNT=16
#
# IPMI
@ -574,8 +487,8 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
CONFIG_NVRAM=y
CONFIG_RTC=y
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@ -596,9 +509,8 @@ CONFIG_RTC=y
#
# Hardware Monitoring support
#
CONFIG_HWMON=y
# CONFIG_HWMON is not set
# CONFIG_HWMON_VID is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
@ -621,18 +533,72 @@ CONFIG_HWMON=y
#
# Graphics support
#
# CONFIG_FB is not set
CONFIG_FB=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
CONFIG_FB_SOFT_CURSOR=y
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
CONFIG_FB_ARMCLCD=y
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
#
# Console display driver support
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
#
# Logo configuration
#
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_LOGO_LINUX_CLUT224=y
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
#
# CONFIG_SOUND is not set
CONFIG_SOUND=y
#
# Advanced Linux Sound Architecture
#
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
# CONFIG_SND_SEQUENCER is not set
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
#
# Generic devices
#
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_MTPAV is not set
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
#
# ALSA ARM devices
#
# CONFIG_SND_ARMAACI is not set
#
# Open Sound System
#
# CONFIG_SOUND_PRIME is not set
#
# USB support
@ -654,32 +620,17 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
# CONFIG_EXT2_FS_POSIX_ACL is not set
# CONFIG_EXT2_FS_SECURITY 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_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
CONFIG_REISERFS_FS=m
# CONFIG_REISERFS_CHECK is not set
# CONFIG_REISERFS_PROC_INFO is not set
# CONFIG_REISERFS_FS_XATTR is not set
# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
CONFIG_QUOTA=y
# CONFIG_QFMT_V1 is not set
# CONFIG_QFMT_V2 is not set
CONFIG_QUOTACTL=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
@ -694,8 +645,11 @@ CONFIG_DNOTIFY=y
#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=y
# CONFIG_MSDOS_FS is not set
# CONFIG_VFAT_FS is not set
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# CONFIG_NTFS_FS is not set
#
@ -704,7 +658,6 @@ CONFIG_DNOTIFY=y
CONFIG_PROC_FS=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
# CONFIG_RELAYFS_FS is not set
@ -712,22 +665,10 @@ CONFIG_RAMFS=y
#
# 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_JFFS_FS is not set
CONFIG_JFFS2_FS=m
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=m
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
@ -740,32 +681,16 @@ CONFIG_CRAMFS=m
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
# CONFIG_NFSD_V3_ACL is not set
CONFIG_NFSD_V4=y
CONFIG_NFSD_TCP=y
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
# CONFIG_SMB_NLS_DEFAULT is not set
CONFIG_CIFS=m
# CONFIG_CIFS_STATS is not set
# CONFIG_CIFS_XATTR is not set
# CONFIG_CIFS_EXPERIMENTAL 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
@ -802,7 +727,7 @@ CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
# CONFIG_NLS_ASCII is not set
# CONFIG_NLS_ISO8859_1 is not set
CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
@ -817,35 +742,27 @@ CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set
#
# Profiling support
#
# CONFIG_PROFILING is not set
#
# Kernel hacking
#
CONFIG_PRINTK_TIME=y
# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_MAGIC_SYSRQ is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
CONFIG_DEBUG_PREEMPT=y
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_BUGVERBOSE is not set
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_FS is not set
CONFIG_FRAME_POINTER=y
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_WAITQ=y
# CONFIG_DEBUG_WAITQ is not set
CONFIG_DEBUG_ERRORS=y
CONFIG_DEBUG_LL=y
# CONFIG_DEBUG_ICEDCC is not set
# CONFIG_DEBUG_CLPS711X_UART2 is not set
# CONFIG_DEBUG_LL is not set
#
# Security options
@ -856,31 +773,7 @@ CONFIG_DEBUG_LL=y
#
# Cryptographic options
#
CONFIG_CRYPTO=y
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_SHA1 is not set
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_TGR192 is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
# CONFIG_CRYPTO_SERPENT is not set
# CONFIG_CRYPTO_AES is not set
# CONFIG_CRYPTO_CAST5 is not set
# CONFIG_CRYPTO_CAST6 is not set
# CONFIG_CRYPTO_TEA is not set
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_TEST is not set
# CONFIG_CRYPTO is not set
#
# Hardware crypto devices
@ -893,5 +786,4 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
CONFIG_ZLIB_INFLATE=y

View File

@ -785,7 +785,7 @@ __kuser_helper_end:
* SP points to a minimal amount of processor-private memory, the address
* of which is copied into r0 for the mode specific abort handler.
*/
.macro vector_stub, name, correction=0
.macro vector_stub, name, mode, correction=0
.align 5
vector_\name:
@ -805,15 +805,14 @@ vector_\name:
@ Prepare for SVC32 mode. IRQs remain disabled.
@
mrs r0, cpsr
bic r0, r0, #MODE_MASK
orr r0, r0, #SVC_MODE
eor r0, r0, #(\mode ^ SVC_MODE)
msr spsr_cxsf, r0
@
@ the branch table must immediately follow this code
@
mov r0, sp
and lr, lr, #0x0f
mov r0, sp
ldr lr, [pc, lr, lsl #2]
movs pc, lr @ branch to handler in SVC mode
.endm
@ -823,7 +822,7 @@ __stubs_start:
/*
* Interrupt dispatcher
*/
vector_stub irq, 4
vector_stub irq, IRQ_MODE, 4
.long __irq_usr @ 0 (USR_26 / USR_32)
.long __irq_invalid @ 1 (FIQ_26 / FIQ_32)
@ -846,7 +845,7 @@ __stubs_start:
* Data abort dispatcher
* Enter in ABT mode, spsr = USR CPSR, lr = USR PC
*/
vector_stub dabt, 8
vector_stub dabt, ABT_MODE, 8
.long __dabt_usr @ 0 (USR_26 / USR_32)
.long __dabt_invalid @ 1 (FIQ_26 / FIQ_32)
@ -869,7 +868,7 @@ __stubs_start:
* Prefetch abort dispatcher
* Enter in ABT mode, spsr = USR CPSR, lr = USR PC
*/
vector_stub pabt, 4
vector_stub pabt, ABT_MODE, 4
.long __pabt_usr @ 0 (USR_26 / USR_32)
.long __pabt_invalid @ 1 (FIQ_26 / FIQ_32)
@ -892,7 +891,7 @@ __stubs_start:
* Undef instr entry dispatcher
* Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
*/
vector_stub und
vector_stub und, UND_MODE
.long __und_usr @ 0 (USR_26 / USR_32)
.long __und_invalid @ 1 (FIQ_26 / FIQ_32)

View File

@ -338,7 +338,8 @@ void cpu_init(void)
BUG();
}
dump_cpu_info(cpu);
if (system_state == SYSTEM_BOOTING)
dump_cpu_info(cpu);
/*
* setup stacks for re-entrant exception handlers
@ -838,7 +839,12 @@ static int c_show(struct seq_file *m, void *v)
#if defined(CONFIG_SMP)
for_each_online_cpu(i) {
seq_printf(m, "Processor\t: %d\n", i);
/*
* glibc reads /proc/cpuinfo to determine the number of
* online processors, looking for lines beginning with
* "processor". Give glibc what it expects.
*/
seq_printf(m, "processor\t: %d\n", i);
seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),
(per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100);

View File

@ -1,6 +1,6 @@
#include <linux/config.h>
#if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_CPU_MPCORE)
#if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_CPU_32v6K)
.macro bitop, instr
mov r2, #1
and r3, r0, #7 @ Get bit offset

View File

@ -43,8 +43,6 @@ ENTRY(__arch_copy_to_user)
stmfd sp!, {r2, r4 - r7, lr}
cmp r2, #4
blt .c2u_not_enough
PLD( pld [r1, #0] )
PLD( pld [r0, #0] )
ands ip, r0, #3
bne .c2u_dest_not_aligned
.c2u_dest_aligned:
@ -73,25 +71,13 @@ USER( strt r3, [r0], #4) @ May fault
sub r2, r2, ip
subs ip, ip, #32
blt .c2u_0rem8lp
PLD( pld [r1, #28] )
PLD( pld [r0, #28] )
PLD( subs ip, ip, #64 )
PLD( blt .c2u_0cpynopld )
PLD( pld [r1, #60] )
PLD( pld [r0, #60] )
.c2u_0cpy8lp:
PLD( pld [r1, #92] )
PLD( pld [r0, #92] )
.c2u_0cpynopld: ldmia r1!, {r3 - r6}
.c2u_0cpy8lp: ldmia r1!, {r3 - r6}
stmia r0!, {r3 - r6} @ Shouldnt fault
ldmia r1!, {r3 - r6}
subs ip, ip, #32
stmia r0!, {r3 - r6} @ Shouldnt fault
bpl .c2u_0cpy8lp
PLD( cmn ip, #64 )
PLD( bge .c2u_0cpynopld )
PLD( add ip, ip, #64 )
.c2u_0rem8lp: cmn ip, #16
ldmgeia r1!, {r3 - r6}
@ -143,17 +129,8 @@ USER( strt r3, [r0], #4) @ May fault
sub r2, r2, ip
subs ip, ip, #16
blt .c2u_1rem8lp
PLD( pld [r1, #12] )
PLD( pld [r0, #12] )
PLD( subs ip, ip, #32 )
PLD( blt .c2u_1cpynopld )
PLD( pld [r1, #28] )
PLD( pld [r0, #28] )
.c2u_1cpy8lp:
PLD( pld [r1, #44] )
PLD( pld [r0, #44] )
.c2u_1cpynopld: mov r3, r7, pull #8
.c2u_1cpy8lp: mov r3, r7, pull #8
ldmia r1!, {r4 - r7}
subs ip, ip, #16
orr r3, r3, r4, push #24
@ -165,9 +142,6 @@ USER( strt r3, [r0], #4) @ May fault
orr r6, r6, r7, push #24
stmia r0!, {r3 - r6} @ Shouldnt fault
bpl .c2u_1cpy8lp
PLD( cmn ip, #32 )
PLD( bge .c2u_1cpynopld )
PLD( add ip, ip, #32 )
.c2u_1rem8lp: tst ip, #8
movne r3, r7, pull #8
@ -210,17 +184,8 @@ USER( strt r3, [r0], #4) @ May fault
sub r2, r2, ip
subs ip, ip, #16
blt .c2u_2rem8lp
PLD( pld [r1, #12] )
PLD( pld [r0, #12] )
PLD( subs ip, ip, #32 )
PLD( blt .c2u_2cpynopld )
PLD( pld [r1, #28] )
PLD( pld [r0, #28] )
.c2u_2cpy8lp:
PLD( pld [r1, #44] )
PLD( pld [r0, #44] )
.c2u_2cpynopld: mov r3, r7, pull #16
.c2u_2cpy8lp: mov r3, r7, pull #16
ldmia r1!, {r4 - r7}
subs ip, ip, #16
orr r3, r3, r4, push #16
@ -232,9 +197,6 @@ USER( strt r3, [r0], #4) @ May fault
orr r6, r6, r7, push #16
stmia r0!, {r3 - r6} @ Shouldnt fault
bpl .c2u_2cpy8lp
PLD( cmn ip, #32 )
PLD( bge .c2u_2cpynopld )
PLD( add ip, ip, #32 )
.c2u_2rem8lp: tst ip, #8
movne r3, r7, pull #16
@ -277,17 +239,8 @@ USER( strt r3, [r0], #4) @ May fault
sub r2, r2, ip
subs ip, ip, #16
blt .c2u_3rem8lp
PLD( pld [r1, #12] )
PLD( pld [r0, #12] )
PLD( subs ip, ip, #32 )
PLD( blt .c2u_3cpynopld )
PLD( pld [r1, #28] )
PLD( pld [r0, #28] )
.c2u_3cpy8lp:
PLD( pld [r1, #44] )
PLD( pld [r0, #44] )
.c2u_3cpynopld: mov r3, r7, pull #24
.c2u_3cpy8lp: mov r3, r7, pull #24
ldmia r1!, {r4 - r7}
subs ip, ip, #16
orr r3, r3, r4, push #8
@ -299,9 +252,6 @@ USER( strt r3, [r0], #4) @ May fault
orr r6, r6, r7, push #8
stmia r0!, {r3 - r6} @ Shouldnt fault
bpl .c2u_3cpy8lp
PLD( cmn ip, #32 )
PLD( bge .c2u_3cpynopld )
PLD( add ip, ip, #32 )
.c2u_3rem8lp: tst ip, #8
movne r3, r7, pull #24
@ -356,8 +306,6 @@ ENTRY(__arch_copy_from_user)
stmfd sp!, {r0, r2, r4 - r7, lr}
cmp r2, #4
blt .cfu_not_enough
PLD( pld [r1, #0] )
PLD( pld [r0, #0] )
ands ip, r0, #3
bne .cfu_dest_not_aligned
.cfu_dest_aligned:
@ -385,25 +333,13 @@ USER( ldrt r3, [r1], #4)
sub r2, r2, ip
subs ip, ip, #32
blt .cfu_0rem8lp
PLD( pld [r1, #28] )
PLD( pld [r0, #28] )
PLD( subs ip, ip, #64 )
PLD( blt .cfu_0cpynopld )
PLD( pld [r1, #60] )
PLD( pld [r0, #60] )
.cfu_0cpy8lp:
PLD( pld [r1, #92] )
PLD( pld [r0, #92] )
.cfu_0cpynopld: ldmia r1!, {r3 - r6} @ Shouldnt fault
.cfu_0cpy8lp: ldmia r1!, {r3 - r6} @ Shouldnt fault
stmia r0!, {r3 - r6}
ldmia r1!, {r3 - r6} @ Shouldnt fault
subs ip, ip, #32
stmia r0!, {r3 - r6}
bpl .cfu_0cpy8lp
PLD( cmn ip, #64 )
PLD( bge .cfu_0cpynopld )
PLD( add ip, ip, #64 )
.cfu_0rem8lp: cmn ip, #16
ldmgeia r1!, {r3 - r6} @ Shouldnt fault
@ -456,17 +392,8 @@ USER( ldrt r7, [r1], #4) @ May fault
sub r2, r2, ip
subs ip, ip, #16
blt .cfu_1rem8lp
PLD( pld [r1, #12] )
PLD( pld [r0, #12] )
PLD( subs ip, ip, #32 )
PLD( blt .cfu_1cpynopld )
PLD( pld [r1, #28] )
PLD( pld [r0, #28] )
.cfu_1cpy8lp:
PLD( pld [r1, #44] )
PLD( pld [r0, #44] )
.cfu_1cpynopld: mov r3, r7, pull #8
.cfu_1cpy8lp: mov r3, r7, pull #8
ldmia r1!, {r4 - r7} @ Shouldnt fault
subs ip, ip, #16
orr r3, r3, r4, push #24
@ -478,9 +405,6 @@ USER( ldrt r7, [r1], #4) @ May fault
orr r6, r6, r7, push #24
stmia r0!, {r3 - r6}
bpl .cfu_1cpy8lp
PLD( cmn ip, #32 )
PLD( bge .cfu_1cpynopld )
PLD( add ip, ip, #32 )
.cfu_1rem8lp: tst ip, #8
movne r3, r7, pull #8
@ -523,17 +447,8 @@ USER( ldrt r7, [r1], #4) @ May fault
sub r2, r2, ip
subs ip, ip, #16
blt .cfu_2rem8lp
PLD( pld [r1, #12] )
PLD( pld [r0, #12] )
PLD( subs ip, ip, #32 )
PLD( blt .cfu_2cpynopld )
PLD( pld [r1, #28] )
PLD( pld [r0, #28] )
.cfu_2cpy8lp:
PLD( pld [r1, #44] )
PLD( pld [r0, #44] )
.cfu_2cpynopld: mov r3, r7, pull #16
.cfu_2cpy8lp: mov r3, r7, pull #16
ldmia r1!, {r4 - r7} @ Shouldnt fault
subs ip, ip, #16
orr r3, r3, r4, push #16
@ -545,9 +460,6 @@ USER( ldrt r7, [r1], #4) @ May fault
orr r6, r6, r7, push #16
stmia r0!, {r3 - r6}
bpl .cfu_2cpy8lp
PLD( cmn ip, #32 )
PLD( bge .cfu_2cpynopld )
PLD( add ip, ip, #32 )
.cfu_2rem8lp: tst ip, #8
movne r3, r7, pull #16
@ -590,17 +502,8 @@ USER( ldrt r7, [r1], #4) @ May fault
sub r2, r2, ip
subs ip, ip, #16
blt .cfu_3rem8lp
PLD( pld [r1, #12] )
PLD( pld [r0, #12] )
PLD( subs ip, ip, #32 )
PLD( blt .cfu_3cpynopld )
PLD( pld [r1, #28] )
PLD( pld [r0, #28] )
.cfu_3cpy8lp:
PLD( pld [r1, #44] )
PLD( pld [r0, #44] )
.cfu_3cpynopld: mov r3, r7, pull #24
.cfu_3cpy8lp: mov r3, r7, pull #24
ldmia r1!, {r4 - r7} @ Shouldnt fault
orr r3, r3, r4, push #8
mov r4, r4, pull #24
@ -612,9 +515,6 @@ USER( ldrt r7, [r1], #4) @ May fault
stmia r0!, {r3 - r6}
subs ip, ip, #16
bpl .cfu_3cpy8lp
PLD( cmn ip, #32 )
PLD( bge .cfu_3cpynopld )
PLD( add ip, ip, #32 )
.cfu_3rem8lp: tst ip, #8
movne r3, r7, pull #24

View File

@ -69,17 +69,6 @@ config EP72XX_ROM_BOOT
You almost surely want to say N here.
config MACH_MP1000
bool "MACH_MP1000"
help
Say Y if you intend to run the kernel on the Comdial MP1000 platform.
config MP1000_90MHZ
bool "MP1000_90MHZ"
depends on MACH_MP1000
help
Say Y if you have the MP1000 configured to be set at 90MHZ rather than 74MHZ
endmenu
endif

View File

@ -15,7 +15,6 @@ obj-$(CONFIG_ARCH_CDB89712) += cdb89712.o
obj-$(CONFIG_ARCH_CLEP7312) += clep7312.o
obj-$(CONFIG_ARCH_EDB7211) += edb7211-arch.o edb7211-mm.o
obj-$(CONFIG_ARCH_FORTUNET) += fortunet.o
obj-$(CONFIG_MACH_MP1000) += mp1000-mach.o mp1000-mm.o mp1000-seprom.o
obj-$(CONFIG_ARCH_P720T) += p720t.o
leds-$(CONFIG_ARCH_P720T) += p720t-leds.o
obj-$(CONFIG_LEDS) += $(leds-y)

View File

@ -55,22 +55,22 @@ static struct map_desc edb7211_io_desc[] __initdata = {
.virtual = EP7211_VIRT_EXTKBD,
.pfn = __phys_to_pfn(EP7211_PHYS_EXTKBD),
.length = SZ_1M,
.type - MT_DEVICE
.type = MT_DEVICE,
}, { /* and CS8900A Ethernet chip */
.virtual = EP7211_VIRT_CS8900A,
.pfn = __phys_to_pfn(EP7211_PHYS_CS8900A),
.length = SZ_1M,
.type = MT_DEVICE
.type = MT_DEVICE,
}, { /* flash banks */
.virtual = EP7211_VIRT_FLASH1,
.pfn = __phys_to_pfn(EP7211_PHYS_FLASH1),
.length = SZ_8M,
.type = MT_DEVICE
.type = MT_DEVICE,
}, {
.virtual = EP7211_VIRT_FLASH2,
.pfn = __phys_to_pfn(EP7211_PHYS_FLASH2),
.length = SZ_8M,
.type = MT_DEVICE
.type = MT_DEVICE,
}
};

View File

@ -1,49 +0,0 @@
/*
* linux/arch/arm/mach-mp1000/mp1000.c
*
* Copyright (C) 2005 Comdial Corporation
*
* 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/string.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/arch/mp1000-seprom.h>
#include "common.h"
extern void mp1000_map_io(void);
static void __init mp1000_init(void)
{
seprom_init();
}
MACHINE_START(MP1000, "Comdial MP1000")
/* Maintainer: Jon Ringle */
.phys_ram = 0xc0000000,
.phys_io = 0x80000000,
.io_pg_offst = ((0xff000000) >> 18) & 0xfffc,
.boot_params = 0xc0015100,
.map_io = mp1000_map_io,
.init_irq = clps711x_init_irq,
.init_machine = mp1000_init,
.timer = &clps711x_timer,
MACHINE_END

View File

@ -1,47 +0,0 @@
/*
* linux/arch/arm/mach-mp1000/mm.c
*
* Extra MM routines for the MP1000
*
* Copyright (C) 2005 Comdial Corporation
*
* 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/kernel.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/sizes.h>
#include <asm/mach/map.h>
extern void clps711x_map_io(void);
static struct map_desc mp1000_io_desc[] __initdata = {
{ MP1000_EIO_BASE, MP1000_EIO_START, MP1000_EIO_SIZE, MT_DEVICE },
{ MP1000_FIO_BASE, MP1000_FIO_START, MP1000_FIO_SIZE, MT_DEVICE },
{ MP1000_LIO_BASE, MP1000_LIO_START, MP1000_LIO_SIZE, MT_DEVICE },
{ MP1000_NIO_BASE, MP1000_NIO_START, MP1000_NIO_SIZE, MT_DEVICE },
{ MP1000_IDE_BASE, MP1000_IDE_START, MP1000_IDE_SIZE, MT_DEVICE },
{ MP1000_DSP_BASE, MP1000_DSP_START, MP1000_DSP_SIZE, MT_DEVICE }
};
void __init mp1000_map_io(void)
{
clps711x_map_io();
iotable_init(mp1000_io_desc, ARRAY_SIZE(mp1000_io_desc));
}

View File

@ -1,195 +0,0 @@
/*`
* mp1000-seprom.c
*
* This file contains the Serial EEPROM code for the MP1000 board
*
* Copyright (C) 2005 Comdial Corporation
*
* 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/kernel.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/hardware/clps7111.h>
#include <asm/arch/mp1000-seprom.h>
/* If SepromInit() can initialize and checksum the seprom successfully, */
/* then it will point seprom_data_ptr at the shadow copy. */
static eeprom_struct seprom_data; /* shadow copy of seprom content */
eeprom_struct *seprom_data_ptr = 0; /* 0 => not initialized */
/*
* Port D Bit 5 is Chip Select for EEPROM
* Port E Bit 0 is Input, Data out from EEPROM
* Port E Bit 1 is Output, Data in to EEPROM
* Port E Bit 2 is Output, CLK to EEPROM
*/
static char *port_d_ptr = (char *)(CLPS7111_VIRT_BASE + PDDR);
static char *port_e_ptr = (char *)(CLPS7111_VIRT_BASE + PEDR);
#define NO_OF_SHORTS 64 // Device is 64 x 16 bits
#define ENABLE_RW 0
#define DISABLE_RW 1
static inline void toggle_seprom_clock(void)
{
*port_e_ptr |= HwPortESepromCLK;
*port_e_ptr &= ~(HwPortESepromCLK);
}
static inline void select_eeprom(void)
{
*port_d_ptr |= HwPortDEECS;
*port_e_ptr &= ~(HwPortESepromCLK);
}
static inline void deselect_eeprom(void)
{
*port_d_ptr &= ~(HwPortDEECS);
*port_e_ptr &= ~(HwPortESepromDIn);
}
/*
* GetSepromDataPtr - returns pointer to shadow (RAM) copy of seprom
* and returns 0 if seprom is not initialized or
* has a checksum error.
*/
eeprom_struct* get_seprom_ptr(void)
{
return seprom_data_ptr;
}
unsigned char* get_eeprom_mac_address(void)
{
return seprom_data_ptr->variant.eprom_struct.mac_Address;
}
/*
* ReadSProm, Physically reads data from the Serial PROM
*/
static void read_sprom(short address, int length, eeprom_struct *buffer)
{
short data = COMMAND_READ | (address & 0x3F);
short bit;
int i;
select_eeprom();
// Clock in 9 bits of the command
for (i = 0, bit = 0x100; i < 9; i++, bit >>= 1) {
if (data & bit)
*port_e_ptr |= HwPortESepromDIn;
else
*port_e_ptr &= ~(HwPortESepromDIn);
toggle_seprom_clock();
}
//
// Now read one or more shorts of data from the Seprom
//
while (length-- > 0) {
data = 0;
// Read 16 bits at a time
for (i = 0; i < 16; i++) {
data <<= 1;
toggle_seprom_clock();
data |= *port_e_ptr & HwPortESepromDOut;
}
buffer->variant.eprom_short_data[address++] = data;
}
deselect_eeprom();
return;
}
/*
* ReadSerialPROM
*
* Input: Pointer to array of 64 x 16 Bits
*
* Output: if no problem reading data is filled in
*/
static void read_serial_prom(eeprom_struct *data)
{
read_sprom(0, 64, data);
}
//
// Compute Serial EEPROM checksum
//
// Input: Pointer to struct with Eprom data
//
// Output: The computed Eprom checksum
//
static short compute_seprom_checksum(eeprom_struct *data)
{
short checksum = 0;
int i;
for (i = 0; i < 126; i++) {
checksum += (short)data->variant.eprom_byte_data[i];
}
return((short)(0x5555 - (checksum & 0xFFFF)));
}
//
// Make sure the data port bits for the SEPROM are correctly initialised
//
void __init seprom_init(void)
{
short checksum;
// Init Port D
*(char *)(CLPS7111_VIRT_BASE + PDDDR) = 0x0;
*(char *)(CLPS7111_VIRT_BASE + PDDR) = 0x15;
// Init Port E
*(int *)(CLPS7111_VIRT_BASE + PEDDR) = 0x06;
*(int *)(CLPS7111_VIRT_BASE + PEDR) = 0x04;
//
// Make sure that EEPROM struct size never exceeds 128 bytes
//
if (sizeof(eeprom_struct) > 128) {
panic("Serial PROM struct size > 128, aborting read\n");
}
read_serial_prom(&seprom_data);
checksum = compute_seprom_checksum(&seprom_data);
if (checksum != seprom_data.variant.eprom_short_data[63]) {
panic("Serial EEPROM checksum failed\n");
}
seprom_data_ptr = &seprom_data;
}

View File

@ -402,6 +402,40 @@ static void ixp2000_pci_irq_unmask(unsigned int irq)
ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp | (1 << 27)));
}
/*
* Error interrupts. These are used extensively by the microengine drivers
*/
static void ixp2000_err_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
{
int i;
unsigned long status = *IXP2000_IRQ_ERR_STATUS;
for(i = 31; i >= 0; i--) {
if(status & (1 << i)) {
desc = irq_desc + IRQ_IXP2000_DRAM0_MIN_ERR + i;
desc->handle(IRQ_IXP2000_DRAM0_MIN_ERR + i, desc, regs);
}
}
}
static void ixp2000_err_irq_mask(unsigned int irq)
{
ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_CLR,
(1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)));
}
static void ixp2000_err_irq_unmask(unsigned int irq)
{
ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_SET,
(1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)));
}
static struct irqchip ixp2000_err_irq_chip = {
.ack = ixp2000_err_irq_mask,
.mask = ixp2000_err_irq_mask,
.unmask = ixp2000_err_irq_unmask
};
static struct irqchip ixp2000_pci_irq_chip = {
.ack = ixp2000_pci_irq_mask,
.mask = ixp2000_pci_irq_mask,
@ -459,6 +493,18 @@ void __init ixp2000_init_irq(void)
} else set_irq_flags(irq, 0);
}
for (irq = IRQ_IXP2000_DRAM0_MIN_ERR; irq <= IRQ_IXP2000_SP_INT; irq++) {
if((1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)) &
IXP2000_VALID_ERR_IRQ_MASK) {
set_irq_chip(irq, &ixp2000_err_irq_chip);
set_irq_handler(irq, do_level_IRQ);
set_irq_flags(irq, IRQF_VALID);
}
else
set_irq_flags(irq, 0);
}
set_irq_chained_handler(IRQ_IXP2000_ERRSUM, ixp2000_err_irq_handler);
/*
* GPIO IRQs are invalid until someone sets the interrupt mode
* by calling set_irq_type().

View File

@ -69,19 +69,19 @@ static struct sys_timer enp2611_timer = {
static struct map_desc enp2611_io_desc[] __initdata = {
{
.virtual = ENP2611_CALEB_VIRT_BASE,
.physical = ENP2611_CALEB_PHYS_BASE,
.pfn = __phys_to_pfn(ENP2611_CALEB_PHYS_BASE),
.length = ENP2611_CALEB_SIZE,
.type = MT_IXP2000_DEVICE
.type = MT_IXP2000_DEVICE,
}, {
.virtual = ENP2611_PM3386_0_VIRT_BASE,
.physical = ENP2611_PM3386_0_PHYS_BASE,
.pfn = __phys_to_pfn(ENP2611_PM3386_0_PHYS_BASE),
.length = ENP2611_PM3386_0_SIZE,
.type = MT_IXP2000_DEVICE
.type = MT_IXP2000_DEVICE,
}, {
.virtual = ENP2611_PM3386_1_VIRT_BASE,
.physical = ENP2611_PM3386_1_PHYS_BASE,
.pfn = __phys_to_pfn(ENP2611_PM3386_1_PHYS_BASE),
.length = ENP2611_PM3386_1_SIZE,
.type = MT_IXP2000_DEVICE
.type = MT_IXP2000_DEVICE,
}
};

View File

@ -91,8 +91,8 @@ EXPORT_SYMBOL(ixp2000_uengine_csr_write);
void ixp2000_uengine_reset(u32 uengine_mask)
{
ixp2000_reg_write(IXP2000_RESET1, uengine_mask & ixp2000_uengine_mask);
ixp2000_reg_write(IXP2000_RESET1, 0);
ixp2000_reg_wrb(IXP2000_RESET1, uengine_mask & ixp2000_uengine_mask);
ixp2000_reg_wrb(IXP2000_RESET1, 0);
}
EXPORT_SYMBOL(ixp2000_uengine_reset);
@ -452,21 +452,20 @@ static int __init ixp2000_uengine_init(void)
/*
* Reset microengines.
*/
ixp2000_reg_write(IXP2000_RESET1, ixp2000_uengine_mask);
ixp2000_reg_write(IXP2000_RESET1, 0);
ixp2000_uengine_reset(ixp2000_uengine_mask);
/*
* Synchronise timestamp counters across all microengines.
*/
value = ixp2000_reg_read(IXP2000_MISC_CONTROL);
ixp2000_reg_write(IXP2000_MISC_CONTROL, value & ~0x80);
ixp2000_reg_wrb(IXP2000_MISC_CONTROL, value & ~0x80);
for (uengine = 0; uengine < 32; uengine++) {
if (ixp2000_uengine_mask & (1 << uengine)) {
ixp2000_uengine_csr_write(uengine, TIMESTAMP_LOW, 0);
ixp2000_uengine_csr_write(uengine, TIMESTAMP_HIGH, 0);
}
}
ixp2000_reg_write(IXP2000_MISC_CONTROL, value | 0x80);
ixp2000_reg_wrb(IXP2000_MISC_CONTROL, value | 0x80);
return 0;
}

View File

@ -427,7 +427,7 @@ void __init ixp4xx_pci_preinit(void)
#ifdef __ARMEB__
*PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS | PCI_CSR_ADS;
#else
*PCI_CSR = PCI_CSR_IC;
*PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE;
#endif
pr_debug("DONE\n");

View File

@ -27,7 +27,8 @@ config PXA_SHARPSL
Say Y here if you intend to run this kernel on a
Sharp Zaurus SL-5600 (Poodle), SL-C700 (Corgi),
SL-C750 (Shepherd), SL-C760 (Husky), SL-C1000 (Akita),
SL-C3000 (Spitz) or SL-C3100 (Borzoi) handheld computer.
SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa)
handheld computer.
endchoice
@ -37,7 +38,7 @@ choice
prompt "Select target Sharp Zaurus device range"
config PXA_SHARPSL_25x
bool "Sharp PXA25x models (SL-5600 and SL-C7xx)"
bool "Sharp PXA25x models (SL-5600, SL-C7xx and SL-C6000x)"
select PXA25x
config PXA_SHARPSL_27x
@ -80,6 +81,10 @@ config MACH_BORZOI
depends PXA_SHARPSL_27x
select PXA_SHARP_Cxx00
config MACH_TOSA
bool "Enable Sharp SL-6000x (Tosa) Support"
depends PXA_SHARPSL
config PXA25x
bool
help

View File

@ -14,6 +14,7 @@ obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o ssp.o
obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o ssp.o
obj-$(CONFIG_MACH_POODLE) += poodle.o
obj-$(CONFIG_MACH_TOSA) += tosa.o
# Support for blinky lights
led-y := leds.o

View File

@ -19,16 +19,20 @@
#include <linux/major.h>
#include <linux/fb.h>
#include <linux/interrupt.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/mach-types.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/sizes.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/flash.h>
#include <asm/hardware/sa1111.h>
@ -199,10 +203,75 @@ static struct platform_device smc91x_device = {
.resource = smc91x_resources,
};
static struct resource flash_resources[] = {
[0] = {
.start = 0x00000000,
.end = SZ_64M - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 0x04000000,
.end = 0x04000000 + SZ_64M - 1,
.flags = IORESOURCE_MEM,
},
};
static struct mtd_partition lubbock_partitions[] = {
{
.name = "Bootloader",
.size = 0x00040000,
.offset = 0,
.mask_flags = MTD_WRITEABLE /* force read-only */
},{
.name = "Kernel",
.size = 0x00100000,
.offset = 0x00040000,
},{
.name = "Filesystem",
.size = MTDPART_SIZ_FULL,
.offset = 0x00140000
}
};
static struct flash_platform_data lubbock_flash_data[2] = {
{
.map_name = "cfi_probe",
.parts = lubbock_partitions,
.nr_parts = ARRAY_SIZE(lubbock_partitions),
}, {
.map_name = "cfi_probe",
.parts = NULL,
.nr_parts = 0,
}
};
static struct platform_device lubbock_flash_device[2] = {
{
.name = "pxa2xx-flash",
.id = 0,
.dev = {
.platform_data = &lubbock_flash_data[0],
},
.resource = &flash_resources[0],
.num_resources = 1,
},
{
.name = "pxa2xx-flash",
.id = 1,
.dev = {
.platform_data = &lubbock_flash_data[1],
},
.resource = &flash_resources[1],
.num_resources = 1,
},
};
static struct platform_device *devices[] __initdata = {
&sa1111_device,
&lub_audio_device,
&smc91x_device,
&lubbock_flash_device[0],
&lubbock_flash_device[1],
};
static struct pxafb_mach_info sharp_lm8v31 __initdata = {
@ -315,10 +384,21 @@ static struct pxaficp_platform_data lubbock_ficp_platform_data = {
static void __init lubbock_init(void)
{
int flashboot = (LUB_CONF_SWITCHES & 1);
pxa_set_udc_info(&udc_info);
set_pxa_fb_info(&sharp_lm8v31);
pxa_set_mci_info(&lubbock_mci_platform_data);
pxa_set_ficp_info(&lubbock_ficp_platform_data);
lubbock_flash_data[0].width = lubbock_flash_data[1].width =
(BOOT_DEF & 1) ? 2 : 4;
/* Compensate for the nROMBT switch which swaps the flash banks */
printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n",
flashboot?"Flash":"ROM", flashboot);
lubbock_flash_data[flashboot^1].name = "application-flash";
lubbock_flash_data[flashboot].name = "boot-rom";
(void) platform_add_devices(devices, ARRAY_SIZE(devices));
}

View File

@ -20,6 +20,9 @@
#include <linux/sched.h>
#include <linux/bitops.h>
#include <linux/fb.h>
#include <linux/ioport.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <asm/types.h>
#include <asm/setup.h>
@ -27,10 +30,12 @@
#include <asm/mach-types.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/sizes.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/flash.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/mainstone.h>
@ -190,6 +195,69 @@ static struct platform_device mst_audio_device = {
.dev = { .platform_data = &mst_audio_ops },
};
static struct resource flash_resources[] = {
[0] = {
.start = PXA_CS0_PHYS,
.end = PXA_CS0_PHYS + SZ_64M - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = PXA_CS1_PHYS,
.end = PXA_CS1_PHYS + SZ_64M - 1,
.flags = IORESOURCE_MEM,
},
};
static struct mtd_partition mainstoneflash0_partitions[] = {
{
.name = "Bootloader",
.size = 0x00040000,
.offset = 0,
.mask_flags = MTD_WRITEABLE /* force read-only */
},{
.name = "Kernel",
.size = 0x00400000,
.offset = 0x00040000,
},{
.name = "Filesystem",
.size = MTDPART_SIZ_FULL,
.offset = 0x00440000
}
};
static struct flash_platform_data mst_flash_data[2] = {
{
.map_name = "cfi_probe",
.parts = mainstoneflash0_partitions,
.nr_parts = ARRAY_SIZE(mainstoneflash0_partitions),
}, {
.map_name = "cfi_probe",
.parts = NULL,
.nr_parts = 0,
}
};
static struct platform_device mst_flash_device[2] = {
{
.name = "pxa2xx-flash",
.id = 0,
.dev = {
.platform_data = &mst_flash_data[0],
},
.resource = &flash_resources[0],
.num_resources = 1,
},
{
.name = "pxa2xx-flash",
.id = 1,
.dev = {
.platform_data = &mst_flash_data[1],
},
.resource = &flash_resources[1],
.num_resources = 1,
},
};
static void mainstone_backlight_power(int on)
{
if (on) {
@ -318,16 +386,34 @@ static struct pxaficp_platform_data mainstone_ficp_platform_data = {
.transceiver_mode = mainstone_irda_transceiver_mode,
};
static struct platform_device *platform_devices[] __initdata = {
&smc91x_device,
&mst_audio_device,
&mst_flash_device[0],
&mst_flash_device[1],
};
static void __init mainstone_init(void)
{
int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
mst_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4;
mst_flash_data[1].width = 4;
/* Compensate for SW7 which swaps the flash banks */
mst_flash_data[SW7].name = "processor-flash";
mst_flash_data[SW7 ^ 1].name = "mainboard-flash";
printk(KERN_NOTICE "Mainstone configured to boot from %s\n",
mst_flash_data[0].name);
/*
* On Mainstone, we route AC97_SYSCLK via GPIO45 to
* the audio daughter card
*/
pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD);
platform_device_register(&smc91x_device);
platform_device_register(&mst_audio_device);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
/* reading Mainstone's "Virtual Configuration Register"
might be handy to select LCD type here */

View File

@ -12,6 +12,7 @@
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/suspend.h>
#include <linux/errno.h>
#include <linux/time.h>
@ -19,6 +20,7 @@
#include <asm/hardware.h>
#include <asm/memory.h>
#include <asm/system.h>
#include <asm/arch/pm.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/lubbock.h>
#include <asm/mach/time.h>
@ -72,7 +74,7 @@ enum { SLEEP_SAVE_START = 0,
};
static int pxa_pm_enter(suspend_state_t state)
int pxa_pm_enter(suspend_state_t state)
{
unsigned long sleep_save[SLEEP_SAVE_SIZE];
unsigned long checksum = 0;
@ -191,6 +193,8 @@ static int pxa_pm_enter(suspend_state_t state)
return 0;
}
EXPORT_SYMBOL_GPL(pxa_pm_enter);
unsigned long sleep_phys_sp(void *sp)
{
return virt_to_phys(sp);
@ -199,21 +203,25 @@ unsigned long sleep_phys_sp(void *sp)
/*
* Called after processes are frozen, but before we shut down devices.
*/
static int pxa_pm_prepare(suspend_state_t state)
int pxa_pm_prepare(suspend_state_t state)
{
extern int pxa_cpu_pm_prepare(suspend_state_t state);
return pxa_cpu_pm_prepare(state);
}
EXPORT_SYMBOL_GPL(pxa_pm_prepare);
/*
* Called after devices are re-setup, but before processes are thawed.
*/
static int pxa_pm_finish(suspend_state_t state)
int pxa_pm_finish(suspend_state_t state)
{
return 0;
}
EXPORT_SYMBOL_GPL(pxa_pm_finish);
/*
* Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
*/
@ -230,4 +238,4 @@ static int __init pxa_pm_init(void)
return 0;
}
late_initcall(pxa_pm_init);
device_initcall(pxa_pm_init);

162
arch/arm/mach-pxa/tosa.c Normal file
View File

@ -0,0 +1,162 @@
/*
* Support for Sharp SL-C6000x PDAs
* Model: (Tosa)
*
* Copyright (c) 2005 Dirk Opfer
*
* Based on code written by Sharp/Lineo for 2.4 kernels
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/mmc/host.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/mach-types.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/arch/irda.h>
#include <asm/arch/mmc.h>
#include <asm/arch/udc.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/irq.h>
#include <asm/arch/tosa.h>
#include <asm/hardware/scoop.h>
#include <asm/mach/sharpsl_param.h>
#include "generic.h"
/*
* SCOOP Device
*/
static struct resource tosa_scoop_resources[] = {
[0] = {
.start = TOSA_CF_PHYS,
.end = TOSA_CF_PHYS + 0xfff,
.flags = IORESOURCE_MEM,
},
};
static struct scoop_config tosa_scoop_setup = {
.io_dir = TOSA_SCOOP_IO_DIR,
.io_out = TOSA_SCOOP_IO_OUT,
};
struct platform_device tosascoop_device = {
.name = "sharp-scoop",
.id = 0,
.dev = {
.platform_data = &tosa_scoop_setup,
},
.num_resources = ARRAY_SIZE(tosa_scoop_resources),
.resource = tosa_scoop_resources,
};
/*
* SCOOP Device Jacket
*/
static struct resource tosa_scoop_jc_resources[] = {
[0] = {
.start = TOSA_SCOOP_PHYS + 0x40,
.end = TOSA_SCOOP_PHYS + 0xfff,
.flags = IORESOURCE_MEM,
},
};
static struct scoop_config tosa_scoop_jc_setup = {
.io_dir = TOSA_SCOOP_JC_IO_DIR,
.io_out = TOSA_SCOOP_JC_IO_OUT,
};
struct platform_device tosascoop_jc_device = {
.name = "sharp-scoop",
.id = 1,
.dev = {
.platform_data = &tosa_scoop_jc_setup,
.parent = &tosascoop_device.dev,
},
.num_resources = ARRAY_SIZE(tosa_scoop_jc_resources),
.resource = tosa_scoop_jc_resources,
};
static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = {
{
.dev = &tosascoop_device.dev,
.irq = TOSA_IRQ_GPIO_CF_IRQ,
.cd_irq = TOSA_IRQ_GPIO_CF_CD,
.cd_irq_str = "PCMCIA0 CD",
},{
.dev = &tosascoop_jc_device.dev,
.irq = TOSA_IRQ_GPIO_JC_CF_IRQ,
.cd_irq = -1,
},
};
static struct platform_device *devices[] __initdata = {
&tosascoop_device,
&tosascoop_jc_device,
};
static void __init tosa_init(void)
{
pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_IN);
pxa_gpio_mode(TOSA_GPIO_TC6393_INT | GPIO_IN);
/* setup sleep mode values */
PWER = 0x00000002;
PFER = 0x00000000;
PRER = 0x00000002;
PGSR0 = 0x00000000;
PGSR1 = 0x00FF0002;
PGSR2 = 0x00014000;
PCFR |= PCFR_OPDE;
// enable batt_fault
PMCR = 0x01;
platform_add_devices(devices, ARRAY_SIZE(devices));
scoop_num = 2;
scoop_devs = &tosa_pcmcia_scoop[0];
}
static void __init fixup_tosa(struct machine_desc *desc,
struct tag *tags, char **cmdline, struct meminfo *mi)
{
sharpsl_save_param();
mi->nr_banks=1;
mi->bank[0].start = 0xa0000000;
mi->bank[0].node = 0;
mi->bank[0].size = (64*1024*1024);
}
MACHINE_START(TOSA, "SHARP Tosa")
.phys_ram = 0xa0000000,
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_tosa,
.map_io = pxa_map_io,
.init_irq = pxa_init_irq,
.init_machine = tosa_init,
.timer = &pxa_timer,
MACHINE_END

View File

@ -250,6 +250,18 @@ config CPU_V6
select CPU_COPY_V6
select CPU_TLB_V6
# ARMv6k
config CPU_32v6K
bool "Support ARM V6K processor extensions" if !SMP
depends on CPU_V6
default y if SMP
help
Say Y here if your ARMv6 processor supports the 'K' extension.
This enables the kernel to use some instructions not present
on previous processors, and as such a kernel build with this
enabled will not boot on processors with do not support these
instructions.
# Figure out what processor architecture version we should be using.
# This defines the compiler instruction set which depends on the machine type.
config CPU_32v3

View File

@ -469,14 +469,14 @@ void __init create_mapping(struct map_desc *md)
if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
printk(KERN_WARNING "BUG: not creating mapping for "
"0x%016llx at 0x%08lx in user region\n",
"0x%08llx at 0x%08lx in user region\n",
__pfn_to_phys((u64)md->pfn), md->virtual);
return;
}
if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
printk(KERN_WARNING "BUG: mapping for 0x%016llx at 0x%08lx "
printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx "
"overlaps vmalloc space\n",
__pfn_to_phys((u64)md->pfn), md->virtual);
}
@ -492,14 +492,14 @@ void __init create_mapping(struct map_desc *md)
if(md->pfn >= 0x100000) {
if(domain) {
printk(KERN_ERR "MM: invalid domain in supersection "
"mapping for 0x%016llx at 0x%08lx\n",
"mapping for 0x%08llx at 0x%08lx\n",
__pfn_to_phys((u64)md->pfn), md->virtual);
return;
}
if((md->virtual | md->length | __pfn_to_phys(md->pfn))
& ~SUPERSECTION_MASK) {
printk(KERN_ERR "MM: cannot create mapping for "
"0x%016llx at 0x%08lx invalid alignment\n",
"0x%08llx at 0x%08lx invalid alignment\n",
__pfn_to_phys((u64)md->pfn), md->virtual);
return;
}

View File

@ -108,8 +108,11 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
/*
* Sets the lazy trigger so that the next I/O operation will
* reload the correct bitmap.
* Reset the owner so that a process switch will not set
* tss->io_bitmap_base to IO_BITMAP_OFFSET.
*/
tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
tss->io_bitmap_owner = NULL;
put_cpu();

View File

@ -300,6 +300,7 @@ config PPC_PMAC64
bool
depends on PPC_PMAC && POWER4
select U3_DART
select GENERIC_TBSYNC
default y
config PPC_PREP
@ -314,15 +315,17 @@ config PPC_MAPLE
bool " Maple 970FX Evaluation Board"
select U3_DART
select MPIC_BROKEN_U3
select GENERIC_TBSYNC
default n
help
This option enables support for the Maple 970FX Evaluation Board.
For more informations, refer to <http://www.970eval.com>
config PPC_BPA
bool " Broadband Processor Architecture"
config PPC_CELL
bool " Cell Broadband Processor Architecture"
depends on PPC_MULTIPLATFORM && PPC64
select PPC_RTAS
select MMIO_NVRAM
config PPC_OF
bool
@ -353,13 +356,26 @@ config RTAS_ERROR_LOGGING
depends on PPC_RTAS
default n
config RTAS_PROC
bool "Proc interface to RTAS"
depends on PPC_RTAS
default y
config RTAS_FLASH
tristate "Firmware flash interface"
depends on PPC64 && RTAS_PROC
config MMIO_NVRAM
bool
default n
config MPIC_BROKEN_U3
bool
depends on PPC_MAPLE
default y
config BPA_IIC
depends on PPC_BPA
config CELL_IIC
depends on PPC_CELL
bool
default y
@ -372,6 +388,11 @@ config PPC_MPC106
bool
default n
config GENERIC_TBSYNC
bool
default y if CONFIG_PPC32 && CONFIG_SMP
default n
source "drivers/cpufreq/Kconfig"
config CPU_FREQ_PMAC
@ -582,6 +603,15 @@ config NODES_SPAN_OTHER_NODES
def_bool y
depends on NEED_MULTIPLE_NODES
config PPC_64K_PAGES
bool "64k page size"
help
This option changes the kernel logical page size to 64k. On machines
without processor support for 64k pages, the kernel will simulate
them by loading each individual 4k page on demand transparently,
while on hardware with such support, it will be used to map
normal application pages.
config SCHED_SMT
bool "SMT (Hyperthreading) scheduler support"
depends on PPC64 && SMP

View File

@ -12,9 +12,6 @@
# Rewritten by Cort Dougan and Paul Mackerras
#
# This must match PAGE_OFFSET in include/asm-powerpc/page.h.
KERNELLOAD := $(CONFIG_KERNEL_START)
HAS_BIARCH := $(call cc-option-yn, -m32)
ifeq ($(CONFIG_PPC64),y)
@ -59,7 +56,7 @@ override LD += -m elf$(SZ)ppc
override CC += -m$(SZ)
endif
LDFLAGS_vmlinux := -Ttext $(KERNELLOAD) -Bstatic -e $(KERNELLOAD)
LDFLAGS_vmlinux := -Bstatic
# The -Iarch/$(ARCH)/include is temporary while we are merging
CPPFLAGS += -Iarch/$(ARCH) -Iarch/$(ARCH)/include

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,998 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.14-rc4
# Thu Oct 20 08:30:56 2005
#
CONFIG_64BIT=y
CONFIG_MMU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_EARLY_PRINTK=y
CONFIG_COMPAT=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_FORCE_MAX_ZONEORDER=13
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=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_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_CPUSETS is not set
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_CC_ALIGN_FUNCTIONS=0
CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
#
# Loadable module support
#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
CONFIG_OBSOLETE_MODPARM=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_KMOD=y
CONFIG_STOP_MACHINE=y
CONFIG_SYSVIPC_COMPAT=y
#
# Platform support
#
CONFIG_PPC_ISERIES=y
# CONFIG_PPC_MULTIPLATFORM is not set
CONFIG_PPC=y
CONFIG_PPC64=y
CONFIG_IBMVIO=y
# CONFIG_POWER4_ONLY is not set
CONFIG_IOMMU_VMERGE=y
CONFIG_SMP=y
CONFIG_NR_CPUS=32
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_FLATMEM_ENABLE=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_NUMA is not set
# CONFIG_SCHED_SMT is not set
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
# CONFIG_PREEMPT_BKL is not set
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
CONFIG_GENERIC_HARDIRQS=y
CONFIG_LPARCFG=y
CONFIG_SECCOMP=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_ISA_DMA_API=y
#
# Bus Options
#
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_LEGACY_PROC=y
# CONFIG_PCI_DEBUG is not set
#
# PCCARD (PCMCIA/CardBus) support
#
# CONFIG_PCCARD is not set
#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
#
# Networking
#
CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
CONFIG_NET_KEY=m
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_FIB_HASH=y
# CONFIG_IP_PNP is not set
CONFIG_NET_IPIP=y
# CONFIG_NET_IPGRE is not set
# CONFIG_IP_MROUTE is not set
# CONFIG_ARPD is not set
CONFIG_SYN_COOKIES=y
CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_TUNNEL=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
#
# IP: Virtual Server Configuration
#
# CONFIG_IP_VS is not set
# CONFIG_IPV6 is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
# CONFIG_NETFILTER_NETLINK is not set
#
# IP: Netfilter Configuration
#
CONFIG_IP_NF_CONNTRACK=m
CONFIG_IP_NF_CT_ACCT=y
CONFIG_IP_NF_CONNTRACK_MARK=y
CONFIG_IP_NF_CONNTRACK_EVENTS=y
CONFIG_IP_NF_CT_PROTO_SCTP=m
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
# CONFIG_IP_NF_NETBIOS_NS is not set
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
# CONFIG_IP_NF_PPTP is not set
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
CONFIG_IP_NF_MATCH_IPRANGE=m
CONFIG_IP_NF_MATCH_MAC=m
CONFIG_IP_NF_MATCH_PKTTYPE=m
CONFIG_IP_NF_MATCH_MARK=m
CONFIG_IP_NF_MATCH_MULTIPORT=m
CONFIG_IP_NF_MATCH_TOS=m
CONFIG_IP_NF_MATCH_RECENT=m
CONFIG_IP_NF_MATCH_ECN=m
CONFIG_IP_NF_MATCH_DSCP=m
CONFIG_IP_NF_MATCH_AH_ESP=m
CONFIG_IP_NF_MATCH_LENGTH=m
CONFIG_IP_NF_MATCH_TTL=m
CONFIG_IP_NF_MATCH_TCPMSS=m
CONFIG_IP_NF_MATCH_HELPER=m
CONFIG_IP_NF_MATCH_STATE=m
CONFIG_IP_NF_MATCH_CONNTRACK=m
CONFIG_IP_NF_MATCH_OWNER=m
CONFIG_IP_NF_MATCH_ADDRTYPE=m
CONFIG_IP_NF_MATCH_REALM=m
CONFIG_IP_NF_MATCH_SCTP=m
# CONFIG_IP_NF_MATCH_DCCP is not set
CONFIG_IP_NF_MATCH_COMMENT=m
CONFIG_IP_NF_MATCH_CONNMARK=m
CONFIG_IP_NF_MATCH_CONNBYTES=m
CONFIG_IP_NF_MATCH_HASHLIMIT=m
CONFIG_IP_NF_MATCH_STRING=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_TARGET_TCPMSS=m
CONFIG_IP_NF_TARGET_NFQUEUE=m
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_SAME=m
CONFIG_IP_NF_NAT_SNMP_BASIC=m
CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
CONFIG_IP_NF_NAT_TFTP=m
CONFIG_IP_NF_NAT_AMANDA=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_TOS=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_CLASSIFY=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_TARGET_CONNMARK=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_RAW=m
CONFIG_IP_NF_TARGET_NOTRACK=m
CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
#
# DCCP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP 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_LLC=y
# 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_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_SCHED is not set
CONFIG_NET_CLS_ROUTE=y
#
# 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=m
# CONFIG_DEBUG_DRIVER 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=m
# CONFIG_BLK_DEV_SX8 is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=65536
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
# CONFIG_ATA_OVER_ETH 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_PROC_FS=y
#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
# CONFIG_CHR_DEV_OSST is not set
CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=y
# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_LOGGING is not set
#
# SCSI Transport Attributes
#
CONFIG_SCSI_SPI_ATTRS=y
CONFIG_SCSI_FC_ATTRS=y
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_SCSI_SAS_ATTRS is not set
#
# SCSI low-level drivers
#
# 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_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_SATA 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_IBMVSCSI=m
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
CONFIG_SCSI_QLA2XXX=y
# CONFIG_SCSI_QLA21XX is not set
# CONFIG_SCSI_QLA22XX is not set
# CONFIG_SCSI_QLA2300 is not set
# CONFIG_SCSI_QLA2322 is not set
# CONFIG_SCSI_QLA6312 is not set
# CONFIG_SCSI_QLA24XX is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_DEBUG is not set
#
# Multi-device support (RAID and LVM)
#
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
CONFIG_MD_LINEAR=y
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
CONFIG_MD_RAID10=m
CONFIG_MD_RAID5=y
CONFIG_MD_RAID6=m
CONFIG_MD_MULTIPATH=m
CONFIG_MD_FAULTY=m
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=m
CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m
CONFIG_DM_ZERO=m
# CONFIG_DM_MULTIPATH 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
#
#
# Network device support
#
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
#
# ARCnet devices
#
# CONFIG_ARCNET is not set
#
# PHY device support
#
# CONFIG_PHYLIB is not set
#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
#
# Tulip family network device support
#
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
CONFIG_NET_PCI=y
CONFIG_PCNET32=y
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
# CONFIG_DGRS is not set
# CONFIG_EEPRO100 is not set
CONFIG_E100=y
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
# CONFIG_8139CP is not set
# CONFIG_8139TOO is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_VIA_RHINE is not set
#
# Ethernet (1000 Mbit)
#
CONFIG_ACENIC=m
# CONFIG_ACENIC_OMIT_TIGON_I is not set
# CONFIG_DL2K is not set
CONFIG_E1000=m
# CONFIG_E1000_NAPI 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_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
#
# Token Ring devices
#
CONFIG_TR=y
CONFIG_IBMOL=y
# CONFIG_3C359 is not set
# CONFIG_TMS380TR is not set
#
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
#
# Wan interfaces
#
# CONFIG_WAN is not set
CONFIG_ISERIES_VETH=y
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
CONFIG_PPP=m
# CONFIG_PPP_MULTILINK is not set
# CONFIG_PPP_FILTER is not set
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
CONFIG_PPP_DEFLATE=m
CONFIG_PPP_BSDCOMP=m
CONFIG_PPPOE=m
# CONFIG_SLIP is not set
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
CONFIG_NETCONSOLE=y
CONFIG_NETPOLL=y
CONFIG_NETPOLL_RX=y
CONFIG_NETPOLL_TRAP=y
CONFIG_NET_POLL_CONTROLLER=y
#
# ISDN subsystem
#
# CONFIG_ISDN is not set
#
# Telephony Support
#
# CONFIG_PHONE is not set
#
# Input device support
#
CONFIG_INPUT=y
#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
# 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_SERIAL_NONSTANDARD is not set
#
# Serial drivers
#
# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=m
CONFIG_SERIAL_ICOM=m
# 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_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=y
CONFIG_MAX_RAW_DEVS=256
# CONFIG_HANGCHECK_TIMER is not set
#
# TPM devices
#
# CONFIG_TCG_TPM is not set
#
# I2C support
#
# CONFIG_I2C 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
#
# Misc devices
#
#
# Multimedia Capabilities Port drivers
#
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
#
# Digital Video Broadcasting Devices
#
# CONFIG_DVB is not set
#
# Graphics support
#
# CONFIG_FB 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 is not set
#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
#
# MMC/SD Card support
#
# CONFIG_MMC is not set
#
# InfiniBand support
#
# CONFIG_INFINIBAND is not set
#
# SN Devices
#
#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
CONFIG_EXT2_FS_XIP=y
CONFIG_FS_XIP=y
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
CONFIG_REISERFS_FS=y
# CONFIG_REISERFS_CHECK is not set
# CONFIG_REISERFS_PROC_INFO is not set
CONFIG_REISERFS_FS_XATTR=y
CONFIG_REISERFS_FS_POSIX_ACL=y
CONFIG_REISERFS_FS_SECURITY=y
CONFIG_JFS_FS=m
CONFIG_JFS_POSIX_ACL=y
CONFIG_JFS_SECURITY=y
# CONFIG_JFS_DEBUG is not set
# CONFIG_JFS_STATISTICS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
CONFIG_XFS_EXPORT=y
# CONFIG_XFS_QUOTA is not set
CONFIG_XFS_SECURITY=y
CONFIG_XFS_POSIX_ACL=y
# CONFIG_XFS_RT is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_ZISOFS_FS=y
CONFIG_UDF_FS=m
CONFIG_UDF_NLS=y
#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# CONFIG_NTFS_FS is not set
#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
# CONFIG_RELAYFS_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=y
# 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=y
CONFIG_NFS_V4=y
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=m
CONFIG_NFSD_V2_ACL=y
CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
CONFIG_NFSD_TCP=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
CONFIG_NFS_ACL_SUPPORT=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
CONFIG_RPCSEC_GSS_KRB5=y
CONFIG_RPCSEC_GSS_SPKM3=m
# CONFIG_SMB_FS is not set
CONFIG_CIFS=m
# CONFIG_CIFS_STATS is not set
CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
# CONFIG_CIFS_EXPERIMENTAL 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=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
# CONFIG_NLS_CODEPAGE_850 is not set
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set
#
# iSeries device drivers
#
CONFIG_VIOCONS=y
CONFIG_VIODASD=y
CONFIG_VIOCD=m
CONFIG_VIOTAPE=m
CONFIG_VIOPATH=y
#
# Profiling support
#
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_LOG_BUF_SHIFT=17
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_STACKOVERFLOW=y
# CONFIG_KPROBES is not set
CONFIG_DEBUG_STACK_USAGE=y
# CONFIG_DEBUGGER is not set
# CONFIG_PPCDBG is not set
CONFIG_IRQSTACKS=y
#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
#
# Cryptographic options
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
CONFIG_CRYPTO_TEST=m
#
# Hardware crypto devices
#
#
# Library routines
#
CONFIG_CRC_CCITT=m
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
CONFIG_TEXTSEARCH=y
CONFIG_TEXTSEARCH_KMP=m
CONFIG_TEXTSEARCH_BM=m
CONFIG_TEXTSEARCH_FSM=m

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -13,12 +13,15 @@ endif
obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
signal_32.o pmc.o
obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
ptrace32.o systbl.o
signal_64.o ptrace32.o systbl.o
obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
obj-$(CONFIG_POWER4) += idle_power4.o
obj-$(CONFIG_PPC_OF) += of_device.o
obj-$(CONFIG_PPC_RTAS) += rtas.o
obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
obj-$(CONFIG_RTAS_PROC) += rtas-proc.o
obj-$(CONFIG_IBMVIO) += vio.o
obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
ifeq ($(CONFIG_PPC_MERGE),y)
@ -38,6 +41,7 @@ obj-$(CONFIG_PPC_OF) += prom_init.o
obj-$(CONFIG_MODULES) += ppc_ksyms.o
obj-$(CONFIG_BOOTX_TEXT) += btext.o
obj-$(CONFIG_6xx) += idle_6xx.o
obj-$(CONFIG_SMP) += smp.o
ifeq ($(CONFIG_PPC_ISERIES),y)
$(obj)/head_64.o: $(obj)/lparmap.s
@ -46,8 +50,9 @@ endif
else
# stuff used from here for ARCH=ppc or ARCH=ppc64
smpobj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_PPC64) += traps.o process.o init_task.o time.o \
setup-common.o
setup-common.o $(smpobj-y)
endif

View File

@ -40,7 +40,7 @@
#ifdef CONFIG_PPC64
#include <asm/paca.h>
#include <asm/lppaca.h>
#include <asm/iSeries/HvLpEvent.h>
#include <asm/iseries/hv_lp_event.h>
#include <asm/cache.h>
#include <asm/systemcfg.h>
#include <asm/compat.h>
@ -125,6 +125,9 @@ int main(void)
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));
#ifdef CONFIG_PPC_64K_PAGES
DEFINE(PACAPGDIR, offsetof(struct paca_struct, pgdir));
#endif
#ifdef CONFIG_HUGETLB_PAGE
DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas));
DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas));

View File

@ -240,7 +240,7 @@ struct cpu_spec cpu_specs[] = {
.oprofile_model = &op_model_power4,
#endif
},
{ /* Power5 */
{ /* Power5 GR */
.pvr_mask = 0xffff0000,
.pvr_value = 0x003a0000,
.cpu_name = "POWER5 (gr)",
@ -255,7 +255,7 @@ struct cpu_spec cpu_specs[] = {
.oprofile_model = &op_model_power4,
#endif
},
{ /* Power5 */
{ /* Power5 GS */
.pvr_mask = 0xffff0000,
.pvr_value = 0x003b0000,
.cpu_name = "POWER5 (gs)",

View File

@ -35,7 +35,7 @@
#include <asm/cputable.h>
#include <asm/setup.h>
#include <asm/hvcall.h>
#include <asm/iSeries/LparMap.h>
#include <asm/iseries/lpar_map.h>
#include <asm/thread_info.h>
#ifdef CONFIG_PPC_ISERIES
@ -195,11 +195,11 @@ exception_marker:
#define EX_R12 24
#define EX_R13 32
#define EX_SRR0 40
#define EX_R3 40 /* SLB miss saves R3, but not SRR0 */
#define EX_DAR 48
#define EX_LR 48 /* SLB miss saves LR, but not DAR */
#define EX_DSISR 56
#define EX_CCR 60
#define EX_R3 64
#define EX_LR 72
#define EXCEPTION_PROLOG_PSERIES(area, label) \
mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
@ -419,17 +419,22 @@ data_access_slb_pSeries:
mtspr SPRN_SPRG1,r13
RUNLATCH_ON(r13)
mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
std r3,PACA_EXSLB+EX_R3(r13)
mfspr r3,SPRN_DAR
std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
mfcr r9
#ifdef __DISABLED__
/* Keep that around for when we re-implement dynamic VSIDs */
cmpdi r3,0
bge slb_miss_user_pseries
#endif /* __DISABLED__ */
std r10,PACA_EXSLB+EX_R10(r13)
std r11,PACA_EXSLB+EX_R11(r13)
std r12,PACA_EXSLB+EX_R12(r13)
std r3,PACA_EXSLB+EX_R3(r13)
mfspr r9,SPRN_SPRG1
std r9,PACA_EXSLB+EX_R13(r13)
mfcr r9
mfspr r10,SPRN_SPRG1
std r10,PACA_EXSLB+EX_R13(r13)
mfspr r12,SPRN_SRR1 /* and SRR1 */
mfspr r3,SPRN_DAR
b .do_slb_miss /* Rel. branch works in real mode */
b .slb_miss_realmode /* Rel. branch works in real mode */
STD_EXCEPTION_PSERIES(0x400, instruction_access)
@ -440,17 +445,22 @@ instruction_access_slb_pSeries:
mtspr SPRN_SPRG1,r13
RUNLATCH_ON(r13)
mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
std r3,PACA_EXSLB+EX_R3(r13)
mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
mfcr r9
#ifdef __DISABLED__
/* Keep that around for when we re-implement dynamic VSIDs */
cmpdi r3,0
bge slb_miss_user_pseries
#endif /* __DISABLED__ */
std r10,PACA_EXSLB+EX_R10(r13)
std r11,PACA_EXSLB+EX_R11(r13)
std r12,PACA_EXSLB+EX_R12(r13)
std r3,PACA_EXSLB+EX_R3(r13)
mfspr r9,SPRN_SPRG1
std r9,PACA_EXSLB+EX_R13(r13)
mfcr r9
mfspr r10,SPRN_SPRG1
std r10,PACA_EXSLB+EX_R13(r13)
mfspr r12,SPRN_SRR1 /* and SRR1 */
mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
b .do_slb_miss /* Rel. branch works in real mode */
b .slb_miss_realmode /* Rel. branch works in real mode */
STD_EXCEPTION_PSERIES(0x500, hardware_interrupt)
STD_EXCEPTION_PSERIES(0x600, alignment)
@ -508,6 +518,38 @@ _GLOBAL(do_stab_bolted_pSeries)
mfspr r12,SPRN_SPRG2
EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
/*
* We have some room here we use that to put
* the peries slb miss user trampoline code so it's reasonably
* away from slb_miss_user_common to avoid problems with rfid
*
* This is used for when the SLB miss handler has to go virtual,
* which doesn't happen for now anymore but will once we re-implement
* dynamic VSIDs for shared page tables
*/
#ifdef __DISABLED__
slb_miss_user_pseries:
std r10,PACA_EXGEN+EX_R10(r13)
std r11,PACA_EXGEN+EX_R11(r13)
std r12,PACA_EXGEN+EX_R12(r13)
mfspr r10,SPRG1
ld r11,PACA_EXSLB+EX_R9(r13)
ld r12,PACA_EXSLB+EX_R3(r13)
std r10,PACA_EXGEN+EX_R13(r13)
std r11,PACA_EXGEN+EX_R9(r13)
std r12,PACA_EXGEN+EX_R3(r13)
clrrdi r12,r13,32
mfmsr r10
mfspr r11,SRR0 /* save SRR0 */
ori r12,r12,slb_miss_user_common@l /* virt addr of handler */
ori r10,r10,MSR_IR|MSR_DR|MSR_RI
mtspr SRR0,r12
mfspr r12,SRR1 /* and SRR1 */
mtspr SRR1,r10
rfid
b . /* prevent spec. execution */
#endif /* __DISABLED__ */
/*
* Vectors for the FWNMI option. Share common code.
*/
@ -559,22 +601,59 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
.globl data_access_slb_iSeries
data_access_slb_iSeries:
mtspr SPRN_SPRG1,r13 /* save r13 */
EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
std r3,PACA_EXSLB+EX_R3(r13)
ld r12,PACALPPACA+LPPACASRR1(r13)
mfspr r3,SPRN_DAR
b .do_slb_miss
std r9,PACA_EXSLB+EX_R9(r13)
mfcr r9
#ifdef __DISABLED__
cmpdi r3,0
bge slb_miss_user_iseries
#endif
std r10,PACA_EXSLB+EX_R10(r13)
std r11,PACA_EXSLB+EX_R11(r13)
std r12,PACA_EXSLB+EX_R12(r13)
mfspr r10,SPRN_SPRG1
std r10,PACA_EXSLB+EX_R13(r13)
ld r12,PACALPPACA+LPPACASRR1(r13);
b .slb_miss_realmode
STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN)
.globl instruction_access_slb_iSeries
instruction_access_slb_iSeries:
mtspr SPRN_SPRG1,r13 /* save r13 */
EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
std r3,PACA_EXSLB+EX_R3(r13)
ld r12,PACALPPACA+LPPACASRR1(r13)
ld r3,PACALPPACA+LPPACASRR0(r13)
b .do_slb_miss
ld r3,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */
std r9,PACA_EXSLB+EX_R9(r13)
mfcr r9
#ifdef __DISABLED__
cmpdi r3,0
bge .slb_miss_user_iseries
#endif
std r10,PACA_EXSLB+EX_R10(r13)
std r11,PACA_EXSLB+EX_R11(r13)
std r12,PACA_EXSLB+EX_R12(r13)
mfspr r10,SPRN_SPRG1
std r10,PACA_EXSLB+EX_R13(r13)
ld r12,PACALPPACA+LPPACASRR1(r13);
b .slb_miss_realmode
#ifdef __DISABLED__
slb_miss_user_iseries:
std r10,PACA_EXGEN+EX_R10(r13)
std r11,PACA_EXGEN+EX_R11(r13)
std r12,PACA_EXGEN+EX_R12(r13)
mfspr r10,SPRG1
ld r11,PACA_EXSLB+EX_R9(r13)
ld r12,PACA_EXSLB+EX_R3(r13)
std r10,PACA_EXGEN+EX_R13(r13)
std r11,PACA_EXGEN+EX_R9(r13)
std r12,PACA_EXGEN+EX_R3(r13)
EXCEPTION_PROLOG_ISERIES_2
b slb_miss_user_common
#endif
MASKABLE_EXCEPTION_ISERIES(0x500, hardware_interrupt)
STD_EXCEPTION_ISERIES(0x600, alignment, PACA_EXGEN)
@ -809,6 +888,126 @@ instruction_access_common:
li r5,0x400
b .do_hash_page /* Try to handle as hpte fault */
/*
* Here is the common SLB miss user that is used when going to virtual
* mode for SLB misses, that is currently not used
*/
#ifdef __DISABLED__
.align 7
.globl slb_miss_user_common
slb_miss_user_common:
mflr r10
std r3,PACA_EXGEN+EX_DAR(r13)
stw r9,PACA_EXGEN+EX_CCR(r13)
std r10,PACA_EXGEN+EX_LR(r13)
std r11,PACA_EXGEN+EX_SRR0(r13)
bl .slb_allocate_user
ld r10,PACA_EXGEN+EX_LR(r13)
ld r3,PACA_EXGEN+EX_R3(r13)
lwz r9,PACA_EXGEN+EX_CCR(r13)
ld r11,PACA_EXGEN+EX_SRR0(r13)
mtlr r10
beq- slb_miss_fault
andi. r10,r12,MSR_RI /* check for unrecoverable exception */
beq- unrecov_user_slb
mfmsr r10
.machine push
.machine "power4"
mtcrf 0x80,r9
.machine pop
clrrdi r10,r10,2 /* clear RI before setting SRR0/1 */
mtmsrd r10,1
mtspr SRR0,r11
mtspr SRR1,r12
ld r9,PACA_EXGEN+EX_R9(r13)
ld r10,PACA_EXGEN+EX_R10(r13)
ld r11,PACA_EXGEN+EX_R11(r13)
ld r12,PACA_EXGEN+EX_R12(r13)
ld r13,PACA_EXGEN+EX_R13(r13)
rfid
b .
slb_miss_fault:
EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN)
ld r4,PACA_EXGEN+EX_DAR(r13)
li r5,0
std r4,_DAR(r1)
std r5,_DSISR(r1)
b .handle_page_fault
unrecov_user_slb:
EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN)
DISABLE_INTS
bl .save_nvgprs
1: addi r3,r1,STACK_FRAME_OVERHEAD
bl .unrecoverable_exception
b 1b
#endif /* __DISABLED__ */
/*
* r13 points to the PACA, r9 contains the saved CR,
* r12 contain the saved SRR1, SRR0 is still ready for return
* r3 has the faulting address
* r9 - r13 are saved in paca->exslb.
* r3 is saved in paca->slb_r3
* We assume we aren't going to take any exceptions during this procedure.
*/
_GLOBAL(slb_miss_realmode)
mflr r10
stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
std r10,PACA_EXSLB+EX_LR(r13) /* save LR */
bl .slb_allocate_realmode
/* All done -- return from exception. */
ld r10,PACA_EXSLB+EX_LR(r13)
ld r3,PACA_EXSLB+EX_R3(r13)
lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
#ifdef CONFIG_PPC_ISERIES
ld r11,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */
#endif /* CONFIG_PPC_ISERIES */
mtlr r10
andi. r10,r12,MSR_RI /* check for unrecoverable exception */
beq- unrecov_slb
.machine push
.machine "power4"
mtcrf 0x80,r9
mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
.machine pop
#ifdef CONFIG_PPC_ISERIES
mtspr SPRN_SRR0,r11
mtspr SPRN_SRR1,r12
#endif /* CONFIG_PPC_ISERIES */
ld r9,PACA_EXSLB+EX_R9(r13)
ld r10,PACA_EXSLB+EX_R10(r13)
ld r11,PACA_EXSLB+EX_R11(r13)
ld r12,PACA_EXSLB+EX_R12(r13)
ld r13,PACA_EXSLB+EX_R13(r13)
rfid
b . /* prevent speculative execution */
unrecov_slb:
EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
DISABLE_INTS
bl .save_nvgprs
1: addi r3,r1,STACK_FRAME_OVERHEAD
bl .unrecoverable_exception
b 1b
.align 7
.globl hardware_interrupt_common
.globl hardware_interrupt_entry
@ -1138,62 +1337,6 @@ _GLOBAL(do_stab_bolted)
rfid
b . /* prevent speculative execution */
/*
* r13 points to the PACA, r9 contains the saved CR,
* r11 and r12 contain the saved SRR0 and SRR1.
* r3 has the faulting address
* r9 - r13 are saved in paca->exslb.
* r3 is saved in paca->slb_r3
* We assume we aren't going to take any exceptions during this procedure.
*/
_GLOBAL(do_slb_miss)
mflr r10
stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
std r10,PACA_EXSLB+EX_LR(r13) /* save LR */
bl .slb_allocate /* handle it */
/* All done -- return from exception. */
ld r10,PACA_EXSLB+EX_LR(r13)
ld r3,PACA_EXSLB+EX_R3(r13)
lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
#ifdef CONFIG_PPC_ISERIES
ld r11,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */
#endif /* CONFIG_PPC_ISERIES */
mtlr r10
andi. r10,r12,MSR_RI /* check for unrecoverable exception */
beq- unrecov_slb
.machine push
.machine "power4"
mtcrf 0x80,r9
mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
.machine pop
#ifdef CONFIG_PPC_ISERIES
mtspr SPRN_SRR0,r11
mtspr SPRN_SRR1,r12
#endif /* CONFIG_PPC_ISERIES */
ld r9,PACA_EXSLB+EX_R9(r13)
ld r10,PACA_EXSLB+EX_R10(r13)
ld r11,PACA_EXSLB+EX_R11(r13)
ld r12,PACA_EXSLB+EX_R12(r13)
ld r13,PACA_EXSLB+EX_R13(r13)
rfid
b . /* prevent speculative execution */
unrecov_slb:
EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
DISABLE_INTS
bl .save_nvgprs
1: addi r3,r1,STACK_FRAME_OVERHEAD
bl .unrecoverable_exception
b 1b
/*
* Space for CPU0's segment table.
*
@ -1569,7 +1712,10 @@ _GLOBAL(__secondary_start)
#endif
/* Initialize the first segment table (or SLB) entry */
ld r3,PACASTABVIRT(r13) /* get addr of segment table */
BEGIN_FTR_SECTION
bl .stab_initialize
END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
bl .slb_initialize
/* Initialize the kernel stack. Just a repeat for iSeries. */
LOADADDR(r3,current_set)
@ -1914,24 +2060,6 @@ _GLOBAL(hmt_start_secondary)
blr
#endif
#if defined(CONFIG_KEXEC) || defined(CONFIG_SMP)
_GLOBAL(smp_release_cpus)
/* All secondary cpus are spinning on a common
* spinloop, release them all now so they can start
* to spin on their individual paca spinloops.
* For non SMP kernels, the secondary cpus never
* get out of the common spinloop.
* XXX This does nothing useful on iSeries, secondaries are
* already waiting on their paca.
*/
li r3,1
LOADADDR(r5,__secondary_hold_spinloop)
std r3,0(r5)
sync
blr
#endif /* CONFIG_SMP */
/*
* We put a few things here that have to be page-aligned.
* This stuff goes at the beginning of the bss, which is page-aligned.

View File

@ -8,7 +8,7 @@
*/
#include <asm/mmu.h>
#include <asm/page.h>
#include <asm/iSeries/LparMap.h>
#include <asm/iseries/lpar_map.h>
const struct LparMap __attribute__((__section__(".text"))) xLparMap = {
.xNumberEsids = HvEsidsToMap,
@ -25,7 +25,7 @@ const struct LparMap __attribute__((__section__(".text"))) xLparMap = {
.xRanges = {
{ .xPages = HvPagesToMap,
.xOffset = 0,
.xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - PAGE_SHIFT),
.xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - HW_PAGE_SHIFT),
},
},
};

View File

@ -91,6 +91,22 @@ typedef struct sigaltstack_32 {
compat_size_t ss_size;
} stack_32_t;
struct pt_regs32 {
unsigned int gpr[32];
unsigned int nip;
unsigned int msr;
unsigned int orig_gpr3; /* Used for restarting system calls */
unsigned int ctr;
unsigned int link;
unsigned int xer;
unsigned int ccr;
unsigned int mq; /* 601 only (not used at present) */
unsigned int trap; /* Reason for being here */
unsigned int dar; /* Fault registers */
unsigned int dsisr;
unsigned int result; /* Result of a system call */
};
struct sigcontext32 {
unsigned int _unused[4];
int signal;

View File

@ -81,15 +81,6 @@ EXPORT_SYMBOL(_prep_type);
EXPORT_SYMBOL(ucSystemType);
#endif
#if !defined(__INLINE_BITOPS)
EXPORT_SYMBOL(set_bit);
EXPORT_SYMBOL(clear_bit);
EXPORT_SYMBOL(change_bit);
EXPORT_SYMBOL(test_and_set_bit);
EXPORT_SYMBOL(test_and_clear_bit);
EXPORT_SYMBOL(test_and_change_bit);
#endif /* __INLINE_BITOPS */
EXPORT_SYMBOL(strcpy);
EXPORT_SYMBOL(strncpy);
EXPORT_SYMBOL(strcat);

View File

@ -48,8 +48,8 @@
#include <asm/prom.h>
#ifdef CONFIG_PPC64
#include <asm/firmware.h>
#include <asm/plpar_wrappers.h>
#include <asm/time.h>
#include <asm/machdep.h>
#endif
extern unsigned long _get_SP(void);
@ -201,27 +201,15 @@ int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
}
#endif /* CONFIG_SPE */
static void set_dabr_spr(unsigned long val)
{
mtspr(SPRN_DABR, val);
}
int set_dabr(unsigned long dabr)
{
int ret = 0;
#ifdef CONFIG_PPC64
if (firmware_has_feature(FW_FEATURE_XDABR)) {
/* We want to catch accesses from kernel and userspace */
unsigned long flags = H_DABRX_KERNEL|H_DABRX_USER;
ret = plpar_set_xdabr(dabr, flags);
} else if (firmware_has_feature(FW_FEATURE_DABR)) {
ret = plpar_set_dabr(dabr);
} else
if (ppc_md.set_dabr)
return ppc_md.set_dabr(dabr);
#endif
set_dabr_spr(dabr);
return ret;
mtspr(SPRN_DABR, dabr);
return 0;
}
#ifdef CONFIG_PPC64
@ -566,12 +554,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
#ifdef CONFIG_PPC64
if (cpu_has_feature(CPU_FTR_SLB)) {
unsigned long sp_vsid = get_kernel_vsid(sp);
unsigned long llp = mmu_psize_defs[mmu_linear_psize].sllp;
sp_vsid <<= SLB_VSID_SHIFT;
sp_vsid |= SLB_VSID_KERNEL;
if (cpu_has_feature(CPU_FTR_16M_PAGE))
sp_vsid |= SLB_VSID_L;
sp_vsid |= SLB_VSID_KERNEL | llp;
p->thread.ksp_vsid = sp_vsid;
}

View File

@ -724,10 +724,10 @@ static inline char *find_flat_dt_string(u32 offset)
* used to extract the memory informations at boot before we can
* unflatten the tree
*/
static int __init scan_flat_dt(int (*it)(unsigned long node,
const char *uname, int depth,
void *data),
void *data)
int __init of_scan_flat_dt(int (*it)(unsigned long node,
const char *uname, int depth,
void *data),
void *data)
{
unsigned long p = ((unsigned long)initial_boot_params) +
initial_boot_params->off_dt_struct;
@ -784,8 +784,8 @@ static int __init scan_flat_dt(int (*it)(unsigned long node,
* This function can be used within scan_flattened_dt callback to get
* access to properties
*/
static void* __init get_flat_dt_prop(unsigned long node, const char *name,
unsigned long *size)
void* __init of_get_flat_dt_prop(unsigned long node, const char *name,
unsigned long *size)
{
unsigned long p = node;
@ -1087,7 +1087,7 @@ void __init unflatten_device_tree(void)
static int __init early_init_dt_scan_cpus(unsigned long node,
const char *uname, int depth, void *data)
{
char *type = get_flat_dt_prop(node, "device_type", NULL);
char *type = of_get_flat_dt_prop(node, "device_type", NULL);
u32 *prop;
unsigned long size = 0;
@ -1095,19 +1095,6 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
if (type == NULL || strcmp(type, "cpu") != 0)
return 0;
#ifdef CONFIG_PPC_PSERIES
/* On LPAR, look for the first ibm,pft-size property for the hash table size
*/
if (systemcfg->platform == PLATFORM_PSERIES_LPAR && ppc64_pft_size == 0) {
u32 *pft_size;
pft_size = get_flat_dt_prop(node, "ibm,pft-size", NULL);
if (pft_size != NULL) {
/* pft_size[0] is the NUMA CEC cookie */
ppc64_pft_size = pft_size[1];
}
}
#endif
boot_cpuid = 0;
boot_cpuid_phys = 0;
if (initial_boot_params && initial_boot_params->version >= 2) {
@ -1117,8 +1104,9 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
boot_cpuid_phys = initial_boot_params->boot_cpuid_phys;
} else {
/* Check if it's the boot-cpu, set it's hw index now */
if (get_flat_dt_prop(node, "linux,boot-cpu", NULL) != NULL) {
prop = get_flat_dt_prop(node, "reg", NULL);
if (of_get_flat_dt_prop(node,
"linux,boot-cpu", NULL) != NULL) {
prop = of_get_flat_dt_prop(node, "reg", NULL);
if (prop != NULL)
boot_cpuid_phys = *prop;
}
@ -1127,14 +1115,14 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
#ifdef CONFIG_ALTIVEC
/* Check if we have a VMX and eventually update CPU features */
prop = (u32 *)get_flat_dt_prop(node, "ibm,vmx", &size);
prop = (u32 *)of_get_flat_dt_prop(node, "ibm,vmx", &size);
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 *)get_flat_dt_prop(node, "altivec", NULL);
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;
@ -1147,7 +1135,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
* this by looking at the size of the ibm,ppc-interrupt-server#s
* property
*/
prop = (u32 *)get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s",
prop = (u32 *)of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s",
&size);
cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
if (prop && ((size / sizeof(u32)) > 1))
@ -1170,7 +1158,7 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
return 0;
/* get platform type */
prop = (u32 *)get_flat_dt_prop(node, "linux,platform", NULL);
prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL);
if (prop == NULL)
return 0;
#ifdef CONFIG_PPC64
@ -1183,21 +1171,21 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
#ifdef CONFIG_PPC64
/* check if iommu is forced on or off */
if (get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
iommu_is_off = 1;
if (get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL)
if (of_get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL)
iommu_force_on = 1;
#endif
lprop = get_flat_dt_prop(node, "linux,memory-limit", NULL);
lprop = of_get_flat_dt_prop(node, "linux,memory-limit", NULL);
if (lprop)
memory_limit = *lprop;
#ifdef CONFIG_PPC64
lprop = get_flat_dt_prop(node, "linux,tce-alloc-start", NULL);
lprop = of_get_flat_dt_prop(node, "linux,tce-alloc-start", NULL);
if (lprop)
tce_alloc_start = *lprop;
lprop = get_flat_dt_prop(node, "linux,tce-alloc-end", NULL);
lprop = of_get_flat_dt_prop(node, "linux,tce-alloc-end", NULL);
if (lprop)
tce_alloc_end = *lprop;
#endif
@ -1209,9 +1197,9 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
{
u64 *basep, *entryp;
basep = get_flat_dt_prop(node, "linux,rtas-base", NULL);
entryp = get_flat_dt_prop(node, "linux,rtas-entry", NULL);
prop = get_flat_dt_prop(node, "linux,rtas-size", NULL);
basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL);
entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL);
prop = of_get_flat_dt_prop(node, "linux,rtas-size", NULL);
if (basep && entryp && prop) {
rtas.base = *basep;
rtas.entry = *entryp;
@ -1232,11 +1220,11 @@ static int __init early_init_dt_scan_root(unsigned long node,
if (depth != 0)
return 0;
prop = get_flat_dt_prop(node, "#size-cells", NULL);
prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
dt_root_size_cells = (prop == NULL) ? 1 : *prop;
DBG("dt_root_size_cells = %x\n", dt_root_size_cells);
prop = get_flat_dt_prop(node, "#address-cells", NULL);
prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
DBG("dt_root_addr_cells = %x\n", dt_root_addr_cells);
@ -1271,7 +1259,7 @@ static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
static int __init early_init_dt_scan_memory(unsigned long node,
const char *uname, int depth, void *data)
{
char *type = get_flat_dt_prop(node, "device_type", NULL);
char *type = of_get_flat_dt_prop(node, "device_type", NULL);
cell_t *reg, *endp;
unsigned long l;
@ -1279,13 +1267,13 @@ static int __init early_init_dt_scan_memory(unsigned long node,
if (type == NULL || strcmp(type, "memory") != 0)
return 0;
reg = (cell_t *)get_flat_dt_prop(node, "reg", &l);
reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
if (reg == NULL)
return 0;
endp = reg + (l / sizeof(cell_t));
DBG("memory scan node %s ..., reg size %ld, data: %x %x %x %x, ...\n",
DBG("memory scan node %s, reg size %ld, data: %x %x %x %x,\n",
uname, l, reg[0], reg[1], reg[2], reg[3]);
while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
@ -1343,12 +1331,12 @@ void __init early_init_devtree(void *params)
* device-tree, including the platform type, initrd location and
* size, TCE reserve, and more ...
*/
scan_flat_dt(early_init_dt_scan_chosen, NULL);
of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
/* Scan memory nodes and rebuild LMBs */
lmb_init();
scan_flat_dt(early_init_dt_scan_root, NULL);
scan_flat_dt(early_init_dt_scan_memory, NULL);
of_scan_flat_dt(early_init_dt_scan_root, NULL);
of_scan_flat_dt(early_init_dt_scan_memory, NULL);
lmb_enforce_memory_limit(memory_limit);
lmb_analyze();
#ifdef CONFIG_PPC64
@ -1363,10 +1351,10 @@ void __init early_init_devtree(void *params)
DBG("Scanning CPUs ...\n");
/* Retreive hash table size from flattened tree plus other
* CPU related informations (altivec support, boot CPU ID, ...)
/* Retreive CPU related informations from the flat tree
* (altivec support, boot CPU ID, ...)
*/
scan_flat_dt(early_init_dt_scan_cpus, NULL);
of_scan_flat_dt(early_init_dt_scan_cpus, NULL);
DBG(" <- early_init_devtree()\n");
}

View File

@ -2000,7 +2000,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
#endif
/*
* On pSeries and BPA, copy the CPU hold code
* Copy the CPU hold code
*/
if (RELOC(of_platform) != PLATFORM_POWERMAC)
copy_and_flush(0, KERNELBASE + offset, 0x100, 0);

View File

@ -42,6 +42,13 @@ DEFINE_SPINLOCK(rtas_data_buf_lock);
char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned;
unsigned long rtas_rmo_buf;
/*
* If non-NULL, this gets called when the kernel terminates.
* This is done like this so rtas_flash can be a module.
*/
void (*rtas_flash_term_hook)(int);
EXPORT_SYMBOL(rtas_flash_term_hook);
/*
* call_rtas_display_status and call_rtas_display_status_delay
* are designed only for very early low-level debugging, which
@ -206,6 +213,7 @@ void rtas_progress(char *s, unsigned short hex)
spin_unlock(&progress_lock);
}
EXPORT_SYMBOL(rtas_progress); /* needed by rtas_flash module */
int rtas_token(const char *service)
{
@ -492,6 +500,8 @@ int rtas_set_indicator(int indicator, int index, int new_value)
void rtas_restart(char *cmd)
{
if (rtas_flash_term_hook)
rtas_flash_term_hook(SYS_RESTART);
printk("RTAS system-reboot returned %d\n",
rtas_call(rtas_token("system-reboot"), 0, 1, NULL));
for (;;);
@ -499,6 +509,8 @@ void rtas_restart(char *cmd)
void rtas_power_off(void)
{
if (rtas_flash_term_hook)
rtas_flash_term_hook(SYS_POWER_OFF);
/* allow power on only with power button press */
printk("RTAS power-off returned %d\n",
rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1));
@ -507,7 +519,12 @@ void rtas_power_off(void)
void rtas_halt(void)
{
rtas_power_off();
if (rtas_flash_term_hook)
rtas_flash_term_hook(SYS_HALT);
/* allow power on only with power button press */
printk("RTAS power-off returned %d\n",
rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1));
for (;;);
}
/* Must be in the RMO region, so we place it here */

View File

@ -19,6 +19,7 @@
#include <asm/delay.h>
#include <asm/uaccess.h>
#include <asm/rtas.h>
#include <asm/abs_addr.h>
#define MODULE_VERS "1.0"
#define MODULE_NAME "rtas_flash"
@ -71,10 +72,36 @@
#define VALIDATE_BUF_SIZE 4096
#define RTAS_MSG_MAXLEN 64
struct flash_block {
char *data;
unsigned long length;
};
/* This struct is very similar but not identical to
* that needed by the rtas flash update.
* All we need to do for rtas is rewrite num_blocks
* into a version/length and translate the pointers
* to absolute.
*/
#define FLASH_BLOCKS_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct flash_block))
struct flash_block_list {
unsigned long num_blocks;
struct flash_block_list *next;
struct flash_block blocks[FLASH_BLOCKS_PER_NODE];
};
struct flash_block_list_header { /* just the header of flash_block_list */
unsigned long num_blocks;
struct flash_block_list *next;
};
static struct flash_block_list_header rtas_firmware_flash_list = {0, NULL};
#define FLASH_BLOCK_LIST_VERSION (1UL)
/* Local copy of the flash block list.
* We only allow one open of the flash proc file and create this
* list as we go. This list will be put in the kernel's
* rtas_firmware_flash_list global var once it is fully read.
* list as we go. This list will be put in the
* rtas_firmware_flash_list var once it is fully read.
*
* For convenience as we build the list we use virtual addrs,
* we do not fill in the version number, and the length field
@ -562,6 +589,86 @@ static int validate_flash_release(struct inode *inode, struct file *file)
return 0;
}
static void rtas_flash_firmware(int reboot_type)
{
unsigned long image_size;
struct flash_block_list *f, *next, *flist;
unsigned long rtas_block_list;
int i, status, update_token;
if (rtas_firmware_flash_list.next == NULL)
return; /* nothing to do */
if (reboot_type != SYS_RESTART) {
printk(KERN_ALERT "FLASH: firmware flash requires a reboot\n");
printk(KERN_ALERT "FLASH: the firmware image will NOT be flashed\n");
return;
}
update_token = rtas_token("ibm,update-flash-64-and-reboot");
if (update_token == RTAS_UNKNOWN_SERVICE) {
printk(KERN_ALERT "FLASH: ibm,update-flash-64-and-reboot "
"is not available -- not a service partition?\n");
printk(KERN_ALERT "FLASH: firmware will not be flashed\n");
return;
}
/* NOTE: the "first" block list is a global var with no data
* blocks in the kernel data segment. We do this because
* we want to ensure this block_list addr is under 4GB.
*/
rtas_firmware_flash_list.num_blocks = 0;
flist = (struct flash_block_list *)&rtas_firmware_flash_list;
rtas_block_list = virt_to_abs(flist);
if (rtas_block_list >= 4UL*1024*1024*1024) {
printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n");
return;
}
printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n");
/* Update the block_list in place. */
image_size = 0;
for (f = flist; f; f = next) {
/* Translate data addrs to absolute */
for (i = 0; i < f->num_blocks; i++) {
f->blocks[i].data = (char *)virt_to_abs(f->blocks[i].data);
image_size += f->blocks[i].length;
}
next = f->next;
/* Don't translate NULL pointer for last entry */
if (f->next)
f->next = (struct flash_block_list *)virt_to_abs(f->next);
else
f->next = NULL;
/* make num_blocks into the version/length field */
f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16);
}
printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);
printk(KERN_ALERT "FLASH: performing flash and reboot\n");
rtas_progress("Flashing \n", 0x0);
rtas_progress("Please Wait... ", 0x0);
printk(KERN_ALERT "FLASH: this will take several minutes. Do not power off!\n");
status = rtas_call(update_token, 1, 1, NULL, rtas_block_list);
switch (status) { /* should only get "bad" status */
case 0:
printk(KERN_ALERT "FLASH: success\n");
break;
case -1:
printk(KERN_ALERT "FLASH: hardware error. Firmware may not be not flashed\n");
break;
case -3:
printk(KERN_ALERT "FLASH: image is corrupt or not correct for this platform. Firmware not flashed\n");
break;
case -4:
printk(KERN_ALERT "FLASH: flash failed when partially complete. System may not reboot\n");
break;
default:
printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status);
break;
}
}
static void remove_flash_pde(struct proc_dir_entry *dp)
{
if (dp) {
@ -701,6 +808,7 @@ int __init rtas_flash_init(void)
if (rc != 0)
goto cleanup;
rtas_flash_term_hook = rtas_flash_firmware;
return 0;
cleanup:
@ -714,6 +822,7 @@ cleanup:
void __exit rtas_flash_cleanup(void)
{
rtas_flash_term_hook = NULL;
remove_flash_pde(firmware_flash_pde);
remove_flash_pde(firmware_update_pde);
remove_flash_pde(validate_pde);

View File

@ -170,11 +170,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
}
#ifdef CONFIG_SMP
#ifdef CONFIG_PPC64 /* XXX for now */
pvr = per_cpu(pvr, cpu_id);
#else
pvr = cpu_data[cpu_id].pvr;
#endif
#else
pvr = mfspr(SPRN_PVR);
#endif
@ -201,11 +197,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
#ifdef CONFIG_TAU_AVERAGE
/* more straightforward, but potentially misleading */
seq_printf(m, "temperature \t: %u C (uncalibrated)\n",
cpu_temp(i));
cpu_temp(cpu_id));
#else
/* show the actual temp sensor range */
u32 temp;
temp = cpu_temp_both(i);
temp = cpu_temp_both(cpu_id);
seq_printf(m, "temperature \t: %u-%u C (uncalibrated)\n",
temp & 0xff, temp >> 16);
#endif
@ -408,3 +404,118 @@ static int __init set_preferred_console(void)
}
console_initcall(set_preferred_console);
#endif /* CONFIG_PPC_MULTIPLATFORM */
#ifdef CONFIG_SMP
/**
* setup_cpu_maps - initialize the following cpu maps:
* cpu_possible_map
* cpu_present_map
* cpu_sibling_map
*
* Having the possible map set up early allows us to restrict allocations
* of things like irqstacks to num_possible_cpus() rather than NR_CPUS.
*
* We do not initialize the online map here; cpus set their own bits in
* cpu_online_map as they come up.
*
* This function is valid only for Open Firmware systems. finish_device_tree
* must be called before using this.
*
* While we're here, we may as well set the "physical" cpu ids in the paca.
*/
void __init smp_setup_cpu_maps(void)
{
struct device_node *dn = NULL;
int cpu = 0;
int swap_cpuid = 0;
while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
int *intserv;
int j, len = sizeof(u32), nthreads = 1;
intserv = (int *)get_property(dn, "ibm,ppc-interrupt-server#s",
&len);
if (intserv)
nthreads = len / sizeof(int);
else {
intserv = (int *) get_property(dn, "reg", NULL);
if (!intserv)
intserv = &cpu; /* assume logical == phys */
}
for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
cpu_set(cpu, cpu_present_map);
set_hard_smp_processor_id(cpu, intserv[j]);
if (intserv[j] == boot_cpuid_phys)
swap_cpuid = cpu;
cpu_set(cpu, cpu_possible_map);
cpu++;
}
}
/* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that
* boot cpu is logical 0.
*/
if (boot_cpuid_phys != get_hard_smp_processor_id(0)) {
u32 tmp;
tmp = get_hard_smp_processor_id(0);
set_hard_smp_processor_id(0, boot_cpuid_phys);
set_hard_smp_processor_id(swap_cpuid, tmp);
}
#ifdef CONFIG_PPC64
/*
* On pSeries LPAR, we need to know how many cpus
* could possibly be added to this partition.
*/
if (systemcfg->platform == PLATFORM_PSERIES_LPAR &&
(dn = of_find_node_by_path("/rtas"))) {
int num_addr_cell, num_size_cell, maxcpus;
unsigned int *ireg;
num_addr_cell = prom_n_addr_cells(dn);
num_size_cell = prom_n_size_cells(dn);
ireg = (unsigned int *)
get_property(dn, "ibm,lrdr-capacity", NULL);
if (!ireg)
goto out;
maxcpus = ireg[num_addr_cell + num_size_cell];
/* Double maxcpus for processors which have SMT capability */
if (cpu_has_feature(CPU_FTR_SMT))
maxcpus *= 2;
if (maxcpus > NR_CPUS) {
printk(KERN_WARNING
"Partition configured for %d cpus, "
"operating system maximum is %d.\n",
maxcpus, NR_CPUS);
maxcpus = NR_CPUS;
} else
printk(KERN_INFO "Partition configured for %d cpus.\n",
maxcpus);
for (cpu = 0; cpu < maxcpus; cpu++)
cpu_set(cpu, cpu_possible_map);
out:
of_node_put(dn);
}
/*
* Do the sibling map; assume only two threads per processor.
*/
for_each_cpu(cpu) {
cpu_set(cpu, cpu_sibling_map[cpu]);
if (cpu_has_feature(CPU_FTR_SMT))
cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
}
systemcfg->processorCount = num_present_cpus();
#endif /* CONFIG_PPC64 */
}
#endif /* CONFIG_SMP */

View File

@ -288,6 +288,8 @@ void __init setup_arch(char **cmdline_p)
unflatten_device_tree();
finish_device_tree();
smp_setup_cpu_maps();
#ifdef CONFIG_BOOTX_TEXT
init_boot_display();
#endif

View File

@ -56,7 +56,7 @@
#include <asm/page.h>
#include <asm/mmu.h>
#include <asm/lmb.h>
#include <asm/iSeries/ItLpNaca.h>
#include <asm/iseries/it_lp_naca.h>
#include <asm/firmware.h>
#include <asm/systemcfg.h>
#include <asm/xmon.h>
@ -103,8 +103,6 @@ extern void htab_initialize(void);
extern void early_init_devtree(void *flat_dt);
extern void unflatten_device_tree(void);
extern void smp_release_cpus(void);
int have_of = 1;
int boot_cpuid = 0;
int boot_cpuid_phys = 0;
@ -183,120 +181,14 @@ static int __init early_smt_enabled(char *p)
}
early_param("smt-enabled", early_smt_enabled);
/**
* setup_cpu_maps - initialize the following cpu maps:
* cpu_possible_map
* cpu_present_map
* cpu_sibling_map
*
* Having the possible map set up early allows us to restrict allocations
* of things like irqstacks to num_possible_cpus() rather than NR_CPUS.
*
* We do not initialize the online map here; cpus set their own bits in
* cpu_online_map as they come up.
*
* This function is valid only for Open Firmware systems. finish_device_tree
* must be called before using this.
*
* While we're here, we may as well set the "physical" cpu ids in the paca.
*/
static void __init setup_cpu_maps(void)
{
struct device_node *dn = NULL;
int cpu = 0;
int swap_cpuid = 0;
check_smt_enabled();
while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
u32 *intserv;
int j, len = sizeof(u32), nthreads;
intserv = (u32 *)get_property(dn, "ibm,ppc-interrupt-server#s",
&len);
if (!intserv)
intserv = (u32 *)get_property(dn, "reg", NULL);
nthreads = len / sizeof(u32);
for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
cpu_set(cpu, cpu_present_map);
set_hard_smp_processor_id(cpu, intserv[j]);
if (intserv[j] == boot_cpuid_phys)
swap_cpuid = cpu;
cpu_set(cpu, cpu_possible_map);
cpu++;
}
}
/* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that
* boot cpu is logical 0.
*/
if (boot_cpuid_phys != get_hard_smp_processor_id(0)) {
u32 tmp;
tmp = get_hard_smp_processor_id(0);
set_hard_smp_processor_id(0, boot_cpuid_phys);
set_hard_smp_processor_id(swap_cpuid, tmp);
}
/*
* On pSeries LPAR, we need to know how many cpus
* could possibly be added to this partition.
*/
if (systemcfg->platform == PLATFORM_PSERIES_LPAR &&
(dn = of_find_node_by_path("/rtas"))) {
int num_addr_cell, num_size_cell, maxcpus;
unsigned int *ireg;
num_addr_cell = prom_n_addr_cells(dn);
num_size_cell = prom_n_size_cells(dn);
ireg = (unsigned int *)
get_property(dn, "ibm,lrdr-capacity", NULL);
if (!ireg)
goto out;
maxcpus = ireg[num_addr_cell + num_size_cell];
/* Double maxcpus for processors which have SMT capability */
if (cpu_has_feature(CPU_FTR_SMT))
maxcpus *= 2;
if (maxcpus > NR_CPUS) {
printk(KERN_WARNING
"Partition configured for %d cpus, "
"operating system maximum is %d.\n",
maxcpus, NR_CPUS);
maxcpus = NR_CPUS;
} else
printk(KERN_INFO "Partition configured for %d cpus.\n",
maxcpus);
for (cpu = 0; cpu < maxcpus; cpu++)
cpu_set(cpu, cpu_possible_map);
out:
of_node_put(dn);
}
/*
* Do the sibling map; assume only two threads per processor.
*/
for_each_cpu(cpu) {
cpu_set(cpu, cpu_sibling_map[cpu]);
if (cpu_has_feature(CPU_FTR_SMT))
cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
}
systemcfg->processorCount = num_present_cpus();
}
#else
#define check_smt_enabled()
#endif /* CONFIG_SMP */
extern struct machdep_calls pSeries_md;
extern struct machdep_calls pmac_md;
extern struct machdep_calls maple_md;
extern struct machdep_calls bpa_md;
extern struct machdep_calls cell_md;
extern struct machdep_calls iseries_md;
/* Ultimately, stuff them in an elf section like initcalls... */
@ -310,8 +202,8 @@ static struct machdep_calls __initdata *machines[] = {
#ifdef CONFIG_PPC_MAPLE
&maple_md,
#endif /* CONFIG_PPC_MAPLE */
#ifdef CONFIG_PPC_BPA
&bpa_md,
#ifdef CONFIG_PPC_CELL
&cell_md,
#endif
#ifdef CONFIG_PPC_ISERIES
&iseries_md,
@ -384,22 +276,50 @@ void __init early_setup(unsigned long dt_ptr)
DBG("Found, Initializing memory management...\n");
/*
* Initialize stab / SLB management
*/
if (!firmware_has_feature(FW_FEATURE_ISERIES))
stab_initialize(lpaca->stab_real);
/*
* Initialize the MMU Hash table and create the linear mapping
* of memory
* of memory. Has to be done before stab/slb initialization as
* this is currently where the page size encoding is obtained
*/
htab_initialize();
/*
* Initialize stab / SLB management except on iSeries
*/
if (!firmware_has_feature(FW_FEATURE_ISERIES)) {
if (cpu_has_feature(CPU_FTR_SLB))
slb_initialize();
else
stab_initialize(lpaca->stab_real);
}
DBG(" <- early_setup()\n");
}
#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
void smp_release_cpus(void)
{
extern unsigned long __secondary_hold_spinloop;
DBG(" -> smp_release_cpus()\n");
/* All secondary cpus are spinning on a common spinloop, release them
* all now so they can start to spin on their individual paca
* spinloops. For non SMP kernels, the secondary cpus never get out
* of the common spinloop.
* This is useless but harmless on iSeries, secondaries are already
* waiting on their paca spinloops. */
__secondary_hold_spinloop = 1;
mb();
DBG(" <- smp_release_cpus()\n");
}
#else
#define smp_release_cpus()
#endif /* CONFIG_SMP || CONFIG_KEXEC */
/*
* Initialize some remaining members of the ppc64_caches and systemcfg structures
* (at least until we get rid of them completely). This is mostly some
@ -589,17 +509,13 @@ void __init setup_system(void)
parse_early_param();
#ifdef CONFIG_SMP
/*
* iSeries has already initialized the cpu maps at this point.
*/
setup_cpu_maps();
check_smt_enabled();
smp_setup_cpu_maps();
/* Release secondary cpus out of their spinloops at 0x60 now that
* we can map physical -> logical CPU ids
*/
smp_release_cpus();
#endif
printk("Starting Linux PPC64 %s\n", system_utsname.version);
@ -631,23 +547,6 @@ static int ppc64_panic_event(struct notifier_block *this,
return NOTIFY_DONE;
}
#ifdef CONFIG_PPC_ISERIES
/*
* On iSeries we just parse the mem=X option from the command line.
* On pSeries it's a bit more complicated, see prom_init_mem()
*/
static int __init early_parsemem(char *p)
{
if (!p)
return 0;
memory_limit = ALIGN(memparse(p, &p), PAGE_SIZE);
return 0;
}
early_param("mem", early_parsemem);
#endif /* CONFIG_PPC_ISERIES */
#ifdef CONFIG_IRQSTACKS
static void __init irqstack_early_init(void)
{
@ -658,10 +557,12 @@ static void __init irqstack_early_init(void)
* SLB misses on them.
*/
for_each_cpu(i) {
softirq_ctx[i] = (struct thread_info *)__va(lmb_alloc_base(THREAD_SIZE,
THREAD_SIZE, 0x10000000));
hardirq_ctx[i] = (struct thread_info *)__va(lmb_alloc_base(THREAD_SIZE,
THREAD_SIZE, 0x10000000));
softirq_ctx[i] = (struct thread_info *)
__va(lmb_alloc_base(THREAD_SIZE,
THREAD_SIZE, 0x10000000));
hardirq_ctx[i] = (struct thread_info *)
__va(lmb_alloc_base(THREAD_SIZE,
THREAD_SIZE, 0x10000000));
}
}
#else
@ -689,8 +590,8 @@ static void __init emergency_stack_init(void)
limit = min(0x10000000UL, lmb.rmo_size);
for_each_cpu(i)
paca[i].emergency_sp = __va(lmb_alloc_base(PAGE_SIZE, 128,
limit)) + PAGE_SIZE;
paca[i].emergency_sp =
__va(lmb_alloc_base(HW_PAGE_SIZE, 128, limit)) + HW_PAGE_SIZE;
}
/*

View File

@ -43,7 +43,7 @@
#include <asm/uaccess.h>
#include <asm/cacheflush.h>
#ifdef CONFIG_PPC64
#include <asm/ppc32.h>
#include "ppc32.h"
#include <asm/ppcdebug.h>
#include <asm/unistd.h>
#include <asm/vdso.h>

View File

@ -22,11 +22,11 @@ enum {
};
static struct {
volatile long tb;
volatile long mark;
volatile u64 tb;
volatile u64 mark;
volatile int cmd;
volatile int handshake;
int filler[3];
int filler[2];
volatile int ack;
int filler2[7];
@ -36,89 +36,80 @@ static struct {
static volatile int running;
static void __devinit
enter_contest( long mark, long add )
static void __devinit enter_contest(u64 mark, long add)
{
while( (long)(mftb() - mark) < 0 )
while (get_tb() < mark)
tbsync->race_result = add;
}
void __devinit
smp_generic_take_timebase( void )
void __devinit smp_generic_take_timebase(void)
{
int cmd;
long tb;
u64 tb;
local_irq_disable();
while( !running )
;
while (!running)
barrier();
rmb();
for( ;; ) {
for (;;) {
tbsync->ack = 1;
while( !tbsync->handshake )
;
while (!tbsync->handshake)
barrier();
rmb();
cmd = tbsync->cmd;
tb = tbsync->tb;
mb();
tbsync->ack = 0;
if( cmd == kExit )
return;
if (cmd == kExit)
break;
if( cmd == kSetAndTest ) {
while( tbsync->handshake )
;
asm volatile ("mttbl %0" :: "r" (tb & 0xfffffffful) );
asm volatile ("mttbu %0" :: "r" (tb >> 32) );
} else {
while( tbsync->handshake )
;
}
enter_contest( tbsync->mark, -1 );
while (tbsync->handshake)
barrier();
if (cmd == kSetAndTest)
set_tb(tb >> 32, tb & 0xfffffffful);
enter_contest(tbsync->mark, -1);
}
local_irq_enable();
}
static int __devinit
start_contest( int cmd, long offset, long num )
static int __devinit start_contest(int cmd, long offset, int num)
{
int i, score=0;
long tb, mark;
u64 tb;
long mark;
tbsync->cmd = cmd;
local_irq_disable();
for( i=-3; i<num; ) {
tb = (long)mftb() + 400;
for (i = -3; i < num; ) {
tb = get_tb() + 400;
tbsync->tb = tb + offset;
tbsync->mark = mark = tb + 400;
wmb();
tbsync->handshake = 1;
while( tbsync->ack )
;
while (tbsync->ack)
barrier();
while( (long)(mftb() - tb) <= 0 )
;
while (get_tb() <= tb)
barrier();
tbsync->handshake = 0;
enter_contest( mark, 1 );
enter_contest(mark, 1);
while( !tbsync->ack )
;
while (!tbsync->ack)
barrier();
if ((tbsync->tb ^ (long)mftb()) & 0x8000000000000000ul)
continue;
if( i++ > 0 )
if (i++ > 0)
score += tbsync->race_result;
}
local_irq_enable();
return score;
}
void __devinit
smp_generic_give_timebase( void )
void __devinit smp_generic_give_timebase(void)
{
int i, score, score2, old, min=0, max=5000, offset=1000;
@ -130,14 +121,14 @@ smp_generic_give_timebase( void )
mb();
running = 1;
while( !tbsync->ack )
;
while (!tbsync->ack)
barrier();
printk("Got ack\n");
/* binary search */
for( old=-1 ; old != offset ; offset=(min+max)/2 ) {
score = start_contest( kSetAndTest, offset, NUM_ITER );
for (old = -1; old != offset ; offset = (min+max) / 2) {
score = start_contest(kSetAndTest, offset, NUM_ITER);
printk("score %d, offset %d\n", score, offset );
@ -147,21 +138,22 @@ smp_generic_give_timebase( void )
min = offset;
old = offset;
}
score = start_contest( kSetAndTest, min, NUM_ITER );
score2 = start_contest( kSetAndTest, max, NUM_ITER );
score = start_contest(kSetAndTest, min, NUM_ITER);
score2 = start_contest(kSetAndTest, max, NUM_ITER);
printk( "Min %d (score %d), Max %d (score %d)\n", min, score, max, score2 );
score = abs( score );
score2 = abs( score2 );
printk("Min %d (score %d), Max %d (score %d)\n",
min, score, max, score2);
score = abs(score);
score2 = abs(score2);
offset = (score < score2) ? min : max;
/* guard against inaccurate mttb */
for( i=0; i<10; i++ ) {
start_contest( kSetAndTest, offset, NUM_ITER/10 );
for (i = 0; i < 10; i++) {
start_contest(kSetAndTest, offset, NUM_ITER/10);
if( (score2=start_contest(kTest, offset, NUM_ITER)) < 0 )
if ((score2 = start_contest(kTest, offset, NUM_ITER)) < 0)
score2 = -score2;
if( score2 <= score || score2 < 20 )
if (score2 <= score || score2 < 20)
break;
}
printk("Final offset: %d (%d/%d)\n", offset, score2, NUM_ITER );
@ -170,10 +162,10 @@ smp_generic_give_timebase( void )
tbsync->cmd = kExit;
wmb();
tbsync->handshake = 1;
while( tbsync->ack )
;
while (tbsync->ack)
barrier();
tbsync->handshake = 0;
kfree( tbsync );
kfree(tbsync);
tbsync = NULL;
running = 0;
}

View File

@ -39,13 +39,18 @@
#include <asm/pgtable.h>
#include <asm/prom.h>
#include <asm/smp.h>
#include <asm/paca.h>
#include <asm/time.h>
#include <asm/xmon.h>
#include <asm/machdep.h>
#include <asm/cputable.h>
#include <asm/system.h>
#include <asm/abs_addr.h>
#include <asm/mpic.h>
#ifdef CONFIG_PPC64
#include <asm/paca.h>
#endif
int smp_hw_index[NR_CPUS];
struct thread_info *secondary_ti;
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@ -60,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);
/* SMP operations for this machine */
struct smp_ops_t *smp_ops;
static volatile unsigned int cpu_callin_map[NR_CPUS];
@ -89,7 +95,9 @@ void __devinit smp_mpic_setup_cpu(int cpu)
{
mpic_setup_this_cpu();
}
#endif /* CONFIG_MPIC */
#ifdef CONFIG_PPC64
void __devinit smp_generic_kick_cpu(int nr)
{
BUG_ON(nr < 0 || nr >= NR_CPUS);
@ -102,8 +110,7 @@ void __devinit smp_generic_kick_cpu(int nr)
paca[nr].cpu_start = 1;
smp_mb();
}
#endif /* CONFIG_MPIC */
#endif
void smp_message_recv(int msg, struct pt_regs *regs)
{
@ -111,15 +118,10 @@ void smp_message_recv(int msg, struct pt_regs *regs)
case PPC_MSG_CALL_FUNCTION:
smp_call_function_interrupt();
break;
case PPC_MSG_RESCHEDULE:
case PPC_MSG_RESCHEDULE:
/* XXX Do we have to do this? */
set_need_resched();
break;
#if 0
case PPC_MSG_MIGRATE_TASK:
/* spare */
break;
#endif
#ifdef CONFIG_DEBUGGER
case PPC_MSG_DEBUGGER_BREAK:
debugger_ipi(regs);
@ -171,8 +173,8 @@ static struct call_data_struct {
int wait;
} *call_data;
/* delay of at least 8 seconds on 1GHz cpu */
#define SMP_CALL_TIMEOUT (1UL << (30 + 3))
/* delay of at least 8 seconds */
#define SMP_CALL_TIMEOUT 8
/*
* This function sends a 'generic call function' IPI to all other CPUs
@ -194,7 +196,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
{
struct call_data_struct data;
int ret = -1, cpus;
unsigned long timeout;
u64 timeout;
/* Can deadlock when called with interrupts disabled */
WARN_ON(irqs_disabled());
@ -220,11 +222,12 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
/* Send a message to all other CPUs and wait for them to respond */
smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION);
timeout = get_tb() + (u64) SMP_CALL_TIMEOUT * tb_ticks_per_sec;
/* Wait for response */
timeout = SMP_CALL_TIMEOUT;
while (atomic_read(&data.started) != cpus) {
HMT_low();
if (--timeout == 0) {
if (get_tb() >= timeout) {
printk("smp_call_function on cpu %d: other cpus not "
"responding (%d)\n", smp_processor_id(),
atomic_read(&data.started));
@ -234,10 +237,9 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
}
if (wait) {
timeout = SMP_CALL_TIMEOUT;
while (atomic_read(&data.finished) != cpus) {
HMT_low();
if (--timeout == 0) {
if (get_tb() >= timeout) {
printk("smp_call_function on cpu %d: other "
"cpus not finishing (%d/%d)\n",
smp_processor_id(),
@ -251,7 +253,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
ret = 0;
out:
out:
call_data = NULL;
HMT_medium();
spin_unlock(&call_lock);
@ -313,8 +315,11 @@ static void __init smp_create_idle(unsigned int cpu)
p = fork_idle(cpu);
if (IS_ERR(p))
panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
#ifdef CONFIG_PPC64
paca[cpu].__current = p;
#endif
current_set[cpu] = p->thread_info;
p->thread_info->cpu = cpu;
}
void __init smp_prepare_cpus(unsigned int max_cpus)
@ -333,18 +338,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
smp_store_cpu_info(boot_cpuid);
cpu_callin_map[boot_cpuid] = 1;
#ifndef CONFIG_PPC_ISERIES
paca[boot_cpuid].next_jiffy_update_tb = tb_last_stamp = get_tb();
/*
* Should update do_gtod.stamp_xsec.
* For now we leave it which means the time can be some
* number of msecs off until someone does a settimeofday()
*/
do_gtod.varp->tb_orig_stamp = tb_last_stamp;
systemcfg->tb_orig_stamp = tb_last_stamp;
#endif
max_cpus = smp_ops->probe();
smp_space_timers(max_cpus);
@ -359,8 +352,9 @@ void __devinit smp_prepare_boot_cpu(void)
BUG_ON(smp_processor_id() != boot_cpuid);
cpu_set(boot_cpuid, cpu_online_map);
#ifdef CONFIG_PPC64
paca[boot_cpuid].__current = current;
#endif
current_set[boot_cpuid] = current->thread_info;
}
@ -444,13 +438,16 @@ int __devinit __cpu_up(unsigned int cpu)
{
int c;
secondary_ti = current_set[cpu];
if (!cpu_enable(cpu))
return 0;
if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))
return -EINVAL;
#ifdef CONFIG_PPC64
paca[cpu].default_decr = tb_ticks_per_jiffy;
#endif
/* Make sure callin-map entry is 0 (can be leftover a CPU
* hotplug
@ -513,7 +510,7 @@ int __devinit start_secondary(void *unused)
current->active_mm = &init_mm;
smp_store_cpu_info(cpu);
set_dec(paca[cpu].default_decr);
set_dec(tb_ticks_per_jiffy);
cpu_callin_map[cpu] = 1;
smp_ops->setup_cpu(cpu);

View File

@ -66,8 +66,8 @@
#include <asm/firmware.h>
#endif
#ifdef CONFIG_PPC_ISERIES
#include <asm/iSeries/ItLpQueue.h>
#include <asm/iSeries/HvCallXm.h>
#include <asm/iseries/it_lp_queue.h>
#include <asm/iseries/hv_call_xm.h>
#endif
/* keep track of when we need to update the rtc */

View File

@ -147,8 +147,8 @@ int die(const char *str, struct pt_regs *regs, long err)
printk("POWERMAC ");
nl = 1;
break;
case PLATFORM_BPA:
printk("BPA ");
case PLATFORM_CELL:
printk("CELL ");
nl = 1;
break;
}
@ -749,22 +749,22 @@ static int check_bug_trap(struct pt_regs *regs)
if (bug->line & BUG_WARNING_TRAP) {
/* this is a WARN_ON rather than BUG/BUG_ON */
#ifdef CONFIG_XMON
xmon_printf(KERN_ERR "Badness in %s at %s:%d\n",
xmon_printf(KERN_ERR "Badness in %s at %s:%ld\n",
bug->function, bug->file,
bug->line & ~BUG_WARNING_TRAP);
#endif /* CONFIG_XMON */
printk(KERN_ERR "Badness in %s at %s:%d\n",
printk(KERN_ERR "Badness in %s at %s:%ld\n",
bug->function, bug->file,
bug->line & ~BUG_WARNING_TRAP);
dump_stack();
return 1;
}
#ifdef CONFIG_XMON
xmon_printf(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
xmon_printf(KERN_CRIT "kernel BUG in %s at %s:%ld!\n",
bug->function, bug->file, bug->line);
xmon(regs);
#endif /* CONFIG_XMON */
printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
printk(KERN_CRIT "kernel BUG in %s at %s:%ld!\n",
bug->function, bug->file, bug->line);
return 0;

View File

@ -3,9 +3,12 @@
#include <asm/page.h>
#else
#define PAGE_SIZE 4096
#define KERNELBASE CONFIG_KERNEL_START
#endif
#include <asm-generic/vmlinux.lds.h>
ENTRY(_stext)
#ifdef CONFIG_PPC64
OUTPUT_ARCH(powerpc:common64)
jiffies = jiffies_64;
@ -21,33 +24,9 @@ SECTIONS
*(.exit.data)
}
. = KERNELBASE;
/* Read-only sections, merged into text segment: */
#ifdef CONFIG_PPC32
. = + SIZEOF_HEADERS;
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
.rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
.rela.data : { *(.rela.data) }
.rel.rodata : { *(.rel.rodata) }
.rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
/* .init : { *(.init) } =0*/
.plt : { *(.plt) }
#endif
.text : {
*(.text .text.*)
SCHED_TEXT

View File

@ -3,13 +3,14 @@
#
ifeq ($(CONFIG_PPC_MERGE),y)
obj-y := string.o
obj-y := string.o strcase.o
obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o
endif
obj-y += strcase.o
obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o
obj-y += bitops.o
obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \
memcpy_64.o usercopy_64.o mem_64.o
memcpy_64.o usercopy_64.o mem_64.o string.o \
strcase.o
obj-$(CONFIG_PPC_ISERIES) += e2a.o
obj-$(CONFIG_XMON) += sstep.o

View File

@ -1,79 +1,40 @@
/*
* These are too big to be inlined.
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/bitops.h>
#include <asm/byteorder.h>
#include <asm/bitops.h>
unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
unsigned long offset)
{
const unsigned long *p = addr + (offset >> 6);
unsigned long result = offset & ~63UL;
unsigned long tmp;
if (offset >= size)
return size;
size -= result;
offset &= 63UL;
if (offset) {
tmp = *(p++);
tmp |= ~0UL >> (64 - offset);
if (size < 64)
goto found_first;
if (~tmp)
goto found_middle;
size -= 64;
result += 64;
}
while (size & ~63UL) {
if (~(tmp = *(p++)))
goto found_middle;
result += 64;
size -= 64;
}
if (!size)
return result;
tmp = *p;
found_first:
tmp |= ~0UL << size;
if (tmp == ~0UL) /* Are any bits zero? */
return result + size; /* Nope. */
found_middle:
return result + ffz(tmp);
}
EXPORT_SYMBOL(find_next_zero_bit);
/**
* find_next_bit - find the next set bit in a memory region
* @addr: The address to base the search on
* @offset: The bitnumber to start searching at
* @size: The maximum size to search
*/
unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
unsigned long offset)
{
const unsigned long *p = addr + (offset >> 6);
unsigned long result = offset & ~63UL;
const unsigned long *p = addr + BITOP_WORD(offset);
unsigned long result = offset & ~(BITS_PER_LONG-1);
unsigned long tmp;
if (offset >= size)
return size;
size -= result;
offset &= 63UL;
offset %= BITS_PER_LONG;
if (offset) {
tmp = *(p++);
tmp &= (~0UL << offset);
if (size < 64)
if (size < BITS_PER_LONG)
goto found_first;
if (tmp)
goto found_middle;
size -= 64;
result += 64;
size -= BITS_PER_LONG;
result += BITS_PER_LONG;
}
while (size & ~63UL) {
while (size & ~(BITS_PER_LONG-1)) {
if ((tmp = *(p++)))
goto found_middle;
result += 64;
size -= 64;
result += BITS_PER_LONG;
size -= BITS_PER_LONG;
}
if (!size)
return result;
@ -86,9 +47,52 @@ found_first:
found_middle:
return result + __ffs(tmp);
}
EXPORT_SYMBOL(find_next_bit);
/*
* This implementation of find_{first,next}_zero_bit was stolen from
* Linus' asm-alpha/bitops.h.
*/
unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
unsigned long offset)
{
const unsigned long *p = addr + BITOP_WORD(offset);
unsigned long result = offset & ~(BITS_PER_LONG-1);
unsigned long tmp;
if (offset >= size)
return size;
size -= result;
offset %= BITS_PER_LONG;
if (offset) {
tmp = *(p++);
tmp |= ~0UL >> (BITS_PER_LONG - offset);
if (size < BITS_PER_LONG)
goto found_first;
if (~tmp)
goto found_middle;
size -= BITS_PER_LONG;
result += BITS_PER_LONG;
}
while (size & ~(BITS_PER_LONG-1)) {
if (~(tmp = *(p++)))
goto found_middle;
result += BITS_PER_LONG;
size -= BITS_PER_LONG;
}
if (!size)
return result;
tmp = *p;
found_first:
tmp |= ~0UL << size;
if (tmp == ~0UL) /* Are any bits zero? */
return result + size; /* Nope. */
found_middle:
return result + ffz(tmp);
}
EXPORT_SYMBOL(find_next_zero_bit);
static inline unsigned int ext2_ilog2(unsigned int x)
{
int lz;
@ -106,8 +110,8 @@ static inline unsigned int ext2_ffz(unsigned int x)
return rc;
}
unsigned long find_next_zero_le_bit(const unsigned long *addr, unsigned long size,
unsigned long offset)
unsigned long find_next_zero_le_bit(const unsigned long *addr,
unsigned long size, unsigned long offset)
{
const unsigned int *p = ((const unsigned int *)addr) + (offset >> 5);
unsigned int result = offset & ~31;
@ -143,5 +147,4 @@ found_first:
found_middle:
return result + ext2_ffz(tmp);
}
EXPORT_SYMBOL(find_next_zero_le_bit);

View File

@ -11,7 +11,7 @@
#include <asm/processor.h>
#include <asm/ppc_asm.h>
_GLOBAL(copy_page)
_GLOBAL(copy_4K_page)
std r31,-8(1)
std r30,-16(1)
std r29,-24(1)

View File

@ -24,7 +24,7 @@ _GLOBAL(__copy_tofrom_user)
std r4,-16(r1)
std r5,-8(r1)
dcbt 0,r4
beq .Lcopy_page
beq .Lcopy_page_4K
andi. r6,r6,7
mtcrf 0x01,r5
blt cr1,.Lshort_copy
@ -366,7 +366,7 @@ _GLOBAL(__copy_tofrom_user)
* above (following the .Ldst_aligned label) but it runs slightly
* slower on POWER3.
*/
.Lcopy_page:
.Lcopy_page_4K:
std r31,-32(1)
std r30,-40(1)
std r29,-48(1)

View File

@ -22,7 +22,7 @@
/* waiting for a spinlock... */
#if defined(CONFIG_PPC_SPLPAR) || defined(CONFIG_PPC_ISERIES)
#include <asm/hvcall.h>
#include <asm/iSeries/HvCall.h>
#include <asm/iseries/hv_call.h>
void __spin_yield(raw_spinlock_t *lock)
{

View File

@ -1,7 +1,7 @@
/*
* ppc64 MMU hashtable management routines
*
* (c) Copyright IBM Corp. 2003
* (c) Copyright IBM Corp. 2003, 2005
*
* Maintained by: Benjamin Herrenschmidt
* <benh@kernel.crashing.org>
@ -10,6 +10,7 @@
* described in the kernel's COPYING file.
*/
#include <linux/config.h>
#include <asm/reg.h>
#include <asm/pgtable.h>
#include <asm/mmu.h>
@ -42,14 +43,24 @@
/* Save non-volatile offsets */
#define STK_REG(i) (112 + ((i)-14)*8)
#ifndef CONFIG_PPC_64K_PAGES
/*****************************************************************************
* *
* 4K SW & 4K HW pages implementation *
* *
*****************************************************************************/
/*
* _hash_page(unsigned long ea, unsigned long access, unsigned long vsid,
* pte_t *ptep, unsigned long trap, int local)
* _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
* pte_t *ptep, unsigned long trap, int local)
*
* Adds a page to the hash table. This is the non-LPAR version for now
* Adds a 4K page to the hash table in a segment of 4K pages only
*/
_GLOBAL(__hash_page)
_GLOBAL(__hash_page_4K)
mflr r0
std r0,16(r1)
stdu r1,-STACKFRAMESIZE(r1)
@ -88,7 +99,8 @@ _GLOBAL(__hash_page)
/* If so, just bail out and refault if needed. Someone else
* is changing this PTE anyway and might hash it.
*/
bne- bail_ok
bne- htab_bail_ok
/* Prepare new PTE value (turn access RW into DIRTY, then
* add BUSY,HASHPTE and ACCESSED)
*/
@ -118,10 +130,10 @@ _GLOBAL(__hash_page)
/* Convert linux PTE bits into HW equivalents */
andi. r3,r30,0x1fe /* Get basic set of flags */
xori r3,r3,HW_NO_EXEC /* _PAGE_EXEC -> NOEXEC */
xori r3,r3,HPTE_R_N /* _PAGE_EXEC -> NOEXEC */
rlwinm r0,r30,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */
rlwinm r4,r30,32-7+1,30,30 /* _PAGE_DIRTY -> _PAGE_USER (r4) */
and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY -> r0 bit 30 */
and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
andc r0,r30,r0 /* r0 = pte & ~r0 */
rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */
@ -158,19 +170,21 @@ htab_insert_pte:
andc r30,r30,r0
ori r30,r30,_PAGE_HASHPTE
/* page number in r5 */
rldicl r5,r31,64-PTE_SHIFT,PTE_SHIFT
/* physical address r5 */
rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
sldi r5,r5,PAGE_SHIFT
/* Calculate primary group hash */
and r0,r28,r27
rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
rldicr r3,r0,3,63-3 /* r3 = (hash & mask) << 3 */
/* Call ppc_md.hpte_insert */
ld r7,STK_PARM(r4)(r1) /* Retreive new pp bits */
ld r6,STK_PARM(r4)(r1) /* Retreive new pp bits */
mr r4,r29 /* Retreive va */
li r6,0 /* no vflags */
li r7,0 /* !bolted, !secondary */
li r8,MMU_PAGE_4K /* page size */
_GLOBAL(htab_call_hpte_insert1)
bl . /* Will be patched by htab_finish_init() */
bl . /* Patched by htab_finish_init() */
cmpdi 0,r3,0
bge htab_pte_insert_ok /* Insertion successful */
cmpdi 0,r3,-2 /* Critical failure */
@ -178,19 +192,21 @@ _GLOBAL(htab_call_hpte_insert1)
/* Now try secondary slot */
/* page number in r5 */
rldicl r5,r31,64-PTE_SHIFT,PTE_SHIFT
/* physical address r5 */
rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
sldi r5,r5,PAGE_SHIFT
/* Calculate secondary group hash */
andc r0,r27,r28
rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */
/* Call ppc_md.hpte_insert */
ld r7,STK_PARM(r4)(r1) /* Retreive new pp bits */
ld r6,STK_PARM(r4)(r1) /* Retreive new pp bits */
mr r4,r29 /* Retreive va */
li r6,HPTE_V_SECONDARY@l /* secondary slot */
li r7,HPTE_V_SECONDARY /* !bolted, secondary */
li r8,MMU_PAGE_4K /* page size */
_GLOBAL(htab_call_hpte_insert2)
bl . /* Will be patched by htab_finish_init() */
bl . /* Patched by htab_finish_init() */
cmpdi 0,r3,0
bge+ htab_pte_insert_ok /* Insertion successful */
cmpdi 0,r3,-2 /* Critical failure */
@ -207,14 +223,14 @@ _GLOBAL(htab_call_hpte_insert2)
rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
/* Call ppc_md.hpte_remove */
_GLOBAL(htab_call_hpte_remove)
bl . /* Will be patched by htab_finish_init() */
bl . /* Patched by htab_finish_init() */
/* Try all again */
b htab_insert_pte
bail_ok:
htab_bail_ok:
li r3,0
b bail
b htab_bail
htab_pte_insert_ok:
/* Insert slot number & secondary bit in PTE */
@ -227,7 +243,7 @@ htab_write_out_pte:
ld r6,STK_PARM(r6)(r1)
std r30,0(r6)
li r3, 0
bail:
htab_bail:
ld r27,STK_REG(r27)(r1)
ld r28,STK_REG(r28)(r1)
ld r29,STK_REG(r29)(r1)
@ -256,10 +272,10 @@ htab_modify_pte:
/* Call ppc_md.hpte_updatepp */
mr r5,r29 /* va */
li r6,0 /* large is 0 */
li r6,MMU_PAGE_4K /* page size */
ld r7,STK_PARM(r8)(r1) /* get "local" param */
_GLOBAL(htab_call_hpte_updatepp)
bl . /* Will be patched by htab_finish_init() */
bl . /* Patched by htab_finish_init() */
/* if we failed because typically the HPTE wasn't really here
* we try an insertion.
@ -276,13 +292,556 @@ htab_wrong_access:
/* Bail out clearing reservation */
stdcx. r31,0,r6
li r3,1
b bail
b htab_bail
htab_pte_insert_failure:
/* Bail out restoring old PTE */
ld r6,STK_PARM(r6)(r1)
std r31,0(r6)
li r3,-1
b bail
b htab_bail
#else /* CONFIG_PPC_64K_PAGES */
/*****************************************************************************
* *
* 64K SW & 4K or 64K HW in a 4K segment pages implementation *
* *
*****************************************************************************/
/* _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
* pte_t *ptep, unsigned long trap, int local)
*/
/*
* For now, we do NOT implement Admixed pages
*/
_GLOBAL(__hash_page_4K)
mflr r0
std r0,16(r1)
stdu r1,-STACKFRAMESIZE(r1)
/* Save all params that we need after a function call */
std r6,STK_PARM(r6)(r1)
std r8,STK_PARM(r8)(r1)
/* Add _PAGE_PRESENT to access */
ori r4,r4,_PAGE_PRESENT
/* Save non-volatile registers.
* r31 will hold "old PTE"
* r30 is "new PTE"
* r29 is "va"
* r28 is a hash value
* r27 is hashtab mask (maybe dynamic patched instead ?)
* r26 is the hidx mask
* r25 is the index in combo page
*/
std r25,STK_REG(r25)(r1)
std r26,STK_REG(r26)(r1)
std r27,STK_REG(r27)(r1)
std r28,STK_REG(r28)(r1)
std r29,STK_REG(r29)(r1)
std r30,STK_REG(r30)(r1)
std r31,STK_REG(r31)(r1)
/* Step 1:
*
* Check permissions, atomically mark the linux PTE busy
* and hashed.
*/
1:
ldarx r31,0,r6
/* Check access rights (access & ~(pte_val(*ptep))) */
andc. r0,r4,r31
bne- htab_wrong_access
/* Check if PTE is busy */
andi. r0,r31,_PAGE_BUSY
/* If so, just bail out and refault if needed. Someone else
* is changing this PTE anyway and might hash it.
*/
bne- htab_bail_ok
/* Prepare new PTE value (turn access RW into DIRTY, then
* add BUSY and ACCESSED)
*/
rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */
or r30,r30,r31
ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED | _PAGE_HASHPTE
/* Write the linux PTE atomically (setting busy) */
stdcx. r30,0,r6
bne- 1b
isync
/* Step 2:
*
* Insert/Update the HPTE in the hash table. At this point,
* r4 (access) is re-useable, we use it for the new HPTE flags
*/
/* Load the hidx index */
rldicl r25,r3,64-12,60
/* Calc va and put it in r29 */
rldicr r29,r5,28,63-28 /* r29 = (vsid << 28) */
rldicl r3,r3,0,36 /* r3 = (ea & 0x0fffffff) */
or r29,r3,r29 /* r29 = va
/* Calculate hash value for primary slot and store it in r28 */
rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
rldicl r0,r3,64-12,48 /* (ea >> 12) & 0xffff */
xor r28,r5,r0
/* Convert linux PTE bits into HW equivalents */
andi. r3,r30,0x1fe /* Get basic set of flags */
xori r3,r3,HPTE_R_N /* _PAGE_EXEC -> NOEXEC */
rlwinm r0,r30,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */
rlwinm r4,r30,32-7+1,30,30 /* _PAGE_DIRTY -> _PAGE_USER (r4) */
and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
andc r0,r30,r0 /* r0 = pte & ~r0 */
rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */
/* We eventually do the icache sync here (maybe inline that
* code rather than call a C function...)
*/
BEGIN_FTR_SECTION
mr r4,r30
mr r5,r7
bl .hash_page_do_lazy_icache
END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
/* At this point, r3 contains new PP bits, save them in
* place of "access" in the param area (sic)
*/
std r3,STK_PARM(r4)(r1)
/* Get htab_hash_mask */
ld r4,htab_hash_mask@got(2)
ld r27,0(r4) /* htab_hash_mask -> r27 */
/* Check if we may already be in the hashtable, in this case, we
* go to out-of-line code to try to modify the HPTE. We look for
* the bit at (1 >> (index + 32))
*/
andi. r0,r31,_PAGE_HASHPTE
li r26,0 /* Default hidx */
beq htab_insert_pte
ld r6,STK_PARM(r6)(r1)
ori r26,r6,0x8000 /* Load the hidx mask */
ld r26,0(r26)
addi r5,r25,36 /* Check actual HPTE_SUB bit, this */
rldcr. r0,r31,r5,0 /* must match pgtable.h definition */
bne htab_modify_pte
htab_insert_pte:
/* real page number in r5, PTE RPN value + index */
rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
sldi r5,r5,PAGE_SHIFT-HW_PAGE_SHIFT
add r5,r5,r25
sldi r5,r5,HW_PAGE_SHIFT
/* Calculate primary group hash */
and r0,r28,r27
rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
/* Call ppc_md.hpte_insert */
ld r6,STK_PARM(r4)(r1) /* Retreive new pp bits */
mr r4,r29 /* Retreive va */
li r7,0 /* !bolted, !secondary */
li r8,MMU_PAGE_4K /* page size */
_GLOBAL(htab_call_hpte_insert1)
bl . /* patched by htab_finish_init() */
cmpdi 0,r3,0
bge htab_pte_insert_ok /* Insertion successful */
cmpdi 0,r3,-2 /* Critical failure */
beq- htab_pte_insert_failure
/* Now try secondary slot */
/* real page number in r5, PTE RPN value + index */
rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
sldi r5,r5,PAGE_SHIFT-HW_PAGE_SHIFT
add r5,r5,r25
sldi r5,r5,HW_PAGE_SHIFT
/* Calculate secondary group hash */
andc r0,r27,r28
rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */
/* Call ppc_md.hpte_insert */
ld r6,STK_PARM(r4)(r1) /* Retreive new pp bits */
mr r4,r29 /* Retreive va */
li r7,HPTE_V_SECONDARY /* !bolted, secondary */
li r8,MMU_PAGE_4K /* page size */
_GLOBAL(htab_call_hpte_insert2)
bl . /* patched by htab_finish_init() */
cmpdi 0,r3,0
bge+ htab_pte_insert_ok /* Insertion successful */
cmpdi 0,r3,-2 /* Critical failure */
beq- htab_pte_insert_failure
/* Both are full, we need to evict something */
mftb r0
/* Pick a random group based on TB */
andi. r0,r0,1
mr r5,r28
bne 2f
not r5,r5
2: and r0,r5,r27
rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
/* Call ppc_md.hpte_remove */
_GLOBAL(htab_call_hpte_remove)
bl . /* patched by htab_finish_init() */
/* Try all again */
b htab_insert_pte
htab_bail_ok:
li r3,0
b htab_bail
htab_pte_insert_ok:
/* Insert slot number & secondary bit in PTE second half,
* clear _PAGE_BUSY and set approriate HPTE slot bit
*/
ld r6,STK_PARM(r6)(r1)
li r0,_PAGE_BUSY
andc r30,r30,r0
/* HPTE SUB bit */
li r0,1
subfic r5,r25,27 /* Must match bit position in */
sld r0,r0,r5 /* pgtable.h */
or r30,r30,r0
/* hindx */
sldi r5,r25,2
sld r3,r3,r5
li r4,0xf
sld r4,r4,r5
andc r26,r26,r4
or r26,r26,r3
ori r5,r6,0x8000
std r26,0(r5)
lwsync
std r30,0(r6)
li r3, 0
htab_bail:
ld r25,STK_REG(r25)(r1)
ld r26,STK_REG(r26)(r1)
ld r27,STK_REG(r27)(r1)
ld r28,STK_REG(r28)(r1)
ld r29,STK_REG(r29)(r1)
ld r30,STK_REG(r30)(r1)
ld r31,STK_REG(r31)(r1)
addi r1,r1,STACKFRAMESIZE
ld r0,16(r1)
mtlr r0
blr
htab_modify_pte:
/* Keep PP bits in r4 and slot idx from the PTE around in r3 */
mr r4,r3
sldi r5,r25,2
srd r3,r26,r5
/* Secondary group ? if yes, get a inverted hash value */
mr r5,r28
andi. r0,r3,0x8 /* page secondary ? */
beq 1f
not r5,r5
1: andi. r3,r3,0x7 /* extract idx alone */
/* Calculate proper slot value for ppc_md.hpte_updatepp */
and r0,r5,r27
rldicr r0,r0,3,63-3 /* r0 = (hash & mask) << 3 */
add r3,r0,r3 /* add slot idx */
/* Call ppc_md.hpte_updatepp */
mr r5,r29 /* va */
li r6,MMU_PAGE_4K /* page size */
ld r7,STK_PARM(r8)(r1) /* get "local" param */
_GLOBAL(htab_call_hpte_updatepp)
bl . /* patched by htab_finish_init() */
/* if we failed because typically the HPTE wasn't really here
* we try an insertion.
*/
cmpdi 0,r3,-1
beq- htab_insert_pte
/* Clear the BUSY bit and Write out the PTE */
li r0,_PAGE_BUSY
andc r30,r30,r0
ld r6,STK_PARM(r6)(r1)
std r30,0(r6)
li r3,0
b htab_bail
htab_wrong_access:
/* Bail out clearing reservation */
stdcx. r31,0,r6
li r3,1
b htab_bail
htab_pte_insert_failure:
/* Bail out restoring old PTE */
ld r6,STK_PARM(r6)(r1)
std r31,0(r6)
li r3,-1
b htab_bail
/*****************************************************************************
* *
* 64K SW & 64K HW in a 64K segment pages implementation *
* *
*****************************************************************************/
_GLOBAL(__hash_page_64K)
mflr r0
std r0,16(r1)
stdu r1,-STACKFRAMESIZE(r1)
/* Save all params that we need after a function call */
std r6,STK_PARM(r6)(r1)
std r8,STK_PARM(r8)(r1)
/* Add _PAGE_PRESENT to access */
ori r4,r4,_PAGE_PRESENT
/* Save non-volatile registers.
* r31 will hold "old PTE"
* r30 is "new PTE"
* r29 is "va"
* r28 is a hash value
* r27 is hashtab mask (maybe dynamic patched instead ?)
*/
std r27,STK_REG(r27)(r1)
std r28,STK_REG(r28)(r1)
std r29,STK_REG(r29)(r1)
std r30,STK_REG(r30)(r1)
std r31,STK_REG(r31)(r1)
/* Step 1:
*
* Check permissions, atomically mark the linux PTE busy
* and hashed.
*/
1:
ldarx r31,0,r6
/* Check access rights (access & ~(pte_val(*ptep))) */
andc. r0,r4,r31
bne- ht64_wrong_access
/* Check if PTE is busy */
andi. r0,r31,_PAGE_BUSY
/* If so, just bail out and refault if needed. Someone else
* is changing this PTE anyway and might hash it.
*/
bne- ht64_bail_ok
/* Prepare new PTE value (turn access RW into DIRTY, then
* add BUSY,HASHPTE and ACCESSED)
*/
rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */
or r30,r30,r31
ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED | _PAGE_HASHPTE
/* Write the linux PTE atomically (setting busy) */
stdcx. r30,0,r6
bne- 1b
isync
/* Step 2:
*
* Insert/Update the HPTE in the hash table. At this point,
* r4 (access) is re-useable, we use it for the new HPTE flags
*/
/* Calc va and put it in r29 */
rldicr r29,r5,28,63-28
rldicl r3,r3,0,36
or r29,r3,r29
/* Calculate hash value for primary slot and store it in r28 */
rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
rldicl r0,r3,64-16,52 /* (ea >> 16) & 0xfff */
xor r28,r5,r0
/* Convert linux PTE bits into HW equivalents */
andi. r3,r30,0x1fe /* Get basic set of flags */
xori r3,r3,HPTE_R_N /* _PAGE_EXEC -> NOEXEC */
rlwinm r0,r30,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */
rlwinm r4,r30,32-7+1,30,30 /* _PAGE_DIRTY -> _PAGE_USER (r4) */
and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
andc r0,r30,r0 /* r0 = pte & ~r0 */
rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */
/* We eventually do the icache sync here (maybe inline that
* code rather than call a C function...)
*/
BEGIN_FTR_SECTION
mr r4,r30
mr r5,r7
bl .hash_page_do_lazy_icache
END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
/* At this point, r3 contains new PP bits, save them in
* place of "access" in the param area (sic)
*/
std r3,STK_PARM(r4)(r1)
/* Get htab_hash_mask */
ld r4,htab_hash_mask@got(2)
ld r27,0(r4) /* htab_hash_mask -> r27 */
/* Check if we may already be in the hashtable, in this case, we
* go to out-of-line code to try to modify the HPTE
*/
andi. r0,r31,_PAGE_HASHPTE
bne ht64_modify_pte
ht64_insert_pte:
/* Clear hpte bits in new pte (we also clear BUSY btw) and
* add _PAGE_HASHPTE
*/
lis r0,_PAGE_HPTEFLAGS@h
ori r0,r0,_PAGE_HPTEFLAGS@l
andc r30,r30,r0
ori r30,r30,_PAGE_HASHPTE
/* Phyical address in r5 */
rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
sldi r5,r5,PAGE_SHIFT
/* Calculate primary group hash */
and r0,r28,r27
rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
/* Call ppc_md.hpte_insert */
ld r6,STK_PARM(r4)(r1) /* Retreive new pp bits */
mr r4,r29 /* Retreive va */
li r7,0 /* !bolted, !secondary */
li r8,MMU_PAGE_64K
_GLOBAL(ht64_call_hpte_insert1)
bl . /* patched by htab_finish_init() */
cmpdi 0,r3,0
bge ht64_pte_insert_ok /* Insertion successful */
cmpdi 0,r3,-2 /* Critical failure */
beq- ht64_pte_insert_failure
/* Now try secondary slot */
/* Phyical address in r5 */
rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
sldi r5,r5,PAGE_SHIFT
/* Calculate secondary group hash */
andc r0,r27,r28
rldicr r3,r0,3,63-3 /* r0 = (~hash & mask) << 3 */
/* Call ppc_md.hpte_insert */
ld r6,STK_PARM(r4)(r1) /* Retreive new pp bits */
mr r4,r29 /* Retreive va */
li r7,HPTE_V_SECONDARY /* !bolted, secondary */
li r8,MMU_PAGE_64K
_GLOBAL(ht64_call_hpte_insert2)
bl . /* patched by htab_finish_init() */
cmpdi 0,r3,0
bge+ ht64_pte_insert_ok /* Insertion successful */
cmpdi 0,r3,-2 /* Critical failure */
beq- ht64_pte_insert_failure
/* Both are full, we need to evict something */
mftb r0
/* Pick a random group based on TB */
andi. r0,r0,1
mr r5,r28
bne 2f
not r5,r5
2: and r0,r5,r27
rldicr r3,r0,3,63-3 /* r0 = (hash & mask) << 3 */
/* Call ppc_md.hpte_remove */
_GLOBAL(ht64_call_hpte_remove)
bl . /* patched by htab_finish_init() */
/* Try all again */
b ht64_insert_pte
ht64_bail_ok:
li r3,0
b ht64_bail
ht64_pte_insert_ok:
/* Insert slot number & secondary bit in PTE */
rldimi r30,r3,12,63-15
/* Write out the PTE with a normal write
* (maybe add eieio may be good still ?)
*/
ht64_write_out_pte:
ld r6,STK_PARM(r6)(r1)
std r30,0(r6)
li r3, 0
ht64_bail:
ld r27,STK_REG(r27)(r1)
ld r28,STK_REG(r28)(r1)
ld r29,STK_REG(r29)(r1)
ld r30,STK_REG(r30)(r1)
ld r31,STK_REG(r31)(r1)
addi r1,r1,STACKFRAMESIZE
ld r0,16(r1)
mtlr r0
blr
ht64_modify_pte:
/* Keep PP bits in r4 and slot idx from the PTE around in r3 */
mr r4,r3
rlwinm r3,r31,32-12,29,31
/* Secondary group ? if yes, get a inverted hash value */
mr r5,r28
andi. r0,r31,_PAGE_F_SECOND
beq 1f
not r5,r5
1:
/* Calculate proper slot value for ppc_md.hpte_updatepp */
and r0,r5,r27
rldicr r0,r0,3,63-3 /* r0 = (hash & mask) << 3 */
add r3,r0,r3 /* add slot idx */
/* Call ppc_md.hpte_updatepp */
mr r5,r29 /* va */
li r6,MMU_PAGE_64K
ld r7,STK_PARM(r8)(r1) /* get "local" param */
_GLOBAL(ht64_call_hpte_updatepp)
bl . /* patched by htab_finish_init() */
/* if we failed because typically the HPTE wasn't really here
* we try an insertion.
*/
cmpdi 0,r3,-1
beq- ht64_insert_pte
/* Clear the BUSY bit and Write out the PTE */
li r0,_PAGE_BUSY
andc r30,r30,r0
b ht64_write_out_pte
ht64_wrong_access:
/* Bail out clearing reservation */
stdcx. r31,0,r6
li r3,1
b ht64_bail
ht64_pte_insert_failure:
/* Bail out restoring old PTE */
ld r6,STK_PARM(r6)(r1)
std r31,0(r6)
li r3,-1
b ht64_bail
#endif /* CONFIG_PPC_64K_PAGES */
/*****************************************************************************
* *
* Huge pages implementation is in hugetlbpage.c *
* *
*****************************************************************************/

View File

@ -9,6 +9,9 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#undef DEBUG_LOW
#include <linux/spinlock.h>
#include <linux/bitops.h>
#include <linux/threads.h>
@ -22,11 +25,84 @@
#include <asm/tlbflush.h>
#include <asm/tlb.h>
#include <asm/cputable.h>
#include <asm/udbg.h>
#ifdef DEBUG_LOW
#define DBG_LOW(fmt...) udbg_printf(fmt)
#else
#define DBG_LOW(fmt...)
#endif
#define HPTE_LOCK_BIT 3
static DEFINE_SPINLOCK(native_tlbie_lock);
static inline void __tlbie(unsigned long va, unsigned int psize)
{
unsigned int penc;
/* clear top 16 bits, non SLS segment */
va &= ~(0xffffULL << 48);
switch (psize) {
case MMU_PAGE_4K:
va &= ~0xffful;
asm volatile("tlbie %0,0" : : "r" (va) : "memory");
break;
default:
penc = mmu_psize_defs[psize].penc;
va &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
va |= (0x7f >> (8 - penc)) << 12;
asm volatile("tlbie %0,1" : : "r" (va) : "memory");
break;
}
}
static inline void __tlbiel(unsigned long va, unsigned int psize)
{
unsigned int penc;
/* clear top 16 bits, non SLS segment */
va &= ~(0xffffULL << 48);
switch (psize) {
case MMU_PAGE_4K:
va &= ~0xffful;
asm volatile(".long 0x7c000224 | (%0 << 11) | (0 << 21)"
: : "r"(va) : "memory");
break;
default:
penc = mmu_psize_defs[psize].penc;
va &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
va |= (0x7f >> (8 - penc)) << 12;
asm volatile(".long 0x7c000224 | (%0 << 11) | (1 << 21)"
: : "r"(va) : "memory");
break;
}
}
static inline void tlbie(unsigned long va, int psize, int local)
{
unsigned int use_local = local && cpu_has_feature(CPU_FTR_TLBIEL);
int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
if (use_local)
use_local = mmu_psize_defs[psize].tlbiel;
if (lock_tlbie && !use_local)
spin_lock(&native_tlbie_lock);
asm volatile("ptesync": : :"memory");
if (use_local) {
__tlbiel(va, psize);
asm volatile("ptesync": : :"memory");
} else {
__tlbie(va, psize);
asm volatile("eieio; tlbsync; ptesync": : :"memory");
}
if (lock_tlbie && !use_local)
spin_unlock(&native_tlbie_lock);
}
static inline void native_lock_hpte(hpte_t *hptep)
{
unsigned long *word = &hptep->v;
@ -48,13 +124,19 @@ static inline void native_unlock_hpte(hpte_t *hptep)
}
long native_hpte_insert(unsigned long hpte_group, unsigned long va,
unsigned long prpn, unsigned long vflags,
unsigned long rflags)
unsigned long pa, unsigned long rflags,
unsigned long vflags, int psize)
{
hpte_t *hptep = htab_address + hpte_group;
unsigned long hpte_v, hpte_r;
int i;
if (!(vflags & HPTE_V_BOLTED)) {
DBG_LOW(" insert(group=%lx, va=%016lx, pa=%016lx,"
" rflags=%lx, vflags=%lx, psize=%d)\n",
hpte_group, va, pa, rflags, vflags, psize);
}
for (i = 0; i < HPTES_PER_GROUP; i++) {
if (! (hptep->v & HPTE_V_VALID)) {
/* retry with lock held */
@ -70,10 +152,13 @@ long native_hpte_insert(unsigned long hpte_group, unsigned long va,
if (i == HPTES_PER_GROUP)
return -1;
hpte_v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID;
if (vflags & HPTE_V_LARGE)
va &= ~(1UL << HPTE_V_AVPN_SHIFT);
hpte_r = (prpn << HPTE_R_RPN_SHIFT) | rflags;
hpte_v = hpte_encode_v(va, psize) | vflags | HPTE_V_VALID;
hpte_r = hpte_encode_r(pa, psize) | rflags;
if (!(vflags & HPTE_V_BOLTED)) {
DBG_LOW(" i=%x hpte_v=%016lx, hpte_r=%016lx\n",
i, hpte_v, hpte_r);
}
hptep->r = hpte_r;
/* Guarantee the second dword is visible before the valid bit */
@ -96,6 +181,8 @@ static long native_hpte_remove(unsigned long hpte_group)
int slot_offset;
unsigned long hpte_v;
DBG_LOW(" remove(group=%lx)\n", hpte_group);
/* pick a random entry to start at */
slot_offset = mftb() & 0x7;
@ -126,34 +213,51 @@ static long native_hpte_remove(unsigned long hpte_group)
return i;
}
static inline void set_pp_bit(unsigned long pp, hpte_t *addr)
static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
unsigned long va, int psize, int local)
{
unsigned long old;
unsigned long *p = &addr->r;
hpte_t *hptep = htab_address + slot;
unsigned long hpte_v, want_v;
int ret = 0;
__asm__ __volatile__(
"1: ldarx %0,0,%3\n\
rldimi %0,%2,0,61\n\
stdcx. %0,0,%3\n\
bne 1b"
: "=&r" (old), "=m" (*p)
: "r" (pp), "r" (p), "m" (*p)
: "cc");
want_v = hpte_encode_v(va, psize);
DBG_LOW(" update(va=%016lx, avpnv=%016lx, hash=%016lx, newpp=%x)",
va, want_v & HPTE_V_AVPN, slot, newpp);
native_lock_hpte(hptep);
hpte_v = hptep->v;
/* Even if we miss, we need to invalidate the TLB */
if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) {
DBG_LOW(" -> miss\n");
native_unlock_hpte(hptep);
ret = -1;
} else {
DBG_LOW(" -> hit\n");
/* Update the HPTE */
hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) |
(newpp & (HPTE_R_PP | HPTE_R_N));
native_unlock_hpte(hptep);
}
/* Ensure it is out of the tlb too. */
tlbie(va, psize, local);
return ret;
}
/*
* Only works on small pages. Yes its ugly to have to check each slot in
* the group but we only use this during bootup.
*/
static long native_hpte_find(unsigned long vpn)
static long native_hpte_find(unsigned long va, int psize)
{
hpte_t *hptep;
unsigned long hash;
unsigned long i, j;
long slot;
unsigned long hpte_v;
unsigned long want_v, hpte_v;
hash = hpt_hash(vpn, 0);
hash = hpt_hash(va, mmu_psize_defs[psize].shift);
want_v = hpte_encode_v(va, psize);
for (j = 0; j < 2; j++) {
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
@ -161,7 +265,7 @@ static long native_hpte_find(unsigned long vpn)
hptep = htab_address + slot;
hpte_v = hptep->v;
if ((HPTE_V_AVPN_VAL(hpte_v) == (vpn >> 11))
if (HPTE_V_COMPARE(hpte_v, want_v)
&& (hpte_v & HPTE_V_VALID)
&& ( !!(hpte_v & HPTE_V_SECONDARY) == j)) {
/* HPTE matches */
@ -177,118 +281,90 @@ static long native_hpte_find(unsigned long vpn)
return -1;
}
static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
unsigned long va, int large, int local)
{
hpte_t *hptep = htab_address + slot;
unsigned long hpte_v;
unsigned long avpn = va >> 23;
int ret = 0;
if (large)
avpn &= ~1;
native_lock_hpte(hptep);
hpte_v = hptep->v;
/* Even if we miss, we need to invalidate the TLB */
if ((HPTE_V_AVPN_VAL(hpte_v) != avpn)
|| !(hpte_v & HPTE_V_VALID)) {
native_unlock_hpte(hptep);
ret = -1;
} else {
set_pp_bit(newpp, hptep);
native_unlock_hpte(hptep);
}
/* Ensure it is out of the tlb too */
if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) {
tlbiel(va);
} else {
int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
if (lock_tlbie)
spin_lock(&native_tlbie_lock);
tlbie(va, large);
if (lock_tlbie)
spin_unlock(&native_tlbie_lock);
}
return ret;
}
/*
* Update the page protection bits. Intended to be used to create
* guard pages for kernel data structures on pages which are bolted
* in the HPT. Assumes pages being operated on will not be stolen.
* Does not work on large pages.
*
* No need to lock here because we should be the only user.
*/
static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
int psize)
{
unsigned long vsid, va, vpn, flags = 0;
unsigned long vsid, va;
long slot;
hpte_t *hptep;
int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
vsid = get_kernel_vsid(ea);
va = (vsid << 28) | (ea & 0x0fffffff);
vpn = va >> PAGE_SHIFT;
slot = native_hpte_find(vpn);
slot = native_hpte_find(va, psize);
if (slot == -1)
panic("could not find page to bolt\n");
hptep = htab_address + slot;
set_pp_bit(newpp, hptep);
/* Update the HPTE */
hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) |
(newpp & (HPTE_R_PP | HPTE_R_N));
/* Ensure it is out of the tlb too */
if (lock_tlbie)
spin_lock_irqsave(&native_tlbie_lock, flags);
tlbie(va, 0);
if (lock_tlbie)
spin_unlock_irqrestore(&native_tlbie_lock, flags);
/* Ensure it is out of the tlb too. */
tlbie(va, psize, 0);
}
static void native_hpte_invalidate(unsigned long slot, unsigned long va,
int large, int local)
int psize, int local)
{
hpte_t *hptep = htab_address + slot;
unsigned long hpte_v;
unsigned long avpn = va >> 23;
unsigned long want_v;
unsigned long flags;
int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
if (large)
avpn &= ~1;
local_irq_save(flags);
native_lock_hpte(hptep);
DBG_LOW(" invalidate(va=%016lx, hash: %x)\n", va, slot);
want_v = hpte_encode_v(va, psize);
native_lock_hpte(hptep);
hpte_v = hptep->v;
/* Even if we miss, we need to invalidate the TLB */
if ((HPTE_V_AVPN_VAL(hpte_v) != avpn)
|| !(hpte_v & HPTE_V_VALID)) {
if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID))
native_unlock_hpte(hptep);
} else {
else
/* Invalidate the hpte. NOTE: this also unlocks it */
hptep->v = 0;
/* Invalidate the TLB */
tlbie(va, psize, local);
local_irq_restore(flags);
}
/*
* XXX This need fixing based on page size. It's only used by
* native_hpte_clear() for now which needs fixing too so they
* make a good pair...
*/
static unsigned long slot2va(unsigned long hpte_v, unsigned long slot)
{
unsigned long avpn = HPTE_V_AVPN_VAL(hpte_v);
unsigned long va;
va = avpn << 23;
if (! (hpte_v & HPTE_V_LARGE)) {
unsigned long vpi, pteg;
pteg = slot / HPTES_PER_GROUP;
if (hpte_v & HPTE_V_SECONDARY)
pteg = ~pteg;
vpi = ((va >> 28) ^ pteg) & htab_hash_mask;
va |= vpi << PAGE_SHIFT;
}
/* Invalidate the tlb */
if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) {
tlbiel(va);
} else {
if (lock_tlbie)
spin_lock(&native_tlbie_lock);
tlbie(va, large);
if (lock_tlbie)
spin_unlock(&native_tlbie_lock);
}
local_irq_restore(flags);
return va;
}
/*
@ -298,6 +374,8 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long va,
*
* TODO: add batching support when enabled. remember, no dynamic memory here,
* athough there is the control page available...
*
* XXX FIXME: 4k only for now !
*/
static void native_hpte_clear(void)
{
@ -327,7 +405,7 @@ static void native_hpte_clear(void)
if (hpte_v & HPTE_V_VALID) {
hptep->v = 0;
tlbie(slot2va(hpte_v, slot), hpte_v & HPTE_V_LARGE);
tlbie(slot2va(hpte_v, slot), MMU_PAGE_4K, 0);
}
}
@ -335,59 +413,59 @@ static void native_hpte_clear(void)
local_irq_restore(flags);
}
/*
* Batched hash table flush, we batch the tlbie's to avoid taking/releasing
* the lock all the time
*/
static void native_flush_hash_range(unsigned long number, int local)
{
unsigned long va, vpn, hash, secondary, slot, flags, avpn;
int i, j;
unsigned long va, hash, index, hidx, shift, slot;
hpte_t *hptep;
unsigned long hpte_v;
unsigned long want_v;
unsigned long flags;
real_pte_t pte;
struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
unsigned long large = batch->large;
unsigned long psize = batch->psize;
int i;
local_irq_save(flags);
j = 0;
for (i = 0; i < number; i++) {
va = batch->vaddr[j];
if (large)
vpn = va >> HPAGE_SHIFT;
else
vpn = va >> PAGE_SHIFT;
hash = hpt_hash(vpn, large);
secondary = (pte_val(batch->pte[i]) & _PAGE_SECONDARY) >> 15;
if (secondary)
hash = ~hash;
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
slot += (pte_val(batch->pte[i]) & _PAGE_GROUP_IX) >> 12;
va = batch->vaddr[i];
pte = batch->pte[i];
hptep = htab_address + slot;
avpn = va >> 23;
if (large)
avpn &= ~0x1UL;
native_lock_hpte(hptep);
hpte_v = hptep->v;
/* Even if we miss, we need to invalidate the TLB */
if ((HPTE_V_AVPN_VAL(hpte_v) != avpn)
|| !(hpte_v & HPTE_V_VALID)) {
native_unlock_hpte(hptep);
} else {
/* Invalidate the hpte. NOTE: this also unlocks it */
hptep->v = 0;
}
j++;
pte_iterate_hashed_subpages(pte, psize, va, index, shift) {
hash = hpt_hash(va, shift);
hidx = __rpte_to_hidx(pte, index);
if (hidx & _PTEIDX_SECONDARY)
hash = ~hash;
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
slot += hidx & _PTEIDX_GROUP_IX;
hptep = htab_address + slot;
want_v = hpte_encode_v(va, psize);
native_lock_hpte(hptep);
hpte_v = hptep->v;
if (!HPTE_V_COMPARE(hpte_v, want_v) ||
!(hpte_v & HPTE_V_VALID))
native_unlock_hpte(hptep);
else
hptep->v = 0;
} pte_iterate_hashed_end();
}
if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) {
if (cpu_has_feature(CPU_FTR_TLBIEL) &&
mmu_psize_defs[psize].tlbiel && local) {
asm volatile("ptesync":::"memory");
for (i = 0; i < number; i++) {
va = batch->vaddr[i];
pte = batch->pte[i];
for (i = 0; i < j; i++)
__tlbiel(batch->vaddr[i]);
pte_iterate_hashed_subpages(pte, psize, va, index,
shift) {
__tlbiel(va, psize);
} pte_iterate_hashed_end();
}
asm volatile("ptesync":::"memory");
} else {
int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
@ -396,10 +474,15 @@ static void native_flush_hash_range(unsigned long number, int local)
spin_lock(&native_tlbie_lock);
asm volatile("ptesync":::"memory");
for (i = 0; i < number; i++) {
va = batch->vaddr[i];
pte = batch->pte[i];
for (i = 0; i < j; i++)
__tlbie(batch->vaddr[i], large);
pte_iterate_hashed_subpages(pte, psize, va, index,
shift) {
__tlbie(va, psize);
} pte_iterate_hashed_end();
}
asm volatile("eieio; tlbsync; ptesync":::"memory");
if (lock_tlbie)

View File

@ -19,6 +19,7 @@
*/
#undef DEBUG
#undef DEBUG_LOW
#include <linux/config.h>
#include <linux/spinlock.h>
@ -59,6 +60,15 @@
#define DBG(fmt...)
#endif
#ifdef DEBUG_LOW
#define DBG_LOW(fmt...) udbg_printf(fmt)
#else
#define DBG_LOW(fmt...)
#endif
#define KB (1024)
#define MB (1024*KB)
/*
* Note: pte --> Linux PTE
* HPTE --> PowerPC Hashed Page Table Entry
@ -77,91 +87,290 @@ extern unsigned long dart_tablebase;
hpte_t *htab_address;
unsigned long htab_hash_mask;
unsigned long _SDR1;
struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
int mmu_linear_psize = MMU_PAGE_4K;
int mmu_virtual_psize = MMU_PAGE_4K;
#ifdef CONFIG_HUGETLB_PAGE
int mmu_huge_psize = MMU_PAGE_16M;
unsigned int HPAGE_SHIFT;
#endif
#define KB (1024)
#define MB (1024*KB)
/* There are definitions of page sizes arrays to be used when none
* is provided by the firmware.
*/
static inline void loop_forever(void)
/* Pre-POWER4 CPUs (4k pages only)
*/
struct mmu_psize_def mmu_psize_defaults_old[] = {
[MMU_PAGE_4K] = {
.shift = 12,
.sllp = 0,
.penc = 0,
.avpnm = 0,
.tlbiel = 0,
},
};
/* POWER4, GPUL, POWER5
*
* Support for 16Mb large pages
*/
struct mmu_psize_def mmu_psize_defaults_gp[] = {
[MMU_PAGE_4K] = {
.shift = 12,
.sllp = 0,
.penc = 0,
.avpnm = 0,
.tlbiel = 1,
},
[MMU_PAGE_16M] = {
.shift = 24,
.sllp = SLB_VSID_L,
.penc = 0,
.avpnm = 0x1UL,
.tlbiel = 0,
},
};
int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
unsigned long pstart, unsigned long mode, int psize)
{
volatile unsigned long x = 1;
for(;x;x|=1)
;
}
static inline void create_pte_mapping(unsigned long start, unsigned long end,
unsigned long mode, int large)
{
unsigned long addr;
unsigned int step;
unsigned long vaddr, paddr;
unsigned int step, shift;
unsigned long tmp_mode;
unsigned long vflags;
int ret = 0;
if (large) {
step = 16*MB;
vflags = HPTE_V_BOLTED | HPTE_V_LARGE;
} else {
step = 4*KB;
vflags = HPTE_V_BOLTED;
}
shift = mmu_psize_defs[psize].shift;
step = 1 << shift;
for (addr = start; addr < end; addr += step) {
for (vaddr = vstart, paddr = pstart; vaddr < vend;
vaddr += step, paddr += step) {
unsigned long vpn, hash, hpteg;
unsigned long vsid = get_kernel_vsid(addr);
unsigned long va = (vsid << 28) | (addr & 0xfffffff);
int ret = -1;
if (large)
vpn = va >> HPAGE_SHIFT;
else
vpn = va >> PAGE_SHIFT;
unsigned long vsid = get_kernel_vsid(vaddr);
unsigned long va = (vsid << 28) | (vaddr & 0x0fffffff);
vpn = va >> shift;
tmp_mode = mode;
/* Make non-kernel text non-executable */
if (!in_kernel_text(addr))
tmp_mode = mode | HW_NO_EXEC;
hash = hpt_hash(vpn, large);
if (!in_kernel_text(vaddr))
tmp_mode = mode | HPTE_R_N;
hash = hpt_hash(va, shift);
hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
/* The crap below can be cleaned once ppd_md.probe() can
* set up the hash callbacks, thus we can just used the
* normal insert callback here.
*/
#ifdef CONFIG_PPC_ISERIES
if (systemcfg->platform & PLATFORM_ISERIES_LPAR)
ret = iSeries_hpte_bolt_or_insert(hpteg, va,
virt_to_abs(addr) >> PAGE_SHIFT,
vflags, tmp_mode);
if (systemcfg->platform == PLATFORM_ISERIES_LPAR)
ret = iSeries_hpte_insert(hpteg, va,
virt_to_abs(paddr),
tmp_mode,
HPTE_V_BOLTED,
psize);
else
#endif
#ifdef CONFIG_PPC_PSERIES
if (systemcfg->platform & PLATFORM_LPAR)
ret = pSeries_lpar_hpte_insert(hpteg, va,
virt_to_abs(addr) >> PAGE_SHIFT,
vflags, tmp_mode);
virt_to_abs(paddr),
tmp_mode,
HPTE_V_BOLTED,
psize);
else
#endif
#ifdef CONFIG_PPC_MULTIPLATFORM
ret = native_hpte_insert(hpteg, va,
virt_to_abs(addr) >> PAGE_SHIFT,
vflags, tmp_mode);
virt_to_abs(paddr),
tmp_mode, HPTE_V_BOLTED,
psize);
#endif
if (ret == -1) {
ppc64_terminate_msg(0x20, "create_pte_mapping");
loop_forever();
}
if (ret < 0)
break;
}
return ret < 0 ? ret : 0;
}
static unsigned long get_hashtable_size(void)
static int __init htab_dt_scan_page_sizes(unsigned long node,
const char *uname, int depth,
void *data)
{
char *type = of_get_flat_dt_prop(node, "device_type", NULL);
u32 *prop;
unsigned long size = 0;
/* We are scanning "cpu" nodes only */
if (type == NULL || strcmp(type, "cpu") != 0)
return 0;
prop = (u32 *)of_get_flat_dt_prop(node,
"ibm,segment-page-sizes", &size);
if (prop != NULL) {
DBG("Page sizes from device-tree:\n");
size /= 4;
cur_cpu_spec->cpu_features &= ~(CPU_FTR_16M_PAGE);
while(size > 0) {
unsigned int shift = prop[0];
unsigned int slbenc = prop[1];
unsigned int lpnum = prop[2];
unsigned int lpenc = 0;
struct mmu_psize_def *def;
int idx = -1;
size -= 3; prop += 3;
while(size > 0 && lpnum) {
if (prop[0] == shift)
lpenc = prop[1];
prop += 2; size -= 2;
lpnum--;
}
switch(shift) {
case 0xc:
idx = MMU_PAGE_4K;
break;
case 0x10:
idx = MMU_PAGE_64K;
break;
case 0x14:
idx = MMU_PAGE_1M;
break;
case 0x18:
idx = MMU_PAGE_16M;
cur_cpu_spec->cpu_features |= CPU_FTR_16M_PAGE;
break;
case 0x22:
idx = MMU_PAGE_16G;
break;
}
if (idx < 0)
continue;
def = &mmu_psize_defs[idx];
def->shift = shift;
if (shift <= 23)
def->avpnm = 0;
else
def->avpnm = (1 << (shift - 23)) - 1;
def->sllp = slbenc;
def->penc = lpenc;
/* We don't know for sure what's up with tlbiel, so
* for now we only set it for 4K and 64K pages
*/
if (idx == MMU_PAGE_4K || idx == MMU_PAGE_64K)
def->tlbiel = 1;
else
def->tlbiel = 0;
DBG(" %d: shift=%02x, sllp=%04x, avpnm=%08x, "
"tlbiel=%d, penc=%d\n",
idx, shift, def->sllp, def->avpnm, def->tlbiel,
def->penc);
}
return 1;
}
return 0;
}
static void __init htab_init_page_sizes(void)
{
int rc;
/* Default to 4K pages only */
memcpy(mmu_psize_defs, mmu_psize_defaults_old,
sizeof(mmu_psize_defaults_old));
/*
* Try to find the available page sizes in the device-tree
*/
rc = of_scan_flat_dt(htab_dt_scan_page_sizes, NULL);
if (rc != 0) /* Found */
goto found;
/*
* Not in the device-tree, let's fallback on known size
* list for 16M capable GP & GR
*/
if ((systemcfg->platform != PLATFORM_ISERIES_LPAR) &&
cpu_has_feature(CPU_FTR_16M_PAGE))
memcpy(mmu_psize_defs, mmu_psize_defaults_gp,
sizeof(mmu_psize_defaults_gp));
found:
/*
* Pick a size for the linear mapping. Currently, we only support
* 16M, 1M and 4K which is the default
*/
if (mmu_psize_defs[MMU_PAGE_16M].shift)
mmu_linear_psize = MMU_PAGE_16M;
else if (mmu_psize_defs[MMU_PAGE_1M].shift)
mmu_linear_psize = MMU_PAGE_1M;
/*
* Pick a size for the ordinary pages. Default is 4K, we support
* 64K if cache inhibited large pages are supported by the
* processor
*/
#ifdef CONFIG_PPC_64K_PAGES
if (mmu_psize_defs[MMU_PAGE_64K].shift &&
cpu_has_feature(CPU_FTR_CI_LARGE_PAGE))
mmu_virtual_psize = MMU_PAGE_64K;
#endif
printk(KERN_INFO "Page orders: linear mapping = %d, others = %d\n",
mmu_psize_defs[mmu_linear_psize].shift,
mmu_psize_defs[mmu_virtual_psize].shift);
#ifdef CONFIG_HUGETLB_PAGE
/* Init large page size. Currently, we pick 16M or 1M depending
* on what is available
*/
if (mmu_psize_defs[MMU_PAGE_16M].shift)
mmu_huge_psize = MMU_PAGE_16M;
else if (mmu_psize_defs[MMU_PAGE_1M].shift)
mmu_huge_psize = MMU_PAGE_1M;
/* Calculate HPAGE_SHIFT and sanity check it */
if (mmu_psize_defs[mmu_huge_psize].shift > 16 &&
mmu_psize_defs[mmu_huge_psize].shift < 28)
HPAGE_SHIFT = mmu_psize_defs[mmu_huge_psize].shift;
else
HPAGE_SHIFT = 0; /* No huge pages dude ! */
#endif /* CONFIG_HUGETLB_PAGE */
}
static int __init htab_dt_scan_pftsize(unsigned long node,
const char *uname, int depth,
void *data)
{
char *type = of_get_flat_dt_prop(node, "device_type", NULL);
u32 *prop;
/* We are scanning "cpu" nodes only */
if (type == NULL || strcmp(type, "cpu") != 0)
return 0;
prop = (u32 *)of_get_flat_dt_prop(node, "ibm,pft-size", NULL);
if (prop != NULL) {
/* pft_size[0] is the NUMA CEC cookie */
ppc64_pft_size = prop[1];
return 1;
}
return 0;
}
static unsigned long __init htab_get_table_size(void)
{
unsigned long rnd_mem_size, pteg_count;
/* If hash size wasn't obtained in prom.c, we calculate it now based on
* the total RAM size
/* If hash size isn't already provided by the platform, we try to
* retreive it from the device-tree. If it's not there neither, we
* calculate it now based on the total RAM size
*/
if (ppc64_pft_size == 0)
of_scan_flat_dt(htab_dt_scan_pftsize, NULL);
if (ppc64_pft_size)
return 1UL << ppc64_pft_size;
@ -181,17 +390,21 @@ void __init htab_initialize(void)
unsigned long table, htab_size_bytes;
unsigned long pteg_count;
unsigned long mode_rw;
int i, use_largepages = 0;
unsigned long base = 0, size = 0;
int i;
extern unsigned long tce_alloc_start, tce_alloc_end;
DBG(" -> htab_initialize()\n");
/* Initialize page sizes */
htab_init_page_sizes();
/*
* Calculate the required size of the htab. We want the number of
* PTEGs to equal one half the number of real pages.
*/
htab_size_bytes = get_hashtable_size();
htab_size_bytes = htab_get_table_size();
pteg_count = htab_size_bytes >> 7;
/* For debug, make the HTAB 1/8 as big as it normally would be. */
@ -211,14 +424,11 @@ void __init htab_initialize(void)
* the absolute address space.
*/
table = lmb_alloc(htab_size_bytes, htab_size_bytes);
BUG_ON(table == 0);
DBG("Hash table allocated at %lx, size: %lx\n", table,
htab_size_bytes);
if ( !table ) {
ppc64_terminate_msg(0x20, "hpt space");
loop_forever();
}
htab_address = abs_to_virt(table);
/* htab absolute addr + encoded htabsize */
@ -234,8 +444,6 @@ void __init htab_initialize(void)
* _NOT_ map it to avoid cache paradoxes as it's remapped non
* cacheable later on
*/
if (cpu_has_feature(CPU_FTR_16M_PAGE))
use_largepages = 1;
/* create bolted the linear mapping in the hash table */
for (i=0; i < lmb.memory.cnt; i++) {
@ -246,27 +454,32 @@ void __init htab_initialize(void)
#ifdef CONFIG_U3_DART
/* Do not map the DART space. Fortunately, it will be aligned
* in such a way that it will not cross two lmb regions and will
* fit within a single 16Mb page.
* The DART space is assumed to be a full 16Mb region even if we
* only use 2Mb of that space. We will use more of it later for
* AGP GART. We have to use a full 16Mb large page.
* in such a way that it will not cross two lmb regions and
* will fit within a single 16Mb page.
* The DART space is assumed to be a full 16Mb region even if
* we only use 2Mb of that space. We will use more of it later
* for AGP GART. We have to use a full 16Mb large page.
*/
DBG("DART base: %lx\n", dart_tablebase);
if (dart_tablebase != 0 && dart_tablebase >= base
&& dart_tablebase < (base + size)) {
if (base != dart_tablebase)
create_pte_mapping(base, dart_tablebase, mode_rw,
use_largepages);
BUG_ON(htab_bolt_mapping(base, dart_tablebase,
base, mode_rw,
mmu_linear_psize));
if ((base + size) > (dart_tablebase + 16*MB))
create_pte_mapping(dart_tablebase + 16*MB, base + size,
mode_rw, use_largepages);
BUG_ON(htab_bolt_mapping(dart_tablebase+16*MB,
base + size,
dart_tablebase+16*MB,
mode_rw,
mmu_linear_psize));
continue;
}
#endif /* CONFIG_U3_DART */
create_pte_mapping(base, base + size, mode_rw, use_largepages);
}
BUG_ON(htab_bolt_mapping(base, base + size, base,
mode_rw, mmu_linear_psize));
}
/*
* If we have a memory_limit and we've allocated TCEs then we need to
@ -282,8 +495,9 @@ void __init htab_initialize(void)
if (base + size >= tce_alloc_start)
tce_alloc_start = base + size + 1;
create_pte_mapping(tce_alloc_start, tce_alloc_end,
mode_rw, use_largepages);
BUG_ON(htab_bolt_mapping(tce_alloc_start, tce_alloc_end,
tce_alloc_start, mode_rw,
mmu_linear_psize));
}
DBG(" <- htab_initialize()\n");
@ -298,9 +512,6 @@ unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap)
{
struct page *page;
if (!pfn_valid(pte_pfn(pte)))
return pp;
page = pte_page(pte);
/* page is dirty */
@ -309,7 +520,7 @@ unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap)
__flush_dcache_icache(page_address(page));
set_bit(PG_arch_1, &page->flags);
} else
pp |= HW_NO_EXEC;
pp |= HPTE_R_N;
}
return pp;
}
@ -325,94 +536,169 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
unsigned long vsid;
struct mm_struct *mm;
pte_t *ptep;
int ret;
int user_region = 0;
int local = 0;
cpumask_t tmp;
int rc, user_region = 0, local = 0;
if ((ea & ~REGION_MASK) >= PGTABLE_RANGE)
return 1;
DBG_LOW("hash_page(ea=%016lx, access=%lx, trap=%lx\n",
ea, access, trap);
if ((ea & ~REGION_MASK) >= PGTABLE_RANGE) {
DBG_LOW(" out of pgtable range !\n");
return 1;
}
/* Get region & vsid */
switch (REGION_ID(ea)) {
case USER_REGION_ID:
user_region = 1;
mm = current->mm;
if (! mm)
if (! mm) {
DBG_LOW(" user region with no mm !\n");
return 1;
}
vsid = get_vsid(mm->context.id, ea);
break;
case VMALLOC_REGION_ID:
mm = &init_mm;
vsid = get_kernel_vsid(ea);
break;
#if 0
case KERNEL_REGION_ID:
/*
* Should never get here - entire 0xC0... region is bolted.
* Send the problem up to do_page_fault
*/
#endif
default:
/* Not a valid range
* Send the problem up to do_page_fault
*/
return 1;
break;
}
DBG_LOW(" mm=%p, mm->pgdir=%p, vsid=%016lx\n", mm, mm->pgd, vsid);
/* Get pgdir */
pgdir = mm->pgd;
if (pgdir == NULL)
return 1;
/* Check CPU locality */
tmp = cpumask_of_cpu(smp_processor_id());
if (user_region && cpus_equal(mm->cpu_vm_mask, tmp))
local = 1;
/* Is this a huge page ? */
if (unlikely(in_hugepage_area(mm->context, ea)))
ret = hash_huge_page(mm, access, ea, vsid, local);
else {
ptep = find_linux_pte(pgdir, ea);
if (ptep == NULL)
return 1;
ret = __hash_page(ea, access, vsid, ptep, trap, local);
/* Handle hugepage regions */
if (unlikely(in_hugepage_area(mm->context, ea))) {
DBG_LOW(" -> huge page !\n");
return hash_huge_page(mm, access, ea, vsid, local);
}
return ret;
/* Get PTE and page size from page tables */
ptep = find_linux_pte(pgdir, ea);
if (ptep == NULL || !pte_present(*ptep)) {
DBG_LOW(" no PTE !\n");
return 1;
}
#ifndef CONFIG_PPC_64K_PAGES
DBG_LOW(" i-pte: %016lx\n", pte_val(*ptep));
#else
DBG_LOW(" i-pte: %016lx %016lx\n", pte_val(*ptep),
pte_val(*(ptep + PTRS_PER_PTE)));
#endif
/* Pre-check access permissions (will be re-checked atomically
* in __hash_page_XX but this pre-check is a fast path
*/
if (access & ~pte_val(*ptep)) {
DBG_LOW(" no access !\n");
return 1;
}
/* Do actual hashing */
#ifndef CONFIG_PPC_64K_PAGES
rc = __hash_page_4K(ea, access, vsid, ptep, trap, local);
#else
if (mmu_virtual_psize == MMU_PAGE_64K)
rc = __hash_page_64K(ea, access, vsid, ptep, trap, local);
else
rc = __hash_page_4K(ea, access, vsid, ptep, trap, local);
#endif /* CONFIG_PPC_64K_PAGES */
#ifndef CONFIG_PPC_64K_PAGES
DBG_LOW(" o-pte: %016lx\n", pte_val(*ptep));
#else
DBG_LOW(" o-pte: %016lx %016lx\n", pte_val(*ptep),
pte_val(*(ptep + PTRS_PER_PTE)));
#endif
DBG_LOW(" -> rc=%d\n", rc);
return rc;
}
void flush_hash_page(unsigned long va, pte_t pte, int local)
void hash_preload(struct mm_struct *mm, unsigned long ea,
unsigned long access, unsigned long trap)
{
unsigned long vpn, hash, secondary, slot;
unsigned long huge = pte_huge(pte);
unsigned long vsid;
void *pgdir;
pte_t *ptep;
cpumask_t mask;
unsigned long flags;
int local = 0;
if (huge)
vpn = va >> HPAGE_SHIFT;
/* We don't want huge pages prefaulted for now
*/
if (unlikely(in_hugepage_area(mm->context, ea)))
return;
DBG_LOW("hash_preload(mm=%p, mm->pgdir=%p, ea=%016lx, access=%lx,"
" trap=%lx\n", mm, mm->pgd, ea, access, trap);
/* Get PTE, VSID, access mask */
pgdir = mm->pgd;
if (pgdir == NULL)
return;
ptep = find_linux_pte(pgdir, ea);
if (!ptep)
return;
vsid = get_vsid(mm->context.id, ea);
/* Hash it in */
local_irq_save(flags);
mask = cpumask_of_cpu(smp_processor_id());
if (cpus_equal(mm->cpu_vm_mask, mask))
local = 1;
#ifndef CONFIG_PPC_64K_PAGES
__hash_page_4K(ea, access, vsid, ptep, trap, local);
#else
if (mmu_virtual_psize == MMU_PAGE_64K)
__hash_page_64K(ea, access, vsid, ptep, trap, local);
else
vpn = va >> PAGE_SHIFT;
hash = hpt_hash(vpn, huge);
secondary = (pte_val(pte) & _PAGE_SECONDARY) >> 15;
if (secondary)
hash = ~hash;
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
slot += (pte_val(pte) & _PAGE_GROUP_IX) >> 12;
__hash_page_4K(ea, access, vsid, ptep, trap, local);
#endif /* CONFIG_PPC_64K_PAGES */
local_irq_restore(flags);
}
ppc_md.hpte_invalidate(slot, va, huge, local);
void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int local)
{
unsigned long hash, index, shift, hidx, slot;
DBG_LOW("flush_hash_page(va=%016x)\n", va);
pte_iterate_hashed_subpages(pte, psize, va, index, shift) {
hash = hpt_hash(va, shift);
hidx = __rpte_to_hidx(pte, index);
if (hidx & _PTEIDX_SECONDARY)
hash = ~hash;
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
slot += hidx & _PTEIDX_GROUP_IX;
DBG_LOW(" sub %d: hash=%x, hidx=%x\n", index, slot, hidx);
ppc_md.hpte_invalidate(slot, va, psize, local);
} pte_iterate_hashed_end();
}
void flush_hash_range(unsigned long number, int local)
{
if (ppc_md.flush_hash_range) {
if (ppc_md.flush_hash_range)
ppc_md.flush_hash_range(number, local);
} else {
else {
int i;
struct ppc64_tlb_batch *batch =
&__get_cpu_var(ppc64_tlb_batch);
for (i = 0; i < number; i++)
flush_hash_page(batch->vaddr[i], batch->pte[i], local);
flush_hash_page(batch->vaddr[i], batch->pte[i],
batch->psize, local);
}
}
@ -452,6 +738,18 @@ void __init htab_finish_init(void)
extern unsigned int *htab_call_hpte_remove;
extern unsigned int *htab_call_hpte_updatepp;
#ifdef CONFIG_PPC_64K_PAGES
extern unsigned int *ht64_call_hpte_insert1;
extern unsigned int *ht64_call_hpte_insert2;
extern unsigned int *ht64_call_hpte_remove;
extern unsigned int *ht64_call_hpte_updatepp;
make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert);
make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert);
make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove);
make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp);
#endif /* CONFIG_PPC_64K_PAGES */
make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert);
make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert);
make_bl(htab_call_hpte_remove, ppc_md.hpte_remove);

View File

@ -47,10 +47,25 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
pu = pud_offset(pg, addr);
if (!pud_none(*pu)) {
pm = pmd_offset(pu, addr);
#ifdef CONFIG_PPC_64K_PAGES
/* Currently, we use the normal PTE offset within full
* size PTE pages, thus our huge PTEs are scattered in
* the PTE page and we do waste some. We may change
* that in the future, but the current mecanism keeps
* things much simpler
*/
if (!pmd_none(*pm)) {
/* Note: pte_offset_* are all equivalent on
* ppc64 as we don't have HIGHMEM
*/
pt = pte_offset_kernel(pm, addr);
return pt;
}
#else /* CONFIG_PPC_64K_PAGES */
/* On 4k pages, we put huge PTEs in the PMD page */
pt = (pte_t *)pm;
BUG_ON(!pmd_none(*pm)
&& !(pte_present(*pt) && pte_huge(*pt)));
return pt;
#endif /* CONFIG_PPC_64K_PAGES */
}
}
@ -74,9 +89,16 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
if (pu) {
pm = pmd_alloc(mm, pu, addr);
if (pm) {
#ifdef CONFIG_PPC_64K_PAGES
/* See comment in huge_pte_offset. Note that if we ever
* want to put the page size in the PMD, we would have
* to open code our own pte_alloc* function in order
* to populate and set the size atomically
*/
pt = pte_alloc_map(mm, pm, addr);
#else /* CONFIG_PPC_64K_PAGES */
pt = (pte_t *)pm;
BUG_ON(!pmd_none(*pm)
&& !(pte_present(*pt) && pte_huge(*pt)));
#endif /* CONFIG_PPC_64K_PAGES */
return pt;
}
}
@ -84,35 +106,29 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
return NULL;
}
#define HUGEPTE_BATCH_SIZE (HPAGE_SIZE / PMD_SIZE)
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte)
{
int i;
if (pte_present(*ptep)) {
pte_clear(mm, addr, ptep);
/* We open-code pte_clear because we need to pass the right
* argument to hpte_update (huge / !huge)
*/
unsigned long old = pte_update(ptep, ~0UL);
if (old & _PAGE_HASHPTE)
hpte_update(mm, addr & HPAGE_MASK, ptep, old, 1);
flush_tlb_pending();
}
for (i = 0; i < HUGEPTE_BATCH_SIZE; i++) {
*ptep = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
ptep++;
}
*ptep = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
}
pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep)
{
unsigned long old = pte_update(ptep, ~0UL);
int i;
if (old & _PAGE_HASHPTE)
hpte_update(mm, addr, old, 0);
for (i = 1; i < HUGEPTE_BATCH_SIZE; i++)
ptep[i] = __pte(0);
hpte_update(mm, addr & HPAGE_MASK, ptep, old, 1);
*ptep = __pte(0);
return __pte(old);
}
@ -563,6 +579,8 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
int lastshift;
u16 areamask, curareas;
if (HPAGE_SHIFT == 0)
return -EINVAL;
if (len & ~HPAGE_MASK)
return -EINVAL;
@ -619,19 +637,15 @@ int hash_huge_page(struct mm_struct *mm, unsigned long access,
unsigned long ea, unsigned long vsid, int local)
{
pte_t *ptep;
unsigned long va, vpn;
pte_t old_pte, new_pte;
unsigned long rflags, prpn;
unsigned long old_pte, new_pte;
unsigned long va, rflags, pa;
long slot;
int err = 1;
spin_lock(&mm->page_table_lock);
ptep = huge_pte_offset(mm, ea);
/* Search the Linux page table for a match with va */
va = (vsid << 28) | (ea & 0x0fffffff);
vpn = va >> HPAGE_SHIFT;
/*
* If no pte found or not present, send the problem up to
@ -640,8 +654,6 @@ int hash_huge_page(struct mm_struct *mm, unsigned long access,
if (unlikely(!ptep || pte_none(*ptep)))
goto out;
/* BUG_ON(pte_bad(*ptep)); */
/*
* Check the user's access rights to the page. If access should be
* prevented then send the problem up to do_page_fault.
@ -661,58 +673,64 @@ int hash_huge_page(struct mm_struct *mm, unsigned long access,
*/
old_pte = *ptep;
new_pte = old_pte;
do {
old_pte = pte_val(*ptep);
if (old_pte & _PAGE_BUSY)
goto out;
new_pte = old_pte | _PAGE_BUSY |
_PAGE_ACCESSED | _PAGE_HASHPTE;
} while(old_pte != __cmpxchg_u64((unsigned long *)ptep,
old_pte, new_pte));
rflags = 0x2 | (! (pte_val(new_pte) & _PAGE_RW));
rflags = 0x2 | (!(new_pte & _PAGE_RW));
/* _PAGE_EXEC -> HW_NO_EXEC since it's inverted */
rflags |= ((pte_val(new_pte) & _PAGE_EXEC) ? 0 : HW_NO_EXEC);
rflags |= ((new_pte & _PAGE_EXEC) ? 0 : HPTE_R_N);
/* Check if pte already has an hpte (case 2) */
if (unlikely(pte_val(old_pte) & _PAGE_HASHPTE)) {
if (unlikely(old_pte & _PAGE_HASHPTE)) {
/* There MIGHT be an HPTE for this pte */
unsigned long hash, slot;
hash = hpt_hash(vpn, 1);
if (pte_val(old_pte) & _PAGE_SECONDARY)
hash = hpt_hash(va, HPAGE_SHIFT);
if (old_pte & _PAGE_F_SECOND)
hash = ~hash;
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
slot += (pte_val(old_pte) & _PAGE_GROUP_IX) >> 12;
slot += (old_pte & _PAGE_F_GIX) >> 12;
if (ppc_md.hpte_updatepp(slot, rflags, va, 1, local) == -1)
pte_val(old_pte) &= ~_PAGE_HPTEFLAGS;
old_pte &= ~_PAGE_HPTEFLAGS;
}
if (likely(!(pte_val(old_pte) & _PAGE_HASHPTE))) {
unsigned long hash = hpt_hash(vpn, 1);
if (likely(!(old_pte & _PAGE_HASHPTE))) {
unsigned long hash = hpt_hash(va, HPAGE_SHIFT);
unsigned long hpte_group;
prpn = pte_pfn(old_pte);
pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT;
repeat:
hpte_group = ((hash & htab_hash_mask) *
HPTES_PER_GROUP) & ~0x7UL;
/* Update the linux pte with the HPTE slot */
pte_val(new_pte) &= ~_PAGE_HPTEFLAGS;
pte_val(new_pte) |= _PAGE_HASHPTE;
/* clear HPTE slot informations in new PTE */
new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HASHPTE;
/* Add in WIMG bits */
/* XXX We should store these in the pte */
/* --BenH: I think they are ... */
rflags |= _PAGE_COHERENT;
slot = ppc_md.hpte_insert(hpte_group, va, prpn,
HPTE_V_LARGE, rflags);
/* Insert into the hash table, primary slot */
slot = ppc_md.hpte_insert(hpte_group, va, pa, rflags, 0,
mmu_huge_psize);
/* Primary is full, try the secondary */
if (unlikely(slot == -1)) {
pte_val(new_pte) |= _PAGE_SECONDARY;
new_pte |= _PAGE_F_SECOND;
hpte_group = ((~hash & htab_hash_mask) *
HPTES_PER_GROUP) & ~0x7UL;
slot = ppc_md.hpte_insert(hpte_group, va, prpn,
HPTE_V_LARGE |
slot = ppc_md.hpte_insert(hpte_group, va, pa, rflags,
HPTE_V_SECONDARY,
rflags);
mmu_huge_psize);
if (slot == -1) {
if (mftb() & 0x1)
hpte_group = ((hash & htab_hash_mask) *
@ -726,20 +744,18 @@ repeat:
if (unlikely(slot == -2))
panic("hash_huge_page: pte_insert failed\n");
pte_val(new_pte) |= (slot<<12) & _PAGE_GROUP_IX;
/*
* No need to use ldarx/stdcx here because all who
* might be updating the pte will hold the
* page_table_lock
*/
*ptep = new_pte;
new_pte |= (slot << 12) & _PAGE_F_GIX;
}
/*
* No need to use ldarx/stdcx here because all who
* might be updating the pte will hold the
* page_table_lock
*/
*ptep = __pte(new_pte & ~_PAGE_BUSY);
err = 0;
out:
spin_unlock(&mm->page_table_lock);
return err;
}

View File

@ -188,12 +188,21 @@ static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags)
memset(addr, 0, kmem_cache_size(cache));
}
#ifdef CONFIG_PPC_64K_PAGES
static const int pgtable_cache_size[2] = {
PTE_TABLE_SIZE, PGD_TABLE_SIZE
};
static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
"pte_pmd_cache", "pgd_cache",
};
#else
static const int pgtable_cache_size[2] = {
PTE_TABLE_SIZE, PMD_TABLE_SIZE
};
static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
"pgd_pte_cache", "pud_pmd_cache",
};
#endif /* CONFIG_PPC_64K_PAGES */
kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)];
@ -201,19 +210,14 @@ void pgtable_cache_init(void)
{
int i;
BUILD_BUG_ON(PTE_TABLE_SIZE != pgtable_cache_size[PTE_CACHE_NUM]);
BUILD_BUG_ON(PMD_TABLE_SIZE != pgtable_cache_size[PMD_CACHE_NUM]);
BUILD_BUG_ON(PUD_TABLE_SIZE != pgtable_cache_size[PUD_CACHE_NUM]);
BUILD_BUG_ON(PGD_TABLE_SIZE != pgtable_cache_size[PGD_CACHE_NUM]);
for (i = 0; i < ARRAY_SIZE(pgtable_cache_size); i++) {
int size = pgtable_cache_size[i];
const char *name = pgtable_cache_name[i];
pgtable_cache[i] = kmem_cache_create(name,
size, size,
SLAB_HWCACHE_ALIGN
| SLAB_MUST_HWCACHE_ALIGN,
SLAB_HWCACHE_ALIGN |
SLAB_MUST_HWCACHE_ALIGN,
zero_ctor,
NULL);
if (! pgtable_cache[i])

View File

@ -61,6 +61,9 @@ int init_bootmem_done;
int mem_init_done;
unsigned long memory_limit;
extern void hash_preload(struct mm_struct *mm, unsigned long ea,
unsigned long access, unsigned long trap);
/*
* This is called by /dev/mem to know if a given address has to
* be mapped non-cacheable or not
@ -493,18 +496,10 @@ EXPORT_SYMBOL(flush_icache_user_range);
void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
pte_t pte)
{
/* handle i-cache coherency */
unsigned long pfn = pte_pfn(pte);
#ifdef CONFIG_PPC32
pmd_t *pmd;
#else
unsigned long vsid;
void *pgdir;
pte_t *ptep;
int local = 0;
cpumask_t tmp;
unsigned long flags;
#ifdef CONFIG_PPC_STD_MMU
unsigned long access = 0, trap;
#endif
unsigned long pfn = pte_pfn(pte);
/* handle i-cache coherency */
if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE) &&
@ -535,30 +530,21 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
/* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */
if (!pte_young(pte) || address >= TASK_SIZE)
return;
#ifdef CONFIG_PPC32
if (Hash == 0)
/* We try to figure out if we are coming from an instruction
* access fault and pass that down to __hash_page so we avoid
* double-faulting on execution of fresh text. We have to test
* for regs NULL since init will get here first thing at boot
*
* We also avoid filling the hash if not coming from a fault
*/
if (current->thread.regs == NULL)
return;
pmd = pmd_offset(pgd_offset(vma->vm_mm, address), address);
if (!pmd_none(*pmd))
add_hash_page(vma->vm_mm->context, address, pmd_val(*pmd));
#else
pgdir = vma->vm_mm->pgd;
if (pgdir == NULL)
trap = TRAP(current->thread.regs);
if (trap == 0x400)
access |= _PAGE_EXEC;
else if (trap != 0x300)
return;
ptep = find_linux_pte(pgdir, address);
if (!ptep)
return;
vsid = get_vsid(vma->vm_mm->context.id, address);
local_irq_save(flags);
tmp = cpumask_of_cpu(smp_processor_id());
if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp))
local = 1;
__hash_page(address, 0, vsid, ptep, 0x300, local);
local_irq_restore(flags);
#endif
#endif
hash_preload(vma->vm_mm, address, access, trap);
#endif /* CONFIG_PPC_STD_MMU */
}

View File

@ -101,7 +101,6 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags)
pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
unsigned long vsid;
if (mem_init_done) {
pgdp = pgd_offset_k(ea);
@ -117,28 +116,15 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags)
set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT,
__pgprot(flags)));
} else {
unsigned long va, vpn, hash, hpteg;
/*
* If the mm subsystem is not fully up, we cannot create a
* linux page table entry for this mapping. Simply bolt an
* entry in the hardware page table.
*
*/
vsid = get_kernel_vsid(ea);
va = (vsid << 28) | (ea & 0xFFFFFFF);
vpn = va >> PAGE_SHIFT;
hash = hpt_hash(vpn, 0);
hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
/* Panic if a pte grpup is full */
if (ppc_md.hpte_insert(hpteg, va, pa >> PAGE_SHIFT,
HPTE_V_BOLTED,
_PAGE_NO_CACHE|_PAGE_GUARDED|PP_RWXX)
== -1) {
panic("map_io_page: could not insert mapping");
}
if (htab_bolt_mapping(ea, ea + PAGE_SIZE, pa, flags,
mmu_virtual_psize))
panic("Can't map bolted IO mapping");
}
return 0;
}

View File

@ -178,6 +178,21 @@ void __init setbat(int index, unsigned long virt, unsigned long phys,
bat_addrs[index].phys = phys;
}
/*
* Preload a translation in the hash table
*/
void hash_preload(struct mm_struct *mm, unsigned long ea,
unsigned long access, unsigned long trap)
{
pmd_t *pmd;
if (Hash == 0)
return;
pmd = pmd_offset(pgd_offset(vma->vm_mm, address), address);
if (!pmd_none(*pmd))
add_hash_page(vma->vm_mm->context, address, pmd_val(*pmd));
}
/*
* Initialize the hash table and patch the instructions in hashtable.S.
*/

View File

@ -14,14 +14,32 @@
* 2 of the License, or (at your option) any later version.
*/
#undef DEBUG
#include <linux/config.h>
#include <asm/pgtable.h>
#include <asm/mmu.h>
#include <asm/mmu_context.h>
#include <asm/paca.h>
#include <asm/cputable.h>
#include <asm/cacheflush.h>
extern void slb_allocate(unsigned long ea);
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
#else
#define DBG(fmt...)
#endif
extern void slb_allocate_realmode(unsigned long ea);
extern void slb_allocate_user(unsigned long ea);
static void slb_allocate(unsigned long ea)
{
/* Currently, we do real mode for all SLBs including user, but
* that will change if we bring back dynamic VSIDs
*/
slb_allocate_realmode(ea);
}
static inline unsigned long mk_esid_data(unsigned long ea, unsigned long slot)
{
@ -46,13 +64,15 @@ static void slb_flush_and_rebolt(void)
{
/* If you change this make sure you change SLB_NUM_BOLTED
* appropriately too. */
unsigned long ksp_flags = SLB_VSID_KERNEL;
unsigned long linear_llp, virtual_llp, lflags, vflags;
unsigned long ksp_esid_data;
WARN_ON(!irqs_disabled());
if (cpu_has_feature(CPU_FTR_16M_PAGE))
ksp_flags |= SLB_VSID_L;
linear_llp = mmu_psize_defs[mmu_linear_psize].sllp;
virtual_llp = mmu_psize_defs[mmu_virtual_psize].sllp;
lflags = SLB_VSID_KERNEL | linear_llp;
vflags = SLB_VSID_KERNEL | virtual_llp;
ksp_esid_data = mk_esid_data(get_paca()->kstack, 2);
if ((ksp_esid_data & ESID_MASK) == KERNELBASE)
@ -67,9 +87,9 @@ static void slb_flush_and_rebolt(void)
/* Slot 2 - kernel stack */
"slbmte %2,%3\n"
"isync"
:: "r"(mk_vsid_data(VMALLOCBASE, SLB_VSID_KERNEL)),
:: "r"(mk_vsid_data(VMALLOCBASE, vflags)),
"r"(mk_esid_data(VMALLOCBASE, 1)),
"r"(mk_vsid_data(ksp_esid_data, ksp_flags)),
"r"(mk_vsid_data(ksp_esid_data, lflags)),
"r"(ksp_esid_data)
: "memory");
}
@ -102,6 +122,9 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
get_paca()->slb_cache_ptr = 0;
get_paca()->context = mm->context;
#ifdef CONFIG_PPC_64K_PAGES
get_paca()->pgdir = mm->pgd;
#endif /* CONFIG_PPC_64K_PAGES */
/*
* preload some userspace segments into the SLB.
@ -131,28 +154,77 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
slb_allocate(unmapped_base);
}
static inline void patch_slb_encoding(unsigned int *insn_addr,
unsigned int immed)
{
/* Assume the instruction had a "0" immediate value, just
* "or" in the new value
*/
*insn_addr |= immed;
flush_icache_range((unsigned long)insn_addr, 4+
(unsigned long)insn_addr);
}
void slb_initialize(void)
{
unsigned long linear_llp, virtual_llp;
static int slb_encoding_inited;
extern unsigned int *slb_miss_kernel_load_linear;
extern unsigned int *slb_miss_kernel_load_virtual;
extern unsigned int *slb_miss_user_load_normal;
#ifdef CONFIG_HUGETLB_PAGE
extern unsigned int *slb_miss_user_load_huge;
unsigned long huge_llp;
huge_llp = mmu_psize_defs[mmu_huge_psize].sllp;
#endif
/* Prepare our SLB miss handler based on our page size */
linear_llp = mmu_psize_defs[mmu_linear_psize].sllp;
virtual_llp = mmu_psize_defs[mmu_virtual_psize].sllp;
if (!slb_encoding_inited) {
slb_encoding_inited = 1;
patch_slb_encoding(slb_miss_kernel_load_linear,
SLB_VSID_KERNEL | linear_llp);
patch_slb_encoding(slb_miss_kernel_load_virtual,
SLB_VSID_KERNEL | virtual_llp);
patch_slb_encoding(slb_miss_user_load_normal,
SLB_VSID_USER | virtual_llp);
DBG("SLB: linear LLP = %04x\n", linear_llp);
DBG("SLB: virtual LLP = %04x\n", virtual_llp);
#ifdef CONFIG_HUGETLB_PAGE
patch_slb_encoding(slb_miss_user_load_huge,
SLB_VSID_USER | huge_llp);
DBG("SLB: huge LLP = %04x\n", huge_llp);
#endif
}
/* 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 flags = SLB_VSID_KERNEL;
{
unsigned long lflags, vflags;
/* Invalidate the entire SLB (even slot 0) & all the ERATS */
if (cpu_has_feature(CPU_FTR_16M_PAGE))
flags |= SLB_VSID_L;
lflags = SLB_VSID_KERNEL | linear_llp;
vflags = SLB_VSID_KERNEL | virtual_llp;
asm volatile("isync":::"memory");
asm volatile("slbmte %0,%0"::"r" (0) : "memory");
/* Invalidate the entire SLB (even slot 0) & all the ERATS */
asm volatile("isync":::"memory");
asm volatile("slbmte %0,%0"::"r" (0) : "memory");
asm volatile("isync; slbia; isync":::"memory");
create_slbe(KERNELBASE, flags, 0);
create_slbe(VMALLOCBASE, SLB_VSID_KERNEL, 1);
create_slbe(KERNELBASE, lflags, 0);
/* VMALLOC space has 4K pages always for now */
create_slbe(VMALLOCBASE, vflags, 1);
/* We don't bolt the stack for the time being - we're in boot,
* so the stack is in the bolted segment. By the time it goes
* elsewhere, we'll call _switch() which will bolt in the new
* one. */
asm volatile("isync":::"memory");
#endif
}
#endif /* CONFIG_PPC_ISERIES */
get_paca()->stab_rr = SLB_NUM_BOLTED;
}

View File

@ -18,25 +18,161 @@
#include <linux/config.h>
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/mmu.h>
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>
#include <asm/cputable.h>
#include <asm/page.h>
#include <asm/mmu.h>
#include <asm/pgtable.h>
/* void slb_allocate(unsigned long ea);
/* void slb_allocate_realmode(unsigned long ea);
*
* Create an SLB entry for the given EA (user or kernel).
* r3 = faulting address, r13 = PACA
* r9, r10, r11 are clobbered by this function
* No other registers are examined or changed.
*/
_GLOBAL(slb_allocate)
/*
* First find a slot, round robin. Previously we tried to find
* a free slot first but that took too long. Unfortunately we
* dont have any LRU information to help us choose a slot.
_GLOBAL(slb_allocate_realmode)
/* r3 = faulting address */
srdi r9,r3,60 /* get region */
srdi r10,r3,28 /* get esid */
cmpldi cr7,r9,0xc /* cmp KERNELBASE for later use */
/* r3 = address, r10 = esid, cr7 = <>KERNELBASE */
blt cr7,0f /* user or kernel? */
/* kernel address: proto-VSID = ESID */
/* WARNING - MAGIC: we don't use the VSID 0xfffffffff, but
* this code will generate the protoVSID 0xfffffffff for the
* top segment. That's ok, the scramble below will translate
* it to VSID 0, which is reserved as a bad VSID - one which
* will never have any pages in it. */
/* Check if hitting the linear mapping of the vmalloc/ioremap
* kernel space
*/
bne cr7,1f
/* Linear mapping encoding bits, the "li" instruction below will
* be patched by the kernel at boot
*/
_GLOBAL(slb_miss_kernel_load_linear)
li r11,0
b slb_finish_load
1: /* vmalloc/ioremap mapping encoding bits, the "li" instruction below
* will be patched by the kernel at boot
*/
_GLOBAL(slb_miss_kernel_load_virtual)
li r11,0
b slb_finish_load
0: /* user address: proto-VSID = context << 15 | ESID. First check
* if the address is within the boundaries of the user region
*/
srdi. r9,r10,USER_ESID_BITS
bne- 8f /* invalid ea bits set */
/* Figure out if the segment contains huge pages */
#ifdef CONFIG_HUGETLB_PAGE
BEGIN_FTR_SECTION
b 1f
END_FTR_SECTION_IFCLR(CPU_FTR_16M_PAGE)
lhz r9,PACAHIGHHTLBAREAS(r13)
srdi r11,r10,(HTLB_AREA_SHIFT-SID_SHIFT)
srd r9,r9,r11
lhz r11,PACALOWHTLBAREAS(r13)
srd r11,r11,r10
or. r9,r9,r11
beq 1f
_GLOBAL(slb_miss_user_load_huge)
li r11,0
b 2f
1:
#endif /* CONFIG_HUGETLB_PAGE */
_GLOBAL(slb_miss_user_load_normal)
li r11,0
2:
ld r9,PACACONTEXTID(r13)
rldimi r10,r9,USER_ESID_BITS,0
b slb_finish_load
8: /* invalid EA */
li r10,0 /* BAD_VSID */
li r11,SLB_VSID_USER /* flags don't much matter */
b slb_finish_load
#ifdef __DISABLED__
/* void slb_allocate_user(unsigned long ea);
*
* Create an SLB entry for the given EA (user or kernel).
* r3 = faulting address, r13 = PACA
* r9, r10, r11 are clobbered by this function
* No other registers are examined or changed.
*
* It is called with translation enabled in order to be able to walk the
* page tables. This is not currently used.
*/
_GLOBAL(slb_allocate_user)
/* r3 = faulting address */
srdi r10,r3,28 /* get esid */
crset 4*cr7+lt /* set "user" flag for later */
/* check if we fit in the range covered by the pagetables*/
srdi. r9,r3,PGTABLE_EADDR_SIZE
crnot 4*cr0+eq,4*cr0+eq
beqlr
/* now we need to get to the page tables in order to get the page
* size encoding from the PMD. In the future, we'll be able to deal
* with 1T segments too by getting the encoding from the PGD instead
*/
ld r9,PACAPGDIR(r13)
cmpldi cr0,r9,0
beqlr
rlwinm r11,r10,8,25,28
ldx r9,r9,r11 /* get pgd_t */
cmpldi cr0,r9,0
beqlr
rlwinm r11,r10,3,17,28
ldx r9,r9,r11 /* get pmd_t */
cmpldi cr0,r9,0
beqlr
/* build vsid flags */
andi. r11,r9,SLB_VSID_LLP
ori r11,r11,SLB_VSID_USER
/* get context to calculate proto-VSID */
ld r9,PACACONTEXTID(r13)
rldimi r10,r9,USER_ESID_BITS,0
/* fall through slb_finish_load */
#endif /* __DISABLED__ */
/*
* Finish loading of an SLB entry and return
*
* r3 = EA, r10 = proto-VSID, r11 = flags, clobbers r9, cr7 = <>KERNELBASE
*/
slb_finish_load:
ASM_VSID_SCRAMBLE(r10,r9)
rldimi r11,r10,SLB_VSID_SHIFT,16 /* combine VSID and flags */
/* r3 = EA, r11 = VSID data */
/*
* Find a slot, round robin. Previously we tried to find a
* free slot first but that took too long. Unfortunately we
* dont have any LRU information to help us choose a slot.
*/
#ifdef CONFIG_PPC_ISERIES
/*
* On iSeries, the "bolted" stack segment can be cast out on
@ -45,9 +181,9 @@ _GLOBAL(slb_allocate)
*/
ld r9,PACAKSAVE(r13)
clrrdi r9,r9,28
clrrdi r11,r3,28
clrrdi r3,r3,28
li r10,SLB_NUM_BOLTED-1 /* Stack goes in last bolted slot */
cmpld r9,r11
cmpld r9,r3
beq 3f
#endif /* CONFIG_PPC_ISERIES */
@ -61,63 +197,12 @@ _GLOBAL(slb_allocate)
4:
std r10,PACASTABRR(r13)
3:
/* r3 = faulting address, r10 = entry */
rldimi r3,r10,0,36 /* r3= EA[0:35] | entry */
oris r10,r3,SLB_ESID_V@h /* r3 |= SLB_ESID_V */
srdi r9,r3,60 /* get region */
srdi r3,r3,28 /* get esid */
cmpldi cr7,r9,0xc /* cmp KERNELBASE for later use */
rldimi r10,r3,28,0 /* r10= ESID<<28 | entry */
oris r10,r10,SLB_ESID_V@h /* r10 |= SLB_ESID_V */
/* r3 = esid, r10 = esid_data, cr7 = <>KERNELBASE */
blt cr7,0f /* user or kernel? */
/* kernel address: proto-VSID = ESID */
/* WARNING - MAGIC: we don't use the VSID 0xfffffffff, but
* this code will generate the protoVSID 0xfffffffff for the
* top segment. That's ok, the scramble below will translate
* it to VSID 0, which is reserved as a bad VSID - one which
* will never have any pages in it. */
li r11,SLB_VSID_KERNEL
BEGIN_FTR_SECTION
bne cr7,9f
li r11,(SLB_VSID_KERNEL|SLB_VSID_L)
END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
b 9f
0: /* user address: proto-VSID = context<<15 | ESID */
srdi. r9,r3,USER_ESID_BITS
bne- 8f /* invalid ea bits set */
#ifdef CONFIG_HUGETLB_PAGE
BEGIN_FTR_SECTION
lhz r9,PACAHIGHHTLBAREAS(r13)
srdi r11,r3,(HTLB_AREA_SHIFT-SID_SHIFT)
srd r9,r9,r11
lhz r11,PACALOWHTLBAREAS(r13)
srd r11,r11,r3
or r9,r9,r11
END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
#endif /* CONFIG_HUGETLB_PAGE */
li r11,SLB_VSID_USER
#ifdef CONFIG_HUGETLB_PAGE
BEGIN_FTR_SECTION
rldimi r11,r9,8,55 /* shift masked bit into SLB_VSID_L */
END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
#endif /* CONFIG_HUGETLB_PAGE */
ld r9,PACACONTEXTID(r13)
rldimi r3,r9,USER_ESID_BITS,0
9: /* r3 = protovsid, r11 = flags, r10 = esid_data, cr7 = <>KERNELBASE */
ASM_VSID_SCRAMBLE(r3,r9)
rldimi r11,r3,SLB_VSID_SHIFT,16 /* combine VSID and flags */
/* r3 = ESID data, r11 = VSID data */
/*
* No need for an isync before or after this slbmte. The exception
@ -125,7 +210,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
*/
slbmte r11,r10
bgelr cr7 /* we're done for kernel addresses */
/* we're done for kernel addresses */
crclr 4*cr0+eq /* set result to "success" */
bgelr cr7
/* Update the slb cache */
lhz r3,PACASLBCACHEPTR(r13) /* offset = paca->slb_cache_ptr */
@ -143,9 +230,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
li r3,SLB_CACHE_ENTRIES+1
2:
sth r3,PACASLBCACHEPTR(r13) /* paca->slb_cache_ptr = offset */
crclr 4*cr0+eq /* set result to "success" */
blr
8: /* invalid EA */
li r3,0 /* BAD_VSID */
li r11,SLB_VSID_USER /* flags don't much matter */
b 9b

View File

@ -26,7 +26,6 @@ struct stab_entry {
unsigned long vsid_data;
};
/* Both the segment table and SLB code uses the following cache */
#define NR_STAB_CACHE_ENTRIES 8
DEFINE_PER_CPU(long, stab_cache_ptr);
DEFINE_PER_CPU(long, stab_cache[NR_STAB_CACHE_ENTRIES]);
@ -186,7 +185,7 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm)
/* Never flush the first entry. */
ste += 1;
for (entry = 1;
entry < (PAGE_SIZE / sizeof(struct stab_entry));
entry < (HW_PAGE_SIZE / sizeof(struct stab_entry));
entry++, ste++) {
unsigned long ea;
ea = ste->esid_data & ESID_MASK;
@ -200,6 +199,10 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm)
__get_cpu_var(stab_cache_ptr) = 0;
#ifdef CONFIG_PPC_64K_PAGES
get_paca()->pgdir = mm->pgd;
#endif /* CONFIG_PPC_64K_PAGES */
/* Now preload some entries for the new task */
if (test_tsk_thread_flag(tsk, TIF_32BIT))
unmapped_base = TASK_UNMAPPED_BASE_USER32;
@ -223,8 +226,6 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm)
asm volatile("sync" : : : "memory");
}
extern void slb_initialize(void);
/*
* Allocate segment tables for secondary CPUs. These must all go in
* the first (bolted) segment, so that do_stab_bolted won't get a
@ -243,18 +244,21 @@ void stabs_alloc(void)
if (cpu == 0)
continue; /* stab for CPU 0 is statically allocated */
newstab = lmb_alloc_base(PAGE_SIZE, PAGE_SIZE, 1<<SID_SHIFT);
newstab = lmb_alloc_base(HW_PAGE_SIZE, HW_PAGE_SIZE,
1<<SID_SHIFT);
if (! newstab)
panic("Unable to allocate segment table for CPU %d.\n",
cpu);
newstab += KERNELBASE;
memset((void *)newstab, 0, PAGE_SIZE);
memset((void *)newstab, 0, HW_PAGE_SIZE);
paca[cpu].stab_addr = newstab;
paca[cpu].stab_real = virt_to_abs(newstab);
printk(KERN_DEBUG "Segment table for CPU %d at 0x%lx virtual, 0x%lx absolute\n", cpu, paca[cpu].stab_addr, paca[cpu].stab_real);
printk(KERN_DEBUG "Segment table for CPU %d at 0x%lx "
"virtual, 0x%lx absolute\n",
cpu, paca[cpu].stab_addr, paca[cpu].stab_real);
}
}
@ -267,13 +271,9 @@ void stab_initialize(unsigned long stab)
{
unsigned long vsid = get_kernel_vsid(KERNELBASE);
if (cpu_has_feature(CPU_FTR_SLB)) {
slb_initialize();
} else {
asm volatile("isync; slbia; isync":::"memory");
make_ste(stab, GET_ESID(KERNELBASE), vsid);
asm volatile("isync; slbia; isync":::"memory");
make_ste(stab, GET_ESID(KERNELBASE), vsid);
/* Order update */
asm volatile("sync":::"memory");
}
/* Order update */
asm volatile("sync":::"memory");
}

View File

@ -21,6 +21,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/mm.h>
@ -30,7 +31,7 @@
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <asm/tlb.h>
#include <linux/highmem.h>
#include <asm/bug.h>
DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
@ -126,28 +127,46 @@ void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf)
* (if we remove it we should clear the _PTE_HPTEFLAGS bits).
*/
void hpte_update(struct mm_struct *mm, unsigned long addr,
unsigned long pte, int wrprot)
pte_t *ptep, unsigned long pte, int huge)
{
struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
unsigned long vsid;
unsigned int psize = mmu_virtual_psize;
int i;
i = batch->index;
/* We mask the address for the base page size. Huge pages will
* have applied their own masking already
*/
addr &= PAGE_MASK;
/* Get page size (maybe move back to caller) */
if (huge) {
#ifdef CONFIG_HUGETLB_PAGE
psize = mmu_huge_psize;
#else
BUG();
#endif
}
/*
* This can happen when we are in the middle of a TLB batch and
* we encounter memory pressure (eg copy_page_range when it tries
* to allocate a new pte). If we have to reclaim memory and end
* up scanning and resetting referenced bits then our batch context
* will change mid stream.
*
* We also need to ensure only one page size is present in a given
* batch
*/
if (i != 0 && (mm != batch->mm || batch->large != pte_huge(pte))) {
if (i != 0 && (mm != batch->mm || batch->psize != psize)) {
flush_tlb_pending();
i = 0;
}
if (i == 0) {
batch->mm = mm;
batch->large = pte_huge(pte);
batch->psize = psize;
}
if (addr < KERNELBASE) {
vsid = get_vsid(mm->context.id, addr);
@ -155,7 +174,7 @@ void hpte_update(struct mm_struct *mm, unsigned long addr,
} else
vsid = get_kernel_vsid(addr);
batch->vaddr[i] = (vsid << 28 ) | (addr & 0x0fffffff);
batch->pte[i] = __pte(pte);
batch->pte[i] = __real_pte(__pte(pte), ptep);
batch->index = ++i;
if (i >= PPC64_TLB_BATCH_NR)
flush_tlb_pending();
@ -177,7 +196,8 @@ void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
local = 1;
if (i == 1)
flush_hash_page(batch->vaddr[0], batch->pte[0], local);
flush_hash_page(batch->vaddr[0], batch->pte[0],
batch->psize, local);
else
flush_hash_range(i, local);
batch->index = 0;

View File

@ -11,3 +11,4 @@ obj-$(CONFIG_85xx) += 85xx/
obj-$(CONFIG_PPC_PSERIES) += pseries/
obj-$(CONFIG_PPC_ISERIES) += iseries/
obj-$(CONFIG_PPC_MAPLE) += maple/
obj-$(CONFIG_PPC_CELL) += cell/

View File

@ -0,0 +1,2 @@
obj-y += interrupt.o iommu.o setup.o spider-pic.o
obj-$(CONFIG_SMP) += smp.o

View File

@ -1,5 +1,5 @@
/*
* BPA Internal Interrupt Controller
* Cell Internal Interrupt Controller
*
* (C) Copyright IBM Deutschland Entwicklung GmbH 2005
*
@ -31,7 +31,7 @@
#include <asm/prom.h>
#include <asm/ptrace.h>
#include "bpa_iic.h"
#include "interrupt.h"
struct iic_pending_bits {
u32 data;
@ -89,7 +89,7 @@ static void iic_end(unsigned int irq)
}
static struct hw_interrupt_type iic_pic = {
.typename = " BPA-IIC ",
.typename = " CELL-IIC ",
.startup = iic_startup,
.enable = iic_enable,
.disable = iic_disable,
@ -106,7 +106,7 @@ static int iic_external_get_irq(struct iic_pending_bits pending)
irq = -1;
/*
* This mapping is specific to the Broadband
* This mapping is specific to the Cell Broadband
* Engine. We might need to get the numbers
* from the device tree to support future CPUs.
*/

View File

@ -1,5 +1,5 @@
#ifndef ASM_BPA_IIC_H
#define ASM_BPA_IIC_H
#ifndef ASM_CELL_PIC_H
#define ASM_CELL_PIC_H
#ifdef __KERNEL__
/*
* Mapping of IIC pending bits into per-node
@ -21,7 +21,7 @@
* + node number
* * don't care
*
* A node consists of a Broadband Engine and an optional
* A node consists of a Cell Broadband Engine and an optional
* south bridge device providing a maximum of 64 IRQs.
* The south bridge may be connected to either IOIF0
* or IOIF1.
@ -59,4 +59,4 @@ extern void spider_init_IRQ(void);
extern int spider_get_irq(unsigned long int_pending);
#endif
#endif /* ASM_BPA_IIC_H */
#endif /* ASM_CELL_PIC_H */

View File

@ -1,5 +1,5 @@
/*
* IOMMU implementation for Broadband Processor Architecture
* IOMMU implementation for Cell Broadband Processor Architecture
* We just establish a linear mapping at boot by setting all the
* IOPT cache entries in the CPU.
* The mapping functions should be identical to pci_direct_iommu,
@ -41,7 +41,7 @@
#include <asm/system.h>
#include <asm/ppc-pci.h>
#include "bpa_iommu.h"
#include "iommu.h"
static inline unsigned long
get_iopt_entry(unsigned long real_address, unsigned long ioid,
@ -276,7 +276,7 @@ static void iommu_dev_setup_null(struct pci_dev *d) { }
* for each DMA window used by any device. For now, we
* happen to know that there is only one DMA window in use,
* starting at iopt_phys_offset. */
static void bpa_map_iommu(void)
static void cell_map_iommu(void)
{
unsigned long address;
void __iomem *base;
@ -309,7 +309,7 @@ static void bpa_map_iommu(void)
}
static void *bpa_alloc_coherent(struct device *hwdev, size_t size,
static void *cell_alloc_coherent(struct device *hwdev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
{
void *ret;
@ -317,65 +317,65 @@ static void *bpa_alloc_coherent(struct device *hwdev, size_t size,
ret = (void *)__get_free_pages(flag, get_order(size));
if (ret != NULL) {
memset(ret, 0, size);
*dma_handle = virt_to_abs(ret) | BPA_DMA_VALID;
*dma_handle = virt_to_abs(ret) | CELL_DMA_VALID;
}
return ret;
}
static void bpa_free_coherent(struct device *hwdev, size_t size,
static void cell_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 bpa_map_single(struct device *hwdev, void *ptr,
static dma_addr_t cell_map_single(struct device *hwdev, void *ptr,
size_t size, enum dma_data_direction direction)
{
return virt_to_abs(ptr) | BPA_DMA_VALID;
return virt_to_abs(ptr) | CELL_DMA_VALID;
}
static void bpa_unmap_single(struct device *hwdev, dma_addr_t dma_addr,
static void cell_unmap_single(struct device *hwdev, dma_addr_t dma_addr,
size_t size, enum dma_data_direction direction)
{
}
static int bpa_map_sg(struct device *hwdev, struct scatterlist *sg,
static int cell_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)
| BPA_DMA_VALID;
| CELL_DMA_VALID;
sg->dma_length = sg->length;
}
return nents;
}
static void bpa_unmap_sg(struct device *hwdev, struct scatterlist *sg,
static void cell_unmap_sg(struct device *hwdev, struct scatterlist *sg,
int nents, enum dma_data_direction direction)
{
}
static int bpa_dma_supported(struct device *dev, u64 mask)
static int cell_dma_supported(struct device *dev, u64 mask)
{
return mask < 0x100000000ull;
}
void bpa_init_iommu(void)
void cell_init_iommu(void)
{
bpa_map_iommu();
cell_map_iommu();
/* Direct I/O, IOMMU off */
ppc_md.iommu_dev_setup = iommu_dev_setup_null;
ppc_md.iommu_bus_setup = iommu_bus_setup_null;
pci_dma_ops.alloc_coherent = bpa_alloc_coherent;
pci_dma_ops.free_coherent = bpa_free_coherent;
pci_dma_ops.map_single = bpa_map_single;
pci_dma_ops.unmap_single = bpa_unmap_single;
pci_dma_ops.map_sg = bpa_map_sg;
pci_dma_ops.unmap_sg = bpa_unmap_sg;
pci_dma_ops.dma_supported = bpa_dma_supported;
pci_dma_ops.alloc_coherent = cell_alloc_coherent;
pci_dma_ops.free_coherent = cell_free_coherent;
pci_dma_ops.map_single = cell_map_single;
pci_dma_ops.unmap_single = cell_unmap_single;
pci_dma_ops.map_sg = cell_map_sg;
pci_dma_ops.unmap_sg = cell_unmap_sg;
pci_dma_ops.dma_supported = cell_dma_supported;
}

View File

@ -1,5 +1,5 @@
#ifndef BPA_IOMMU_H
#define BPA_IOMMU_H
#ifndef CELL_IOMMU_H
#define CELL_IOMMU_H
/* some constants */
enum {
@ -55,11 +55,11 @@ enum {
/* The high bit needs to be set on every DMA address,
only 2GB are addressable */
BPA_DMA_VALID = 0x80000000,
BPA_DMA_MASK = 0x7fffffff,
CELL_DMA_VALID = 0x80000000,
CELL_DMA_MASK = 0x7fffffff,
};
void bpa_init_iommu(void);
void cell_init_iommu(void);
#endif

View File

@ -1,11 +1,11 @@
/*
* linux/arch/ppc/kernel/bpa_setup.c
* linux/arch/powerpc/platforms/cell/cell_setup.c
*
* Copyright (C) 1995 Linus Torvalds
* Adapted from 'alpha' version by Gary Thomas
* Modified by Cort Dougan (cort@cs.nmt.edu)
* Modified by PPC64 Team, IBM Corp
* Modified by BPA Team, IBM Deutschland Entwicklung GmbH
* Modified by Cell Team, IBM Deutschland Entwicklung GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -46,8 +46,8 @@
#include <asm/ppc-pci.h>
#include <asm/irq.h>
#include "bpa_iic.h"
#include "bpa_iommu.h"
#include "interrupt.h"
#include "iommu.h"
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@ -55,7 +55,7 @@
#define DBG(fmt...)
#endif
void bpa_show_cpuinfo(struct seq_file *m)
void cell_show_cpuinfo(struct seq_file *m)
{
struct device_node *root;
const char *model = "";
@ -63,22 +63,22 @@ void bpa_show_cpuinfo(struct seq_file *m)
root = of_find_node_by_path("/");
if (root)
model = get_property(root, "model", NULL);
seq_printf(m, "machine\t\t: BPA %s\n", model);
seq_printf(m, "machine\t\t: CHRP %s\n", model);
of_node_put(root);
}
static void bpa_progress(char *s, unsigned short hex)
static void cell_progress(char *s, unsigned short hex)
{
printk("*** %04x : %s\n", hex, s ? s : "");
}
static void __init bpa_setup_arch(void)
static void __init cell_setup_arch(void)
{
ppc_md.init_IRQ = iic_init_IRQ;
ppc_md.get_irq = iic_get_irq;
#ifdef CONFIG_SMP
smp_init_pSeries();
smp_init_cell();
#endif
/* init to some ~sane value until calibrate_delay() runs */
@ -97,39 +97,39 @@ static void __init bpa_setup_arch(void)
conswitchp = &dummy_con;
#endif
bpa_nvram_init();
mmio_nvram_init();
}
/*
* Early initialization. Relocation is on but do not reference unbolted pages
*/
static void __init bpa_init_early(void)
static void __init cell_init_early(void)
{
DBG(" -> bpa_init_early()\n");
DBG(" -> cell_init_early()\n");
hpte_init_native();
bpa_init_iommu();
cell_init_iommu();
ppc64_interrupt_controller = IC_BPA_IIC;
ppc64_interrupt_controller = IC_CELL_PIC;
DBG(" <- bpa_init_early()\n");
DBG(" <- cell_init_early()\n");
}
static int __init bpa_probe(int platform)
static int __init cell_probe(int platform)
{
if (platform != PLATFORM_BPA)
if (platform != PLATFORM_CELL)
return 0;
return 1;
}
struct machdep_calls __initdata bpa_md = {
.probe = bpa_probe,
.setup_arch = bpa_setup_arch,
.init_early = bpa_init_early,
.show_cpuinfo = bpa_show_cpuinfo,
struct machdep_calls __initdata cell_md = {
.probe = cell_probe,
.setup_arch = cell_setup_arch,
.init_early = cell_init_early,
.show_cpuinfo = cell_show_cpuinfo,
.restart = rtas_restart,
.power_off = rtas_power_off,
.halt = rtas_halt,
@ -137,5 +137,5 @@ struct machdep_calls __initdata bpa_md = {
.get_rtc_time = rtas_get_rtc_time,
.set_rtc_time = rtas_set_rtc_time,
.calibrate_decr = generic_calibrate_decr,
.progress = bpa_progress,
.progress = cell_progress,
};

View File

@ -0,0 +1,230 @@
/*
* SMP support for BPA machines.
*
* Dave Engebretsen, Peter Bergner, and
* Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
*
* Plus various changes from other IBM teams...
*
* 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/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/cache.h>
#include <linux/err.h>
#include <linux/sysdev.h>
#include <linux/cpu.h>
#include <asm/ptrace.h>
#include <asm/atomic.h>
#include <asm/irq.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/smp.h>
#include <asm/paca.h>
#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/cputable.h>
#include <asm/firmware.h>
#include <asm/system.h>
#include <asm/rtas.h>
#include "interrupt.h"
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
#else
#define DBG(fmt...)
#endif
/*
* The primary thread of each non-boot processor is recorded here before
* smp init.
*/
static cpumask_t of_spin_map;
extern void pSeries_secondary_smp_init(unsigned long);
/**
* smp_startup_cpu() - start the given cpu
*
* At boot time, there is nothing to do for primary threads which were
* started from Open Firmware. For anything else, call RTAS with the
* appropriate start location.
*
* Returns:
* 0 - failure
* 1 - success
*/
static inline int __devinit smp_startup_cpu(unsigned int lcpu)
{
int status;
unsigned long start_here = __pa((u32)*((unsigned long *)
pSeries_secondary_smp_init));
unsigned int pcpu;
int start_cpu;
if (cpu_isset(lcpu, of_spin_map))
/* Already started by OF and sitting in spin loop */
return 1;
pcpu = get_hard_smp_processor_id(lcpu);
/* Fixup atomic count: it exited inside IRQ handler. */
paca[lcpu].__current->thread_info->preempt_count = 0;
/*
* If the RTAS start-cpu token does not exist then presume the
* cpu is already spinning.
*/
start_cpu = rtas_token("start-cpu");
if (start_cpu == RTAS_UNKNOWN_SERVICE)
return 1;
status = rtas_call(start_cpu, 3, 1, NULL, pcpu, start_here, lcpu);
if (status != 0) {
printk(KERN_ERR "start-cpu failed: %i\n", status);
return 0;
}
return 1;
}
static void smp_iic_message_pass(int target, int msg)
{
unsigned int i;
if (target < NR_CPUS) {
iic_cause_IPI(target, msg);
} else {
for_each_online_cpu(i) {
if (target == MSG_ALL_BUT_SELF
&& i == smp_processor_id())
continue;
iic_cause_IPI(i, msg);
}
}
}
static int __init smp_iic_probe(void)
{
iic_request_IPIs();
return cpus_weight(cpu_possible_map);
}
static void __devinit smp_iic_setup_cpu(int cpu)
{
if (cpu != boot_cpuid)
iic_setup_cpu();
}
static DEFINE_SPINLOCK(timebase_lock);
static unsigned long timebase = 0;
static void __devinit cell_give_timebase(void)
{
spin_lock(&timebase_lock);
rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
timebase = get_tb();
spin_unlock(&timebase_lock);
while (timebase)
barrier();
rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
}
static void __devinit cell_take_timebase(void)
{
while (!timebase)
barrier();
spin_lock(&timebase_lock);
set_tb(timebase >> 32, timebase & 0xffffffff);
timebase = 0;
spin_unlock(&timebase_lock);
}
static void __devinit smp_cell_kick_cpu(int nr)
{
BUG_ON(nr < 0 || nr >= NR_CPUS);
if (!smp_startup_cpu(nr))
return;
/*
* The processor is currently spinning, waiting for the
* cpu_start field to become non-zero After we set cpu_start,
* the processor will continue on to secondary_start
*/
paca[nr].cpu_start = 1;
}
static int smp_cell_cpu_bootable(unsigned int nr)
{
/* Special case - we inhibit secondary thread startup
* during boot if the user requests it. Odd-numbered
* cpus are assumed to be secondary threads.
*/
if (system_state < SYSTEM_RUNNING &&
cpu_has_feature(CPU_FTR_SMT) &&
!smt_enabled_at_boot && nr % 2 != 0)
return 0;
return 1;
}
static struct smp_ops_t bpa_iic_smp_ops = {
.message_pass = smp_iic_message_pass,
.probe = smp_iic_probe,
.kick_cpu = smp_cell_kick_cpu,
.setup_cpu = smp_iic_setup_cpu,
.cpu_bootable = smp_cell_cpu_bootable,
};
/* This is called very early */
void __init smp_init_cell(void)
{
int i;
DBG(" -> smp_init_cell()\n");
smp_ops = &bpa_iic_smp_ops;
/* Mark threads which are still spinning in hold loops. */
if (cpu_has_feature(CPU_FTR_SMT)) {
for_each_present_cpu(i) {
if (i % 2 == 0)
/*
* Even-numbered logical cpus correspond to
* primary threads.
*/
cpu_set(i, of_spin_map);
}
} else {
of_spin_map = cpu_present_map;
}
cpu_clear(boot_cpuid, of_spin_map);
/* Non-lpar has additional take/give timebase */
if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) {
smp_ops->give_timebase = cell_give_timebase;
smp_ops->take_timebase = cell_take_timebase;
}
DBG(" <- smp_init_cell()\n");
}

View File

@ -27,7 +27,7 @@
#include <asm/prom.h>
#include <asm/io.h>
#include "bpa_iic.h"
#include "interrupt.h"
/* register layout taken from Spider spec, table 7.4-4 */
enum {

View File

@ -17,6 +17,7 @@
#include <asm/uaccess.h>
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/rtas.h>
#include "chrp.h"
static unsigned int nvram_size;
@ -25,7 +26,8 @@ static DEFINE_SPINLOCK(nvram_lock);
static unsigned char chrp_nvram_read(int addr)
{
unsigned long done, flags;
unsigned int done;
unsigned long flags;
unsigned char ret;
if (addr >= nvram_size) {
@ -34,7 +36,8 @@ static unsigned char chrp_nvram_read(int addr)
return 0xff;
}
spin_lock_irqsave(&nvram_lock, flags);
if ((call_rtas("nvram-fetch", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done)
if ((rtas_call(rtas_token("nvram-fetch"), 3, 2, &done, addr,
__pa(nvram_buf), 1) != 0) || 1 != done)
ret = 0xff;
else
ret = nvram_buf[0];
@ -45,7 +48,8 @@ static unsigned char chrp_nvram_read(int addr)
static void chrp_nvram_write(int addr, unsigned char val)
{
unsigned long done, flags;
unsigned int done;
unsigned long flags;
if (addr >= nvram_size) {
printk(KERN_DEBUG "%s: write addr %d > nvram_size %u\n",
@ -54,7 +58,8 @@ static void chrp_nvram_write(int addr, unsigned char val)
}
spin_lock_irqsave(&nvram_lock, flags);
nvram_buf[0] = val;
if ((call_rtas("nvram-store", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done)
if ((rtas_call(rtas_token("nvram-store"), 3, 2, &done, addr,
__pa(nvram_buf), 1) != 0) || 1 != done)
printk(KERN_DEBUG "rtas IO error storing 0x%02x at %d", val, addr);
spin_unlock_irqrestore(&nvram_lock, flags);
}

View File

@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/mv643xx.h>
#include <linux/pci.h>

View File

@ -35,43 +35,6 @@
#include <asm/smp.h>
#include <asm/mpic.h>
extern unsigned long smp_chrp_cpu_nr;
static int __init smp_chrp_probe(void)
{
struct device_node *cpus = NULL;
unsigned int *reg;
int reglen;
int ncpus = 0;
int cpuid;
unsigned int phys;
/* Count CPUs in the device-tree */
cpuid = 1; /* the boot cpu is logical cpu 0 */
while ((cpus = of_find_node_by_type(cpus, "cpu")) != NULL) {
phys = ncpus;
reg = (unsigned int *) get_property(cpus, "reg", &reglen);
if (reg && reglen >= sizeof(unsigned int))
/* hmmm, not having a reg property would be bad */
phys = *reg;
if (phys != boot_cpuid_phys) {
set_hard_smp_processor_id(cpuid, phys);
++cpuid;
}
++ncpus;
}
printk(KERN_INFO "CHRP SMP probe found %d cpus\n", ncpus);
/* Nothing more to do if less than 2 of them */
if (ncpus <= 1)
return 1;
mpic_request_ipis();
return ncpus;
}
static void __devinit smp_chrp_kick_cpu(int nr)
{
*(unsigned long *)KERNELBASE = nr;
@ -114,7 +77,7 @@ void __devinit smp_chrp_take_timebase(void)
/* CHRP with openpic */
struct smp_ops_t chrp_smp_ops = {
.message_pass = smp_mpic_message_pass,
.probe = smp_chrp_probe,
.probe = smp_mpic_probe,
.kick_cpu = smp_chrp_kick_cpu,
.setup_cpu = smp_chrp_setup_cpu,
.give_timebase = smp_chrp_give_timebase,

View File

@ -23,8 +23,8 @@
* drive the hypervisor from the OS.
*/
#include <asm/iSeries/HvCallSc.h>
#include <asm/iSeries/HvTypes.h>
#include <asm/iseries/hv_call_sc.h>
#include <asm/iseries/hv_types.h>
#include <asm/mmu.h>
#define HvCallHptGetHptAddress HvCallHpt + 0

View File

@ -25,8 +25,8 @@
#ifndef _PLATFORMS_ISERIES_CALL_PCI_H
#define _PLATFORMS_ISERIES_CALL_PCI_H
#include <asm/iSeries/HvCallSc.h>
#include <asm/iSeries/HvTypes.h>
#include <asm/iseries/hv_call_sc.h>
#include <asm/iseries/hv_types.h>
/*
* DSA == Direct Select Address

View File

@ -23,8 +23,8 @@
* drive the hypervisor from the OS.
*/
#include <asm/iSeries/HvCallSc.h>
#include <asm/iSeries/HvTypes.h>
#include <asm/iseries/hv_call_sc.h>
#include <asm/iseries/hv_types.h>
#define HvCallSmGet64BitsOfAccessMap HvCallSm + 11

View File

@ -39,15 +39,16 @@ static inline void iSeries_hunlock(unsigned long slot)
spin_unlock(&iSeries_hlocks[(slot >> 4) & 0x3f]);
}
static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
unsigned long prpn, unsigned long vflags,
unsigned long rflags)
long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
unsigned long pa, unsigned long rflags,
unsigned long vflags, int psize)
{
unsigned long arpn;
long slot;
hpte_t lhpte;
int secondary = 0;
BUG_ON(psize != MMU_PAGE_4K);
/*
* The hypervisor tries both primary and secondary.
* If we are being called to insert in the secondary,
@ -59,8 +60,19 @@ static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
iSeries_hlock(hpte_group);
slot = HvCallHpt_findValid(&lhpte, va >> PAGE_SHIFT);
BUG_ON(lhpte.v & HPTE_V_VALID);
slot = HvCallHpt_findValid(&lhpte, va >> HW_PAGE_SHIFT);
if (unlikely(lhpte.v & HPTE_V_VALID)) {
if (vflags & HPTE_V_BOLTED) {
HvCallHpt_setSwBits(slot, 0x10, 0);
HvCallHpt_setPp(slot, PP_RWXX);
iSeries_hunlock(hpte_group);
if (slot < 0)
return 0x8 | (slot & 7);
else
return slot & 7;
}
BUG();
}
if (slot == -1) { /* No available entry found in either group */
iSeries_hunlock(hpte_group);
@ -73,10 +85,9 @@ static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
slot &= 0x7fffffffffffffff;
}
arpn = phys_to_abs(prpn << PAGE_SHIFT) >> PAGE_SHIFT;
lhpte.v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID;
lhpte.r = (arpn << HPTE_R_RPN_SHIFT) | rflags;
lhpte.v = hpte_encode_v(va, MMU_PAGE_4K) | vflags | HPTE_V_VALID;
lhpte.r = hpte_encode_r(phys_to_abs(pa), MMU_PAGE_4K) | rflags;
/* Now fill in the actual HPTE */
HvCallHpt_addValidate(slot, secondary, &lhpte);
@ -86,25 +97,6 @@ static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
return (secondary << 3) | (slot & 7);
}
long iSeries_hpte_bolt_or_insert(unsigned long hpte_group,
unsigned long va, unsigned long prpn, unsigned long vflags,
unsigned long rflags)
{
long slot;
hpte_t lhpte;
slot = HvCallHpt_findValid(&lhpte, va >> PAGE_SHIFT);
if (lhpte.v & HPTE_V_VALID) {
/* Bolt the existing HPTE */
HvCallHpt_setSwBits(slot, 0x10, 0);
HvCallHpt_setPp(slot, PP_RWXX);
return 0;
}
return iSeries_hpte_insert(hpte_group, va, prpn, vflags, rflags);
}
static unsigned long iSeries_hpte_getword0(unsigned long slot)
{
hpte_t hpte;
@ -150,15 +142,17 @@ static long iSeries_hpte_remove(unsigned long hpte_group)
* bits 61..63 : PP2,PP1,PP0
*/
static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
unsigned long va, int large, int local)
unsigned long va, int psize, int local)
{
hpte_t hpte;
unsigned long avpn = va >> 23;
unsigned long want_v;
iSeries_hlock(slot);
HvCallHpt_get(&hpte, slot);
if ((HPTE_V_AVPN_VAL(hpte.v) == avpn) && (hpte.v & HPTE_V_VALID)) {
want_v = hpte_encode_v(va, MMU_PAGE_4K);
if (HPTE_V_COMPARE(hpte.v, want_v) && (hpte.v & HPTE_V_VALID)) {
/*
* Hypervisor expects bits as NPPP, which is
* different from how they are mapped in our PP.
@ -210,14 +204,17 @@ static long iSeries_hpte_find(unsigned long vpn)
*
* No need to lock here because we should be the only user.
*/
static void iSeries_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
static void iSeries_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
int psize)
{
unsigned long vsid,va,vpn;
long slot;
BUG_ON(psize != MMU_PAGE_4K);
vsid = get_kernel_vsid(ea);
va = (vsid << 28) | (ea & 0x0fffffff);
vpn = va >> PAGE_SHIFT;
vpn = va >> HW_PAGE_SHIFT;
slot = iSeries_hpte_find(vpn);
if (slot == -1)
panic("updateboltedpp: Could not find page to bolt\n");
@ -225,7 +222,7 @@ static void iSeries_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
}
static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va,
int large, int local)
int psize, int local)
{
unsigned long hpte_v;
unsigned long avpn = va >> 23;

View File

@ -9,9 +9,9 @@
#include <asm/page.h>
#include <asm/abs_addr.h>
#include <asm/iSeries/HvCall.h>
#include <asm/iSeries/HvCallSc.h>
#include <asm/iSeries/HvTypes.h>
#include <asm/iseries/hv_call.h>
#include <asm/iseries/hv_call_sc.h>
#include <asm/iseries/hv_types.h>
void HvCall_writeLogBuffer(const void *buffer, u64 len)
@ -22,7 +22,7 @@ void HvCall_writeLogBuffer(const void *buffer, u64 len)
while (len) {
hv_buf.addr = cur;
left_this_page = ((cur & PAGE_MASK) + PAGE_SIZE) - cur;
left_this_page = ((cur & HW_PAGE_MASK) + HW_PAGE_SIZE) - cur;
if (left_this_page > len)
left_this_page = len;
hv_buf.len = left_this_page;
@ -30,6 +30,6 @@ void HvCall_writeLogBuffer(const void *buffer, u64 len)
HvCall2(HvCallBaseWriteLogBuffer,
virt_to_abs(&hv_buf),
left_this_page);
cur = (cur & PAGE_MASK) + PAGE_SIZE;
cur = (cur & HW_PAGE_MASK) + HW_PAGE_SIZE;
}
}

View File

@ -17,7 +17,7 @@
*/
#include <linux/module.h>
#include <asm/iSeries/HvLpConfig.h>
#include <asm/iseries/hv_lp_config.h>
HvLpIndex HvLpConfig_getLpIndex_outline(void)
{

Some files were not shown because too many files have changed in this diff Show More