2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-16 17:23:55 +08:00

Merge linux-2.6 into linux-acpi-2.6 test

This commit is contained in:
Len Brown 2005-09-03 02:44:09 -04:00
commit 129521dcc9
1031 changed files with 98947 additions and 17551 deletions

View File

@ -135,3 +135,15 @@ Why: With the 16-bit PCMCIA subsystem now behaving (almost) like a
pcmciautils package available at
http://kernel.org/pub/linux/utils/kernel/pcmcia/
Who: Dominik Brodowski <linux@brodo.de>
---------------------------
What: ip_queue and ip6_queue (old ipv4-only and ipv6-only netfilter queue)
When: December 2005
Why: This interface has been obsoleted by the new layer3-independent
"nfnetlink_queue". The Kernel interface is compatible, so the old
ip[6]tables "QUEUE" targets still work and will transparently handle
all packets into nfnetlink queue number 0. Userspace users will have
to link against API-compatible library on top of libnfnetlink_queue
instead of the current 'libipq'.
Who: Harald Welte <laforge@netfilter.org>

View File

@ -0,0 +1,246 @@
===========================
Intel(R) PRO/Wireless 2100 Network Connection Driver for Linux
README.ipw2100
March 14, 2005
===========================
Index
---------------------------
0. Introduction
1. Release 1.1.0 Current Features
2. Command Line Parameters
3. Sysfs Helper Files
4. Radio Kill Switch
5. Dynamic Firmware
6. Power Management
7. Support
8. License
===========================
0. Introduction
------------ ----- ----- ---- --- -- -
This document provides a brief overview of the features supported by the
IPW2100 driver project. The main project website, where the latest
development version of the driver can be found, is:
http://ipw2100.sourceforge.net
There you can find the not only the latest releases, but also information about
potential fixes and patches, as well as links to the development mailing list
for the driver project.
===========================
1. Release 1.1.0 Current Supported Features
---------------------------
- Managed (BSS) and Ad-Hoc (IBSS)
- WEP (shared key and open)
- Wireless Tools support
- 802.1x (tested with XSupplicant 1.0.1)
Enabled (but not supported) features:
- Monitor/RFMon mode
- WPA/WPA2
The distinction between officially supported and enabled is a reflection
on the amount of validation and interoperability testing that has been
performed on a given feature.
===========================
2. Command Line Parameters
---------------------------
If the driver is built as a module, the following optional parameters are used
by entering them on the command line with the modprobe command using this
syntax:
modprobe ipw2100 [<option>=<VAL1><,VAL2>...]
For example, to disable the radio on driver loading, enter:
modprobe ipw2100 disable=1
The ipw2100 driver supports the following module parameters:
Name Value Example:
debug 0x0-0xffffffff debug=1024
mode 0,1,2 mode=1 /* AdHoc */
channel int channel=3 /* Only valid in AdHoc or Monitor */
associate boolean associate=0 /* Do NOT auto associate */
disable boolean disable=1 /* Do not power the HW */
===========================
3. Sysfs Helper Files
---------------------------
There are several ways to control the behavior of the driver. Many of the
general capabilities are exposed through the Wireless Tools (iwconfig). There
are a few capabilities that are exposed through entries in the Linux Sysfs.
----- Driver Level ------
For the driver level files, look in /sys/bus/pci/drivers/ipw2100/
debug_level
This controls the same global as the 'debug' module parameter. For
information on the various debugging levels available, run the 'dvals'
script found in the driver source directory.
NOTE: 'debug_level' is only enabled if CONFIG_IPW2100_DEBUG is turn
on.
----- Device Level ------
For the device level files look in
/sys/bus/pci/drivers/ipw2100/{PCI-ID}/
For example:
/sys/bus/pci/drivers/ipw2100/0000:02:01.0
For the device level files, see /sys/bus/pci/drivers/ipw2100:
rf_kill
read -
0 = RF kill not enabled (radio on)
1 = SW based RF kill active (radio off)
2 = HW based RF kill active (radio off)
3 = Both HW and SW RF kill active (radio off)
write -
0 = If SW based RF kill active, turn the radio back on
1 = If radio is on, activate SW based RF kill
NOTE: If you enable the SW based RF kill and then toggle the HW
based RF kill from ON -> OFF -> ON, the radio will NOT come back on
===========================
4. Radio Kill Switch
---------------------------
Most laptops provide the ability for the user to physically disable the radio.
Some vendors have implemented this as a physical switch that requires no
software to turn the radio off and on. On other laptops, however, the switch
is controlled through a button being pressed and a software driver then making
calls to turn the radio off and on. This is referred to as a "software based
RF kill switch"
See the Sysfs helper file 'rf_kill' for determining the state of the RF switch
on your system.
===========================
5. Dynamic Firmware
---------------------------
As the firmware is licensed under a restricted use license, it can not be
included within the kernel sources. To enable the IPW2100 you will need a
firmware image to load into the wireless NIC's processors.
You can obtain these images from <http://ipw2100.sf.net/firmware.php>.
See INSTALL for instructions on installing the firmware.
===========================
6. Power Management
---------------------------
The IPW2100 supports the configuration of the Power Save Protocol
through a private wireless extension interface. The IPW2100 supports
the following different modes:
off No power management. Radio is always on.
on Automatic power management
1-5 Different levels of power management. The higher the
number the greater the power savings, but with an impact to
packet latencies.
Power management works by powering down the radio after a certain
interval of time has passed where no packets are passed through the
radio. Once powered down, the radio remains in that state for a given
period of time. For higher power savings, the interval between last
packet processed to sleep is shorter and the sleep period is longer.
When the radio is asleep, the access point sending data to the station
must buffer packets at the AP until the station wakes up and requests
any buffered packets. If you have an AP that does not correctly support
the PSP protocol you may experience packet loss or very poor performance
while power management is enabled. If this is the case, you will need
to try and find a firmware update for your AP, or disable power
management (via `iwconfig eth1 power off`)
To configure the power level on the IPW2100 you use a combination of
iwconfig and iwpriv. iwconfig is used to turn power management on, off,
and set it to auto.
iwconfig eth1 power off Disables radio power down
iwconfig eth1 power on Enables radio power management to
last set level (defaults to AUTO)
iwpriv eth1 set_power 0 Sets power level to AUTO and enables
power management if not previously
enabled.
iwpriv eth1 set_power 1-5 Set the power level as specified,
enabling power management if not
previously enabled.
You can view the current power level setting via:
iwpriv eth1 get_power
It will return the current period or timeout that is configured as a string
in the form of xxxx/yyyy (z) where xxxx is the timeout interval (amount of
time after packet processing), yyyy is the period to sleep (amount of time to
wait before powering the radio and querying the access point for buffered
packets), and z is the 'power level'. If power management is turned off the
xxxx/yyyy will be replaced with 'off' -- the level reported will be the active
level if `iwconfig eth1 power on` is invoked.
===========================
7. Support
---------------------------
For general development information and support,
go to:
http://ipw2100.sf.net/
The ipw2100 1.1.0 driver and firmware can be downloaded from:
http://support.intel.com
For installation support on the ipw2100 1.1.0 driver on Linux kernels
2.6.8 or greater, email support is available from:
http://supportmail.intel.com
===========================
8. License
---------------------------
Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
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.
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.
The full GNU General Public License is included in this distribution in the
file called LICENSE.
License Contact Information:
James P. Ketrenos <ipw2100-admin@linux.intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497

View File

@ -0,0 +1,300 @@
Intel(R) PRO/Wireless 2915ABG Driver for Linux in support of:
Intel(R) PRO/Wireless 2200BG Network Connection
Intel(R) PRO/Wireless 2915ABG Network Connection
Note: The Intel(R) PRO/Wireless 2915ABG Driver for Linux and Intel(R)
PRO/Wireless 2200BG Driver for Linux is a unified driver that works on
both hardware adapters listed above. In this document the Intel(R)
PRO/Wireless 2915ABG Driver for Linux will be used to reference the
unified driver.
Copyright (C) 2004-2005, Intel Corporation
README.ipw2200
Version: 1.0.0
Date : January 31, 2005
Index
-----------------------------------------------
1. Introduction
1.1. Overview of features
1.2. Module parameters
1.3. Wireless Extension Private Methods
1.4. Sysfs Helper Files
2. About the Version Numbers
3. Support
4. License
1. Introduction
-----------------------------------------------
The following sections attempt to provide a brief introduction to using
the Intel(R) PRO/Wireless 2915ABG Driver for Linux.
This document is not meant to be a comprehensive manual on
understanding or using wireless technologies, but should be sufficient
to get you moving without wires on Linux.
For information on building and installing the driver, see the INSTALL
file.
1.1. Overview of Features
-----------------------------------------------
The current release (1.0.0) supports the following features:
+ BSS mode (Infrastructure, Managed)
+ IBSS mode (Ad-Hoc)
+ WEP (OPEN and SHARED KEY mode)
+ 802.1x EAP via wpa_supplicant and xsupplicant
+ Wireless Extension support
+ Full B and G rate support (2200 and 2915)
+ Full A rate support (2915 only)
+ Transmit power control
+ S state support (ACPI suspend/resume)
+ long/short preamble support
1.2. Command Line Parameters
-----------------------------------------------
Like many modules used in the Linux kernel, the Intel(R) PRO/Wireless
2915ABG Driver for Linux allows certain configuration options to be
provided as module parameters. The most common way to specify a module
parameter is via the command line.
The general form is:
% modprobe ipw2200 parameter=value
Where the supported parameter are:
associate
Set to 0 to disable the auto scan-and-associate functionality of the
driver. If disabled, the driver will not attempt to scan
for and associate to a network until it has been configured with
one or more properties for the target network, for example configuring
the network SSID. Default is 1 (auto-associate)
Example: % modprobe ipw2200 associate=0
auto_create
Set to 0 to disable the auto creation of an Ad-Hoc network
matching the channel and network name parameters provided.
Default is 1.
channel
channel number for association. The normal method for setting
the channel would be to use the standard wireless tools
(i.e. `iwconfig eth1 channel 10`), but it is useful sometimes
to set this while debugging. Channel 0 means 'ANY'
debug
If using a debug build, this is used to control the amount of debug
info is logged. See the 'dval' and 'load' script for more info on
how to use this (the dval and load scripts are provided as part
of the ipw2200 development snapshot releases available from the
SourceForge project at http://ipw2200.sf.net)
mode
Can be used to set the default mode of the adapter.
0 = Managed, 1 = Ad-Hoc
1.3. Wireless Extension Private Methods
-----------------------------------------------
As an interface designed to handle generic hardware, there are certain
capabilities not exposed through the normal Wireless Tool interface. As
such, a provision is provided for a driver to declare custom, or
private, methods. The Intel(R) PRO/Wireless 2915ABG Driver for Linux
defines several of these to configure various settings.
The general form of using the private wireless methods is:
% iwpriv $IFNAME method parameters
Where $IFNAME is the interface name the device is registered with
(typically eth1, customized via one of the various network interface
name managers, such as ifrename)
The supported private methods are:
get_mode
Can be used to report out which IEEE mode the driver is
configured to support. Example:
% iwpriv eth1 get_mode
eth1 get_mode:802.11bg (6)
set_mode
Can be used to configure which IEEE mode the driver will
support.
Usage:
% iwpriv eth1 set_mode {mode}
Where {mode} is a number in the range 1-7:
1 802.11a (2915 only)
2 802.11b
3 802.11ab (2915 only)
4 802.11g
5 802.11ag (2915 only)
6 802.11bg
7 802.11abg (2915 only)
get_preamble
Can be used to report configuration of preamble length.
set_preamble
Can be used to set the configuration of preamble length:
Usage:
% iwpriv eth1 set_preamble {mode}
Where {mode} is one of:
1 Long preamble only
0 Auto (long or short based on connection)
1.4. Sysfs Helper Files:
-----------------------------------------------
The Linux kernel provides a pseudo file system that can be used to
access various components of the operating system. The Intel(R)
PRO/Wireless 2915ABG Driver for Linux exposes several configuration
parameters through this mechanism.
An entry in the sysfs can support reading and/or writing. You can
typically query the contents of a sysfs entry through the use of cat,
and can set the contents via echo. For example:
% cat /sys/bus/pci/drivers/ipw2200/debug_level
Will report the current debug level of the driver's logging subsystem
(only available if CONFIG_IPW_DEBUG was configured when the driver was
built).
You can set the debug level via:
% echo $VALUE > /sys/bus/pci/drivers/ipw2200/debug_level
Where $VALUE would be a number in the case of this sysfs entry. The
input to sysfs files does not have to be a number. For example, the
firmware loader used by hotplug utilizes sysfs entries for transferring
the firmware image from user space into the driver.
The Intel(R) PRO/Wireless 2915ABG Driver for Linux exposes sysfs entries
at two levels -- driver level, which apply to all instances of the
driver (in the event that there are more than one device installed) and
device level, which applies only to the single specific instance.
1.4.1 Driver Level Sysfs Helper Files
-----------------------------------------------
For the driver level files, look in /sys/bus/pci/drivers/ipw2200/
debug_level
This controls the same global as the 'debug' module parameter
1.4.2 Device Level Sysfs Helper Files
-----------------------------------------------
For the device level files, look in
/sys/bus/pci/drivers/ipw2200/{PCI-ID}/
For example:
/sys/bus/pci/drivers/ipw2200/0000:02:01.0
For the device level files, see /sys/bus/pci/[drivers/ipw2200:
rf_kill
read -
0 = RF kill not enabled (radio on)
1 = SW based RF kill active (radio off)
2 = HW based RF kill active (radio off)
3 = Both HW and SW RF kill active (radio off)
write -
0 = If SW based RF kill active, turn the radio back on
1 = If radio is on, activate SW based RF kill
NOTE: If you enable the SW based RF kill and then toggle the HW
based RF kill from ON -> OFF -> ON, the radio will NOT come back on
ucode
read-only access to the ucode version number
2. About the Version Numbers
-----------------------------------------------
Due to the nature of open source development projects, there are
frequently changes being incorporated that have not gone through
a complete validation process. These changes are incorporated into
development snapshot releases.
Releases are numbered with a three level scheme:
major.minor.development
Any version where the 'development' portion is 0 (for example
1.0.0, 1.1.0, etc.) indicates a stable version that will be made
available for kernel inclusion.
Any version where the 'development' portion is not a 0 (for
example 1.0.1, 1.1.5, etc.) indicates a development version that is
being made available for testing and cutting edge users. The stability
and functionality of the development releases are not know. We make
efforts to try and keep all snapshots reasonably stable, but due to the
frequency of their release, and the desire to get those releases
available as quickly as possible, unknown anomalies should be expected.
The major version number will be incremented when significant changes
are made to the driver. Currently, there are no major changes planned.
3. Support
-----------------------------------------------
For installation support of the 1.0.0 version, you can contact
http://supportmail.intel.com, or you can use the open source project
support.
For general information and support, go to:
http://ipw2200.sf.net/
4. License
-----------------------------------------------
Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
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.
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.
The full GNU General Public License is included in this distribution in the
file called LICENSE.
Contact Information:
James P. Ketrenos <ipw2100-admin@linux.intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497

View File

@ -0,0 +1,352 @@
Chelsio N210 10Gb Ethernet Network Controller
Driver Release Notes for Linux
Version 2.1.1
June 20, 2005
CONTENTS
========
INTRODUCTION
FEATURES
PERFORMANCE
DRIVER MESSAGES
KNOWN ISSUES
SUPPORT
INTRODUCTION
============
This document describes the Linux driver for Chelsio 10Gb Ethernet Network
Controller. This driver supports the Chelsio N210 NIC and is backward
compatible with the Chelsio N110 model 10Gb NICs.
FEATURES
========
Adaptive Interrupts (adaptive-rx)
---------------------------------
This feature provides an adaptive algorithm that adjusts the interrupt
coalescing parameters, allowing the driver to dynamically adapt the latency
settings to achieve the highest performance during various types of network
load.
The interface used to control this feature is ethtool. Please see the
ethtool manpage for additional usage information.
By default, adaptive-rx is disabled.
To enable adaptive-rx:
ethtool -C <interface> adaptive-rx on
To disable adaptive-rx, use ethtool:
ethtool -C <interface> adaptive-rx off
After disabling adaptive-rx, the timer latency value will be set to 50us.
You may set the timer latency after disabling adaptive-rx:
ethtool -C <interface> rx-usecs <microseconds>
An example to set the timer latency value to 100us on eth0:
ethtool -C eth0 rx-usecs 100
You may also provide a timer latency value while disabling adpative-rx:
ethtool -C <interface> adaptive-rx off rx-usecs <microseconds>
If adaptive-rx is disabled and a timer latency value is specified, the timer
will be set to the specified value until changed by the user or until
adaptive-rx is enabled.
To view the status of the adaptive-rx and timer latency values:
ethtool -c <interface>
TCP Segmentation Offloading (TSO) Support
-----------------------------------------
This feature, also known as "large send", enables a system's protocol stack
to offload portions of outbound TCP processing to a network interface card
thereby reducing system CPU utilization and enhancing performance.
The interface used to control this feature is ethtool version 1.8 or higher.
Please see the ethtool manpage for additional usage information.
By default, TSO is enabled.
To disable TSO:
ethtool -K <interface> tso off
To enable TSO:
ethtool -K <interface> tso on
To view the status of TSO:
ethtool -k <interface>
PERFORMANCE
===========
The following information is provided as an example of how to change system
parameters for "performance tuning" an what value to use. You may or may not
want to change these system parameters, depending on your server/workstation
application. Doing so is not warranted in any way by Chelsio Communications,
and is done at "YOUR OWN RISK". Chelsio will not be held responsible for loss
of data or damage to equipment.
Your distribution may have a different way of doing things, or you may prefer
a different method. These commands are shown only to provide an example of
what to do and are by no means definitive.
Making any of the following system changes will only last until you reboot
your system. You may want to write a script that runs at boot-up which
includes the optimal settings for your system.
Setting PCI Latency Timer:
setpci -d 1425:* 0x0c.l=0x0000F800
Disabling TCP timestamp:
sysctl -w net.ipv4.tcp_timestamps=0
Disabling SACK:
sysctl -w net.ipv4.tcp_sack=0
Setting large number of incoming connection requests:
sysctl -w net.ipv4.tcp_max_syn_backlog=3000
Setting maximum receive socket buffer size:
sysctl -w net.core.rmem_max=1024000
Setting maximum send socket buffer size:
sysctl -w net.core.wmem_max=1024000
Set smp_affinity (on a multiprocessor system) to a single CPU:
echo 1 > /proc/irq/<interrupt_number>/smp_affinity
Setting default receive socket buffer size:
sysctl -w net.core.rmem_default=524287
Setting default send socket buffer size:
sysctl -w net.core.wmem_default=524287
Setting maximum option memory buffers:
sysctl -w net.core.optmem_max=524287
Setting maximum backlog (# of unprocessed packets before kernel drops):
sysctl -w net.core.netdev_max_backlog=300000
Setting TCP read buffers (min/default/max):
sysctl -w net.ipv4.tcp_rmem="10000000 10000000 10000000"
Setting TCP write buffers (min/pressure/max):
sysctl -w net.ipv4.tcp_wmem="10000000 10000000 10000000"
Setting TCP buffer space (min/pressure/max):
sysctl -w net.ipv4.tcp_mem="10000000 10000000 10000000"
TCP window size for single connections:
The receive buffer (RX_WINDOW) size must be at least as large as the
Bandwidth-Delay Product of the communication link between the sender and
receiver. Due to the variations of RTT, you may want to increase the buffer
size up to 2 times the Bandwidth-Delay Product. Reference page 289 of
"TCP/IP Illustrated, Volume 1, The Protocols" by W. Richard Stevens.
At 10Gb speeds, use the following formula:
RX_WINDOW >= 1.25MBytes * RTT(in milliseconds)
Example for RTT with 100us: RX_WINDOW = (1,250,000 * 0.1) = 125,000
RX_WINDOW sizes of 256KB - 512KB should be sufficient.
Setting the min, max, and default receive buffer (RX_WINDOW) size:
sysctl -w net.ipv4.tcp_rmem="<min> <default> <max>"
TCP window size for multiple connections:
The receive buffer (RX_WINDOW) size may be calculated the same as single
connections, but should be divided by the number of connections. The
smaller window prevents congestion and facilitates better pacing,
especially if/when MAC level flow control does not work well or when it is
not supported on the machine. Experimentation may be necessary to attain
the correct value. This method is provided as a starting point fot the
correct receive buffer size.
Setting the min, max, and default receive buffer (RX_WINDOW) size is
performed in the same manner as single connection.
DRIVER MESSAGES
===============
The following messages are the most common messages logged by syslog. These
may be found in /var/log/messages.
Driver up:
Chelsio Network Driver - version 2.1.1
NIC detected:
eth#: Chelsio N210 1x10GBaseX NIC (rev #), PCIX 133MHz/64-bit
Link up:
eth#: link is up at 10 Gbps, full duplex
Link down:
eth#: link is down
KNOWN ISSUES
============
These issues have been identified during testing. The following information
is provided as a workaround to the problem. In some cases, this problem is
inherent to Linux or to a particular Linux Distribution and/or hardware
platform.
1. Large number of TCP retransmits on a multiprocessor (SMP) system.
On a system with multiple CPUs, the interrupt (IRQ) for the network
controller may be bound to more than one CPU. This will cause TCP
retransmits if the packet data were to be split across different CPUs
and re-assembled in a different order than expected.
To eliminate the TCP retransmits, set smp_affinity on the particular
interrupt to a single CPU. You can locate the interrupt (IRQ) used on
the N110/N210 by using ifconfig:
ifconfig <dev_name> | grep Interrupt
Set the smp_affinity to a single CPU:
echo 1 > /proc/irq/<interrupt_number>/smp_affinity
It is highly suggested that you do not run the irqbalance daemon on your
system, as this will change any smp_affinity setting you have applied.
The irqbalance daemon runs on a 10 second interval and binds interrupts
to the least loaded CPU determined by the daemon. To disable this daemon:
chkconfig --level 2345 irqbalance off
By default, some Linux distributions enable the kernel feature,
irqbalance, which performs the same function as the daemon. To disable
this feature, add the following line to your bootloader:
noirqbalance
Example using the Grub bootloader:
title Red Hat Enterprise Linux AS (2.4.21-27.ELsmp)
root (hd0,0)
kernel /vmlinuz-2.4.21-27.ELsmp ro root=/dev/hda3 noirqbalance
initrd /initrd-2.4.21-27.ELsmp.img
2. After running insmod, the driver is loaded and the incorrect network
interface is brought up without running ifup.
When using 2.4.x kernels, including RHEL kernels, the Linux kernel
invokes a script named "hotplug". This script is primarily used to
automatically bring up USB devices when they are plugged in, however,
the script also attempts to automatically bring up a network interface
after loading the kernel module. The hotplug script does this by scanning
the ifcfg-eth# config files in /etc/sysconfig/network-scripts, looking
for HWADDR=<mac_address>.
If the hotplug script does not find the HWADDRR within any of the
ifcfg-eth# files, it will bring up the device with the next available
interface name. If this interface is already configured for a different
network card, your new interface will have incorrect IP address and
network settings.
To solve this issue, you can add the HWADDR=<mac_address> key to the
interface config file of your network controller.
To disable this "hotplug" feature, you may add the driver (module name)
to the "blacklist" file located in /etc/hotplug. It has been noted that
this does not work for network devices because the net.agent script
does not use the blacklist file. Simply remove, or rename, the net.agent
script located in /etc/hotplug to disable this feature.
3. Transport Protocol (TP) hangs when running heavy multi-connection traffic
on an AMD Opteron system with HyperTransport PCI-X Tunnel chipset.
If your AMD Opteron system uses the AMD-8131 HyperTransport PCI-X Tunnel
chipset, you may experience the "133-Mhz Mode Split Completion Data
Corruption" bug identified by AMD while using a 133Mhz PCI-X card on the
bus PCI-X bus.
AMD states, "Under highly specific conditions, the AMD-8131 PCI-X Tunnel
can provide stale data via split completion cycles to a PCI-X card that
is operating at 133 Mhz", causing data corruption.
AMD's provides three workarounds for this problem, however, Chelsio
recommends the first option for best performance with this bug:
For 133Mhz secondary bus operation, limit the transaction length and
the number of outstanding transactions, via BIOS configuration
programming of the PCI-X card, to the following:
Data Length (bytes): 1k
Total allowed outstanding transactions: 2
Please refer to AMD 8131-HT/PCI-X Errata 26310 Rev 3.08 August 2004,
section 56, "133-MHz Mode Split Completion Data Corruption" for more
details with this bug and workarounds suggested by AMD.
It may be possible to work outside AMD's recommended PCI-X settings, try
increasing the Data Length to 2k bytes for increased performance. If you
have issues with these settings, please revert to the "safe" settings
and duplicate the problem before submitting a bug or asking for support.
NOTE: The default setting on most systems is 8 outstanding transactions
and 2k bytes data length.
4. On multiprocessor systems, it has been noted that an application which
is handling 10Gb networking can switch between CPUs causing degraded
and/or unstable performance.
If running on an SMP system and taking performance measurements, it
is suggested you either run the latest netperf-2.4.0+ or use a binding
tool such as Tim Hockin's procstate utilities (runon)
<http://www.hockin.org/~thockin/procstate/>.
Binding netserver and netperf (or other applications) to particular
CPUs will have a significant difference in performance measurements.
You may need to experiment which CPU to bind the application to in
order to achieve the best performance for your system.
If you are developing an application designed for 10Gb networking,
please keep in mind you may want to look at kernel functions
sched_setaffinity & sched_getaffinity to bind your application.
If you are just running user-space applications such as ftp, telnet,
etc., you may want to try the runon tool provided by Tim Hockin's
procstate utility. You could also try binding the interface to a
particular CPU: runon 0 ifup eth0
SUPPORT
=======
If you have problems with the software or hardware, please contact our
customer support team via email at support@chelsio.com or check our website
at http://www.chelsio.com
===============================================================================
Chelsio Communications
370 San Aleso Ave.
Suite 100
Sunnyvale, CA 94085
http://www.chelsio.com
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.
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.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
Copyright (c) 2003-2005 Chelsio Communications. All rights reserved.
===============================================================================

View File

@ -111,24 +111,17 @@ hardware.
Interrupts: locally disabled.
This call must not sleep
stop_tx(port,tty_stop)
stop_tx(port)
Stop transmitting characters. This might be due to the CTS
line becoming inactive or the tty layer indicating we want
to stop transmission.
tty_stop: 1 if this call is due to the TTY layer issuing a
TTY stop to the driver (equiv to rs_stop).
to stop transmission due to an XOFF character.
Locking: port->lock taken.
Interrupts: locally disabled.
This call must not sleep
start_tx(port,tty_start)
start transmitting characters. (incidentally, nonempty will
always be nonzero, and shouldn't be used - it will be dropped).
tty_start: 1 if this call was due to the TTY layer issuing
a TTY start to the driver (equiv to rs_start)
start_tx(port)
start transmitting characters.
Locking: port->lock taken.
Interrupts: locally disabled.

View File

@ -132,6 +132,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
mpu_irq - IRQ # for MPU-401 UART (PnP setup)
dma1 - first DMA # for AD1816A chip (PnP setup)
dma2 - second DMA # for AD1816A chip (PnP setup)
clockfreq - Clock frequency for AD1816A chip (default = 0, 33000Hz)
Module supports up to 8 cards, autoprobe and PnP.

View File

@ -3422,10 +3422,17 @@ struct _snd_pcm_runtime {
<para>
The <structfield>iface</structfield> field specifies the type of
the control,
<constant>SNDRV_CTL_ELEM_IFACE_XXX</constant>. There are
<constant>MIXER</constant>, <constant>PCM</constant>,
<constant>CARD</constant>, etc.
the control, <constant>SNDRV_CTL_ELEM_IFACE_XXX</constant>, which
is usually <constant>MIXER</constant>.
Use <constant>CARD</constant> for global controls that are not
logically part of the mixer.
If the control is closely associated with some specific device on
the sound card, use <constant>HWDEP</constant>,
<constant>PCM</constant>, <constant>RAWMIDI</constant>,
<constant>TIMER</constant>, or <constant>SEQUENCER</constant>, and
specify the device number with the
<structfield>device</structfield> and
<structfield>subdevice</structfield> fields.
</para>
<para>

View File

@ -991,6 +991,13 @@ M: mike.miller@hp.com
L: iss_storagedev@hp.com
S: Supported
HOST AP DRIVER
P: Jouni Malinen
M: jkmaline@cc.hut.fi
L: hostap@shmoo.com
W: http://hostap.epitest.fi/
S: Maintained
HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series
P: Jaroslav Kysela
M: perex@suse.cz
@ -2092,6 +2099,12 @@ M: support@simtec.co.uk
W: http://www.simtec.co.uk/products/EB2410ITX/
S: Supported
SIS 190 ETHERNET DRIVER
P: Francois Romieu
M: romieu@fr.zoreil.com
L: netdev@vger.kernel.org
S: Maintained
SIS 5513 IDE CONTROLLER DRIVER
P: Lionel Bouton
M: Lionel.Bouton@inet6.fr
@ -2637,11 +2650,6 @@ S: Maintained
UCLINUX (AND M68KNOMMU)
P: Greg Ungerer
M: gerg@uclinux.org
M: gerg@snapgear.com
P: David McCullough
M: davidm@snapgear.com
P: D. Jeff Dionne (created first uClinux port)
M: jeff@uclinux.org
W: http://www.uclinux.org/
L: uclinux-dev@uclinux.org (subscribers-only)
S: Maintained

View File

@ -365,8 +365,8 @@ config NO_IDLE_HZ
Please note that dynamic tick may affect the accuracy of
timekeeping on some platforms depending on the implementation.
Currently at least OMAP platform is known to have accurate
timekeeping with dynamic tick.
Currently at least OMAP, PXA2xx and SA11x0 platforms are known
to have accurate timekeeping with dynamic tick.
config ARCH_DISCONTIGMEM_ENABLE
bool

View File

@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/smp.h>
#include <linux/cpumask.h>
#include <asm/irq.h>
#include <asm/io.h>

View File

@ -284,7 +284,7 @@ __syscall_start:
.long sys_fstatfs64
.long sys_tgkill
.long sys_utimes
/* 270 */ .long sys_fadvise64_64
/* 270 */ .long sys_arm_fadvise64_64_wrapper
.long sys_pciconfig_iobase
.long sys_pciconfig_read
.long sys_pciconfig_write

View File

@ -265,6 +265,10 @@ sys_futex_wrapper:
str r5, [sp, #4] @ push sixth arg
b sys_futex
sys_arm_fadvise64_64_wrapper:
str r5, [sp, #4] @ push r5 to stack
b sys_arm_fadvise64_64
/*
* Note: off_4k (r5) is always units of 4K. If we can't do the requested
* offset, we return EINVAL.

View File

@ -311,3 +311,13 @@ long execve(const char *filename, char **argv, char **envp)
return ret;
}
EXPORT_SYMBOL(execve);
/*
* Since loff_t is a 64 bit type we avoid a lot of ABI hastle
* with a different argument ordering.
*/
asmlinkage long sys_arm_fadvise64_64(int fd, int advice,
loff_t offset, loff_t len)
{
return sys_fadvise64_64(fd, offset, len, advice);
}

View File

@ -433,10 +433,12 @@ void timer_dyn_reprogram(void)
{
struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
if (dyn_tick) {
write_seqlock(&xtime_lock);
if (dyn_tick->state & DYN_TICK_ENABLED)
dyn_tick->reprogram(next_timer_interrupt() - jiffies);
write_sequnlock(&xtime_lock);
}
}
static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf)

View File

@ -38,90 +38,6 @@
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
enum ixp4xx_irq_type {
IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE
};
static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type);
/*************************************************************************
* GPIO acces functions
*************************************************************************/
/*
* Configure GPIO line for input, interrupt, or output operation
*
* TODO: Enable/disable the irq_desc based on interrupt or output mode.
* TODO: Should these be named ixp4xx_gpio_?
*/
void gpio_line_config(u8 line, u32 style)
{
static const int gpio2irq[] = {
6, 7, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
};
u32 enable;
volatile u32 *int_reg;
u32 int_style;
enum ixp4xx_irq_type irq_type;
enable = *IXP4XX_GPIO_GPOER;
if (style & IXP4XX_GPIO_OUT) {
enable &= ~((1) << line);
} else if (style & IXP4XX_GPIO_IN) {
enable |= ((1) << line);
switch (style & IXP4XX_GPIO_INTSTYLE_MASK)
{
case (IXP4XX_GPIO_ACTIVE_HIGH):
int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH;
irq_type = IXP4XX_IRQ_LEVEL;
break;
case (IXP4XX_GPIO_ACTIVE_LOW):
int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW;
irq_type = IXP4XX_IRQ_LEVEL;
break;
case (IXP4XX_GPIO_RISING_EDGE):
int_style = IXP4XX_GPIO_STYLE_RISING_EDGE;
irq_type = IXP4XX_IRQ_EDGE;
break;
case (IXP4XX_GPIO_FALLING_EDGE):
int_style = IXP4XX_GPIO_STYLE_FALLING_EDGE;
irq_type = IXP4XX_IRQ_EDGE;
break;
case (IXP4XX_GPIO_TRANSITIONAL):
int_style = IXP4XX_GPIO_STYLE_TRANSITIONAL;
irq_type = IXP4XX_IRQ_EDGE;
break;
default:
int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH;
irq_type = IXP4XX_IRQ_LEVEL;
break;
}
if (style & IXP4XX_GPIO_INTSTYLE_MASK)
ixp4xx_config_irq(gpio2irq[line], irq_type);
if (line >= 8) { /* pins 8-15 */
line -= 8;
int_reg = IXP4XX_GPIO_GPIT2R;
}
else { /* pins 0-7 */
int_reg = IXP4XX_GPIO_GPIT1R;
}
/* Clear the style for the appropriate pin */
*int_reg &= ~(IXP4XX_GPIO_STYLE_CLEAR <<
(line * IXP4XX_GPIO_STYLE_SIZE));
/* Set the new style */
*int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE));
}
*IXP4XX_GPIO_GPOER = enable;
}
EXPORT_SYMBOL(gpio_line_config);
/*************************************************************************
* IXP4xx chipset I/O mapping
*************************************************************************/
@ -165,6 +81,69 @@ void __init ixp4xx_map_io(void)
* (be it PCI or something else) configures that GPIO line
* as an IRQ.
**************************************************************************/
enum ixp4xx_irq_type {
IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE
};
static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type);
/*
* IRQ -> GPIO mapping table
*/
static int irq2gpio[32] = {
-1, -1, -1, -1, -1, -1, 0, 1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, -1, -1,
};
static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
{
int line = irq2gpio[irq];
u32 int_style;
enum ixp4xx_irq_type irq_type;
volatile u32 *int_reg;
/*
* Only for GPIO IRQs
*/
if (line < 0)
return -EINVAL;
if (type & IRQT_BOTHEDGE) {
int_style = IXP4XX_GPIO_STYLE_TRANSITIONAL;
irq_type = IXP4XX_IRQ_EDGE;
} else if (type & IRQT_RISING) {
int_style = IXP4XX_GPIO_STYLE_RISING_EDGE;
irq_type = IXP4XX_IRQ_EDGE;
} else if (type & IRQT_FALLING) {
int_style = IXP4XX_GPIO_STYLE_FALLING_EDGE;
irq_type = IXP4XX_IRQ_EDGE;
} else if (type & IRQT_HIGH) {
int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH;
irq_type = IXP4XX_IRQ_LEVEL;
} else if (type & IRQT_LOW) {
int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW;
irq_type = IXP4XX_IRQ_LEVEL;
}
ixp4xx_config_irq(irq, irq_type);
if (line >= 8) { /* pins 8-15 */
line -= 8;
int_reg = IXP4XX_GPIO_GPIT2R;
} else { /* pins 0-7 */
int_reg = IXP4XX_GPIO_GPIT1R;
}
/* Clear the style for the appropriate pin */
*int_reg &= ~(IXP4XX_GPIO_STYLE_CLEAR <<
(line * IXP4XX_GPIO_STYLE_SIZE));
/* Set the new style */
*int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE));
}
static void ixp4xx_irq_mask(unsigned int irq)
{
if (cpu_is_ixp46x() && irq >= 32)
@ -183,12 +162,6 @@ static void ixp4xx_irq_unmask(unsigned int irq)
static void ixp4xx_irq_ack(unsigned int irq)
{
static int irq2gpio[32] = {
-1, -1, -1, -1, -1, -1, 0, 1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, -1, -1,
};
int line = (irq < 32) ? irq2gpio[irq] : -1;
if (line >= 0)
@ -209,12 +182,14 @@ static struct irqchip ixp4xx_irq_level_chip = {
.ack = ixp4xx_irq_mask,
.mask = ixp4xx_irq_mask,
.unmask = ixp4xx_irq_level_unmask,
.type = ixp4xx_set_irq_type
};
static struct irqchip ixp4xx_irq_edge_chip = {
.ack = ixp4xx_irq_ack,
.mask = ixp4xx_irq_mask,
.unmask = ixp4xx_irq_unmask,
.type = ixp4xx_set_irq_type
};
static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type)

View File

@ -30,11 +30,8 @@ extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
void __init coyote_pci_preinit(void)
{
gpio_line_config(COYOTE_PCI_SLOT0_PIN,
IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
gpio_line_config(COYOTE_PCI_SLOT1_PIN,
IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
set_irq_type(IRQ_COYOTE_PCI_SLOT0, IRQT_LOW);
set_irq_type(IRQ_COYOTE_PCI_SLOT1, IRQT_LOW);
gpio_line_isr_clear(COYOTE_PCI_SLOT0_PIN);
gpio_line_isr_clear(COYOTE_PCI_SLOT1_PIN);

View File

@ -24,11 +24,6 @@
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
void __init coyote_map_io(void)
{
ixp4xx_map_io();
}
static struct flash_platform_data coyote_flash_data = {
.map_name = "cfi_probe",
.width = 2,
@ -107,7 +102,7 @@ MACHINE_START(ADI_COYOTE, "ADI Engineering Coyote")
.phys_ram = PHYS_OFFSET,
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = coyote_map_io,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
.boot_params = 0x0100,
@ -125,7 +120,7 @@ MACHINE_START(IXDPG425, "Intel IXDPG425")
.phys_ram = PHYS_OFFSET,
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = coyote_map_io,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
.boot_params = 0x0100,

View File

@ -35,26 +35,20 @@ extern void ixp4xx_pci_preinit(void);
extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
/*
/*
* The exact GPIO pins and IRQs are defined in arch-ixp4xx/gtwx5715.h
* Slot 0 isn't actually populated with a card connector but
* we initialize it anyway in case a future version has the
* slot populated or someone with good soldering skills has
* some free time.
*/
static void gtwx5715_init_gpio(u8 pin, u32 style)
{
gpio_line_config(pin, style | IXP4XX_GPIO_ACTIVE_LOW);
if (style & IXP4XX_GPIO_IN) gpio_line_isr_clear(pin);
}
void __init gtwx5715_pci_preinit(void)
{
gtwx5715_init_gpio(GTWX5715_PCI_SLOT0_INTA_GPIO, IXP4XX_GPIO_IN);
gtwx5715_init_gpio(GTWX5715_PCI_SLOT1_INTA_GPIO, IXP4XX_GPIO_IN);
set_irq_type(GTWX5715_PCI_SLOT0_INTA_IRQ, IRQT_LOW);
set_irq_type(GTWX5715_PCI_SLOT0_INTB_IRQ, IRQT_LOW);
set_irq_type(GTWX5715_PCI_SLOT1_INTA_IRQ, IRQT_LOW);
set_irq_type(GTWX5715_PCI_SLOT1_INTB_IRQ, IRQT_LOW);
ixp4xx_pci_preinit();
}

View File

@ -101,12 +101,6 @@ static struct platform_device gtwx5715_uart_device = {
.resource = gtwx5715_uart_resources,
};
void __init gtwx5715_map_io(void)
{
ixp4xx_map_io();
}
static struct flash_platform_data gtwx5715_flash_data = {
.map_name = "cfi_probe",
.width = 2,
@ -144,7 +138,7 @@ MACHINE_START(GTWX5715, "Gemtek GTWX5715 (Linksys WRV54G)")
.phys_ram = PHYS_OFFSET,
.phys_io = IXP4XX_UART2_BASE_PHYS,
.io_pg_offst = ((IXP4XX_UART2_BASE_VIRT) >> 18) & 0xfffc,
.map_io = gtwx5715_map_io,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
.boot_params = 0x0100,

View File

@ -27,14 +27,10 @@
void __init ixdp425_pci_preinit(void)
{
gpio_line_config(IXDP425_PCI_INTA_PIN,
IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
gpio_line_config(IXDP425_PCI_INTB_PIN,
IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
gpio_line_config(IXDP425_PCI_INTC_PIN,
IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
gpio_line_config(IXDP425_PCI_INTD_PIN,
IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
set_irq_type(IRQ_IXDP425_PCI_INTA, IRQT_LOW);
set_irq_type(IRQ_IXDP425_PCI_INTB, IRQT_LOW);
set_irq_type(IRQ_IXDP425_PCI_INTC, IRQT_LOW);
set_irq_type(IRQ_IXDP425_PCI_INTD, IRQT_LOW);
gpio_line_isr_clear(IXDP425_PCI_INTA_PIN);
gpio_line_isr_clear(IXDP425_PCI_INTB_PIN);

View File

@ -24,11 +24,6 @@
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
void __init ixdp425_map_io(void)
{
ixp4xx_map_io();
}
static struct flash_platform_data ixdp425_flash_data = {
.map_name = "cfi_probe",
.width = 2,
@ -133,7 +128,7 @@ MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
.phys_ram = PHYS_OFFSET,
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixdp425_map_io,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
.boot_params = 0x0100,
@ -145,7 +140,7 @@ MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
.phys_ram = PHYS_OFFSET,
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixdp425_map_io,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
.boot_params = 0x0100,
@ -157,7 +152,7 @@ MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
.phys_ram = PHYS_OFFSET,
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixdp425_map_io,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
.boot_params = 0x0100,
@ -176,7 +171,7 @@ MACHINE_START(AVILA, "Gateworks Avila Network Platform")
.phys_ram = PHYS_OFFSET,
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixdp425_map_io,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
.boot_params = 0x0100,

View File

@ -29,8 +29,8 @@ extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
void __init ixdpg425_pci_preinit(void)
{
gpio_line_config(6, IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
gpio_line_config(7, IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
set_irq_type(IRQ_IXP4XX_GPIO6, IRQT_LOW);
set_irq_type(IRQ_IXP4XX_GPIO7, IRQT_LOW);
gpio_line_isr_clear(6);
gpio_line_isr_clear(7);

View File

@ -70,6 +70,11 @@ static unsigned long pxa_gettimeoffset (void)
return usec;
}
#ifdef CONFIG_NO_IDLE_HZ
static unsigned long initial_match;
static int match_posponed;
#endif
static irqreturn_t
pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
@ -77,11 +82,19 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
write_seqlock(&xtime_lock);
#ifdef CONFIG_NO_IDLE_HZ
if (match_posponed) {
match_posponed = 0;
OSMR0 = initial_match;
}
#endif
/* Loop until we get ahead of the free running timer.
* This ensures an exact clock tick count and time accuracy.
* IRQs are disabled inside the loop to ensure coherence between
* lost_ticks (updated in do_timer()) and the match reg value, so we
* can use do_gettimeofday() from interrupt handlers.
* Since IRQs are disabled at this point, coherence between
* lost_ticks(updated in do_timer()) and the match reg value is
* ensured, hence we can use do_gettimeofday() from interrupt
* handlers.
*
* HACK ALERT: it seems that the PXA timer regs aren't updated right
* away in all cases when a write occurs. We therefore compare with
@ -126,6 +139,42 @@ static void __init pxa_timer_init(void)
OSCR = 0; /* initialize free-running timer, force first match */
}
#ifdef CONFIG_NO_IDLE_HZ
static int pxa_dyn_tick_enable_disable(void)
{
/* nothing to do */
return 0;
}
static void pxa_dyn_tick_reprogram(unsigned long ticks)
{
if (ticks > 1) {
initial_match = OSMR0;
OSMR0 = initial_match + ticks * LATCH;
match_posponed = 1;
}
}
static irqreturn_t
pxa_dyn_tick_handler(int irq, void *dev_id, struct pt_regs *regs)
{
if (match_posponed) {
match_posponed = 0;
OSMR0 = initial_match;
if ( (signed long)(initial_match - OSCR) <= 8 )
return pxa_timer_interrupt(irq, dev_id, regs);
}
return IRQ_NONE;
}
static struct dyn_tick_timer pxa_dyn_tick = {
.enable = pxa_dyn_tick_enable_disable,
.disable = pxa_dyn_tick_enable_disable,
.reprogram = pxa_dyn_tick_reprogram,
.handler = pxa_dyn_tick_handler,
};
#endif
#ifdef CONFIG_PM
static unsigned long osmr[4], oier;
@ -161,4 +210,7 @@ struct sys_timer pxa_timer = {
.suspend = pxa_timer_suspend,
.resume = pxa_timer_resume,
.offset = pxa_gettimeoffset,
#ifdef CONFIG_NO_IDLE_HZ
.dyn_tick = &pxa_dyn_tick,
#endif
};

View File

@ -388,6 +388,7 @@ int __init s3c24xx_setup_clocks(unsigned long xtal,
unsigned long hclk,
unsigned long pclk)
{
unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
struct clk *clkp = init_clocks;
int ptr;
int ret;
@ -446,5 +447,13 @@ int __init s3c24xx_setup_clocks(unsigned long xtal,
}
}
/* show the clock-slow value */
printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",
print_mhz(xtal / ( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),
(clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",
(clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
(clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
return 0;
}

View File

@ -68,6 +68,7 @@ static struct clk s3c2440_clk_ac97 = {
static int s3c2440_clk_add(struct sys_device *sysdev)
{
unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
struct clk *clk_h;
struct clk *clk_p;
struct clk *clk_xtal;
@ -80,8 +81,9 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal->rate);
printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n",
print_mhz(s3c2440_clk_upll.rate));
printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz, DVS %s\n",
print_mhz(s3c2440_clk_upll.rate),
(camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
clk_p = clk_get(NULL, "pclk");
clk_h = clk_get(NULL, "hclk");

View File

@ -70,15 +70,11 @@ static unsigned long sa1100_gettimeoffset (void)
return usec;
}
/*
* We will be entered with IRQs enabled.
*
* Loop until we get ahead of the free running timer.
* This ensures an exact clock tick count and time accuracy.
* IRQs are disabled inside the loop to ensure coherence between
* lost_ticks (updated in do_timer()) and the match reg value, so we
* can use do_gettimeofday() from interrupt handlers.
*/
#ifdef CONFIG_NO_IDLE_HZ
static unsigned long initial_match;
static int match_posponed;
#endif
static irqreturn_t
sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
@ -86,6 +82,21 @@ sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
write_seqlock(&xtime_lock);
#ifdef CONFIG_NO_IDLE_HZ
if (match_posponed) {
match_posponed = 0;
OSMR0 = initial_match;
}
#endif
/*
* Loop until we get ahead of the free running timer.
* This ensures an exact clock tick count and time accuracy.
* Since IRQs are disabled at this point, coherence between
* lost_ticks(updated in do_timer()) and the match reg value is
* ensured, hence we can use do_gettimeofday() from interrupt
* handlers.
*/
do {
timer_tick(regs);
OSSR = OSSR_M0; /* Clear match on timer 0 */
@ -120,6 +131,42 @@ static void __init sa1100_timer_init(void)
OSCR = 0; /* initialize free-running timer, force first match */
}
#ifdef CONFIG_NO_IDLE_HZ
static int sa1100_dyn_tick_enable_disable(void)
{
/* nothing to do */
return 0;
}
static void sa1100_dyn_tick_reprogram(unsigned long ticks)
{
if (ticks > 1) {
initial_match = OSMR0;
OSMR0 = initial_match + ticks * LATCH;
match_posponed = 1;
}
}
static irqreturn_t
sa1100_dyn_tick_handler(int irq, void *dev_id, struct pt_regs *regs)
{
if (match_posponed) {
match_posponed = 0;
OSMR0 = initial_match;
if ((signed long)(initial_match - OSCR) <= 0)
return sa1100_timer_interrupt(irq, dev_id, regs);
}
return IRQ_NONE;
}
static struct dyn_tick_timer sa1100_dyn_tick = {
.enable = sa1100_dyn_tick_enable_disable,
.disable = sa1100_dyn_tick_enable_disable,
.reprogram = sa1100_dyn_tick_reprogram,
.handler = sa1100_dyn_tick_handler,
};
#endif
#ifdef CONFIG_PM
unsigned long osmr[4], oier;
@ -156,4 +203,7 @@ struct sys_timer sa1100_timer = {
.suspend = sa1100_timer_suspend,
.resume = sa1100_timer_resume,
.offset = sa1100_gettimeoffset,
#ifdef CONFIG_NO_IDLE_HZ
.dyn_tick = &sa1100_dyn_tick,
#endif
};

View File

@ -45,7 +45,7 @@
#define LDST_P_EQ_U(i) ((((i) ^ ((i) >> 1)) & (1 << 23)) == 0)
#define LDSTH_I_BIT(i) (i & (1 << 22)) /* half-word immed */
#define LDSTHD_I_BIT(i) (i & (1 << 22)) /* double/half-word immed */
#define LDM_S_BIT(i) (i & (1 << 22)) /* write CPSR from SPSR */
#define RN_BITS(i) ((i >> 16) & 15) /* Rn */
@ -68,6 +68,7 @@ static unsigned long ai_sys;
static unsigned long ai_skipped;
static unsigned long ai_half;
static unsigned long ai_word;
static unsigned long ai_dword;
static unsigned long ai_multi;
static int ai_usermode;
@ -93,6 +94,8 @@ proc_alignment_read(char *page, char **start, off_t off, int count, int *eof,
p += sprintf(p, "Skipped:\t%lu\n", ai_skipped);
p += sprintf(p, "Half:\t\t%lu\n", ai_half);
p += sprintf(p, "Word:\t\t%lu\n", ai_word);
if (cpu_architecture() >= CPU_ARCH_ARMv5TE)
p += sprintf(p, "DWord:\t\t%lu\n", ai_dword);
p += sprintf(p, "Multi:\t\t%lu\n", ai_multi);
p += sprintf(p, "User faults:\t%i (%s)\n", ai_usermode,
usermode_action[ai_usermode]);
@ -283,12 +286,6 @@ do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *r
{
unsigned int rd = RD_BITS(instr);
if ((instr & 0x01f00ff0) == 0x01000090)
goto swp;
if ((instr & 0x90) != 0x90 || (instr & 0x60) == 0)
goto bad;
ai_half += 1;
if (user_mode(regs))
@ -323,10 +320,47 @@ do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *r
return TYPE_LDST;
swp:
printk(KERN_ERR "Alignment trap: not handling swp instruction\n");
bad:
return TYPE_ERROR;
fault:
return TYPE_FAULT;
}
static int
do_alignment_ldrdstrd(unsigned long addr, unsigned long instr,
struct pt_regs *regs)
{
unsigned int rd = RD_BITS(instr);
ai_dword += 1;
if (user_mode(regs))
goto user;
if ((instr & 0xf0) == 0xd0) {
unsigned long val;
get32_unaligned_check(val, addr);
regs->uregs[rd] = val;
get32_unaligned_check(val, addr+4);
regs->uregs[rd+1] = val;
} else {
put32_unaligned_check(regs->uregs[rd], addr);
put32_unaligned_check(regs->uregs[rd+1], addr+4);
}
return TYPE_LDST;
user:
if ((instr & 0xf0) == 0xd0) {
unsigned long val;
get32t_unaligned_check(val, addr);
regs->uregs[rd] = val;
get32t_unaligned_check(val, addr+4);
regs->uregs[rd+1] = val;
} else {
put32t_unaligned_check(regs->uregs[rd], addr);
put32t_unaligned_check(regs->uregs[rd+1], addr+4);
}
return TYPE_LDST;
fault:
return TYPE_FAULT;
@ -617,12 +651,20 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
regs->ARM_pc += thumb_mode(regs) ? 2 : 4;
switch (CODING_BITS(instr)) {
case 0x00000000: /* ldrh or strh */
if (LDSTH_I_BIT(instr))
case 0x00000000: /* 3.13.4 load/store instruction extensions */
if (LDSTHD_I_BIT(instr))
offset.un = (instr & 0xf00) >> 4 | (instr & 15);
else
offset.un = regs->uregs[RM_BITS(instr)];
if ((instr & 0x000000f0) == 0x000000b0 || /* LDRH, STRH */
(instr & 0x001000f0) == 0x001000f0) /* LDRSH */
handler = do_alignment_ldrhstrh;
else if ((instr & 0x001000f0) == 0x000000d0 || /* LDRD */
(instr & 0x001000f0) == 0x000000f0) /* STRD */
handler = do_alignment_ldrdstrd;
else
goto bad;
break;
case 0x04000000: /* ldr or str immediate */

View File

@ -275,11 +275,9 @@ alloc_init_supersection(unsigned long virt, unsigned long phys, int prot)
int i;
for (i = 0; i < 16; i += 1) {
alloc_init_section(virt, phys & SUPERSECTION_MASK,
prot | PMD_SECT_SUPER);
alloc_init_section(virt, phys, prot | PMD_SECT_SUPER);
virt += (PGDIR_SIZE / 2);
phys += (PGDIR_SIZE / 2);
}
}
@ -297,14 +295,10 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg
pte_t *ptep;
if (pmd_none(*pmdp)) {
unsigned long pmdval;
ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
sizeof(pte_t));
pmdval = __pa(ptep) | prot_l1;
pmdp[0] = __pmd(pmdval);
pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
flush_pmd_entry(pmdp);
__pmd_populate(pmdp, __pa(ptep) | prot_l1);
}
ptep = pte_offset_kernel(pmdp, virt);
@ -459,7 +453,7 @@ static void __init build_mem_type_table(void)
for (i = 0; i < 16; i++) {
unsigned long v = pgprot_val(protection_map[i]);
v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot;
v = (v & ~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot;
protection_map[i] = __pgprot(v);
}
@ -583,23 +577,23 @@ static void __init create_mapping(struct map_desc *md)
*/
void setup_mm_for_reboot(char mode)
{
unsigned long pmdval;
unsigned long base_pmdval;
pgd_t *pgd;
pmd_t *pmd;
int i;
int cpu_arch = cpu_architecture();
if (current->mm && current->mm->pgd)
pgd = current->mm->pgd;
else
pgd = init_mm.pgd;
for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++) {
pmdval = (i << PGDIR_SHIFT) |
PMD_SECT_AP_WRITE | PMD_SECT_AP_READ |
PMD_TYPE_SECT;
if (cpu_arch <= CPU_ARCH_ARMv5TEJ)
pmdval |= PMD_BIT4;
base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ)
base_pmdval |= PMD_BIT4;
for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++, pgd++) {
unsigned long pmdval = (i << PGDIR_SHIFT) | base_pmdval;
pmd_t *pmd;
pmd = pmd_off(pgd, i << PGDIR_SHIFT);
pmd[0] = __pmd(pmdval);
pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));

View File

@ -165,7 +165,6 @@ static int __init pcibios_init(void)
if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
pcibios_sort();
#endif
pci_assign_unassigned_resources();
return 0;
}

View File

@ -170,43 +170,26 @@ static void __init pcibios_allocate_resources(int pass)
static int __init pcibios_assign_resources(void)
{
struct pci_dev *dev = NULL;
int idx;
struct resource *r;
struct resource *r, *pr;
if (!(pci_probe & PCI_ASSIGN_ROMS)) {
/* Try to use BIOS settings for ROMs, otherwise let
pci_assign_unassigned_resources() allocate the new
addresses. */
for_each_pci_dev(dev) {
int class = dev->class >> 8;
/* Don't touch classless devices and host bridges */
if (!class || class == PCI_CLASS_BRIDGE_HOST)
continue;
for(idx=0; idx<6; idx++) {
r = &dev->resource[idx];
/*
* Don't touch IDE controllers and I/O ports of video cards!
*/
if ((class == PCI_CLASS_STORAGE_IDE && idx < 4) ||
(class == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO)))
continue;
/*
* We shall assign a new address to this resource, either because
* the BIOS forgot to do so or because we have decided the old
* address was unusable for some reason.
*/
if (!r->start && r->end)
pci_assign_resource(dev, idx);
}
if (pci_probe & PCI_ASSIGN_ROMS) {
r = &dev->resource[PCI_ROM_RESOURCE];
if (!r->flags || !r->start)
continue;
pr = pci_find_parent_resource(dev, r);
if (!pr || request_resource(pr, r) < 0) {
r->end -= r->start;
r->start = 0;
if (r->end)
pci_assign_resource(dev, PCI_ROM_RESOURCE);
}
}
}
pci_assign_unassigned_resources();
return 0;
}

View File

@ -357,6 +357,12 @@ source "kernel/power/Kconfig"
source "drivers/acpi/Kconfig"
if PM
source "arch/ia64/kernel/cpufreq/Kconfig"
endif
endmenu
if !IA64_HP_SIM

View File

@ -237,17 +237,6 @@ sal_emulator (long index, unsigned long in1, unsigned long in2,
return ((struct sal_ret_values) {status, r9, r10, r11});
}
/*
* This is here to work around a bug in egcs-1.1.1b that causes the
* compiler to crash (seems like a bug in the new alias analysis code.
*/
void *
id (long addr)
{
return (void *) addr;
}
struct ia64_boot_param *
sys_fw_init (const char *args, int arglen)
{

View File

@ -29,7 +29,6 @@
#include <asm/uaccess.h>
#include <asm/rse.h>
#include <asm/sigcontext.h>
#include <asm/segment.h>
#include "ia32priv.h"

View File

@ -20,6 +20,7 @@ obj-$(CONFIG_SMP) += smp.o smpboot.o domain.o
obj-$(CONFIG_NUMA) += numa.o
obj-$(CONFIG_PERFMON) += perfmon_default_smpl.o
obj-$(CONFIG_IA64_CYCLONE) += cyclone.o
obj-$(CONFIG_CPU_FREQ) += cpufreq/
obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o
obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o
obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o

View File

@ -0,0 +1,29 @@
#
# CPU Frequency scaling
#
menu "CPU Frequency scaling"
source "drivers/cpufreq/Kconfig"
if CPU_FREQ
comment "CPUFreq processor drivers"
config IA64_ACPI_CPUFREQ
tristate "ACPI Processor P-States driver"
select CPU_FREQ_TABLE
depends on ACPI_PROCESSOR
help
This driver adds a CPUFreq driver which utilizes the ACPI
Processor Performance States.
For details, take a look at <file:Documentation/cpu-freq/>.
If in doubt, say N.
endif # CPU_FREQ
endmenu

View File

@ -0,0 +1 @@
obj-$(CONFIG_IA64_ACPI_CPUFREQ) += acpi-cpufreq.o

View File

@ -0,0 +1,499 @@
/*
* arch/ia64/kernel/cpufreq/acpi-cpufreq.c
* This file provides the ACPI based P-state support. This
* module works with generic cpufreq infrastructure. Most of
* the code is based on i386 version
* (arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c)
*
* Copyright (C) 2005 Intel Corp
* Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/pal.h>
#include <linux/acpi.h>
#include <acpi/processor.h>
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "acpi-cpufreq", msg)
MODULE_AUTHOR("Venkatesh Pallipadi");
MODULE_DESCRIPTION("ACPI Processor P-States Driver");
MODULE_LICENSE("GPL");
struct cpufreq_acpi_io {
struct acpi_processor_performance acpi_data;
struct cpufreq_frequency_table *freq_table;
unsigned int resume;
};
static struct cpufreq_acpi_io *acpi_io_data[NR_CPUS];
static struct cpufreq_driver acpi_cpufreq_driver;
static int
processor_set_pstate (
u32 value)
{
s64 retval;
dprintk("processor_set_pstate\n");
retval = ia64_pal_set_pstate((u64)value);
if (retval) {
dprintk("Failed to set freq to 0x%x, with error 0x%x\n",
value, retval);
return -ENODEV;
}
return (int)retval;
}
static int
processor_get_pstate (
u32 *value)
{
u64 pstate_index = 0;
s64 retval;
dprintk("processor_get_pstate\n");
retval = ia64_pal_get_pstate(&pstate_index);
*value = (u32) pstate_index;
if (retval)
dprintk("Failed to get current freq with "
"error 0x%x, idx 0x%x\n", retval, *value);
return (int)retval;
}
/* To be used only after data->acpi_data is initialized */
static unsigned
extract_clock (
struct cpufreq_acpi_io *data,
unsigned value,
unsigned int cpu)
{
unsigned long i;
dprintk("extract_clock\n");
for (i = 0; i < data->acpi_data.state_count; i++) {
if (value >= data->acpi_data.states[i].control)
return data->acpi_data.states[i].core_frequency;
}
return data->acpi_data.states[i-1].core_frequency;
}
static unsigned int
processor_get_freq (
struct cpufreq_acpi_io *data,
unsigned int cpu)
{
int ret = 0;
u32 value = 0;
cpumask_t saved_mask;
unsigned long clock_freq;
dprintk("processor_get_freq\n");
saved_mask = current->cpus_allowed;
set_cpus_allowed(current, cpumask_of_cpu(cpu));
if (smp_processor_id() != cpu) {
ret = -EAGAIN;
goto migrate_end;
}
/*
* processor_get_pstate gets the average frequency since the
* last get. So, do two PAL_get_freq()...
*/
ret = processor_get_pstate(&value);
ret = processor_get_pstate(&value);
if (ret) {
set_cpus_allowed(current, saved_mask);
printk(KERN_WARNING "get performance failed with error %d\n",
ret);
ret = -EAGAIN;
goto migrate_end;
}
clock_freq = extract_clock(data, value, cpu);
ret = (clock_freq*1000);
migrate_end:
set_cpus_allowed(current, saved_mask);
return ret;
}
static int
processor_set_freq (
struct cpufreq_acpi_io *data,
unsigned int cpu,
int state)
{
int ret = 0;
u32 value = 0;
struct cpufreq_freqs cpufreq_freqs;
cpumask_t saved_mask;
int retval;
dprintk("processor_set_freq\n");
saved_mask = current->cpus_allowed;
set_cpus_allowed(current, cpumask_of_cpu(cpu));
if (smp_processor_id() != cpu) {
retval = -EAGAIN;
goto migrate_end;
}
if (state == data->acpi_data.state) {
if (unlikely(data->resume)) {
dprintk("Called after resume, resetting to P%d\n", state);
data->resume = 0;
} else {
dprintk("Already at target state (P%d)\n", state);
retval = 0;
goto migrate_end;
}
}
dprintk("Transitioning from P%d to P%d\n",
data->acpi_data.state, state);
/* cpufreq frequency struct */
cpufreq_freqs.cpu = cpu;
cpufreq_freqs.old = data->freq_table[data->acpi_data.state].frequency;
cpufreq_freqs.new = data->freq_table[state].frequency;
/* notify cpufreq */
cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE);
/*
* First we write the target state's 'control' value to the
* control_register.
*/
value = (u32) data->acpi_data.states[state].control;
dprintk("Transitioning to state: 0x%08x\n", value);
ret = processor_set_pstate(value);
if (ret) {
unsigned int tmp = cpufreq_freqs.new;
cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE);
cpufreq_freqs.new = cpufreq_freqs.old;
cpufreq_freqs.old = tmp;
cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE);
cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE);
printk(KERN_WARNING "Transition failed with error %d\n", ret);
retval = -ENODEV;
goto migrate_end;
}
cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE);
data->acpi_data.state = state;
retval = 0;
migrate_end:
set_cpus_allowed(current, saved_mask);
return (retval);
}
static unsigned int
acpi_cpufreq_get (
unsigned int cpu)
{
struct cpufreq_acpi_io *data = acpi_io_data[cpu];
dprintk("acpi_cpufreq_get\n");
return processor_get_freq(data, cpu);
}
static int
acpi_cpufreq_target (
struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
unsigned int next_state = 0;
unsigned int result = 0;
dprintk("acpi_cpufreq_setpolicy\n");
result = cpufreq_frequency_table_target(policy,
data->freq_table, target_freq, relation, &next_state);
if (result)
return (result);
result = processor_set_freq(data, policy->cpu, next_state);
return (result);
}
static int
acpi_cpufreq_verify (
struct cpufreq_policy *policy)
{
unsigned int result = 0;
struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
dprintk("acpi_cpufreq_verify\n");
result = cpufreq_frequency_table_verify(policy,
data->freq_table);
return (result);
}
/*
* processor_init_pdc - let BIOS know about the SMP capabilities
* of this driver
* @perf: processor-specific acpi_io_data struct
* @cpu: CPU being initialized
*
* To avoid issues with legacy OSes, some BIOSes require to be informed of
* the SMP capabilities of OS P-state driver. Here we set the bits in _PDC
* accordingly. Actual call to _PDC is done in driver/acpi/processor.c
*/
static void
processor_init_pdc (
struct acpi_processor_performance *perf,
unsigned int cpu,
struct acpi_object_list *obj_list
)
{
union acpi_object *obj;
u32 *buf;
dprintk("processor_init_pdc\n");
perf->pdc = NULL;
/* Initialize pdc. It will be used later. */
if (!obj_list)
return;
if (!(obj_list->count && obj_list->pointer))
return;
obj = obj_list->pointer;
if ((obj->buffer.length == 12) && obj->buffer.pointer) {
buf = (u32 *)obj->buffer.pointer;
buf[0] = ACPI_PDC_REVISION_ID;
buf[1] = 1;
buf[2] = ACPI_PDC_EST_CAPABILITY_SMP;
perf->pdc = obj_list;
}
return;
}
static int
acpi_cpufreq_cpu_init (
struct cpufreq_policy *policy)
{
unsigned int i;
unsigned int cpu = policy->cpu;
struct cpufreq_acpi_io *data;
unsigned int result = 0;
union acpi_object arg0 = {ACPI_TYPE_BUFFER};
u32 arg0_buf[3];
struct acpi_object_list arg_list = {1, &arg0};
dprintk("acpi_cpufreq_cpu_init\n");
/* setup arg_list for _PDC settings */
arg0.buffer.length = 12;
arg0.buffer.pointer = (u8 *) arg0_buf;
data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
if (!data)
return (-ENOMEM);
memset(data, 0, sizeof(struct cpufreq_acpi_io));
acpi_io_data[cpu] = data;
processor_init_pdc(&data->acpi_data, cpu, &arg_list);
result = acpi_processor_register_performance(&data->acpi_data, cpu);
data->acpi_data.pdc = NULL;
if (result)
goto err_free;
/* capability check */
if (data->acpi_data.state_count <= 1) {
dprintk("No P-States\n");
result = -ENODEV;
goto err_unreg;
}
if ((data->acpi_data.control_register.space_id !=
ACPI_ADR_SPACE_FIXED_HARDWARE) ||
(data->acpi_data.status_register.space_id !=
ACPI_ADR_SPACE_FIXED_HARDWARE)) {
dprintk("Unsupported address space [%d, %d]\n",
(u32) (data->acpi_data.control_register.space_id),
(u32) (data->acpi_data.status_register.space_id));
result = -ENODEV;
goto err_unreg;
}
/* alloc freq_table */
data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) *
(data->acpi_data.state_count + 1),
GFP_KERNEL);
if (!data->freq_table) {
result = -ENOMEM;
goto err_unreg;
}
/* detect transition latency */
policy->cpuinfo.transition_latency = 0;
for (i=0; i<data->acpi_data.state_count; i++) {
if ((data->acpi_data.states[i].transition_latency * 1000) >
policy->cpuinfo.transition_latency) {
policy->cpuinfo.transition_latency =
data->acpi_data.states[i].transition_latency * 1000;
}
}
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cur = processor_get_freq(data, policy->cpu);
/* table init */
for (i = 0; i <= data->acpi_data.state_count; i++)
{
data->freq_table[i].index = i;
if (i < data->acpi_data.state_count) {
data->freq_table[i].frequency =
data->acpi_data.states[i].core_frequency * 1000;
} else {
data->freq_table[i].frequency = CPUFREQ_TABLE_END;
}
}
result = cpufreq_frequency_table_cpuinfo(policy, data->freq_table);
if (result) {
goto err_freqfree;
}
/* notify BIOS that we exist */
acpi_processor_notify_smm(THIS_MODULE);
printk(KERN_INFO "acpi-cpufreq: CPU%u - ACPI performance management "
"activated.\n", cpu);
for (i = 0; i < data->acpi_data.state_count; i++)
dprintk(" %cP%d: %d MHz, %d mW, %d uS, %d uS, 0x%x 0x%x\n",
(i == data->acpi_data.state?'*':' '), i,
(u32) data->acpi_data.states[i].core_frequency,
(u32) data->acpi_data.states[i].power,
(u32) data->acpi_data.states[i].transition_latency,
(u32) data->acpi_data.states[i].bus_master_latency,
(u32) data->acpi_data.states[i].status,
(u32) data->acpi_data.states[i].control);
cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu);
/* the first call to ->target() should result in us actually
* writing something to the appropriate registers. */
data->resume = 1;
return (result);
err_freqfree:
kfree(data->freq_table);
err_unreg:
acpi_processor_unregister_performance(&data->acpi_data, cpu);
err_free:
kfree(data);
acpi_io_data[cpu] = NULL;
return (result);
}
static int
acpi_cpufreq_cpu_exit (
struct cpufreq_policy *policy)
{
struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
dprintk("acpi_cpufreq_cpu_exit\n");
if (data) {
cpufreq_frequency_table_put_attr(policy->cpu);
acpi_io_data[policy->cpu] = NULL;
acpi_processor_unregister_performance(&data->acpi_data,
policy->cpu);
kfree(data);
}
return (0);
}
static struct freq_attr* acpi_cpufreq_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
NULL,
};
static struct cpufreq_driver acpi_cpufreq_driver = {
.verify = acpi_cpufreq_verify,
.target = acpi_cpufreq_target,
.get = acpi_cpufreq_get,
.init = acpi_cpufreq_cpu_init,
.exit = acpi_cpufreq_cpu_exit,
.name = "acpi-cpufreq",
.owner = THIS_MODULE,
.attr = acpi_cpufreq_attr,
};
static int __init
acpi_cpufreq_init (void)
{
dprintk("acpi_cpufreq_init\n");
return cpufreq_register_driver(&acpi_cpufreq_driver);
}
static void __exit
acpi_cpufreq_exit (void)
{
dprintk("acpi_cpufreq_exit\n");
cpufreq_unregister_driver(&acpi_cpufreq_driver);
return;
}
late_initcall(acpi_cpufreq_init);
module_exit(acpi_cpufreq_exit);

View File

@ -35,7 +35,7 @@ arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len
return -ENOMEM;
#ifdef CONFIG_HUGETLB_PAGE
if (REGION_NUMBER(addr) == REGION_HPAGE)
if (REGION_NUMBER(addr) == RGN_HPAGE)
addr = 0;
#endif
if (!addr)

View File

@ -184,7 +184,7 @@ uncached_free_page(unsigned long maddr)
{
int node;
node = nasid_to_cnodeid(NASID_GET(maddr));
node = paddr_to_nid(maddr - __IA64_UNCACHED_OFFSET);
dprintk(KERN_DEBUG "uncached_free_page(%lx) on node %i\n", maddr, node);
@ -217,7 +217,7 @@ uncached_build_memmap(unsigned long start, unsigned long end, void *arg)
memset((char *)vstart, 0, length);
node = nasid_to_cnodeid(NASID_GET(start));
node = paddr_to_nid(start);
for (; vstart < vend ; vstart += PAGE_SIZE) {
dprintk(KERN_INFO "sticking %lx into the pool!\n", vstart);

View File

@ -6,7 +6,7 @@ obj-y := io.o
lib-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \
__divdi3.o __udivdi3.o __moddi3.o __umoddi3.o \
bitop.o checksum.o clear_page.o csum_partial_copy.o copy_page.o \
bitop.o checksum.o clear_page.o csum_partial_copy.o \
clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o \
flush.o ip_fast_csum.o do_csum.o \
memset.o strlen.o swiotlb.o

View File

@ -93,8 +93,7 @@ static int __init
setup_io_tlb_npages(char *str)
{
if (isdigit(*str)) {
io_tlb_nslabs = simple_strtoul(str, &str, 0) <<
(PAGE_SHIFT - IO_TLB_SHIFT);
io_tlb_nslabs = simple_strtoul(str, &str, 0);
/* avoid tail segment of size < IO_TLB_SEGSIZE */
io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
}
@ -117,7 +116,7 @@ swiotlb_init_with_default_size (size_t default_size)
unsigned long i;
if (!io_tlb_nslabs) {
io_tlb_nslabs = (default_size >> PAGE_SHIFT);
io_tlb_nslabs = (default_size >> IO_TLB_SHIFT);
io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
}

View File

@ -76,7 +76,7 @@ int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
return -EINVAL;
if (addr & ~HPAGE_MASK)
return -EINVAL;
if (REGION_NUMBER(addr) != REGION_HPAGE)
if (REGION_NUMBER(addr) != RGN_HPAGE)
return -EINVAL;
return 0;
@ -87,7 +87,7 @@ struct page *follow_huge_addr(struct mm_struct *mm, unsigned long addr, int writ
struct page *page;
pte_t *ptep;
if (REGION_NUMBER(addr) != REGION_HPAGE)
if (REGION_NUMBER(addr) != RGN_HPAGE)
return ERR_PTR(-EINVAL);
ptep = huge_pte_offset(mm, addr);
@ -142,8 +142,8 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, u
return -ENOMEM;
if (len & ~HPAGE_MASK)
return -EINVAL;
/* This code assumes that REGION_HPAGE != 0. */
if ((REGION_NUMBER(addr) != REGION_HPAGE) || (addr & (HPAGE_SIZE - 1)))
/* This code assumes that RGN_HPAGE != 0. */
if ((REGION_NUMBER(addr) != RGN_HPAGE) || (addr & (HPAGE_SIZE - 1)))
addr = HPAGE_REGION_BASE;
else
addr = ALIGN(addr, HPAGE_SIZE);

View File

@ -24,7 +24,6 @@
#include <asm/machvec.h>
#include <asm/page.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/sal.h>

View File

@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved.
* Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
*/
#ifndef _ASM_IA64_SN_TIO_H
@ -26,6 +26,10 @@
#define TIO_ITTE_VALID_MASK 0x1
#define TIO_ITTE_VALID_SHIFT 16
#define TIO_ITTE_WIDGET(itte) \
(((itte) >> TIO_ITTE_WIDGET_SHIFT) & TIO_ITTE_WIDGET_MASK)
#define TIO_ITTE_VALID(itte) \
(((itte) >> TIO_ITTE_VALID_SHIFT) & TIO_ITTE_VALID_MASK)
#define TIO_ITTE_PUT(nasid, bigwin, widget, addr, valid) \
REMOTE_HUB_S((nasid), TIO_ITTE(bigwin), \

View File

@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1992 - 1997, 2000-2004 Silicon Graphics, Inc. All rights reserved.
* Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved.
*/
#ifndef _ASM_IA64_SN_XTALK_HUBDEV_H
#define _ASM_IA64_SN_XTALK_HUBDEV_H
@ -16,6 +16,9 @@
#define IIO_ITTE_WIDGET_MASK ((1<<IIO_ITTE_WIDGET_BITS)-1)
#define IIO_ITTE_WIDGET_SHIFT 8
#define IIO_ITTE_WIDGET(itte) \
(((itte) >> IIO_ITTE_WIDGET_SHIFT) & IIO_ITTE_WIDGET_MASK)
/*
* Use the top big window as a surrogate for the first small window
*/
@ -34,7 +37,8 @@ struct sn_flush_device_list {
unsigned long sfdl_force_int_addr;
unsigned long sfdl_flush_value;
volatile unsigned long *sfdl_flush_addr;
uint64_t sfdl_persistent_busnum;
uint32_t sfdl_persistent_busnum;
uint32_t sfdl_persistent_segment;
struct pcibus_info *sfdl_pcibus_info;
spinlock_t sfdl_flush_lock;
};
@ -58,7 +62,8 @@ struct hubdev_info {
void *hdi_nodepda;
void *hdi_node_vertex;
void *hdi_xtalk_vertex;
uint32_t max_segment_number;
uint32_t max_pcibus_number;
};
extern void hubdev_init_node(nodepda_t *, cnodeid_t);

View File

@ -29,16 +29,30 @@
/* two interfaces on two btes */
#define MAX_INTERFACES_TO_TRY 4
#define MAX_NODES_TO_TRY 2
static struct bteinfo_s *bte_if_on_node(nasid_t nasid, int interface)
{
nodepda_t *tmp_nodepda;
if (nasid_to_cnodeid(nasid) == -1)
return (struct bteinfo_s *)NULL;;
tmp_nodepda = NODEPDA(nasid_to_cnodeid(nasid));
return &tmp_nodepda->bte_if[interface];
}
static inline void bte_start_transfer(struct bteinfo_s *bte, u64 len, u64 mode)
{
if (is_shub2()) {
BTE_CTRL_STORE(bte, (IBLS_BUSY | ((len) | (mode) << 24)));
} else {
BTE_LNSTAT_STORE(bte, len);
BTE_CTRL_STORE(bte, mode);
}
}
/************************************************************************
* Block Transfer Engine copy related functions.
*
@ -67,13 +81,15 @@ bte_result_t bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification)
{
u64 transfer_size;
u64 transfer_stat;
u64 notif_phys_addr;
struct bteinfo_s *bte;
bte_result_t bte_status;
unsigned long irq_flags;
unsigned long itc_end = 0;
struct bteinfo_s *btes_to_try[MAX_INTERFACES_TO_TRY];
int bte_if_index;
int bte_pri, bte_sec;
int nasid_to_try[MAX_NODES_TO_TRY];
int my_nasid = get_nasid();
int bte_if_index, nasid_index;
int bte_first, btes_per_node = BTES_PER_NODE;
BTE_PRINTK(("bte_copy(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%p)\n",
src, dest, len, mode, notification));
@ -86,36 +102,26 @@ bte_result_t bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification)
(src & L1_CACHE_MASK) || (dest & L1_CACHE_MASK));
BUG_ON(!(len < ((BTE_LEN_MASK + 1) << L1_CACHE_SHIFT)));
/* CPU 0 (per node) tries bte0 first, CPU 1 try bte1 first */
if (cpuid_to_subnode(smp_processor_id()) == 0) {
bte_pri = 0;
bte_sec = 1;
} else {
bte_pri = 1;
bte_sec = 0;
}
/*
* Start with interface corresponding to cpu number
*/
bte_first = raw_smp_processor_id() % btes_per_node;
if (mode & BTE_USE_DEST) {
/* try remote then local */
btes_to_try[0] = bte_if_on_node(NASID_GET(dest), bte_pri);
btes_to_try[1] = bte_if_on_node(NASID_GET(dest), bte_sec);
nasid_to_try[0] = NASID_GET(dest);
if (mode & BTE_USE_ANY) {
btes_to_try[2] = bte_if_on_node(get_nasid(), bte_pri);
btes_to_try[3] = bte_if_on_node(get_nasid(), bte_sec);
nasid_to_try[1] = my_nasid;
} else {
btes_to_try[2] = NULL;
btes_to_try[3] = NULL;
nasid_to_try[1] = (int)NULL;
}
} else {
/* try local then remote */
btes_to_try[0] = bte_if_on_node(get_nasid(), bte_pri);
btes_to_try[1] = bte_if_on_node(get_nasid(), bte_sec);
nasid_to_try[0] = my_nasid;
if (mode & BTE_USE_ANY) {
btes_to_try[2] = bte_if_on_node(NASID_GET(dest), bte_pri);
btes_to_try[3] = bte_if_on_node(NASID_GET(dest), bte_sec);
nasid_to_try[1] = NASID_GET(dest);
} else {
btes_to_try[2] = NULL;
btes_to_try[3] = NULL;
nasid_to_try[1] = (int)NULL;
}
}
@ -123,11 +129,12 @@ retry_bteop:
do {
local_irq_save(irq_flags);
bte_if_index = 0;
bte_if_index = bte_first;
nasid_index = 0;
/* Attempt to lock one of the BTE interfaces. */
while (bte_if_index < MAX_INTERFACES_TO_TRY) {
bte = btes_to_try[bte_if_index++];
while (nasid_index < MAX_NODES_TO_TRY) {
bte = bte_if_on_node(nasid_to_try[nasid_index],bte_if_index);
if (bte == NULL) {
continue;
@ -143,6 +150,15 @@ retry_bteop:
break;
}
}
bte_if_index = (bte_if_index + 1) % btes_per_node; /* Next interface */
if (bte_if_index == bte_first) {
/*
* We've tried all interfaces on this node
*/
nasid_index++;
}
bte = NULL;
}
@ -169,7 +185,13 @@ retry_bteop:
/* Initialize the notification to a known value. */
*bte->most_rcnt_na = BTE_WORD_BUSY;
notif_phys_addr = TO_PHYS(ia64_tpa((unsigned long)bte->most_rcnt_na));
if (is_shub2()) {
src = SH2_TIO_PHYS_TO_DMA(src);
dest = SH2_TIO_PHYS_TO_DMA(dest);
notif_phys_addr = SH2_TIO_PHYS_TO_DMA(notif_phys_addr);
}
/* Set the source and destination registers */
BTE_PRINTKV(("IBSA = 0x%lx)\n", (TO_PHYS(src))));
BTE_SRC_STORE(bte, TO_PHYS(src));
@ -177,14 +199,12 @@ retry_bteop:
BTE_DEST_STORE(bte, TO_PHYS(dest));
/* Set the notification register */
BTE_PRINTKV(("IBNA = 0x%lx)\n",
TO_PHYS(ia64_tpa((unsigned long)bte->most_rcnt_na))));
BTE_NOTIF_STORE(bte,
TO_PHYS(ia64_tpa((unsigned long)bte->most_rcnt_na)));
BTE_PRINTKV(("IBNA = 0x%lx)\n", notif_phys_addr));
BTE_NOTIF_STORE(bte, notif_phys_addr);
/* Initiate the transfer */
BTE_PRINTK(("IBCT = 0x%lx)\n", BTE_VALID_MODE(mode)));
BTE_START_TRANSFER(bte, transfer_size, BTE_VALID_MODE(mode));
bte_start_transfer(bte, transfer_size, BTE_VALID_MODE(mode));
itc_end = ia64_get_itc() + (40000000 * local_cpu_data->cyc_per_usec);
@ -195,6 +215,7 @@ retry_bteop:
}
while ((transfer_stat = *bte->most_rcnt_na) == BTE_WORD_BUSY) {
cpu_relax();
if (ia64_get_itc() > itc_end) {
BTE_PRINTK(("BTE timeout nasid 0x%x bte%d IBLS = 0x%lx na 0x%lx\n",
NASID_GET(bte->bte_base_addr), bte->bte_num,

View File

@ -76,7 +76,7 @@ void hubiio_crb_free(struct hubdev_info *hubdev_info, int crbnum)
*/
REMOTE_HUB_S(hubdev_info->hdi_nasid, IIO_ICDR, (IIO_ICDR_PND | crbnum));
while (REMOTE_HUB_L(hubdev_info->hdi_nasid, IIO_ICDR) & IIO_ICDR_PND)
udelay(1);
cpu_relax();
}

View File

@ -18,6 +18,7 @@
#include <asm/sn/simulator.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/tioca_provider.h>
#include <asm/sn/tioce_provider.h>
#include "xtalk/hubdev.h"
#include "xtalk/xwidgetdev.h"
@ -44,6 +45,9 @@ int sn_ioif_inited = 0; /* SN I/O infrastructure initialized? */
struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */
static int max_segment_number = 0; /* Default highest segment number */
static int max_pcibus_number = 255; /* Default highest pci bus number */
/*
* Hooks and struct for unsupported pci providers
*/
@ -157,13 +161,28 @@ static void sn_fixup_ionodes(void)
uint64_t nasid;
int i, widget;
/*
* Get SGI Specific HUB chipset information.
* Inform Prom that this kernel can support domain bus numbering.
*/
for (i = 0; i < numionodes; i++) {
hubdev = (struct hubdev_info *)(NODEPDA(i)->pdinfo);
nasid = cnodeid_to_nasid(i);
hubdev->max_segment_number = 0xffffffff;
hubdev->max_pcibus_number = 0xff;
status = sal_get_hubdev_info(nasid, (uint64_t) __pa(hubdev));
if (status)
continue;
/* Save the largest Domain and pcibus numbers found. */
if (hubdev->max_segment_number) {
/*
* Dealing with a Prom that supports segments.
*/
max_segment_number = hubdev->max_segment_number;
max_pcibus_number = hubdev->max_pcibus_number;
}
/* Attach the error interrupt handlers */
if (nasid & 1)
ice_error_init(hubdev);
@ -230,7 +249,7 @@ void sn_pci_unfixup_slot(struct pci_dev *dev)
void sn_pci_fixup_slot(struct pci_dev *dev)
{
int idx;
int segment = 0;
int segment = pci_domain_nr(dev->bus);
int status = 0;
struct pcibus_bussoft *bs;
struct pci_bus *host_pci_bus;
@ -283,9 +302,9 @@ void sn_pci_fixup_slot(struct pci_dev *dev)
* PCI host_pci_dev struct and set up host bus linkages
*/
bus_no = SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32;
bus_no = (SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32) & 0xff;
devfn = SN_PCIDEV_INFO(dev)->pdi_slot_host_handle & 0xffffffff;
host_pci_bus = pci_find_bus(pci_domain_nr(dev->bus), bus_no);
host_pci_bus = pci_find_bus(segment, bus_no);
host_pci_dev = pci_get_slot(host_pci_bus, devfn);
SN_PCIDEV_INFO(dev)->host_pci_dev = host_pci_dev;
@ -333,6 +352,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
prom_bussoft_ptr = __va(prom_bussoft_ptr);
controller = kcalloc(1,sizeof(struct pci_controller), GFP_KERNEL);
controller->segment = segment;
if (!controller)
BUG();
@ -390,7 +410,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
if (controller->node >= num_online_nodes()) {
struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus);
printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%lu"
printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%u"
"L_IO=%lx L_MEM=%lx BASE=%lx\n",
b->bs_asic_type, b->bs_xid, b->bs_persist_busnum,
b->bs_legacy_io, b->bs_legacy_mem, b->bs_base);
@ -445,6 +465,7 @@ sn_sysdata_free_start:
static int __init sn_pci_init(void)
{
int i = 0;
int j = 0;
struct pci_dev *pci_dev = NULL;
extern void sn_init_cpei_timer(void);
#ifdef CONFIG_PROC_FS
@ -464,6 +485,7 @@ static int __init sn_pci_init(void)
pcibr_init_provider();
tioca_init_provider();
tioce_init_provider();
/*
* This is needed to avoid bounce limit checks in the blk layer
@ -479,8 +501,9 @@ static int __init sn_pci_init(void)
#endif
/* busses are not known yet ... */
for (i = 0; i < PCI_BUSES_TO_SCAN; i++)
sn_pci_controller_fixup(0, i, NULL);
for (i = 0; i <= max_segment_number; i++)
for (j = 0; j <= max_pcibus_number; j++)
sn_pci_controller_fixup(i, j, NULL);
/*
* Generic Linux PCI Layer has created the pci_bus and pci_dev

View File

@ -5,7 +5,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
* Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
*/
#include <linux/irq.h>
@ -76,15 +76,13 @@ static void sn_enable_irq(unsigned int irq)
static void sn_ack_irq(unsigned int irq)
{
uint64_t event_occurred, mask = 0;
int nasid;
u64 event_occurred, mask = 0;
irq = irq & 0xff;
nasid = get_nasid();
event_occurred =
HUB_L((uint64_t *) GLOBAL_MMR_ADDR(nasid, SH_EVENT_OCCURRED));
HUB_L((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED));
mask = event_occurred & SH_ALL_INT_MASK;
HUB_S((uint64_t *) GLOBAL_MMR_ADDR(nasid, SH_EVENT_OCCURRED_ALIAS),
HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS),
mask);
__set_bit(irq, (volatile void *)pda->sn_in_service_ivecs);
@ -93,15 +91,12 @@ static void sn_ack_irq(unsigned int irq)
static void sn_end_irq(unsigned int irq)
{
int nasid;
int ivec;
uint64_t event_occurred;
u64 event_occurred;
ivec = irq & 0xff;
if (ivec == SGI_UART_VECTOR) {
nasid = get_nasid();
event_occurred = HUB_L((uint64_t *) GLOBAL_MMR_ADDR
(nasid, SH_EVENT_OCCURRED));
event_occurred = HUB_L((u64*)LOCAL_MMR_ADDR (SH_EVENT_OCCURRED));
/* If the UART bit is set here, we may have received an
* interrupt from the UART that the driver missed. To
* make sure, we IPI ourselves to force us to look again.
@ -132,6 +127,7 @@ static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask)
int local_widget, status;
nasid_t local_nasid;
struct sn_irq_info *new_irq_info;
struct sn_pcibus_provider *pci_provider;
new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC);
if (new_irq_info == NULL)
@ -171,8 +167,9 @@ static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask)
new_irq_info->irq_cpuid = cpuid;
register_intr_pda(new_irq_info);
if (IS_PCI_BRIDGE_ASIC(new_irq_info->irq_bridge_type))
pcibr_change_devices_irq(new_irq_info);
pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type];
if (pci_provider && pci_provider->target_interrupt)
(pci_provider->target_interrupt)(new_irq_info);
spin_lock(&sn_irq_info_lock);
list_replace_rcu(&sn_irq_info->list, &new_irq_info->list);
@ -317,6 +314,16 @@ void sn_irq_unfixup(struct pci_dev *pci_dev)
pci_dev_put(pci_dev);
}
static inline void
sn_call_force_intr_provider(struct sn_irq_info *sn_irq_info)
{
struct sn_pcibus_provider *pci_provider;
pci_provider = sn_pci_provider[sn_irq_info->irq_bridge_type];
if (pci_provider && pci_provider->force_interrupt)
(*pci_provider->force_interrupt)(sn_irq_info);
}
static void force_interrupt(int irq)
{
struct sn_irq_info *sn_irq_info;
@ -325,11 +332,9 @@ static void force_interrupt(int irq)
return;
rcu_read_lock();
list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[irq], list) {
if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type) &&
(sn_irq_info->irq_bridge != NULL))
pcibr_force_interrupt(sn_irq_info);
}
list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[irq], list)
sn_call_force_intr_provider(sn_irq_info);
rcu_read_unlock();
}
@ -351,6 +356,14 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info)
struct pcidev_info *pcidev_info;
struct pcibus_info *pcibus_info;
/*
* Bridge types attached to TIO (anything but PIC) do not need this WAR
* since they do not target Shub II interrupt registers. If that
* ever changes, this check needs to accomodate.
*/
if (sn_irq_info->irq_bridge_type != PCIIO_ASIC_TYPE_PIC)
return;
pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
if (!pcidev_info)
return;
@ -377,16 +390,12 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info)
break;
}
if (!test_bit(irr_bit, &irr_reg)) {
if (!test_bit(irq, pda->sn_soft_irr)) {
if (!test_bit(irq, pda->sn_in_service_ivecs)) {
regval &= 0xff;
if (sn_irq_info->irq_int_bit & regval &
sn_irq_info->irq_last_intr) {
regval &=
~(sn_irq_info->
irq_int_bit & regval);
pcibr_force_interrupt(sn_irq_info);
}
regval &= ~(sn_irq_info->irq_int_bit & regval);
sn_call_force_intr_provider(sn_irq_info);
}
}
}
@ -404,12 +413,6 @@ void sn_lb_int_war_check(void)
rcu_read_lock();
for (i = pda->sn_first_irq; i <= pda->sn_last_irq; i++) {
list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[i], list) {
/*
* Only call for PCI bridges that are fully
* initialized.
*/
if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type) &&
(sn_irq_info->irq_bridge != NULL))
sn_check_intr(i, sn_irq_info);
}
}

View File

@ -80,8 +80,6 @@ EXPORT_PER_CPU_SYMBOL(__sn_cnodeid_to_nasid);
DEFINE_PER_CPU(struct nodepda_s *, __sn_nodepda);
EXPORT_PER_CPU_SYMBOL(__sn_nodepda);
partid_t sn_partid = -1;
EXPORT_SYMBOL(sn_partid);
char sn_system_serial_number_string[128];
EXPORT_SYMBOL(sn_system_serial_number_string);
u64 sn_partition_serial_number;
@ -403,6 +401,7 @@ static void __init sn_init_pdas(char **cmdline_p)
memset(nodepdaindr[cnode], 0, sizeof(nodepda_t));
memset(nodepdaindr[cnode]->phys_cpuid, -1,
sizeof(nodepdaindr[cnode]->phys_cpuid));
spin_lock_init(&nodepdaindr[cnode]->ptc_lock);
}
/*
@ -532,8 +531,8 @@ void __init sn_cpu_init(void)
*/
{
u64 pio1[] = {SH1_PIO_WRITE_STATUS_0, 0, SH1_PIO_WRITE_STATUS_1, 0};
u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1,
SH2_PIO_WRITE_STATUS_2, SH2_PIO_WRITE_STATUS_3};
u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_2,
SH2_PIO_WRITE_STATUS_1, SH2_PIO_WRITE_STATUS_3};
u64 *pio;
pio = is_shub1() ? pio1 : pio2;
pda->pio_write_status_addr = (volatile unsigned long *) LOCAL_MMR_ADDR(pio[slice]);

View File

@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved.
* Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
*/
#include <asm/types.h>
@ -11,7 +11,7 @@
#define DEADLOCKBIT SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT
#define WRITECOUNTMASK SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK
#define ALIAS_OFFSET (SH1_PIO_WRITE_STATUS_0_ALIAS-SH1_PIO_WRITE_STATUS_0)
#define ALIAS_OFFSET 8
.global sn2_ptc_deadlock_recovery_core
@ -36,13 +36,15 @@ sn2_ptc_deadlock_recovery_core:
extr.u piowcphy=piowc,0,61;; // Convert piowc to uncached physical address
dep piowcphy=-1,piowcphy,63,1
movl mask=WRITECOUNTMASK
mov r8=r0
1:
add scr2=ALIAS_OFFSET,piowc // Address of WRITE_STATUS alias register
mov scr1=7;; // Clear DEADLOCK, WRITE_ERROR, MULTI_WRITE_ERROR
st8.rel [scr2]=scr1;;
;;
ld8.acq scr1=[scr2];;
5: ld8.acq scr1=[piowc];; // Wait for PIOs to complete.
hint @pause
and scr2=scr1,mask;; // mask of writecount bits
cmp.ne p6,p0=zeroval,scr2
(p6) br.cond.sptk 5b
@ -57,6 +59,7 @@ sn2_ptc_deadlock_recovery_core:
st8.rel [ptc0]=data0 // Write PTC0 & wait for completion.
5: ld8.acq scr1=[piowcphy];; // Wait for PIOs to complete.
hint @pause
and scr2=scr1,mask;; // mask of writecount bits
cmp.ne p6,p0=zeroval,scr2
(p6) br.cond.sptk 5b;;
@ -67,6 +70,7 @@ sn2_ptc_deadlock_recovery_core:
(p7) st8.rel [ptc1]=data1;; // Now write PTC1.
5: ld8.acq scr1=[piowcphy];; // Wait for PIOs to complete.
hint @pause
and scr2=scr1,mask;; // mask of writecount bits
cmp.ne p6,p0=zeroval,scr2
(p6) br.cond.sptk 5b
@ -77,6 +81,7 @@ sn2_ptc_deadlock_recovery_core:
srlz.i;;
////////////// END PHYSICAL MODE ////////////////////
(p8) add r8=1,r8
(p8) br.cond.spnt 1b;; // Repeat if DEADLOCK occurred.
br.ret.sptk rp

View File

@ -5,7 +5,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved.
* Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
*/
#include <linux/init.h>
@ -20,6 +20,8 @@
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/nodemask.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <asm/processor.h>
#include <asm/irq.h>
@ -39,12 +41,120 @@
#include <asm/sn/nodepda.h>
#include <asm/sn/rw_mmr.h>
void sn2_ptc_deadlock_recovery(volatile unsigned long *, unsigned long data0,
volatile unsigned long *, unsigned long data1);
DEFINE_PER_CPU(struct ptc_stats, ptcstats);
DECLARE_PER_CPU(struct ptc_stats, ptcstats);
static __cacheline_aligned DEFINE_SPINLOCK(sn2_global_ptc_lock);
static unsigned long sn2_ptc_deadlock_count;
void sn2_ptc_deadlock_recovery(short *, short, int, volatile unsigned long *, unsigned long data0,
volatile unsigned long *, unsigned long data1);
#ifdef DEBUG_PTC
/*
* ptctest:
*
* xyz - 3 digit hex number:
* x - Force PTC purges to use shub:
* 0 - no force
* 1 - force
* y - interupt enable
* 0 - disable interrupts
* 1 - leave interuupts enabled
* z - type of lock:
* 0 - global lock
* 1 - node local lock
* 2 - no lock
*
* Note: on shub1, only ptctest == 0 is supported. Don't try other values!
*/
static unsigned int sn2_ptctest = 0;
static int __init ptc_test(char *str)
{
get_option(&str, &sn2_ptctest);
return 1;
}
__setup("ptctest=", ptc_test);
static inline int ptc_lock(unsigned long *flagp)
{
unsigned long opt = sn2_ptctest & 255;
switch (opt) {
case 0x00:
spin_lock_irqsave(&sn2_global_ptc_lock, *flagp);
break;
case 0x01:
spin_lock_irqsave(&sn_nodepda->ptc_lock, *flagp);
break;
case 0x02:
local_irq_save(*flagp);
break;
case 0x10:
spin_lock(&sn2_global_ptc_lock);
break;
case 0x11:
spin_lock(&sn_nodepda->ptc_lock);
break;
case 0x12:
break;
default:
BUG();
}
return opt;
}
static inline void ptc_unlock(unsigned long flags, int opt)
{
switch (opt) {
case 0x00:
spin_unlock_irqrestore(&sn2_global_ptc_lock, flags);
break;
case 0x01:
spin_unlock_irqrestore(&sn_nodepda->ptc_lock, flags);
break;
case 0x02:
local_irq_restore(flags);
break;
case 0x10:
spin_unlock(&sn2_global_ptc_lock);
break;
case 0x11:
spin_unlock(&sn_nodepda->ptc_lock);
break;
case 0x12:
break;
default:
BUG();
}
}
#else
#define sn2_ptctest 0
static inline int ptc_lock(unsigned long *flagp)
{
spin_lock_irqsave(&sn2_global_ptc_lock, *flagp);
return 0;
}
static inline void ptc_unlock(unsigned long flags, int opt)
{
spin_unlock_irqrestore(&sn2_global_ptc_lock, flags);
}
#endif
struct ptc_stats {
unsigned long ptc_l;
unsigned long change_rid;
unsigned long shub_ptc_flushes;
unsigned long nodes_flushed;
unsigned long deadlocks;
unsigned long lock_itc_clocks;
unsigned long shub_itc_clocks;
unsigned long shub_itc_clocks_max;
};
static inline unsigned long wait_piowc(void)
{
@ -89,9 +199,9 @@ void
sn2_global_tlb_purge(unsigned long start, unsigned long end,
unsigned long nbits)
{
int i, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0;
int i, opt, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0;
volatile unsigned long *ptc0, *ptc1;
unsigned long flags = 0, data0 = 0, data1 = 0;
unsigned long itc, itc2, flags, data0 = 0, data1 = 0;
struct mm_struct *mm = current->active_mm;
short nasids[MAX_NUMNODES], nix;
nodemask_t nodes_flushed;
@ -114,16 +224,19 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
start += (1UL << nbits);
} while (start < end);
ia64_srlz_i();
__get_cpu_var(ptcstats).ptc_l++;
preempt_enable();
return;
}
if (atomic_read(&mm->mm_users) == 1) {
flush_tlb_mm(mm);
__get_cpu_var(ptcstats).change_rid++;
preempt_enable();
return;
}
itc = ia64_get_itc();
nix = 0;
for_each_node_mask(cnode, nodes_flushed)
nasids[nix++] = cnodeid_to_nasid(cnode);
@ -148,7 +261,12 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
mynasid = get_nasid();
spin_lock_irqsave(&sn2_global_ptc_lock, flags);
itc = ia64_get_itc();
opt = ptc_lock(&flags);
itc2 = ia64_get_itc();
__get_cpu_var(ptcstats).lock_itc_clocks += itc2 - itc;
__get_cpu_var(ptcstats).shub_ptc_flushes++;
__get_cpu_var(ptcstats).nodes_flushed += nix;
do {
if (shub1)
@ -157,7 +275,7 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
data0 = (data0 & ~SH2_PTC_ADDR_MASK) | (start & SH2_PTC_ADDR_MASK);
for (i = 0; i < nix; i++) {
nasid = nasids[i];
if (unlikely(nasid == mynasid)) {
if ((!(sn2_ptctest & 3)) && unlikely(nasid == mynasid)) {
ia64_ptcga(start, nbits << 2);
ia64_srlz_i();
} else {
@ -169,18 +287,22 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
flushed = 1;
}
}
if (flushed
&& (wait_piowc() &
SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK)) {
sn2_ptc_deadlock_recovery(ptc0, data0, ptc1, data1);
(SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK))) {
sn2_ptc_deadlock_recovery(nasids, nix, mynasid, ptc0, data0, ptc1, data1);
}
start += (1UL << nbits);
} while (start < end);
spin_unlock_irqrestore(&sn2_global_ptc_lock, flags);
itc2 = ia64_get_itc() - itc2;
__get_cpu_var(ptcstats).shub_itc_clocks += itc2;
if (itc2 > __get_cpu_var(ptcstats).shub_itc_clocks_max)
__get_cpu_var(ptcstats).shub_itc_clocks_max = itc2;
ptc_unlock(flags, opt);
preempt_enable();
}
@ -192,31 +314,29 @@ sn2_global_tlb_purge(unsigned long start, unsigned long end,
* TLB flush transaction. The recovery sequence is somewhat tricky & is
* coded in assembly language.
*/
void sn2_ptc_deadlock_recovery(volatile unsigned long *ptc0, unsigned long data0,
void sn2_ptc_deadlock_recovery(short *nasids, short nix, int mynasid, volatile unsigned long *ptc0, unsigned long data0,
volatile unsigned long *ptc1, unsigned long data1)
{
extern void sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long,
volatile unsigned long *, unsigned long, volatile unsigned long *, unsigned long);
int cnode, mycnode, nasid;
volatile unsigned long *piows;
volatile unsigned long zeroval;
short nasid, i;
unsigned long *piows, zeroval;
sn2_ptc_deadlock_count++;
__get_cpu_var(ptcstats).deadlocks++;
piows = pda->pio_write_status_addr;
piows = (unsigned long *) pda->pio_write_status_addr;
zeroval = pda->pio_write_status_val;
mycnode = numa_node_id();
for_each_online_node(cnode) {
if (is_headless_node(cnode) || cnode == mycnode)
for (i=0; i < nix; i++) {
nasid = nasids[i];
if (!(sn2_ptctest & 3) && nasid == mynasid)
continue;
nasid = cnodeid_to_nasid(cnode);
ptc0 = CHANGE_NASID(nasid, ptc0);
if (ptc1)
ptc1 = CHANGE_NASID(nasid, ptc1);
sn2_ptc_deadlock_recovery_core(ptc0, data0, ptc1, data1, piows, zeroval);
}
}
/**
@ -293,3 +413,93 @@ void sn2_send_IPI(int cpuid, int vector, int delivery_mode, int redirect)
sn_send_IPI_phys(nasid, physid, vector, delivery_mode);
}
#ifdef CONFIG_PROC_FS
#define PTC_BASENAME "sgi_sn/ptc_statistics"
static void *sn2_ptc_seq_start(struct seq_file *file, loff_t * offset)
{
if (*offset < NR_CPUS)
return offset;
return NULL;
}
static void *sn2_ptc_seq_next(struct seq_file *file, void *data, loff_t * offset)
{
(*offset)++;
if (*offset < NR_CPUS)
return offset;
return NULL;
}
static void sn2_ptc_seq_stop(struct seq_file *file, void *data)
{
}
static int sn2_ptc_seq_show(struct seq_file *file, void *data)
{
struct ptc_stats *stat;
int cpu;
cpu = *(loff_t *) data;
if (!cpu) {
seq_printf(file, "# ptc_l change_rid shub_ptc_flushes shub_nodes_flushed deadlocks lock_nsec shub_nsec shub_nsec_max\n");
seq_printf(file, "# ptctest %d\n", sn2_ptctest);
}
if (cpu < NR_CPUS && cpu_online(cpu)) {
stat = &per_cpu(ptcstats, cpu);
seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l,
stat->change_rid, stat->shub_ptc_flushes, stat->nodes_flushed,
stat->deadlocks,
1000 * stat->lock_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec,
1000 * stat->shub_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec,
1000 * stat->shub_itc_clocks_max / per_cpu(cpu_info, cpu).cyc_per_usec);
}
return 0;
}
static struct seq_operations sn2_ptc_seq_ops = {
.start = sn2_ptc_seq_start,
.next = sn2_ptc_seq_next,
.stop = sn2_ptc_seq_stop,
.show = sn2_ptc_seq_show
};
int sn2_ptc_proc_open(struct inode *inode, struct file *file)
{
return seq_open(file, &sn2_ptc_seq_ops);
}
static struct file_operations proc_sn2_ptc_operations = {
.open = sn2_ptc_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
static struct proc_dir_entry *proc_sn2_ptc;
static int __init sn2_ptc_init(void)
{
if (!(proc_sn2_ptc = create_proc_entry(PTC_BASENAME, 0444, NULL))) {
printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME);
return -EINVAL;
}
proc_sn2_ptc->proc_fops = &proc_sn2_ptc_operations;
spin_lock_init(&sn2_global_ptc_lock);
return 0;
}
static void __exit sn2_ptc_exit(void)
{
remove_proc_entry(PTC_BASENAME, NULL);
}
module_init(sn2_ptc_init);
module_exit(sn2_ptc_exit);
#endif /* CONFIG_PROC_FS */

View File

@ -36,7 +36,6 @@
#include <asm/topology.h>
#include <asm/smp.h>
#include <asm/semaphore.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <asm/sal.h>
#include <asm/sn/io.h>
@ -59,7 +58,7 @@ static int sn_hwperf_enum_objects(int *nobj, struct sn_hwperf_object_info **ret)
struct sn_hwperf_object_info *objbuf = NULL;
if ((e = sn_hwperf_init()) < 0) {
printk("sn_hwperf_init failed: err %d\n", e);
printk(KERN_ERR "sn_hwperf_init failed: err %d\n", e);
goto out;
}
@ -111,7 +110,7 @@ static int sn_hwperf_geoid_to_cnode(char *location)
if (sn_hwperf_location_to_bpos(location, &rack, &bay, &slot, &slab))
return -1;
for (cnode = 0; cnode < numionodes; cnode++) {
for_each_node(cnode) {
geoid = cnodeid_get_geoid(cnode);
module_id = geo_module(geoid);
this_rack = MODULE_GET_RACK(module_id);
@ -124,11 +123,13 @@ static int sn_hwperf_geoid_to_cnode(char *location)
}
}
return cnode < numionodes ? cnode : -1;
return node_possible(cnode) ? cnode : -1;
}
static int sn_hwperf_obj_to_cnode(struct sn_hwperf_object_info * obj)
{
if (!SN_HWPERF_IS_NODE(obj) && !SN_HWPERF_IS_IONODE(obj))
BUG();
if (!obj->sn_hwp_this_part)
return -1;
return sn_hwperf_geoid_to_cnode(obj->location);
@ -174,31 +175,199 @@ static const char *sn_hwperf_get_slabname(struct sn_hwperf_object_info *obj,
return slabname;
}
static void print_pci_topology(struct seq_file *s,
struct sn_hwperf_object_info *obj, int *ordinal,
u64 rack, u64 bay, u64 slot, u64 slab)
static void print_pci_topology(struct seq_file *s)
{
char *p1;
char *p2;
char *pg;
char *p;
size_t sz;
int e;
if (!(pg = (char *)get_zeroed_page(GFP_KERNEL)))
return; /* ignore */
if (ia64_sn_ioif_get_pci_topology(rack, bay, slot, slab,
__pa(pg), PAGE_SIZE) == SN_HWPERF_OP_OK) {
for (p1=pg; *p1 && p1 < pg + PAGE_SIZE;) {
if (!(p2 = strchr(p1, '\n')))
for (sz = PAGE_SIZE; sz < 16 * PAGE_SIZE; sz += PAGE_SIZE) {
if (!(p = (char *)kmalloc(sz, GFP_KERNEL)))
break;
e = ia64_sn_ioif_get_pci_topology(__pa(p), sz);
if (e == SALRET_OK)
seq_puts(s, p);
kfree(p);
if (e == SALRET_OK || e == SALRET_NOT_IMPLEMENTED)
break;
*p2 = '\0';
seq_printf(s, "pcibus %d %s-%s\n",
*ordinal, obj->location, p1);
(*ordinal)++;
p1 = p2 + 1;
}
}
free_page((unsigned long)pg);
}
static inline int sn_hwperf_has_cpus(cnodeid_t node)
{
return node_online(node) && nr_cpus_node(node);
}
static inline int sn_hwperf_has_mem(cnodeid_t node)
{
return node_online(node) && NODE_DATA(node)->node_present_pages;
}
static struct sn_hwperf_object_info *
sn_hwperf_findobj_id(struct sn_hwperf_object_info *objbuf,
int nobj, int id)
{
int i;
struct sn_hwperf_object_info *p = objbuf;
for (i=0; i < nobj; i++, p++) {
if (p->id == id)
return p;
}
return NULL;
}
static int sn_hwperf_get_nearest_node_objdata(struct sn_hwperf_object_info *objbuf,
int nobj, cnodeid_t node, cnodeid_t *near_mem_node, cnodeid_t *near_cpu_node)
{
int e;
struct sn_hwperf_object_info *nodeobj = NULL;
struct sn_hwperf_object_info *op;
struct sn_hwperf_object_info *dest;
struct sn_hwperf_object_info *router;
struct sn_hwperf_port_info ptdata[16];
int sz, i, j;
cnodeid_t c;
int found_mem = 0;
int found_cpu = 0;
if (!node_possible(node))
return -EINVAL;
if (sn_hwperf_has_cpus(node)) {
if (near_cpu_node)
*near_cpu_node = node;
found_cpu++;
}
if (sn_hwperf_has_mem(node)) {
if (near_mem_node)
*near_mem_node = node;
found_mem++;
}
if (found_cpu && found_mem)
return 0; /* trivially successful */
/* find the argument node object */
for (i=0, op=objbuf; i < nobj; i++, op++) {
if (!SN_HWPERF_IS_NODE(op) && !SN_HWPERF_IS_IONODE(op))
continue;
if (node == sn_hwperf_obj_to_cnode(op)) {
nodeobj = op;
break;
}
}
if (!nodeobj) {
e = -ENOENT;
goto err;
}
/* get it's interconnect topology */
sz = op->ports * sizeof(struct sn_hwperf_port_info);
if (sz > sizeof(ptdata))
BUG();
e = ia64_sn_hwperf_op(sn_hwperf_master_nasid,
SN_HWPERF_ENUM_PORTS, nodeobj->id, sz,
(u64)&ptdata, 0, 0, NULL);
if (e != SN_HWPERF_OP_OK) {
e = -EINVAL;
goto err;
}
/* find nearest node with cpus and nearest memory */
for (router=NULL, j=0; j < op->ports; j++) {
dest = sn_hwperf_findobj_id(objbuf, nobj, ptdata[j].conn_id);
if (!dest || SN_HWPERF_FOREIGN(dest) ||
!SN_HWPERF_IS_NODE(dest) || SN_HWPERF_IS_IONODE(dest)) {
continue;
}
c = sn_hwperf_obj_to_cnode(dest);
if (!found_cpu && sn_hwperf_has_cpus(c)) {
if (near_cpu_node)
*near_cpu_node = c;
found_cpu++;
}
if (!found_mem && sn_hwperf_has_mem(c)) {
if (near_mem_node)
*near_mem_node = c;
found_mem++;
}
if (SN_HWPERF_IS_ROUTER(dest))
router = dest;
}
if (router && (!found_cpu || !found_mem)) {
/* search for a node connected to the same router */
sz = router->ports * sizeof(struct sn_hwperf_port_info);
if (sz > sizeof(ptdata))
BUG();
e = ia64_sn_hwperf_op(sn_hwperf_master_nasid,
SN_HWPERF_ENUM_PORTS, router->id, sz,
(u64)&ptdata, 0, 0, NULL);
if (e != SN_HWPERF_OP_OK) {
e = -EINVAL;
goto err;
}
for (j=0; j < router->ports; j++) {
dest = sn_hwperf_findobj_id(objbuf, nobj,
ptdata[j].conn_id);
if (!dest || dest->id == node ||
SN_HWPERF_FOREIGN(dest) ||
!SN_HWPERF_IS_NODE(dest) ||
SN_HWPERF_IS_IONODE(dest)) {
continue;
}
c = sn_hwperf_obj_to_cnode(dest);
if (!found_cpu && sn_hwperf_has_cpus(c)) {
if (near_cpu_node)
*near_cpu_node = c;
found_cpu++;
}
if (!found_mem && sn_hwperf_has_mem(c)) {
if (near_mem_node)
*near_mem_node = c;
found_mem++;
}
if (found_cpu && found_mem)
break;
}
}
if (!found_cpu || !found_mem) {
/* resort to _any_ node with CPUs and memory */
for (i=0, op=objbuf; i < nobj; i++, op++) {
if (SN_HWPERF_FOREIGN(op) ||
SN_HWPERF_IS_IONODE(op) ||
!SN_HWPERF_IS_NODE(op)) {
continue;
}
c = sn_hwperf_obj_to_cnode(op);
if (!found_cpu && sn_hwperf_has_cpus(c)) {
if (near_cpu_node)
*near_cpu_node = c;
found_cpu++;
}
if (!found_mem && sn_hwperf_has_mem(c)) {
if (near_mem_node)
*near_mem_node = c;
found_mem++;
}
if (found_cpu && found_mem)
break;
}
}
if (!found_cpu || !found_mem)
e = -ENODATA;
err:
return e;
}
static int sn_topology_show(struct seq_file *s, void *d)
{
int sz;
@ -215,7 +384,6 @@ static int sn_topology_show(struct seq_file *s, void *d)
struct sn_hwperf_object_info *p;
struct sn_hwperf_object_info *obj = d; /* this object */
struct sn_hwperf_object_info *objs = s->private; /* all objects */
int rack, bay, slot, slab;
u8 shubtype;
u8 system_size;
u8 sharing_size;
@ -225,7 +393,6 @@ static int sn_topology_show(struct seq_file *s, void *d)
u8 region_size;
u16 nasid_mask;
int nasid_msb;
int pci_bus_ordinal = 0;
if (obj == objs) {
seq_printf(s, "# sn_topology version 2\n");
@ -253,6 +420,8 @@ static int sn_topology_show(struct seq_file *s, void *d)
shubtype ? "shub2" : "shub1",
(u64)nasid_mask << nasid_shift, nasid_msb, nasid_shift,
system_size, sharing_size, coher, region_size);
print_pci_topology(s);
}
if (SN_HWPERF_FOREIGN(obj)) {
@ -272,11 +441,24 @@ static int sn_topology_show(struct seq_file *s, void *d)
if (!SN_HWPERF_IS_NODE(obj) && !SN_HWPERF_IS_IONODE(obj))
seq_putc(s, '\n');
else {
cnodeid_t near_mem = -1;
cnodeid_t near_cpu = -1;
seq_printf(s, ", nasid 0x%x", cnodeid_to_nasid(ordinal));
for (i=0; i < numionodes; i++) {
if (sn_hwperf_get_nearest_node_objdata(objs, sn_hwperf_obj_cnt,
ordinal, &near_mem, &near_cpu) == 0) {
seq_printf(s, ", near_mem_nodeid %d, near_cpu_nodeid %d",
near_mem, near_cpu);
}
if (!SN_HWPERF_IS_IONODE(obj)) {
for_each_online_node(i) {
seq_printf(s, i ? ":%d" : ", dist %d",
node_distance(ordinal, i));
}
}
seq_putc(s, '\n');
/*
@ -300,17 +482,6 @@ static int sn_topology_show(struct seq_file *s, void *d)
seq_putc(s, '\n');
}
}
/*
* PCI busses attached to this node, if any
*/
if (sn_hwperf_location_to_bpos(obj->location,
&rack, &bay, &slot, &slab)) {
/* export pci bus info */
print_pci_topology(s, obj, &pci_bus_ordinal,
rack, bay, slot, slab);
}
}
if (obj->ports) {
@ -572,6 +743,8 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, u64 arg)
if ((r = sn_hwperf_enum_objects(&nobj, &objs)) == 0) {
memset(p, 0, a.sz);
for (i = 0; i < nobj; i++) {
if (!SN_HWPERF_IS_NODE(objs + i))
continue;
node = sn_hwperf_obj_to_cnode(objs + i);
for_each_online_cpu(j) {
if (node != cpu_to_node(j))
@ -598,7 +771,7 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, u64 arg)
case SN_HWPERF_GET_NODE_NASID:
if (a.sz != sizeof(u64) ||
(node = a.arg) < 0 || node >= numionodes) {
(node = a.arg) < 0 || !node_possible(node)) {
r = -EINVAL;
goto error;
}
@ -627,6 +800,14 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, u64 arg)
vfree(objs);
goto error;
}
if (!SN_HWPERF_IS_NODE(objs + i) &&
!SN_HWPERF_IS_IONODE(objs + i)) {
r = -ENOENT;
vfree(objs);
goto error;
}
*(u64 *)p = (u64)sn_hwperf_obj_to_cnode(objs + i);
vfree(objs);
}
@ -692,6 +873,7 @@ static int sn_hwperf_init(void)
/* single threaded, once-only initialization */
down(&sn_hwperf_init_mutex);
if (sn_hwperf_salheap) {
up(&sn_hwperf_init_mutex);
return e;
@ -742,19 +924,6 @@ out:
sn_hwperf_salheap = NULL;
sn_hwperf_obj_cnt = 0;
}
if (!e) {
/*
* Register a dynamic misc device for ioctl. Platforms
* supporting hotplug will create /dev/sn_hwperf, else
* user can to look up the minor number in /proc/misc.
*/
if ((e = misc_register(&sn_hwperf_dev)) != 0) {
printk(KERN_ERR "sn_hwperf_init: misc register "
"for \"sn_hwperf\" failed, err %d\n", e);
}
}
up(&sn_hwperf_init_mutex);
return e;
}
@ -782,3 +951,41 @@ int sn_topology_release(struct inode *inode, struct file *file)
vfree(seq->private);
return seq_release(inode, file);
}
int sn_hwperf_get_nearest_node(cnodeid_t node,
cnodeid_t *near_mem_node, cnodeid_t *near_cpu_node)
{
int e;
int nobj;
struct sn_hwperf_object_info *objbuf;
if ((e = sn_hwperf_enum_objects(&nobj, &objbuf)) == 0) {
e = sn_hwperf_get_nearest_node_objdata(objbuf, nobj,
node, near_mem_node, near_cpu_node);
vfree(objbuf);
}
return e;
}
static int __devinit sn_hwperf_misc_register_init(void)
{
int e;
sn_hwperf_init();
/*
* Register a dynamic misc device for hwperf ioctls. Platforms
* supporting hotplug will create /dev/sn_hwperf, else user
* can to look up the minor number in /proc/misc.
*/
if ((e = misc_register(&sn_hwperf_dev)) != 0) {
printk(KERN_ERR "sn_hwperf_misc_register_init: failed to "
"register misc device for \"%s\"\n", sn_hwperf_dev.name);
}
return e;
}
device_initcall(sn_hwperf_misc_register_init); /* after misc_init() */
EXPORT_SYMBOL(sn_hwperf_get_nearest_node);

View File

@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved.
* Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
*/
#include <linux/config.h>
#include <asm/uaccess.h>
@ -15,7 +15,7 @@
static int partition_id_show(struct seq_file *s, void *p)
{
seq_printf(s, "%d\n", sn_local_partid());
seq_printf(s, "%d\n", sn_partition_id);
return 0;
}

View File

@ -1,7 +1,7 @@
/*
*
*
* Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved.
* Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License
@ -50,6 +50,7 @@ void sn_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
LED_CPU_HEARTBEAT, LED_CPU_HEARTBEAT);
}
if (is_shub1()) {
if (enable_shub_wars_1_1()) {
/* Bugfix code for SHUB 1.1 */
if (pda->pio_shub_war_cam_addr)
@ -60,4 +61,5 @@ void sn_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
pda->sn_lb_int_war_ticks++;
if (pda->sn_lb_int_war_ticks >= SN_LB_INT_WAR_INTERVAL)
pda->sn_lb_int_war_ticks = 0;
}
}

View File

@ -7,4 +7,4 @@
#
# Makefile for the sn pci general routines.
obj-y := pci_dma.o tioca_provider.o pcibr/
obj-y := pci_dma.o tioca_provider.o tioce_provider.o pcibr/

View File

@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2001-2004 Silicon Graphics, Inc. All rights reserved.
* Copyright (C) 2001-2005 Silicon Graphics, Inc. All rights reserved.
*/
#include <linux/types.h>
@ -215,8 +215,8 @@ void sn_dma_flush(uint64_t addr)
int is_tio;
int wid_num;
int i, j;
int bwin;
uint64_t flags;
uint64_t itte;
struct hubdev_info *hubinfo;
volatile struct sn_flush_device_list *p;
struct sn_flush_nasid_entry *flush_nasid_list;
@ -233,31 +233,36 @@ void sn_dma_flush(uint64_t addr)
if (!hubinfo) {
BUG();
}
is_tio = (nasid & 1);
if (is_tio) {
wid_num = TIO_SWIN_WIDGETNUM(addr);
bwin = TIO_BWIN_WINDOWNUM(addr);
} else {
wid_num = SWIN_WIDGETNUM(addr);
bwin = BWIN_WINDOWNUM(addr);
}
flush_nasid_list = &hubinfo->hdi_flush_nasid_list;
if (flush_nasid_list->widget_p == NULL)
return;
if (bwin > 0) {
uint64_t itte = flush_nasid_list->iio_itte[bwin];
is_tio = (nasid & 1);
if (is_tio) {
wid_num = (itte >> TIO_ITTE_WIDGET_SHIFT) &
TIO_ITTE_WIDGET_MASK;
} else {
wid_num = (itte >> IIO_ITTE_WIDGET_SHIFT) &
IIO_ITTE_WIDGET_MASK;
}
}
if (flush_nasid_list->widget_p == NULL)
int itte_index;
if (TIO_HWIN(addr))
itte_index = 0;
else if (TIO_BWIN_WINDOWNUM(addr))
itte_index = TIO_BWIN_WINDOWNUM(addr);
else
itte_index = -1;
if (itte_index >= 0) {
itte = flush_nasid_list->iio_itte[itte_index];
if (! TIO_ITTE_VALID(itte))
return;
wid_num = TIO_ITTE_WIDGET(itte);
} else
wid_num = TIO_SWIN_WIDGETNUM(addr);
} else {
if (BWIN_WINDOWNUM(addr)) {
itte = flush_nasid_list->iio_itte[BWIN_WINDOWNUM(addr)];
wid_num = IIO_ITTE_WIDGET(itte);
} else
wid_num = SWIN_WIDGETNUM(addr);
}
if (flush_nasid_list->widget_p[wid_num] == NULL)
return;
p = &flush_nasid_list->widget_p[wid_num][0];
@ -283,10 +288,16 @@ void sn_dma_flush(uint64_t addr)
/*
* For TIOCP use the Device(x) Write Request Buffer Flush Bridge
* register since it ensures the data has entered the coherence
* domain, unlike PIC
* domain, unlike PIC.
*/
if (is_tio) {
uint32_t tio_id = REMOTE_HUB_L(nasid, TIO_NODE_ID);
/*
* Note: devices behind TIOCE should never be matched in the
* above code, and so the following code is PIC/CP centric.
* If CE ever needs the sn_dma_flush mechanism, we will have
* to account for that here and in tioce_bus_fixup().
*/
uint32_t tio_id = HUB_L(TIO_IOSPACE_ADDR(nasid, TIO_NODE_ID));
uint32_t revnum = XWIDGET_PART_REV_NUM(tio_id);
/* TIOCP BRINGUP WAR (PV907516): Don't write buffer flush reg */
@ -306,7 +317,8 @@ void sn_dma_flush(uint64_t addr)
*(volatile uint32_t *)(p->sfdl_force_int_addr) = 1;
/* wait for the interrupt to come back. */
while (*(p->sfdl_flush_addr) != 0x10f) ;
while (*(p->sfdl_flush_addr) != 0x10f)
cpu_relax();
/* okay, everything is synched up. */
spin_unlock_irqrestore((spinlock_t *)&p->sfdl_flush_lock, flags);

View File

@ -15,6 +15,7 @@
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/pcidev.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/sn2/sn_hwperf.h>
#include "xtalk/xwidgetdev.h"
#include "xtalk/hubdev.h"
@ -60,7 +61,7 @@ static int sal_pcibr_error_interrupt(struct pcibus_info *soft)
ret_stuff.status = 0;
ret_stuff.v0 = 0;
segment = 0;
segment = soft->pbi_buscommon.bs_persist_segment;
busnum = soft->pbi_buscommon.bs_persist_busnum;
SAL_CALL_NOLOCK(ret_stuff,
(u64) SN_SAL_IOIF_ERROR_INTERRUPT,
@ -88,6 +89,7 @@ void *
pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller)
{
int nasid, cnode, j;
cnodeid_t near_cnode;
struct hubdev_info *hubdev_info;
struct pcibus_info *soft;
struct sn_flush_device_list *sn_flush_device_list;
@ -115,7 +117,7 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
/*
* register the bridge's error interrupt handler
*/
if (request_irq(SGI_PCIBR_ERROR, (void *)pcibr_error_intr_handler,
if (request_irq(SGI_PCIASIC_ERROR, (void *)pcibr_error_intr_handler,
SA_SHIRQ, "PCIBR error", (void *)(soft))) {
printk(KERN_WARNING
"pcibr cannot allocate interrupt for error handler\n");
@ -142,9 +144,12 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
j++, sn_flush_device_list++) {
if (sn_flush_device_list->sfdl_slot == -1)
continue;
if (sn_flush_device_list->
if ((sn_flush_device_list->
sfdl_persistent_segment ==
soft->pbi_buscommon.bs_persist_segment) &&
(sn_flush_device_list->
sfdl_persistent_busnum ==
soft->pbi_buscommon.bs_persist_busnum)
soft->pbi_buscommon.bs_persist_busnum))
sn_flush_device_list->sfdl_pcibus_info =
soft;
}
@ -158,12 +163,18 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
memset(soft->pbi_int_ate_resource.ate, 0,
(soft->pbi_int_ate_size * sizeof(uint64_t)));
if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP)
/*
* TIO PCI Bridge with no closest node information.
* FIXME: Find another way to determine the closest node
*/
controller->node = -1;
if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) {
/* TIO PCI Bridge: find nearest node with CPUs */
int e = sn_hwperf_get_nearest_node(cnode, NULL, &near_cnode);
if (e < 0) {
near_cnode = (cnodeid_t)-1; /* use any node */
printk(KERN_WARNING "pcibr_bus_fixup: failed to find "
"near node with CPUs to TIO node %d, err=%d\n",
cnode, e);
}
controller->node = near_cnode;
}
else
controller->node = cnode;
return soft;
@ -175,6 +186,9 @@ void pcibr_force_interrupt(struct sn_irq_info *sn_irq_info)
struct pcibus_info *pcibus_info;
int bit = sn_irq_info->irq_int_bit;
if (! sn_irq_info->irq_bridge)
return;
pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
if (pcidev_info) {
pcibus_info =
@ -184,7 +198,7 @@ void pcibr_force_interrupt(struct sn_irq_info *sn_irq_info)
}
}
void pcibr_change_devices_irq(struct sn_irq_info *sn_irq_info)
void pcibr_target_interrupt(struct sn_irq_info *sn_irq_info)
{
struct pcidev_info *pcidev_info;
struct pcibus_info *pcibus_info;
@ -219,6 +233,8 @@ struct sn_pcibus_provider pcibr_provider = {
.dma_map_consistent = pcibr_dma_map_consistent,
.dma_unmap = pcibr_dma_unmap,
.bus_fixup = pcibr_bus_fixup,
.force_interrupt = pcibr_force_interrupt,
.target_interrupt = pcibr_target_interrupt
};
int

View File

@ -559,7 +559,7 @@ tioca_error_intr_handler(int irq, void *arg, struct pt_regs *pt)
ret_stuff.status = 0;
ret_stuff.v0 = 0;
segment = 0;
segment = soft->ca_common.bs_persist_segment;
busnum = soft->ca_common.bs_persist_busnum;
SAL_CALL_NOLOCK(ret_stuff,
@ -622,7 +622,8 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
nasid_to_cnodeid(tioca_common->ca_closest_nasid);
tioca_common->ca_kernel_private = (uint64_t) tioca_kern;
bus = pci_find_bus(0, tioca_common->ca_common.bs_persist_busnum);
bus = pci_find_bus(tioca_common->ca_common.bs_persist_segment,
tioca_common->ca_common.bs_persist_busnum);
BUG_ON(!bus);
tioca_kern->ca_devices = &bus->devices;
@ -656,6 +657,8 @@ static struct sn_pcibus_provider tioca_pci_interfaces = {
.dma_map_consistent = tioca_dma_map,
.dma_unmap = tioca_dma_unmap,
.bus_fixup = tioca_bus_fixup,
.force_interrupt = NULL,
.target_interrupt = NULL
};
/**

View File

@ -0,0 +1,771 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2003-2005 Silicon Graphics, Inc. All Rights Reserved.
*/
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/addrs.h>
#include <asm/sn/pcidev.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/tioce_provider.h>
/**
* Bus address ranges for the 5 flavors of TIOCE DMA
*/
#define TIOCE_D64_MIN 0x8000000000000000UL
#define TIOCE_D64_MAX 0xffffffffffffffffUL
#define TIOCE_D64_ADDR(a) ((a) >= TIOCE_D64_MIN)
#define TIOCE_D32_MIN 0x0000000080000000UL
#define TIOCE_D32_MAX 0x00000000ffffffffUL
#define TIOCE_D32_ADDR(a) ((a) >= TIOCE_D32_MIN && (a) <= TIOCE_D32_MAX)
#define TIOCE_M32_MIN 0x0000000000000000UL
#define TIOCE_M32_MAX 0x000000007fffffffUL
#define TIOCE_M32_ADDR(a) ((a) >= TIOCE_M32_MIN && (a) <= TIOCE_M32_MAX)
#define TIOCE_M40_MIN 0x0000004000000000UL
#define TIOCE_M40_MAX 0x0000007fffffffffUL
#define TIOCE_M40_ADDR(a) ((a) >= TIOCE_M40_MIN && (a) <= TIOCE_M40_MAX)
#define TIOCE_M40S_MIN 0x0000008000000000UL
#define TIOCE_M40S_MAX 0x000000ffffffffffUL
#define TIOCE_M40S_ADDR(a) ((a) >= TIOCE_M40S_MIN && (a) <= TIOCE_M40S_MAX)
/*
* ATE manipulation macros.
*/
#define ATE_PAGESHIFT(ps) (__ffs(ps))
#define ATE_PAGEMASK(ps) ((ps)-1)
#define ATE_PAGE(x, ps) ((x) >> ATE_PAGESHIFT(ps))
#define ATE_NPAGES(start, len, pagesize) \
(ATE_PAGE((start)+(len)-1, pagesize) - ATE_PAGE(start, pagesize) + 1)
#define ATE_VALID(ate) ((ate) & (1UL << 63))
#define ATE_MAKE(addr, ps) (((addr) & ~ATE_PAGEMASK(ps)) | (1UL << 63))
/*
* Flavors of ate-based mapping supported by tioce_alloc_map()
*/
#define TIOCE_ATE_M32 1
#define TIOCE_ATE_M40 2
#define TIOCE_ATE_M40S 3
#define KB(x) ((x) << 10)
#define MB(x) ((x) << 20)
#define GB(x) ((x) << 30)
/**
* tioce_dma_d64 - create a DMA mapping using 64-bit direct mode
* @ct_addr: system coretalk address
*
* Map @ct_addr into 64-bit CE bus space. No device context is necessary
* and no CE mapping are consumed.
*
* Bits 53:0 come from the coretalk address. The remaining bits are set as
* follows:
*
* 63 - must be 1 to indicate d64 mode to CE hardware
* 62 - barrier bit ... controlled with tioce_dma_barrier()
* 61 - 0 since this is not an MSI transaction
* 60:54 - reserved, MBZ
*/
static uint64_t
tioce_dma_d64(unsigned long ct_addr)
{
uint64_t bus_addr;
bus_addr = ct_addr | (1UL << 63);
return bus_addr;
}
/**
* pcidev_to_tioce - return misc ce related pointers given a pci_dev
* @pci_dev: pci device context
* @base: ptr to store struct tioce_mmr * for the CE holding this device
* @kernel: ptr to store struct tioce_kernel * for the CE holding this device
* @port: ptr to store the CE port number that this device is on
*
* Return pointers to various CE-related structures for the CE upstream of
* @pci_dev.
*/
static inline void
pcidev_to_tioce(struct pci_dev *pdev, struct tioce **base,
struct tioce_kernel **kernel, int *port)
{
struct pcidev_info *pcidev_info;
struct tioce_common *ce_common;
struct tioce_kernel *ce_kernel;
pcidev_info = SN_PCIDEV_INFO(pdev);
ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info;
ce_kernel = (struct tioce_kernel *)ce_common->ce_kernel_private;
if (base)
*base = (struct tioce *)ce_common->ce_pcibus.bs_base;
if (kernel)
*kernel = ce_kernel;
/*
* we use port as a zero-based value internally, even though the
* documentation is 1-based.
*/
if (port)
*port =
(pdev->bus->number < ce_kernel->ce_port1_secondary) ? 0 : 1;
}
/**
* tioce_alloc_map - Given a coretalk address, map it to pcie bus address
* space using one of the various ATE-based address modes.
* @ce_kern: tioce context
* @type: map mode to use
* @port: 0-based port that the requesting device is downstream of
* @ct_addr: the coretalk address to map
* @len: number of bytes to map
*
* Given the addressing type, set up various paramaters that define the
* ATE pool to use. Search for a contiguous block of entries to cover the
* length, and if enough resources exist, fill in the ATE's and construct a
* tioce_dmamap struct to track the mapping.
*/
static uint64_t
tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
uint64_t ct_addr, int len)
{
int i;
int j;
int first;
int last;
int entries;
int nates;
int pagesize;
uint64_t *ate_shadow;
uint64_t *ate_reg;
uint64_t addr;
struct tioce *ce_mmr;
uint64_t bus_base;
struct tioce_dmamap *map;
ce_mmr = (struct tioce *)ce_kern->ce_common->ce_pcibus.bs_base;
switch (type) {
case TIOCE_ATE_M32:
/*
* The first 64 entries of the ate3240 pool are dedicated to
* super-page (TIOCE_ATE_M40S) mode.
*/
first = 64;
entries = TIOCE_NUM_M3240_ATES - 64;
ate_shadow = ce_kern->ce_ate3240_shadow;
ate_reg = ce_mmr->ce_ure_ate3240;
pagesize = ce_kern->ce_ate3240_pagesize;
bus_base = TIOCE_M32_MIN;
break;
case TIOCE_ATE_M40:
first = 0;
entries = TIOCE_NUM_M40_ATES;
ate_shadow = ce_kern->ce_ate40_shadow;
ate_reg = ce_mmr->ce_ure_ate40;
pagesize = MB(64);
bus_base = TIOCE_M40_MIN;
break;
case TIOCE_ATE_M40S:
/*
* ate3240 entries 0-31 are dedicated to port1 super-page
* mappings. ate3240 entries 32-63 are dedicated to port2.
*/
first = port * 32;
entries = 32;
ate_shadow = ce_kern->ce_ate3240_shadow;
ate_reg = ce_mmr->ce_ure_ate3240;
pagesize = GB(16);
bus_base = TIOCE_M40S_MIN;
break;
default:
return 0;
}
nates = ATE_NPAGES(ct_addr, len, pagesize);
if (nates > entries)
return 0;
last = first + entries - nates;
for (i = first; i <= last; i++) {
if (ATE_VALID(ate_shadow[i]))
continue;
for (j = i; j < i + nates; j++)
if (ATE_VALID(ate_shadow[j]))
break;
if (j >= i + nates)
break;
}
if (i > last)
return 0;
map = kcalloc(1, sizeof(struct tioce_dmamap), GFP_ATOMIC);
if (!map)
return 0;
addr = ct_addr;
for (j = 0; j < nates; j++) {
uint64_t ate;
ate = ATE_MAKE(addr, pagesize);
ate_shadow[i + j] = ate;
ate_reg[i + j] = ate;
addr += pagesize;
}
map->refcnt = 1;
map->nbytes = nates * pagesize;
map->ct_start = ct_addr & ~ATE_PAGEMASK(pagesize);
map->pci_start = bus_base + (i * pagesize);
map->ate_hw = &ate_reg[i];
map->ate_shadow = &ate_shadow[i];
map->ate_count = nates;
list_add(&map->ce_dmamap_list, &ce_kern->ce_dmamap_list);
return (map->pci_start + (ct_addr - map->ct_start));
}
/**
* tioce_dma_d32 - create a DMA mapping using 32-bit direct mode
* @pdev: linux pci_dev representing the function
* @paddr: system physical address
*
* Map @paddr into 32-bit bus space of the CE associated with @pcidev_info.
*/
static uint64_t
tioce_dma_d32(struct pci_dev *pdev, uint64_t ct_addr)
{
int dma_ok;
int port;
struct tioce *ce_mmr;
struct tioce_kernel *ce_kern;
uint64_t ct_upper;
uint64_t ct_lower;
dma_addr_t bus_addr;
ct_upper = ct_addr & ~0x3fffffffUL;
ct_lower = ct_addr & 0x3fffffffUL;
pcidev_to_tioce(pdev, &ce_mmr, &ce_kern, &port);
if (ce_kern->ce_port[port].dirmap_refcnt == 0) {
volatile uint64_t tmp;
ce_kern->ce_port[port].dirmap_shadow = ct_upper;
ce_mmr->ce_ure_dir_map[port] = ct_upper;
tmp = ce_mmr->ce_ure_dir_map[port];
dma_ok = 1;
} else
dma_ok = (ce_kern->ce_port[port].dirmap_shadow == ct_upper);
if (dma_ok) {
ce_kern->ce_port[port].dirmap_refcnt++;
bus_addr = TIOCE_D32_MIN + ct_lower;
} else
bus_addr = 0;
return bus_addr;
}
/**
* tioce_dma_barrier - swizzle a TIOCE bus address to include or exclude
* the barrier bit.
* @bus_addr: bus address to swizzle
*
* Given a TIOCE bus address, set the appropriate bit to indicate barrier
* attributes.
*/
static uint64_t
tioce_dma_barrier(uint64_t bus_addr, int on)
{
uint64_t barrier_bit;
/* barrier not supported in M40/M40S mode */
if (TIOCE_M40_ADDR(bus_addr) || TIOCE_M40S_ADDR(bus_addr))
return bus_addr;
if (TIOCE_D64_ADDR(bus_addr))
barrier_bit = (1UL << 62);
else /* must be m32 or d32 */
barrier_bit = (1UL << 30);
return (on) ? (bus_addr | barrier_bit) : (bus_addr & ~barrier_bit);
}
/**
* tioce_dma_unmap - release CE mapping resources
* @pdev: linux pci_dev representing the function
* @bus_addr: bus address returned by an earlier tioce_dma_map
* @dir: mapping direction (unused)
*
* Locate mapping resources associated with @bus_addr and release them.
* For mappings created using the direct modes there are no resources
* to release.
*/
void
tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
{
int i;
int port;
struct tioce_kernel *ce_kern;
struct tioce *ce_mmr;
unsigned long flags;
bus_addr = tioce_dma_barrier(bus_addr, 0);
pcidev_to_tioce(pdev, &ce_mmr, &ce_kern, &port);
/* nothing to do for D64 */
if (TIOCE_D64_ADDR(bus_addr))
return;
spin_lock_irqsave(&ce_kern->ce_lock, flags);
if (TIOCE_D32_ADDR(bus_addr)) {
if (--ce_kern->ce_port[port].dirmap_refcnt == 0) {
ce_kern->ce_port[port].dirmap_shadow = 0;
ce_mmr->ce_ure_dir_map[port] = 0;
}
} else {
struct tioce_dmamap *map;
list_for_each_entry(map, &ce_kern->ce_dmamap_list,
ce_dmamap_list) {
uint64_t last;
last = map->pci_start + map->nbytes - 1;
if (bus_addr >= map->pci_start && bus_addr <= last)
break;
}
if (&map->ce_dmamap_list == &ce_kern->ce_dmamap_list) {
printk(KERN_WARNING
"%s: %s - no map found for bus_addr 0x%lx\n",
__FUNCTION__, pci_name(pdev), bus_addr);
} else if (--map->refcnt == 0) {
for (i = 0; i < map->ate_count; i++) {
map->ate_shadow[i] = 0;
map->ate_hw[i] = 0;
}
list_del(&map->ce_dmamap_list);
kfree(map);
}
}
spin_unlock_irqrestore(&ce_kern->ce_lock, flags);
}
/**
* tioce_do_dma_map - map pages for PCI DMA
* @pdev: linux pci_dev representing the function
* @paddr: host physical address to map
* @byte_count: bytes to map
*
* This is the main wrapper for mapping host physical pages to CE PCI space.
* The mapping mode used is based on the device's dma_mask.
*/
static uint64_t
tioce_do_dma_map(struct pci_dev *pdev, uint64_t paddr, size_t byte_count,
int barrier)
{
unsigned long flags;
uint64_t ct_addr;
uint64_t mapaddr = 0;
struct tioce_kernel *ce_kern;
struct tioce_dmamap *map;
int port;
uint64_t dma_mask;
dma_mask = (barrier) ? pdev->dev.coherent_dma_mask : pdev->dma_mask;
/* cards must be able to address at least 31 bits */
if (dma_mask < 0x7fffffffUL)
return 0;
ct_addr = PHYS_TO_TIODMA(paddr);
/*
* If the device can generate 64 bit addresses, create a D64 map.
* Since this should never fail, bypass the rest of the checks.
*/
if (dma_mask == ~0UL) {
mapaddr = tioce_dma_d64(ct_addr);
goto dma_map_done;
}
pcidev_to_tioce(pdev, NULL, &ce_kern, &port);
spin_lock_irqsave(&ce_kern->ce_lock, flags);
/*
* D64 didn't work ... See if we have an existing map that covers
* this address range. Must account for devices dma_mask here since
* an existing map might have been done in a mode using more pci
* address bits than this device can support.
*/
list_for_each_entry(map, &ce_kern->ce_dmamap_list, ce_dmamap_list) {
uint64_t last;
last = map->ct_start + map->nbytes - 1;
if (ct_addr >= map->ct_start &&
ct_addr + byte_count - 1 <= last &&
map->pci_start <= dma_mask) {
map->refcnt++;
mapaddr = map->pci_start + (ct_addr - map->ct_start);
break;
}
}
/*
* If we don't have a map yet, and the card can generate 40
* bit addresses, try the M40/M40S modes. Note these modes do not
* support a barrier bit, so if we need a consistent map these
* won't work.
*/
if (!mapaddr && !barrier && dma_mask >= 0xffffffffffUL) {
/*
* We have two options for 40-bit mappings: 16GB "super" ATE's
* and 64MB "regular" ATE's. We'll try both if needed for a
* given mapping but which one we try first depends on the
* size. For requests >64MB, prefer to use a super page with
* regular as the fallback. Otherwise, try in the reverse order.
*/
if (byte_count > MB(64)) {
mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40S,
port, ct_addr, byte_count);
if (!mapaddr)
mapaddr =
tioce_alloc_map(ce_kern, TIOCE_ATE_M40, -1,
ct_addr, byte_count);
} else {
mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40, -1,
ct_addr, byte_count);
if (!mapaddr)
mapaddr =
tioce_alloc_map(ce_kern, TIOCE_ATE_M40S,
port, ct_addr, byte_count);
}
}
/*
* 32-bit direct is the next mode to try
*/
if (!mapaddr && dma_mask >= 0xffffffffUL)
mapaddr = tioce_dma_d32(pdev, ct_addr);
/*
* Last resort, try 32-bit ATE-based map.
*/
if (!mapaddr)
mapaddr =
tioce_alloc_map(ce_kern, TIOCE_ATE_M32, -1, ct_addr,
byte_count);
spin_unlock_irqrestore(&ce_kern->ce_lock, flags);
dma_map_done:
if (mapaddr & barrier)
mapaddr = tioce_dma_barrier(mapaddr, 1);
return mapaddr;
}
/**
* tioce_dma - standard pci dma map interface
* @pdev: pci device requesting the map
* @paddr: system physical address to map into pci space
* @byte_count: # bytes to map
*
* Simply call tioce_do_dma_map() to create a map with the barrier bit clear
* in the address.
*/
static uint64_t
tioce_dma(struct pci_dev *pdev, uint64_t paddr, size_t byte_count)
{
return tioce_do_dma_map(pdev, paddr, byte_count, 0);
}
/**
* tioce_dma_consistent - consistent pci dma map interface
* @pdev: pci device requesting the map
* @paddr: system physical address to map into pci space
* @byte_count: # bytes to map
*
* Simply call tioce_do_dma_map() to create a map with the barrier bit set
* in the address.
*/ static uint64_t
tioce_dma_consistent(struct pci_dev *pdev, uint64_t paddr, size_t byte_count)
{
return tioce_do_dma_map(pdev, paddr, byte_count, 1);
}
/**
* tioce_error_intr_handler - SGI TIO CE error interrupt handler
* @irq: unused
* @arg: pointer to tioce_common struct for the given CE
* @pt: unused
*
* Handle a CE error interrupt. Simply a wrapper around a SAL call which
* defers processing to the SGI prom.
*/ static irqreturn_t
tioce_error_intr_handler(int irq, void *arg, struct pt_regs *pt)
{
struct tioce_common *soft = arg;
struct ia64_sal_retval ret_stuff;
ret_stuff.status = 0;
ret_stuff.v0 = 0;
SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_ERROR_INTERRUPT,
soft->ce_pcibus.bs_persist_segment,
soft->ce_pcibus.bs_persist_busnum, 0, 0, 0, 0, 0);
return IRQ_HANDLED;
}
/**
* tioce_kern_init - init kernel structures related to a given TIOCE
* @tioce_common: ptr to a cached tioce_common struct that originated in prom
*/ static struct tioce_kernel *
tioce_kern_init(struct tioce_common *tioce_common)
{
int i;
uint32_t tmp;
struct tioce *tioce_mmr;
struct tioce_kernel *tioce_kern;
tioce_kern = kcalloc(1, sizeof(struct tioce_kernel), GFP_KERNEL);
if (!tioce_kern) {
return NULL;
}
tioce_kern->ce_common = tioce_common;
spin_lock_init(&tioce_kern->ce_lock);
INIT_LIST_HEAD(&tioce_kern->ce_dmamap_list);
tioce_common->ce_kernel_private = (uint64_t) tioce_kern;
/*
* Determine the secondary bus number of the port2 logical PPB.
* This is used to decide whether a given pci device resides on
* port1 or port2. Note: We don't have enough plumbing set up
* here to use pci_read_config_xxx() so use the raw_pci_ops vector.
*/
raw_pci_ops->read(tioce_common->ce_pcibus.bs_persist_segment,
tioce_common->ce_pcibus.bs_persist_busnum,
PCI_DEVFN(2, 0), PCI_SECONDARY_BUS, 1, &tmp);
tioce_kern->ce_port1_secondary = (uint8_t) tmp;
/*
* Set PMU pagesize to the largest size available, and zero out
* the ate's.
*/
tioce_mmr = (struct tioce *)tioce_common->ce_pcibus.bs_base;
tioce_mmr->ce_ure_page_map &= ~CE_URE_PAGESIZE_MASK;
tioce_mmr->ce_ure_page_map |= CE_URE_256K_PAGESIZE;
tioce_kern->ce_ate3240_pagesize = KB(256);
for (i = 0; i < TIOCE_NUM_M40_ATES; i++) {
tioce_kern->ce_ate40_shadow[i] = 0;
tioce_mmr->ce_ure_ate40[i] = 0;
}
for (i = 0; i < TIOCE_NUM_M3240_ATES; i++) {
tioce_kern->ce_ate3240_shadow[i] = 0;
tioce_mmr->ce_ure_ate3240[i] = 0;
}
return tioce_kern;
}
/**
* tioce_force_interrupt - implement altix force_interrupt() backend for CE
* @sn_irq_info: sn asic irq that we need an interrupt generated for
*
* Given an sn_irq_info struct, set the proper bit in ce_adm_force_int to
* force a secondary interrupt to be generated. This is to work around an
* asic issue where there is a small window of opportunity for a legacy device
* interrupt to be lost.
*/
static void
tioce_force_interrupt(struct sn_irq_info *sn_irq_info)
{
struct pcidev_info *pcidev_info;
struct tioce_common *ce_common;
struct tioce *ce_mmr;
uint64_t force_int_val;
if (!sn_irq_info->irq_bridge)
return;
if (sn_irq_info->irq_bridge_type != PCIIO_ASIC_TYPE_TIOCE)
return;
pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
if (!pcidev_info)
return;
ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info;
ce_mmr = (struct tioce *)ce_common->ce_pcibus.bs_base;
/*
* irq_int_bit is originally set up by prom, and holds the interrupt
* bit shift (not mask) as defined by the bit definitions in the
* ce_adm_int mmr. These shifts are not the same for the
* ce_adm_force_int register, so do an explicit mapping here to make
* things clearer.
*/
switch (sn_irq_info->irq_int_bit) {
case CE_ADM_INT_PCIE_PORT1_DEV_A_SHFT:
force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT1_DEV_A_SHFT;
break;
case CE_ADM_INT_PCIE_PORT1_DEV_B_SHFT:
force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT1_DEV_B_SHFT;
break;
case CE_ADM_INT_PCIE_PORT1_DEV_C_SHFT:
force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT1_DEV_C_SHFT;
break;
case CE_ADM_INT_PCIE_PORT1_DEV_D_SHFT:
force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT1_DEV_D_SHFT;
break;
case CE_ADM_INT_PCIE_PORT2_DEV_A_SHFT:
force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT2_DEV_A_SHFT;
break;
case CE_ADM_INT_PCIE_PORT2_DEV_B_SHFT:
force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT2_DEV_B_SHFT;
break;
case CE_ADM_INT_PCIE_PORT2_DEV_C_SHFT:
force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT2_DEV_C_SHFT;
break;
case CE_ADM_INT_PCIE_PORT2_DEV_D_SHFT:
force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT2_DEV_D_SHFT;
break;
default:
return;
}
ce_mmr->ce_adm_force_int = force_int_val;
}
/**
* tioce_target_interrupt - implement set_irq_affinity for tioce resident
* functions. Note: only applies to line interrupts, not MSI's.
*
* @sn_irq_info: SN IRQ context
*
* Given an sn_irq_info, set the associated CE device's interrupt destination
* register. Since the interrupt destination registers are on a per-ce-slot
* basis, this will retarget line interrupts for all functions downstream of
* the slot.
*/
static void
tioce_target_interrupt(struct sn_irq_info *sn_irq_info)
{
struct pcidev_info *pcidev_info;
struct tioce_common *ce_common;
struct tioce *ce_mmr;
int bit;
pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
if (!pcidev_info)
return;
ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info;
ce_mmr = (struct tioce *)ce_common->ce_pcibus.bs_base;
bit = sn_irq_info->irq_int_bit;
ce_mmr->ce_adm_int_mask |= (1UL << bit);
ce_mmr->ce_adm_int_dest[bit] =
((uint64_t)sn_irq_info->irq_irq << INTR_VECTOR_SHFT) |
sn_irq_info->irq_xtalkaddr;
ce_mmr->ce_adm_int_mask &= ~(1UL << bit);
tioce_force_interrupt(sn_irq_info);
}
/**
* tioce_bus_fixup - perform final PCI fixup for a TIO CE bus
* @prom_bussoft: Common prom/kernel struct representing the bus
*
* Replicates the tioce_common pointed to by @prom_bussoft in kernel
* space. Allocates and initializes a kernel-only area for a given CE,
* and sets up an irq for handling CE error interrupts.
*
* On successful setup, returns the kernel version of tioce_common back to
* the caller.
*/
static void *
tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller)
{
struct tioce_common *tioce_common;
/*
* Allocate kernel bus soft and copy from prom.
*/
tioce_common = kcalloc(1, sizeof(struct tioce_common), GFP_KERNEL);
if (!tioce_common)
return NULL;
memcpy(tioce_common, prom_bussoft, sizeof(struct tioce_common));
tioce_common->ce_pcibus.bs_base |= __IA64_UNCACHED_OFFSET;
if (tioce_kern_init(tioce_common) == NULL) {
kfree(tioce_common);
return NULL;
}
if (request_irq(SGI_PCIASIC_ERROR,
tioce_error_intr_handler,
SA_SHIRQ, "TIOCE error", (void *)tioce_common))
printk(KERN_WARNING
"%s: Unable to get irq %d. "
"Error interrupts won't be routed for "
"TIOCE bus %04x:%02x\n",
__FUNCTION__, SGI_PCIASIC_ERROR,
tioce_common->ce_pcibus.bs_persist_segment,
tioce_common->ce_pcibus.bs_persist_busnum);
return tioce_common;
}
static struct sn_pcibus_provider tioce_pci_interfaces = {
.dma_map = tioce_dma,
.dma_map_consistent = tioce_dma_consistent,
.dma_unmap = tioce_dma_unmap,
.bus_fixup = tioce_bus_fixup,
.force_interrupt = tioce_force_interrupt,
.target_interrupt = tioce_target_interrupt
};
/**
* tioce_init_provider - init SN PCI provider ops for TIO CE
*/
int
tioce_init_provider(void)
{
sn_pci_provider[PCIIO_ASIC_TYPE_TIOCE] = &tioce_pci_interfaces;
return 0;
}

View File

@ -71,21 +71,31 @@ config M5206e
help
Motorola ColdFire 5206e processor support.
config M523x
bool "MCF523x"
help
Freescale Coldfire 5230/1/2/4/5 processor support
config M5249
bool "MCF5249"
help
Motorola ColdFire 5249 processor support.
config M527x
bool "MCF527x"
config M5271
bool "MCF5271"
help
Freescale (Motorola) ColdFire 5270/5271/5274/5275 processor support.
Freescale (Motorola) ColdFire 5270/5271 processor support.
config M5272
bool "MCF5272"
help
Motorola ColdFire 5272 processor support.
config M5275
bool "MCF5275"
help
Freescale (Motorola) ColdFire 5274/5275 processor support.
config M528x
bool "MCF528x"
help
@ -103,9 +113,14 @@ config M5407
endchoice
config M527x
bool
depends on (M5271 || M5275)
default y
config COLDFIRE
bool
depends on (M5206 || M5206e || M5249 || M527x || M5272 || M528x || M5307 || M5407)
depends on (M5206 || M5206e || M523x || M5249 || M527x || M5272 || M528x || M5307 || M5407)
default y
choice
@ -183,6 +198,11 @@ config CLOCK_60MHz
help
Select a 60MHz CPU clock frequency.
config CLOCK_62_5MHz
bool "62.5MHz"
help
Select a 62.5MHz CPU clock frequency.
config CLOCK_64MHz
bool "64MHz"
help
@ -302,6 +322,12 @@ config ELITE
help
Support for the Motorola M5206eLITE board.
config M5235EVB
bool "Freescale M5235EVB support"
depends on M523x
help
Support for the Freescale M5235EVB board.
config M5249C3
bool "Motorola M5249C3 board support"
depends on M5249
@ -310,13 +336,13 @@ config M5249C3
config M5271EVB
bool "Freescale (Motorola) M5271EVB board support"
depends on M527x
depends on M5271
help
Support for the Freescale (Motorola) M5271EVB board.
config M5275EVB
bool "Freescale (Motorola) M5275EVB board support"
depends on M527x
depends on M5275
help
Support for the Freescale (Motorola) M5275EVB board.
@ -344,6 +370,12 @@ config COBRA5282
help
Support for the senTec COBRA5282 board.
config SOM5282EM
bool "EMAC.Inc SOM5282EM board support"
depends on M528x
help
Support for the EMAC.Inc SOM5282EM module.
config ARN5307
bool "Arnewsh 5307 board support"
depends on M5307
@ -410,6 +442,12 @@ config CPU16B
help
Support for the SNEHA CPU16B board.
config MOD5272
bool "Netburner MOD-5272 board support"
depends on M5272
help
Support for the Netburner MOD-5272 board.
config ROMFS_FROM_ROM
bool " ROMFS image not RAM resident"
depends on (NETtel || SNAPGEAR)
@ -430,7 +468,7 @@ config ARNEWSH
config MOTOROLA
bool
default y
depends on (M5206eC3 || M5249C3 || M5271EVB || M5272C3 || M5275EVB || M5282EVB || M5307C3 || M5407C3)
depends on (M5206eC3 || M5235EVB || M5249C3 || M5271EVB || M5272C3 || M5275EVB || M5282EVB || M5307C3 || M5407C3)
config HW_FEITH
bool
@ -442,6 +480,11 @@ config senTec
default y
depends on (COBRA5272 || COBRA5282)
config EMAC_INC
bool
default y
depends on (SOM5282EM)
config SNEHA
bool
default y
@ -455,6 +498,15 @@ config LARGE_ALLOCS
a lot of RAM, and you need to able to allocate very large
contiguous chunks. If unsure, say N.
config 4KSTACKS
bool "Use 4Kb for kernel stacks instead of 8Kb"
default y
help
If you say Y here the kernel will use a 4Kb stacksize for the
kernel stack attached to each process/thread. This facilitates
running more threads on a system and also reduces the pressure
on the VM subsystem for higher order allocations.
choice
prompt "RAM size"
default AUTO

View File

@ -14,6 +14,7 @@ platform-$(CONFIG_M68VZ328) := 68VZ328
platform-$(CONFIG_M68360) := 68360
platform-$(CONFIG_M5206) := 5206
platform-$(CONFIG_M5206e) := 5206e
platform-$(CONFIG_M523x) := 523x
platform-$(CONFIG_M5249) := 5249
platform-$(CONFIG_M527x) := 527x
platform-$(CONFIG_M5272) := 5272
@ -29,6 +30,7 @@ board-$(CONFIG_UCQUICC) := uCquicc
board-$(CONFIG_DRAGEN2) := de2
board-$(CONFIG_ARNEWSH) := ARNEWSH
board-$(CONFIG_MOTOROLA) := MOTOROLA
board-$(CONFIG_M5235EVB) := M5235EVB
board-$(CONFIG_M5271EVB) := M5271EVB
board-$(CONFIG_M5275EVB) := M5275EVB
board-$(CONFIG_M5282EVB) := M5282EVB
@ -39,6 +41,7 @@ board-$(CONFIG_SECUREEDGEMP3) := MP3
board-$(CONFIG_CLEOPATRA) := CLEOPATRA
board-$(CONFIG_senTec) := senTec
board-$(CONFIG_SNEHA) := SNEHA
board-$(CONFIG_MOD5272) := MOD5272
BOARD := $(board-y)
model-$(CONFIG_RAMKERNEL) := ram
@ -53,6 +56,7 @@ MODEL := $(model-y)
#
cpuclass-$(CONFIG_M5206) := 5307
cpuclass-$(CONFIG_M5206e) := 5307
cpuclass-$(CONFIG_M523x) := 5307
cpuclass-$(CONFIG_M5249) := 5307
cpuclass-$(CONFIG_M527x) := 5307
cpuclass-$(CONFIG_M5272) := 5307
@ -76,6 +80,7 @@ export PLATFORM BOARD MODEL CPUCLASS
#
cflags-$(CONFIG_M5206) := -m5200 -Wa,-S -Wa,-m5200
cflags-$(CONFIG_M5206e) := -m5200 -Wa,-S -Wa,-m5200
cflags-$(CONFIG_M523x) := -m5307 -Wa,-S -Wa,-m5307
cflags-$(CONFIG_M5249) := -m5200 -Wa,-S -Wa,-m5200
cflags-$(CONFIG_M527x) := -m5307 -Wa,-S -Wa,-m5307
cflags-$(CONFIG_M5272) := -m5307 -Wa,-S -Wa,-m5307

View File

@ -1,24 +1,48 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.13-uc0
# Wed Aug 31 15:03:26 2005
#
CONFIG_M68KNOMMU=y
# CONFIG_MMU is not set
# CONFIG_FPU is not set
CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
CONFIG_GENERIC_CALIBRATE_DELAY=y
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
# CONFIG_SYSVIPC is not set
CONFIG_LOCALVERSION=""
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_SYSCTL is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_AUDIT is not set
# CONFIG_HOTPLUG is not set
# CONFIG_KOBJECT_UEVENT is not set
# CONFIG_IKCONFIG is not set
CONFIG_EMBEDDED=y
# CONFIG_KALLSYMS is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_BASE_FULL=y
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_CC_ALIGN_FUNCTIONS=0
CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
CONFIG_BASE_SMALL=0
#
# Loadable module support
@ -34,9 +58,11 @@ CONFIG_LOG_BUF_SHIFT=14
# CONFIG_M68360 is not set
# CONFIG_M5206 is not set
# CONFIG_M5206e is not set
# CONFIG_M523x is not set
# CONFIG_M5249 is not set
# CONFIG_M527x is not set
# CONFIG_M5271 is not set
CONFIG_M5272=y
# CONFIG_M5275 is not set
# CONFIG_M528x is not set
# CONFIG_M5307 is not set
# CONFIG_M5407 is not set
@ -54,6 +80,8 @@ CONFIG_COLDFIRE=y
# CONFIG_CLOCK_50MHz is not set
# CONFIG_CLOCK_54MHz is not set
# CONFIG_CLOCK_60MHz is not set
# CONFIG_CLOCK_62_5MHz is not set
# CONFIG_CLOCK_64MHz is not set
CONFIG_CLOCK_66MHz=y
# CONFIG_CLOCK_70MHz is not set
# CONFIG_CLOCK_100MHz is not set
@ -65,13 +93,19 @@ CONFIG_CLOCK_66MHz=y
# Platform
#
CONFIG_M5272C3=y
# CONFIG_COBRA5272 is not set
# CONFIG_CANCam is not set
# CONFIG_SCALES is not set
# CONFIG_NETtel is not set
# CONFIG_CPU16B is not set
# CONFIG_MOD5272 is not set
CONFIG_MOTOROLA=y
# CONFIG_LARGE_ALLOCS is not set
# CONFIG_RAMAUTO is not set
CONFIG_4KSTACKS=y
CONFIG_RAMAUTO=y
# CONFIG_RAM4MB is not set
# CONFIG_RAM8MB is not set
CONFIG_RAM16MB=y
# CONFIG_RAM16MB is not set
# CONFIG_RAM32MB is not set
CONFIG_RAMAUTOBIT=y
# CONFIG_RAM8BIT is not set
@ -79,33 +113,117 @@ CONFIG_RAMAUTOBIT=y
# CONFIG_RAM32BIT is not set
CONFIG_RAMKERNEL=y
# CONFIG_ROMKERNEL is not set
# CONFIG_HIMEMKERNEL 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
#
# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
#
# CONFIG_PCI is not set
# CONFIG_HOTPLUG is not set
#
# PCCARD (PCMCIA/CardBus) support
#
# CONFIG_PCCARD is not set
#
# PCI Hotplug Support
#
#
# Executable file formats
#
CONFIG_KCORE_AOUT=y
CONFIG_BINFMT_FLAT=y
# CONFIG_BINFMT_ZFLAT is not set
# CONFIG_BINFMT_SHARED_FLAT is not set
# CONFIG_BINFMT_MISC is not set
#
# Power management options
#
# CONFIG_PM is not set
#
# Networking
#
CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_FIB_HASH=y
# CONFIG_IP_PNP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_ARPD is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_TUNNEL is not set
# CONFIG_IP_TCPDIAG is not set
# CONFIG_IP_TCPDIAG_IPV6 is not set
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
# CONFIG_IPV6 is not set
# CONFIG_NETFILTER 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
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
#
# Device Drivers
#
#
# Generic Driver Options
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
@ -116,35 +234,50 @@ CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
#
# RAM/ROM/Flash chip drivers
#
# CONFIG_MTD_CFI is not set
# CONFIG_MTD_JEDECPROBE 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=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
CONFIG_MTD_RAM=y
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
# CONFIG_MTD_OBSOLETE_CHIPS is not set
#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_UCLINUX=y
# CONFIG_MTD_SNAPGEARuC is not set
# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
#
# CONFIG_MTD_SLRAM is not set
# 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
#
# CONFIG_MTD_DOC1000 is not set
# CONFIG_MTD_DOC2000 is not set
# CONFIG_MTD_DOC2001 is not set
# CONFIG_MTD_DOC2001PLUS is not set
#
# NAND Flash Device Drivers
@ -159,21 +292,32 @@ CONFIG_MTD_UCLINUX=y
#
# Plug and Play support
#
# CONFIG_PNP is not set
#
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_BLK_DEV_BLKMEM is not set
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CDROM_PKTCDVD is not set
#
# ATA/IDE/MFM/RLL support
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
# CONFIG_IOSCHED_AS is not set
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
# CONFIG_ATA_OVER_ETH is not set
#
# ATA/ATAPI/MFM/RLL support
#
# CONFIG_IDE is not set
@ -190,121 +334,75 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
#
# Fusion MPT device support
#
# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
#
#
# I2O device support
#
#
# Networking support
# Network device support
#
CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
# CONFIG_NETLINK_DEV is not set
# CONFIG_NETFILTER is not set
# CONFIG_FILTER is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
# CONFIG_IP_PNP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_ARPD is not set
# CONFIG_INET_ECN is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_XFRM_USER is not set
# CONFIG_IPV6 is not set
#
# SCTP Configuration (EXPERIMENTAL)
#
CONFIG_IPV6_SCTP__=y
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_LLC is not set
# CONFIG_DECNET is not set
# CONFIG_BRIDGE 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_HW_FLOWCONTROL is not set
#
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_ETHERTAP is not set
#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NE2000 is not set
# CONFIG_NET_PCI is not set
CONFIG_FEC=y
# CONFIG_FEC2 is not set
#
# Ethernet (1000 Mbit)
#
CONFIG_PPP=y
# CONFIG_PPP_MULTILINK is not set
# CONFIG_PPP_ASYNC is not set
# CONFIG_PPP_SYNC_TTY is not set
# CONFIG_PPP_DEFLATE is not set
# CONFIG_PPP_BSDCOMP is not set
# CONFIG_PPPOE is not set
# CONFIG_SLIP is not set
#
# Ethernet (10000 Mbit)
#
#
# Token Ring devices
#
#
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
#
# Token Ring devices (depends on LLC=y)
#
# CONFIG_SHAPER is not set
#
# Wan interfaces
#
# CONFIG_WAN is not set
#
# Amateur Radio support
#
# CONFIG_HAMRADIO is not set
#
# IrDA (infrared) support
#
# CONFIG_IRDA is not set
CONFIG_PPP=y
# CONFIG_PPP_MULTILINK is not set
# CONFIG_PPP_FILTER is not set
# CONFIG_PPP_ASYNC is not set
# CONFIG_PPP_SYNC_TTY is not set
# CONFIG_PPP_DEFLATE is not set
# CONFIG_PPP_BSDCOMP is not set
# CONFIG_PPPOE is not set
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
#
# CONFIG_ISDN_BOOL is not set
# CONFIG_ISDN is not set
#
# Telephony Support
@ -314,50 +412,20 @@ CONFIG_PPP=y
#
# Input device support
#
CONFIG_INPUT=y
# CONFIG_INPUT is not set
#
# Userland interfaces
#
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 is not set
#
# Input I/O drivers
# Hardware I/O ports
#
# CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set
CONFIG_SOUND_GAMEPORT=y
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_CT82C710 is not set
#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_SUNKBD 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_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
#
# Character devices
#
# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_LEDMAN is not set
# CONFIG_RESETSWITCH is not set
#
@ -370,25 +438,8 @@ CONFIG_MOUSE_PS2=y
#
CONFIG_SERIAL_COLDFIRE=y
# CONFIG_UNIX98_PTYS is not set
#
# I2C support
#
# CONFIG_I2C is not set
#
# I2C Hardware Sensors Mainboard support
#
#
# I2C Hardware Sensors Chip support
#
#
# Mice
#
# CONFIG_BUSMOUSE is not set
# CONFIG_QIC02_TAPE is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
#
# IPMI
@ -399,40 +450,114 @@ CONFIG_SERIAL_COLDFIRE=y
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
# CONFIG_NVRAM is not set
# CONFIG_MCFWATCHDOG is not set
# CONFIG_RTC is not set
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
#
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
# CONFIG_AGP is not set
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_HANGCHECK_TIMER is not set
#
# TPM devices
#
# CONFIG_MCF_QSPI is not set
# CONFIG_M41T11M6 is not set
#
# I2C support
#
# CONFIG_I2C is not set
# CONFIG_I2C_SENSOR is not set
#
# Dallas's 1-wire bus
#
# CONFIG_W1 is not set
#
# Hardware Monitoring support
#
# CONFIG_HWMON is not set
#
# Misc devices
#
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
#
# Digital Video Broadcasting Devices
#
# CONFIG_DVB is not set
#
# Graphics support
#
# CONFIG_FB is not set
#
# SPI support
#
# CONFIG_SPI is not set
#
# Sound
#
# CONFIG_SOUND is not set
#
# USB support
#
# CONFIG_USB_ARCH_HAS_HCD is not set
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
#
# MMC/SD Card support
#
# CONFIG_MMC is not set
#
# InfiniBand support
#
#
# SN Devices
#
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP 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 is not set
#
# XFS support
#
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
CONFIG_ROMFS_FS=y
CONFIG_MAGIC_ROM_PTR=y
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
# CONFIG_DNOTIFY is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
@ -445,15 +570,17 @@ CONFIG_ROMFS_FS=y
#
# DOS/FAT/NT Filesystems
#
# CONFIG_FAT_FS is not set
# CONFIG_MSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_NTFS_FS is not set
#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
# CONFIG_DEVFS_FS is not set
CONFIG_SYSFS=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
#
@ -462,6 +589,7 @@ CONFIG_RAMFS=y
# 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
@ -479,12 +607,10 @@ CONFIG_RAMFS=y
#
# CONFIG_NFS_FS is not set
# CONFIG_NFSD is not set
# CONFIG_EXPORTFS 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_INTERMEZZO_FS is not set
# CONFIG_AFS_FS is not set
#
@ -494,30 +620,19 @@ CONFIG_RAMFS=y
CONFIG_MSDOS_PARTITION=y
#
# Graphics support
# Native Language Support
#
# CONFIG_FB is not set
#
# Sound
#
# CONFIG_SOUND is not set
#
# USB support
#
#
# Bluetooth support
#
# CONFIG_BT is not set
# CONFIG_NLS is not set
#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_FULLDEBUG is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_HIGHPROFILE is not set
# CONFIG_BOOTPARAM is not set
# CONFIG_DUMPTOFLASH is not set
# CONFIG_NO_KERNEL_MSG is not set
# CONFIG_BDM_DISABLE is not set
@ -525,6 +640,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
#
@ -532,7 +648,13 @@ CONFIG_MSDOS_PARTITION=y
#
# CONFIG_CRYPTO is not set
#
# Hardware crypto devices
#
#
# Library routines
#
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC32 is not set
# CONFIG_LIBCRC32C is not set

View File

@ -23,6 +23,7 @@
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/fb.h>
#include <linux/module.h>
#include <linux/console.h>
#include <linux/genhd.h>
#include <linux/errno.h>
@ -45,6 +46,9 @@ unsigned long rom_length;
unsigned long memory_start;
unsigned long memory_end;
EXPORT_SYMBOL(memory_start);
EXPORT_SYMBOL(memory_end);
char command_line[COMMAND_LINE_SIZE];
/* setup some dummy routines */
@ -103,15 +107,21 @@ void (*mach_power_off)( void ) = NULL;
#if defined(CONFIG_M5206e)
#define CPU "COLDFIRE(m5206e)"
#endif
#if defined(CONFIG_M523x)
#define CPU "COLDFIRE(m523x)"
#endif
#if defined(CONFIG_M5249)
#define CPU "COLDFIRE(m5249)"
#endif
#if defined(CONFIG_M527x)
#define CPU "COLDFIRE(m5270/5271/5274/5275)"
#if defined(CONFIG_M5271)
#define CPU "COLDFIRE(m5270/5271)"
#endif
#if defined(CONFIG_M5272)
#define CPU "COLDFIRE(m5272)"
#endif
#if defined(CONFIG_M5275)
#define CPU "COLDFIRE(m5274/5275)"
#endif
#if defined(CONFIG_M528x)
#define CPU "COLDFIRE(m5280/5282)"
#endif
@ -200,6 +210,9 @@ void setup_arch(char **cmdline_p)
#ifdef CONFIG_DRAGEN2
printk(KERN_INFO "DragonEngine II board support by Georges Menie\n");
#endif
#ifdef CONFIG_M5235EVB
printk(KERN_INFO "Motorola M5235EVB support (C)2005 Syn-tech Systems, Inc. (Jate Sujjavanich)");
#endif
#ifdef DEBUG
printk(KERN_DEBUG "KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x "

View File

@ -21,6 +21,7 @@
#include <linux/signal.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/a.out.h>
#include <linux/user.h>
@ -38,7 +39,7 @@
#include <asm/machdep.h>
#include <asm/siginfo.h>
static char *vec_names[] = {
static char const * const vec_names[] = {
"RESET SP", "RESET PC", "BUS ERROR", "ADDRESS ERROR",
"ILLEGAL INSTRUCTION", "ZERO DIVIDE", "CHK", "TRAPcc",
"PRIVILEGE VIOLATION", "TRACE", "LINE 1010", "LINE 1111",
@ -106,17 +107,20 @@ asmlinkage void buserr_c(struct frame *fp)
int kstack_depth_to_print = 48;
void show_stack(struct task_struct *task, unsigned long *esp)
void show_stack(struct task_struct *task, unsigned long *stack)
{
unsigned long *stack, *endstack, addr;
unsigned long *endstack, addr;
extern char _start, _etext;
int i;
if (esp == NULL)
esp = (unsigned long *) &esp;
if (!stack) {
if (task)
stack = (unsigned long *)task->thread.ksp;
else
stack = (unsigned long *)&stack;
}
stack = esp;
addr = (unsigned long) esp;
addr = (unsigned long) stack;
endstack = (unsigned long *) PAGE_ALIGN(addr);
printk(KERN_EMERG "Stack from %08lx:", (unsigned long)stack);
@ -306,6 +310,8 @@ void dump_stack(void)
show_stack(current, &stack);
}
EXPORT_SYMBOL(dump_stack);
#ifdef CONFIG_M68KFPU_EMU
asmlinkage void fpemu_signal(int signal, int code, void *addr)
{

View File

@ -107,7 +107,7 @@
*/
#if defined(CONFIG_ELITE)
#define RAM_START 0x30020000
#define RAM_END 0xe0000
#define RAM_LENGTH 0xe0000
#endif
/*
@ -118,7 +118,8 @@
#if defined(CONFIG_M5206eC3) || defined(CONFIG_M5249C3) || \
defined(CONFIG_M5272C3) || defined(CONFIG_M5307C3) || \
defined(CONFIG_ARN5307) || defined(CONFIG_M5407C3) || \
defined(CONFIG_M5271EVB) || defined(CONFIG_M5275EVB)
defined(CONFIG_M5271EVB) || defined(CONFIG_M5275EVB) || \
defined(CONFIG_M5235EVB)
#define RAM_START 0x20000
#define RAM_LENGTH 0x3e0000
#endif
@ -145,6 +146,16 @@
#define RAM_LENGTH 0x3f0000
#endif
/*
* The EMAC SoM-5282EM module.
*/
#if defined(CONFIG_SOM5282EM)
#define RAM_START 0x10000
#define RAM_LENGTH 0xff0000
#endif
/*
* These flash boot boards use all of ram for operation. Again the
* actual memory size is not important here, assume at least 4MiB.
@ -158,7 +169,7 @@
#endif
/*
* Sneha Boards mimimun memmory
* Sneha Boards mimimun memory
* The end of RAM will vary depending on how much ram is fitted,
* but this isn't important here, we assume at least 4MiB.
*/
@ -167,6 +178,12 @@
#define RAM_LENGTH 0x3e0000
#endif
#if defined(CONFIG_MOD5272)
#define RAM_START 0x02000000
#define RAM_LENGTH 0x00800000
#define RAMVEC_START 0x20000000
#define RAMVEC_LENGTH 0x00000400
#endif
#if defined(CONFIG_RAMKERNEL)
#define TEXT ram

View File

@ -0,0 +1,82 @@
/***************************************************************************/
/*
* linux/arch/m68knommu/platform/523x/config.c
*
* Sub-architcture dependant initialization code for the Freescale
* 523x CPUs.
*
* Copyright (C) 1999-2005, Greg Ungerer (gerg@snapgear.com)
* Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
*/
/***************************************************************************/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/param.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/dma.h>
#include <asm/traps.h>
#include <asm/machdep.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfdma.h>
/***************************************************************************/
void coldfire_pit_tick(void);
void coldfire_pit_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
unsigned long coldfire_pit_offset(void);
void coldfire_trap_init(void);
void coldfire_reset(void);
/***************************************************************************/
/*
* DMA channel base address table.
*/
unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS] = {
MCF_MBAR + MCFDMA_BASE0,
};
unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
/***************************************************************************/
void mcf_disableall(void)
{
*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff;
}
/***************************************************************************/
void mcf_autovector(unsigned int vec)
{
/* Everything is auto-vectored on the 5272 */
}
/***************************************************************************/
void config_BSP(char *commandp, int size)
{
mcf_disableall();
#ifdef CONFIG_BOOTPARAM
strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
commandp[size-1] = 0;
#else
memset(commandp, 0, size);
#endif
mach_sched_init = coldfire_pit_init;
mach_tick = coldfire_pit_tick;
mach_gettimeoffset = coldfire_pit_offset;
mach_trap_init = coldfire_trap_init;
mach_reset = coldfire_reset;
}
/***************************************************************************/

View File

@ -39,14 +39,18 @@
* Memory size exceptions for special cases. Some boards may be set
* for auto memory sizing, but we can't do it that way for some reason.
* For example the 5206eLITE board has static RAM, and auto-detecting
* the SDRAM will do you no good at all.
* the SDRAM will do you no good at all. Same goes for the MOD5272.
*/
#ifdef CONFIG_RAMAUTO
#if defined(CONFIG_M5206eLITE)
#define MEM_SIZE 0x00100000 /* 1MiB default memory */
#endif
#if defined(CONFIG_MOD5272)
#define MEM_SIZE 0x00800000 /* 8MiB default memory */
#endif
#endif /* CONFIG_RAMAUTO */
/*
* If we don't have a fixed memory size now, then lets build in code
* to auto detect the DRAM size. Obviously this is the prefered
@ -100,11 +104,15 @@
/*
* Most ColdFire boards have their DRAM starting at address 0.
* Notable exception is the 5206eLITE board.
* Notable exception is the 5206eLITE board, another is the MOD5272.
*/
#if defined(CONFIG_M5206eLITE)
#define MEM_BASE 0x30000000
#endif
#if defined(CONFIG_MOD5272)
#define MEM_BASE 0x02000000
#define VBR_BASE 0x20000000 /* vectors in SRAM */
#endif
#ifndef MEM_BASE
#define MEM_BASE 0x00000000 /* memory base at address 0 */
@ -188,6 +196,7 @@ _start:
movel %a7,_rambase
GET_MEM_SIZE /* macro code determines size */
addl %a7,%d0
movel %d0,_ramend /* set end ram addr */
/*

View File

@ -79,7 +79,7 @@ ENTRY(system_call)
movel %sp@(PT_ORIG_D0),%d0
movel %sp,%d1 /* get thread_info pointer */
andl #0xffffe000,%d1
andl #-THREAD_SIZE,%d1
movel %d1,%a2
btst #TIF_SYSCALL_TRACE,%a2@(TI_FLAGS)
jne do_trace
@ -105,7 +105,7 @@ Luser_return:
andw #ALLOWINT,%sr
movel %sp,%d1 /* get thread_info pointer */
andl #0xffffe000,%d1
andl #-THREAD_SIZE,%d1
movel %d1,%a2
move %a2@(TI_FLAGS),%d1 /* thread_info->flags */
andl #_TIF_WORK_MASK,%d1

View File

@ -96,7 +96,7 @@ Luser_return:
andw #ALLOWINT,%sr
movel %sp,%d1 /* get thread_info pointer */
andl #0xffffe000,%d1
andl #-THREAD_SIZE,%d1
movel %d1,%a2
move %a2@(TI_FLAGS),%d1 /* thread_info->flags */
andl #_TIF_WORK_MASK,%d1

View File

@ -21,11 +21,13 @@ CC := $(CC) -m32
endif
LDFLAGS_vmlinux := -Ttext $(KERNELLOAD) -Bstatic
CPPFLAGS += -Iarch/$(ARCH)
CPPFLAGS += -Iarch/$(ARCH) -Iinclude3
AFLAGS += -Iarch/$(ARCH)
CFLAGS += -Iarch/$(ARCH) -msoft-float -pipe \
-ffixed-r2 -mmultiple
CPP = $(CC) -E $(CFLAGS)
# Temporary hack until we have migrated to asm-powerpc
LINUXINCLUDE += -Iinclude3
CHECKFLAGS += -D__powerpc__
@ -101,6 +103,7 @@ endef
archclean:
$(Q)$(MAKE) $(clean)=arch/ppc/boot
$(Q)rm -rf include3
prepare: include/asm-$(ARCH)/offsets.h checkbin
@ -110,6 +113,12 @@ arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
include/asm-$(ARCH)/offsets.h: arch/$(ARCH)/kernel/asm-offsets.s
$(call filechk,gen-asm-offsets)
# Temporary hack until we have migrated to asm-powerpc
include/asm: include3/asm
include3/asm:
$(Q)if [ ! -d include3 ]; then mkdir -p include3; fi
$(Q)ln -fsn $(srctree)/include/asm-powerpc include3/asm
# Use the file '.tmp_gas_check' for binutils tests, as gas won't output
# to stdout and these checks are run even on install targets.
TOUT := .tmp_gas_check

View File

@ -1,203 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#define ElfHeaderSize (64 * 1024)
#define ElfPages (ElfHeaderSize / 4096)
#define KERNELBASE (0xc0000000)
void get4k(FILE *file, char *buf )
{
unsigned j;
unsigned num = fread(buf, 1, 4096, file);
for ( j=num; j<4096; ++j )
buf[j] = 0;
}
void put4k(FILE *file, char *buf )
{
fwrite(buf, 1, 4096, file);
}
void death(const char *msg, FILE *fdesc, const char *fname)
{
printf(msg);
fclose(fdesc);
unlink(fname);
exit(1);
}
int main(int argc, char **argv)
{
char inbuf[4096];
FILE *ramDisk = NULL;
FILE *inputVmlinux = NULL;
FILE *outputVmlinux = NULL;
unsigned i = 0;
u_int32_t ramFileLen = 0;
u_int32_t ramLen = 0;
u_int32_t roundR = 0;
u_int32_t kernelLen = 0;
u_int32_t actualKernelLen = 0;
u_int32_t round = 0;
u_int32_t roundedKernelLen = 0;
u_int32_t ramStartOffs = 0;
u_int32_t ramPages = 0;
u_int32_t roundedKernelPages = 0;
u_int32_t hvReleaseData = 0;
u_int32_t eyeCatcher = 0xc8a5d9c4;
u_int32_t naca = 0;
u_int32_t xRamDisk = 0;
u_int32_t xRamDiskSize = 0;
if ( argc < 2 ) {
printf("Name of RAM disk file missing.\n");
exit(1);
}
if ( argc < 3 ) {
printf("Name of vmlinux file missing.\n");
exit(1);
}
if ( argc < 4 ) {
printf("Name of vmlinux output file missing.\n");
exit(1);
}
ramDisk = fopen(argv[1], "r");
if ( ! ramDisk ) {
printf("RAM disk file \"%s\" failed to open.\n", argv[1]);
exit(1);
}
inputVmlinux = fopen(argv[2], "r");
if ( ! inputVmlinux ) {
printf("vmlinux file \"%s\" failed to open.\n", argv[2]);
exit(1);
}
outputVmlinux = fopen(argv[3], "w+");
if ( ! outputVmlinux ) {
printf("output vmlinux file \"%s\" failed to open.\n", argv[3]);
exit(1);
}
fseek(ramDisk, 0, SEEK_END);
ramFileLen = ftell(ramDisk);
fseek(ramDisk, 0, SEEK_SET);
printf("%s file size = %d\n", argv[1], ramFileLen);
ramLen = ramFileLen;
roundR = 4096 - (ramLen % 4096);
if ( roundR ) {
printf("Rounding RAM disk file up to a multiple of 4096, adding %d\n", roundR);
ramLen += roundR;
}
printf("Rounded RAM disk size is %d\n", ramLen);
fseek(inputVmlinux, 0, SEEK_END);
kernelLen = ftell(inputVmlinux);
fseek(inputVmlinux, 0, SEEK_SET);
printf("kernel file size = %d\n", kernelLen);
if ( kernelLen == 0 ) {
printf("You must have a linux kernel specified as argv[2]\n");
exit(1);
}
actualKernelLen = kernelLen - ElfHeaderSize;
printf("actual kernel length (minus ELF header) = %d\n", actualKernelLen);
round = actualKernelLen % 4096;
roundedKernelLen = actualKernelLen;
if ( round )
roundedKernelLen += (4096 - round);
printf("actual kernel length rounded up to a 4k multiple = %d\n", roundedKernelLen);
ramStartOffs = roundedKernelLen;
ramPages = ramLen / 4096;
printf("RAM disk pages to copy = %d\n", ramPages);
// Copy 64K ELF header
for (i=0; i<(ElfPages); ++i) {
get4k( inputVmlinux, inbuf );
put4k( outputVmlinux, inbuf );
}
roundedKernelPages = roundedKernelLen / 4096;
fseek(inputVmlinux, ElfHeaderSize, SEEK_SET);
for ( i=0; i<roundedKernelPages; ++i ) {
get4k( inputVmlinux, inbuf );
put4k( outputVmlinux, inbuf );
}
for ( i=0; i<ramPages; ++i ) {
get4k( ramDisk, inbuf );
put4k( outputVmlinux, inbuf );
}
/* Close the input files */
fclose(ramDisk);
fclose(inputVmlinux);
/* And flush the written output file */
fflush(outputVmlinux);
/* fseek to the hvReleaseData pointer */
fseek(outputVmlinux, ElfHeaderSize + 0x24, SEEK_SET);
if (fread(&hvReleaseData, 4, 1, outputVmlinux) != 1) {
death("Could not read hvReleaseData pointer\n", outputVmlinux, argv[3]);
}
hvReleaseData = ntohl(hvReleaseData); /* Convert to native int */
printf("hvReleaseData is at %08x\n", hvReleaseData);
/* fseek to the hvReleaseData */
fseek(outputVmlinux, ElfHeaderSize + hvReleaseData, SEEK_SET);
if (fread(inbuf, 0x40, 1, outputVmlinux) != 1) {
death("Could not read hvReleaseData\n", outputVmlinux, argv[3]);
}
/* Check hvReleaseData sanity */
if (memcmp(inbuf, &eyeCatcher, 4) != 0) {
death("hvReleaseData is invalid\n", outputVmlinux, argv[3]);
}
/* Get the naca pointer */
naca = ntohl(*((u_int32_t *) &inbuf[0x0c])) - KERNELBASE;
printf("naca is at %08x\n", naca);
/* fseek to the naca */
fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET);
if (fread(inbuf, 0x18, 1, outputVmlinux) != 1) {
death("Could not read naca\n", outputVmlinux, argv[3]);
}
xRamDisk = ntohl(*((u_int32_t *) &inbuf[0x0c]));
xRamDiskSize = ntohl(*((u_int32_t *) &inbuf[0x14]));
/* Make sure a RAM disk isn't already present */
if ((xRamDisk != 0) || (xRamDiskSize != 0)) {
death("RAM disk is already attached to this kernel\n", outputVmlinux, argv[3]);
}
/* Fill in the values */
*((u_int32_t *) &inbuf[0x0c]) = htonl(ramStartOffs);
*((u_int32_t *) &inbuf[0x14]) = htonl(ramPages);
/* Write out the new naca */
fflush(outputVmlinux);
fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET);
if (fwrite(inbuf, 0x18, 1, outputVmlinux) != 1) {
death("Could not write naca\n", outputVmlinux, argv[3]);
}
printf("RAM Disk of 0x%x pages size is attached to the kernel at offset 0x%08x\n",
ramPages, ramStartOffs);
/* Done */
fclose(outputVmlinux);
/* Set permission to executable */
chmod(argv[3], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
return 0;
}

View File

@ -249,8 +249,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_NO_DPM)
sync
isync
/* Enable L2 HW prefetch
/* Enable L2 HW prefetch, if L2 is enabled
*/
mfspr r3,SPRN_L2CR
andis. r3,r3,L2CR_L2E@h
beqlr
mfspr r3,SPRN_MSSCR0
ori r3,r3,3
sync

View File

@ -156,6 +156,26 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
The bit moved on the 7450.....
****/
BEGIN_FTR_SECTION
/* Disable L2 prefetch on some 745x and try to ensure
* L2 prefetch engines are idle. As explained by errata
* text, we can't be sure they are, we just hope very hard
* that well be enough (sic !). At least I noticed Apple
* doesn't even bother doing the dcbf's here...
*/
mfspr r4,SPRN_MSSCR0
rlwinm r4,r4,0,0,29
sync
mtspr SPRN_MSSCR0,r4
sync
isync
lis r4,KERNELBASE@h
dcbf 0,r4
dcbf 0,r4
dcbf 0,r4
dcbf 0,r4
END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
/* TODO: use HW flush assist when available */
lis r4,0x0002
@ -231,6 +251,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
mtspr SPRN_L2CR,r3
sync
/* Enable L2 HW prefetch on 744x/745x */
BEGIN_FTR_SECTION
mfspr r3,SPRN_MSSCR0
ori r3,r3,3
sync
mtspr SPRN_MSSCR0,r3
sync
isync
END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
4:
/* Restore HID0[DPM] to whatever it was before */

View File

@ -57,7 +57,7 @@ unsigned char __res[sizeof(bd_t)];
extern void m8xx_ide_init(void);
extern unsigned long find_available_memory(void);
extern void m8xx_cpm_reset();
extern void m8xx_cpm_reset(void);
extern void m8xx_wdt_handler_install(bd_t *bp);
extern void rpxfb_alloc_pages(void);
extern void cpm_interrupt_init(void);
@ -266,8 +266,8 @@ m8xx_show_percpuinfo(struct seq_file *m, int i)
bp = (bd_t *)__res;
seq_printf(m, "clock\t\t: %ldMHz\n"
"bus clock\t: %ldMHz\n",
seq_printf(m, "clock\t\t: %uMHz\n"
"bus clock\t: %uMHz\n",
bp->bi_intfreq / 1000000,
bp->bi_busfreq / 1000000);

View File

@ -302,12 +302,6 @@ config GENERIC_HARDIRQS
bool
default y
config MSCHUNKS
bool
depends on PPC_ISERIES
default y
config PPC_RTAS
bool
depends on PPC_PSERIES || PPC_BPA
@ -350,13 +344,46 @@ config SECCOMP
If unsure, say Y. Only embedded should say N here.
source "fs/Kconfig.binfmt"
config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs"
depends on SMP && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC)
select HOTPLUG
---help---
Say Y here to be able to turn CPUs off and on.
Say N if you are unsure.
config PROC_DEVICETREE
bool "Support for Open Firmware device tree in /proc"
depends on !PPC_ISERIES
help
This option adds a device-tree directory under /proc which contains
an image of the device tree that the kernel copies from Open
Firmware. If unsure, say Y here.
config CMDLINE_BOOL
bool "Default bootloader kernel arguments"
depends on !PPC_ISERIES
config CMDLINE
string "Initial kernel command string"
depends on CMDLINE_BOOL
default "console=ttyS0,9600 console=tty0 root=/dev/sda2"
help
On some platforms, there is currently no way for the boot loader to
pass arguments to the kernel. For these platforms, you can supply
some command-line options at build time by entering them here. In
most cases you will need to specify the root device here.
endmenu
config ISA_DMA_API
bool
default y
menu "General setup"
menu "Bus Options"
config ISA
bool
@ -389,45 +416,12 @@ config PCI_DOMAINS
bool
default PCI
source "fs/Kconfig.binfmt"
source "drivers/pci/Kconfig"
config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs"
depends on SMP && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC)
select HOTPLUG
---help---
Say Y here to be able to turn CPUs off and on.
Say N if you are unsure.
source "drivers/pcmcia/Kconfig"
source "drivers/pci/hotplug/Kconfig"
config PROC_DEVICETREE
bool "Support for Open Firmware device tree in /proc"
depends on !PPC_ISERIES
help
This option adds a device-tree directory under /proc which contains
an image of the device tree that the kernel copies from Open
Firmware. If unsure, say Y here.
config CMDLINE_BOOL
bool "Default bootloader kernel arguments"
depends on !PPC_ISERIES
config CMDLINE
string "Initial kernel command string"
depends on CMDLINE_BOOL
default "console=ttyS0,9600 console=tty0 root=/dev/sda2"
help
On some platforms, there is currently no way for the boot loader to
pass arguments to the kernel. For these platforms, you can supply
some command-line options at build time by entering them here. In
most cases you will need to specify the root device here.
endmenu
source "net/Kconfig"

View File

@ -55,6 +55,8 @@ LDFLAGS := -m elf64ppc
LDFLAGS_vmlinux := -Bstatic -e $(KERNELLOAD) -Ttext $(KERNELLOAD)
CFLAGS += -msoft-float -pipe -mminimal-toc -mtraceback=none \
-mcall-aixdesc
# Temporary hack until we have migrated to asm-powerpc
CPPFLAGS += -Iinclude3
GCC_VERSION := $(call cc-version)
GCC_BROKEN_VEC := $(shell if [ $(GCC_VERSION) -lt 0400 ] ; then echo "y"; fi ;)
@ -112,6 +114,7 @@ all: $(KBUILD_IMAGE)
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
$(Q)rm -rf include3
prepare: include/asm-ppc64/offsets.h
@ -121,6 +124,12 @@ arch/ppc64/kernel/asm-offsets.s: include/asm include/linux/version.h \
include/asm-ppc64/offsets.h: arch/ppc64/kernel/asm-offsets.s
$(call filechk,gen-asm-offsets)
# Temporary hack until we have migrated to asm-powerpc
include/asm: include3/asm
include3/asm:
$(Q)if [ ! -d include3 ]; then mkdir -p include3; fi;
$(Q)ln -fsn $(srctree)/include/asm-powerpc include3/asm
define archhelp
echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
echo ' zImage.initrd- Compressed kernel image with initrd attached,'

View File

@ -22,8 +22,8 @@
HOSTCC := gcc
BOOTCFLAGS := $(HOSTCFLAGS) $(LINUXINCLUDE) -fno-builtin
BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional
BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem $(shell $(CROSS32CC) -print-file-name=include)
BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
BOOTLFLAGS := -Ttext 0x00400000 -e _start -T $(srctree)/$(src)/zImage.lds
OBJCOPYFLAGS := contents,alloc,load,readonly,data

View File

@ -157,7 +157,7 @@ main(int ac, char **av)
PUT_32BE(ns, strlen(arch) + 1);
PUT_32BE(ns + 4, N_DESCR * 4);
PUT_32BE(ns + 8, 0x1275);
strcpy(&buf[ns + 12], arch);
strcpy((char *) &buf[ns + 12], arch);
ns += 12 + strlen(arch) + 1;
for (i = 0; i < N_DESCR; ++i, ns += 4)
PUT_32BE(ns, descr[i]);
@ -172,7 +172,7 @@ main(int ac, char **av)
PUT_32BE(ns, strlen(rpaname) + 1);
PUT_32BE(ns + 4, sizeof(rpanote));
PUT_32BE(ns + 8, 0x12759999);
strcpy(&buf[ns + 12], rpaname);
strcpy((char *) &buf[ns + 12], rpaname);
ns += 12 + ROUNDUP(strlen(rpaname) + 1);
for (i = 0; i < N_RPA_DESCR; ++i, ns += 4)
PUT_32BE(ns, rpanote[i]);

View File

@ -9,7 +9,7 @@
* NOTE: this code runs in 32 bit mode and is packaged as ELF32.
*/
#include <asm/ppc_asm.h>
#include "ppc_asm.h"
.text
.globl _start

View File

@ -13,7 +13,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <asm/ppc_asm.h>
#include "ppc_asm.h"
.globl __div64_32
__div64_32:

149
arch/ppc64/boot/elf.h Normal file
View File

@ -0,0 +1,149 @@
#ifndef _PPC_BOOT_ELF_H_
#define _PPC_BOOT_ELF_H_
/* 32-bit ELF base types. */
typedef unsigned int Elf32_Addr;
typedef unsigned short Elf32_Half;
typedef unsigned int Elf32_Off;
typedef signed int Elf32_Sword;
typedef unsigned int Elf32_Word;
/* 64-bit ELF base types. */
typedef unsigned long long Elf64_Addr;
typedef unsigned short Elf64_Half;
typedef signed short Elf64_SHalf;
typedef unsigned long long Elf64_Off;
typedef signed int Elf64_Sword;
typedef unsigned int Elf64_Word;
typedef unsigned long long Elf64_Xword;
typedef signed long long Elf64_Sxword;
/* These constants are for the segment types stored in the image headers */
#define PT_NULL 0
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_INTERP 3
#define PT_NOTE 4
#define PT_SHLIB 5
#define PT_PHDR 6
#define PT_TLS 7 /* Thread local storage segment */
#define PT_LOOS 0x60000000 /* OS-specific */
#define PT_HIOS 0x6fffffff /* OS-specific */
#define PT_LOPROC 0x70000000
#define PT_HIPROC 0x7fffffff
#define PT_GNU_EH_FRAME 0x6474e550
#define PT_GNU_STACK (PT_LOOS + 0x474e551)
/* These constants define the different elf file types */
#define ET_NONE 0
#define ET_REL 1
#define ET_EXEC 2
#define ET_DYN 3
#define ET_CORE 4
#define ET_LOPROC 0xff00
#define ET_HIPROC 0xffff
/* These constants define the various ELF target machines */
#define EM_NONE 0
#define EM_PPC 20 /* PowerPC */
#define EM_PPC64 21 /* PowerPC64 */
#define EI_NIDENT 16
typedef struct elf32_hdr {
unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry; /* Entry point */
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
} Elf32_Ehdr;
typedef struct elf64_hdr {
unsigned char e_ident[16]; /* ELF "magic number" */
Elf64_Half e_type;
Elf64_Half e_machine;
Elf64_Word e_version;
Elf64_Addr e_entry; /* Entry point virtual address */
Elf64_Off e_phoff; /* Program header table file offset */
Elf64_Off e_shoff; /* Section header table file offset */
Elf64_Word e_flags;
Elf64_Half e_ehsize;
Elf64_Half e_phentsize;
Elf64_Half e_phnum;
Elf64_Half e_shentsize;
Elf64_Half e_shnum;
Elf64_Half e_shstrndx;
} Elf64_Ehdr;
/* These constants define the permissions on sections in the program
header, p_flags. */
#define PF_R 0x4
#define PF_W 0x2
#define PF_X 0x1
typedef struct elf32_phdr {
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
} Elf32_Phdr;
typedef struct elf64_phdr {
Elf64_Word p_type;
Elf64_Word p_flags;
Elf64_Off p_offset; /* Segment file offset */
Elf64_Addr p_vaddr; /* Segment virtual address */
Elf64_Addr p_paddr; /* Segment physical address */
Elf64_Xword p_filesz; /* Segment size in file */
Elf64_Xword p_memsz; /* Segment size in memory */
Elf64_Xword p_align; /* Segment alignment, file & memory */
} Elf64_Phdr;
#define EI_MAG0 0 /* e_ident[] indexes */
#define EI_MAG1 1
#define EI_MAG2 2
#define EI_MAG3 3
#define EI_CLASS 4
#define EI_DATA 5
#define EI_VERSION 6
#define EI_OSABI 7
#define EI_PAD 8
#define ELFMAG0 0x7f /* EI_MAG */
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'
#define ELFMAG "\177ELF"
#define SELFMAG 4
#define ELFCLASSNONE 0 /* EI_CLASS */
#define ELFCLASS32 1
#define ELFCLASS64 2
#define ELFCLASSNUM 3
#define ELFDATANONE 0 /* e_ident[EI_DATA] */
#define ELFDATA2LSB 1
#define ELFDATA2MSB 2
#define EV_NONE 0 /* e_version, EI_VERSION */
#define EV_CURRENT 1
#define EV_NUM 2
#define ELFOSABI_NONE 0
#define ELFOSABI_LINUX 3
#endif /* _PPC_BOOT_ELF_H_ */

View File

@ -8,36 +8,28 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include "ppc32-types.h"
#include <stdarg.h>
#include <stddef.h>
#include "elf.h"
#include "page.h"
#include "string.h"
#include "stdio.h"
#include "prom.h"
#include "zlib.h"
#include <linux/elf.h>
#include <linux/string.h>
#include <asm/processor.h>
#include <asm/page.h>
extern void *finddevice(const char *);
extern int getprop(void *, const char *, void *, int);
extern void printf(const char *fmt, ...);
extern int sprintf(char *buf, const char *fmt, ...);
void gunzip(void *, int, unsigned char *, int *);
void *claim(unsigned int, unsigned int, unsigned int);
void flush_cache(void *, unsigned long);
void pause(void);
extern void exit(void);
static void gunzip(void *, int, unsigned char *, int *);
extern void flush_cache(void *, unsigned long);
unsigned long strlen(const char *s);
void *memmove(void *dest, const void *src, unsigned long n);
void *memcpy(void *dest, const void *src, unsigned long n);
/* Value picked to match that used by yaboot */
#define PROG_START 0x01400000
#define RAM_END (256<<20) // Fixme: use OF */
char *avail_ram;
char *begin_avail, *end_avail;
char *avail_high;
unsigned int heap_use;
unsigned int heap_max;
static char *avail_ram;
static char *begin_avail, *end_avail;
static char *avail_high;
static unsigned int heap_use;
static unsigned int heap_max;
extern char _start[];
extern char _vmlinux_start[];
@ -52,9 +44,9 @@ struct addr_range {
unsigned long size;
unsigned long memsize;
};
struct addr_range vmlinux = {0, 0, 0};
struct addr_range vmlinuz = {0, 0, 0};
struct addr_range initrd = {0, 0, 0};
static struct addr_range vmlinux = {0, 0, 0};
static struct addr_range vmlinuz = {0, 0, 0};
static struct addr_range initrd = {0, 0, 0};
static char scratch[128<<10]; /* 128kB of scratch space for gunzip */
@ -64,13 +56,6 @@ typedef void (*kernel_entry_t)( unsigned long,
void *);
int (*prom)(void *);
void *chosen_handle;
void *stdin;
void *stdout;
void *stderr;
#undef DEBUG
static unsigned long claim_base = PROG_START;
@ -277,7 +262,7 @@ void zfree(void *x, void *addr, unsigned nb)
#define DEFLATED 8
void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
{
z_stream s;
int r, i, flags;

34
arch/ppc64/boot/page.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef _PPC_BOOT_PAGE_H
#define _PPC_BOOT_PAGE_H
/*
* Copyright (C) 2001 PPC64 Team, IBM Corp
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifdef __ASSEMBLY__
#define ASM_CONST(x) x
#else
#define __ASM_CONST(x) x##UL
#define ASM_CONST(x) __ASM_CONST(x)
#endif
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 12
#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
/* align addr on a size boundary - adjust address up/down if needed */
#define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
#define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1)))
/* align addr on a size boundary - adjust address up if needed */
#define _ALIGN(addr,size) _ALIGN_UP(addr,size)
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE)
#endif /* _PPC_BOOT_PAGE_H */

View File

@ -1,36 +0,0 @@
#ifndef _PPC64_TYPES_H
#define _PPC64_TYPES_H
typedef __signed__ char __s8;
typedef unsigned char __u8;
typedef __signed__ short __s16;
typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
typedef __signed__ long long __s64;
typedef unsigned long long __u64;
typedef signed char s8;
typedef unsigned char u8;
typedef signed short s16;
typedef unsigned short u16;
typedef signed int s32;
typedef unsigned int u32;
typedef signed long long s64;
typedef unsigned long long u64;
typedef struct {
__u32 u[4];
} __attribute((aligned(16))) __vector128;
#define BITS_PER_LONG 32
typedef __vector128 vector128;
#endif /* _PPC64_TYPES_H */

62
arch/ppc64/boot/ppc_asm.h Normal file
View File

@ -0,0 +1,62 @@
#ifndef _PPC64_PPC_ASM_H
#define _PPC64_PPC_ASM_H
/*
*
* Definitions used by various bits of low-level assembly code on PowerPC.
*
* Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan.
*
* 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.
*/
/* Condition Register Bit Fields */
#define cr0 0
#define cr1 1
#define cr2 2
#define cr3 3
#define cr4 4
#define cr5 5
#define cr6 6
#define cr7 7
/* General Purpose Registers (GPRs) */
#define r0 0
#define r1 1
#define r2 2
#define r3 3
#define r4 4
#define r5 5
#define r6 6
#define r7 7
#define r8 8
#define r9 9
#define r10 10
#define r11 11
#define r12 12
#define r13 13
#define r14 14
#define r15 15
#define r16 16
#define r17 17
#define r18 18
#define r19 19
#define r20 20
#define r21 21
#define r22 22
#define r23 23
#define r24 24
#define r25 25
#define r26 26
#define r27 27
#define r28 28
#define r29 29
#define r30 30
#define r31 31
#endif /* _PPC64_PPC_ASM_H */

View File

@ -7,43 +7,19 @@
* 2 of the License, or (at your option) any later version.
*/
#include <stdarg.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/ctype.h>
extern __u32 __div64_32(unsigned long long *dividend, __u32 divisor);
/* The unnecessary pointer compare is there
* to check for type safety (n must be 64bit)
*/
# define do_div(n,base) ({ \
__u32 __base = (base); \
__u32 __rem; \
(void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \
if (((n) >> 32) == 0) { \
__rem = (__u32)(n) % __base; \
(n) = (__u32)(n) / __base; \
} else \
__rem = __div64_32(&(n), __base); \
__rem; \
})
#include <stddef.h>
#include "string.h"
#include "stdio.h"
#include "prom.h"
int (*prom)(void *);
void *chosen_handle;
void *stdin;
void *stdout;
void *stderr;
void exit(void);
void *finddevice(const char *name);
int getprop(void *phandle, const char *name, void *buf, int buflen);
void chrpboot(int a1, int a2, void *prom); /* in main.c */
int printf(char *fmt, ...);
/* there is no convenient header to get this from... -- paulus */
extern unsigned long strlen(const char *);
int
write(void *handle, void *ptr, int nb)
@ -210,107 +186,6 @@ fputs(char *str, void *f)
return write(f, str, n) == n? 0: -1;
}
int
readchar(void)
{
char ch;
for (;;) {
switch (read(stdin, &ch, 1)) {
case 1:
return ch;
case -1:
printf("read(stdin) returned -1\r\n");
return -1;
}
}
}
static char line[256];
static char *lineptr;
static int lineleft;
int
getchar(void)
{
int c;
if (lineleft == 0) {
lineptr = line;
for (;;) {
c = readchar();
if (c == -1 || c == 4)
break;
if (c == '\r' || c == '\n') {
*lineptr++ = '\n';
putchar('\n');
break;
}
switch (c) {
case 0177:
case '\b':
if (lineptr > line) {
putchar('\b');
putchar(' ');
putchar('\b');
--lineptr;
}
break;
case 'U' & 0x1F:
while (lineptr > line) {
putchar('\b');
putchar(' ');
putchar('\b');
--lineptr;
}
break;
default:
if (lineptr >= &line[sizeof(line) - 1])
putchar('\a');
else {
putchar(c);
*lineptr++ = c;
}
}
}
lineleft = lineptr - line;
lineptr = line;
}
if (lineleft == 0)
return -1;
--lineleft;
return *lineptr++;
}
/* String functions lifted from lib/vsprintf.c and lib/ctype.c */
unsigned char _ctype[] = {
_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
size_t strnlen(const char * s, size_t count)
{
const char *sc;
@ -320,44 +195,30 @@ size_t strnlen(const char * s, size_t count)
return sc - s;
}
unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
{
unsigned long result = 0,value;
extern unsigned int __div64_32(unsigned long long *dividend,
unsigned int divisor);
if (!base) {
base = 10;
if (*cp == '0') {
base = 8;
cp++;
if ((*cp == 'x') && isxdigit(cp[1])) {
cp++;
base = 16;
}
}
}
while (isxdigit(*cp) &&
(value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
result = result*base + value;
cp++;
}
if (endp)
*endp = (char *)cp;
return result;
}
long simple_strtol(const char *cp,char **endp,unsigned int base)
{
if(*cp=='-')
return -simple_strtoul(cp+1,endp,base);
return simple_strtoul(cp,endp,base);
}
/* The unnecessary pointer compare is there
* to check for type safety (n must be 64bit)
*/
# define do_div(n,base) ({ \
unsigned int __base = (base); \
unsigned int __rem; \
(void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \
if (((n) >> 32) == 0) { \
__rem = (unsigned int)(n) % __base; \
(n) = (unsigned int)(n) / __base; \
} else \
__rem = __div64_32(&(n), __base); \
__rem; \
})
static int skip_atoi(const char **s)
{
int i=0;
int i, c;
while (isdigit(**s))
i = i*10 + *((*s)++) - '0';
for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s)
i = i*10 + c - '0';
return i;
}
@ -436,9 +297,6 @@ static char * number(char * str, unsigned long long num, int base, int size, int
return str;
}
/* Forward decl. needed for IP address printing stuff... */
int sprintf(char * buf, const char *fmt, ...);
int vsprintf(char *buf, const char *fmt, va_list args)
{
int len;
@ -477,7 +335,7 @@ int vsprintf(char *buf, const char *fmt, va_list args)
/* get field width */
field_width = -1;
if (isdigit(*fmt))
if ('0' <= *fmt && *fmt <= '9')
field_width = skip_atoi(&fmt);
else if (*fmt == '*') {
++fmt;
@ -493,7 +351,7 @@ int vsprintf(char *buf, const char *fmt, va_list args)
precision = -1;
if (*fmt == '.') {
++fmt;
if (isdigit(*fmt))
if ('0' <= *fmt && *fmt <= '9')
precision = skip_atoi(&fmt);
else if (*fmt == '*') {
++fmt;
@ -628,7 +486,7 @@ int sprintf(char * buf, const char *fmt, ...)
static char sprint_buf[1024];
int
printf(char *fmt, ...)
printf(const char *fmt, ...)
{
va_list args;
int n;

18
arch/ppc64/boot/prom.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef _PPC_BOOT_PROM_H_
#define _PPC_BOOT_PROM_H_
extern int (*prom) (void *);
extern void *chosen_handle;
extern void *stdin;
extern void *stdout;
extern void *stderr;
extern int write(void *handle, void *ptr, int nb);
extern int read(void *handle, void *ptr, int nb);
extern void exit(void);
extern void pause(void);
extern void *finddevice(const char *);
extern void *claim(unsigned long virt, unsigned long size, unsigned long align);
extern int getprop(void *phandle, const char *name, void *buf, int buflen);
#endif /* _PPC_BOOT_PROM_H_ */

16
arch/ppc64/boot/stdio.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef _PPC_BOOT_STDIO_H_
#define _PPC_BOOT_STDIO_H_
extern int printf(const char *fmt, ...);
extern int sprintf(char *buf, const char *fmt, ...);
extern int vsprintf(char *buf, const char *fmt, va_list args);
extern int putc(int c, void *f);
extern int putchar(int c);
extern int getchar(void);
extern int fputs(char *str, void *f);
#endif /* _PPC_BOOT_STDIO_H_ */

View File

@ -9,7 +9,7 @@
* NOTE: this code runs in 32 bit mode and is packaged as ELF32.
*/
#include <asm/ppc_asm.h>
#include "ppc_asm.h"
.text
.globl strcpy

16
arch/ppc64/boot/string.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef _PPC_BOOT_STRING_H_
#define _PPC_BOOT_STRING_H_
extern char *strcpy(char *dest, const char *src);
extern char *strncpy(char *dest, const char *src, size_t n);
extern char *strcat(char *dest, const char *src);
extern int strcmp(const char *s1, const char *s2);
extern size_t strlen(const char *s);
extern size_t strnlen(const char *s, size_t count);
extern void *memset(void *s, int c, size_t n);
extern void *memmove(void *dest, const void *src, unsigned long n);
extern void *memcpy(void *dest, const void *src, unsigned long n);
extern int memcmp(const void *s1, const void *s2, size_t n);
#endif /* _PPC_BOOT_STRING_H_ */

View File

@ -107,7 +107,7 @@ extern void *memcpy(void *, const void *, unsigned long);
/* Diagnostic functions */
#ifdef DEBUG_ZLIB
# include <stdio.h>
# include "stdio.h"
# ifndef verbose
# define verbose 0
# endif

View File

@ -103,10 +103,10 @@ CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
# CONFIG_PREEMPT_BKL is not set
CONFIG_HZ_100=y
# CONFIG_HZ_250 is not set
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_1000 is not set
CONFIG_HZ=100
CONFIG_HZ=250
CONFIG_GENERIC_HARDIRQS=y
CONFIG_SECCOMP=y
CONFIG_ISA_DMA_API=y

View File

@ -94,12 +94,11 @@ CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
# CONFIG_PREEMPT_BKL is not set
CONFIG_HZ_100=y
# CONFIG_HZ_250 is not set
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_1000 is not set
CONFIG_HZ=100
CONFIG_HZ=250
CONFIG_GENERIC_HARDIRQS=y
CONFIG_MSCHUNKS=y
CONFIG_LPARCFG=y
CONFIG_SECCOMP=y
CONFIG_ISA_DMA_API=y

View File

@ -103,10 +103,10 @@ CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
# CONFIG_PREEMPT_BKL is not set
CONFIG_HZ_100=y
# CONFIG_HZ_250 is not set
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_1000 is not set
CONFIG_HZ=100
CONFIG_HZ=250
CONFIG_GENERIC_HARDIRQS=y
CONFIG_SECCOMP=y
CONFIG_ISA_DMA_API=y

View File

@ -112,10 +112,10 @@ CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
# CONFIG_PREEMPT_BKL is not set
CONFIG_HZ_100=y
# CONFIG_HZ_250 is not set
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_1000 is not set
CONFIG_HZ=100
CONFIG_HZ=250
CONFIG_EEH=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_PPC_RTAS=y

View File

@ -114,10 +114,10 @@ CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
# CONFIG_PREEMPT_BKL is not set
CONFIG_HZ_100=y
# CONFIG_HZ_250 is not set
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_1000 is not set
CONFIG_HZ=100
CONFIG_HZ=250
CONFIG_EEH=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_PPC_RTAS=y

View File

@ -51,6 +51,17 @@ struct HvReleaseData hvReleaseData = {
0xf4, 0x4b, 0xf6, 0xf4 },
};
/*
* The NACA. The first dword of the naca is required by the iSeries
* hypervisor to point to itVpdAreas. The hypervisor finds the NACA
* through the pointer in hvReleaseData.
*/
struct naca_struct naca = {
.xItVpdAreas = &itVpdAreas,
.xRamDisk = 0,
.xRamDiskSize = 0,
};
extern void system_reset_iSeries(void);
extern void machine_check_iSeries(void);
extern void data_access_iSeries(void);
@ -214,29 +225,3 @@ struct ItVpdAreas itVpdAreas = {
0,0
}
};
struct msChunks msChunks;
EXPORT_SYMBOL(msChunks);
/* Depending on whether this is called from iSeries or pSeries setup
* code, the location of the msChunks struct may or may not have
* to be reloc'd, so we force the caller to do that for us by passing
* in a pointer to the structure.
*/
unsigned long
msChunks_alloc(unsigned long mem, unsigned long num_chunks, unsigned long chunk_size)
{
unsigned long offset = reloc_offset();
struct msChunks *_msChunks = PTRRELOC(&msChunks);
_msChunks->num_chunks = num_chunks;
_msChunks->chunk_size = chunk_size;
_msChunks->chunk_shift = __ilog2(chunk_size);
_msChunks->chunk_mask = (1UL<<_msChunks->chunk_shift)-1;
mem = _ALIGN(mem, sizeof(msChunks_entry));
_msChunks->abs = (msChunks_entry *)(mem + offset);
mem += num_chunks * sizeof(msChunks_entry);
return mem;
}

View File

@ -11,7 +11,7 @@ obj-y := setup.o entry.o traps.o irq.o idle.o dma.o \
udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \
ptrace32.o signal32.o rtc.o init_task.o \
lmb.o cputable.o cpu_setup_power4.o idle_power4.o \
iommu.o sysfs.o vdso.o pmc.o
iommu.o sysfs.o vdso.o pmc.o firmware.o
obj-y += vdso32/ vdso64/
obj-$(CONFIG_PPC_OF) += of_device.o
@ -50,7 +50,10 @@ obj-$(CONFIG_LPARCFG) += lparcfg.o
obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
obj-$(CONFIG_BOOTX_TEXT) += btext.o
obj-$(CONFIG_HVCS) += hvcserver.o
obj-$(CONFIG_IBMVIO) += vio.o
vio-obj-$(CONFIG_PPC_PSERIES) += pSeries_vio.o
vio-obj-$(CONFIG_PPC_ISERIES) += iSeries_vio.o
obj-$(CONFIG_IBMVIO) += vio.o $(vio-obj-y)
obj-$(CONFIG_XICS) += xics.o
obj-$(CONFIG_MPIC) += mpic.o

View File

@ -94,7 +94,8 @@ int main(void)
DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
#ifdef CONFIG_HUGETLB_PAGE
DEFINE(PACAHTLBSEGS, offsetof(struct paca_struct, context.htlb_segs));
DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas));
DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas));
#endif /* CONFIG_HUGETLB_PAGE */
DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr));
DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));

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