forked from Minki/linux
Merge linux-2.6 into linux-acpi-2.6 test
This commit is contained in:
commit
129521dcc9
@ -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>
|
||||
|
246
Documentation/networking/README.ipw2100
Normal file
246
Documentation/networking/README.ipw2100
Normal 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
|
||||
|
300
Documentation/networking/README.ipw2200
Normal file
300
Documentation/networking/README.ipw2200
Normal 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
|
||||
|
||||
|
352
Documentation/networking/cxgb.txt
Normal file
352
Documentation/networking/cxgb.txt
Normal 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.
|
||||
|
||||
===============================================================================
|
@ -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.
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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>
|
||||
|
18
MAINTAINERS
18
MAINTAINERS
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -433,10 +433,12 @@ void timer_dyn_reprogram(void)
|
||||
{
|
||||
struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
|
||||
|
||||
write_seqlock(&xtime_lock);
|
||||
if (dyn_tick->state & DYN_TICK_ENABLED)
|
||||
dyn_tick->reprogram(next_timer_interrupt() - jiffies);
|
||||
write_sequnlock(&xtime_lock);
|
||||
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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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)];
|
||||
handler = do_alignment_ldrhstrh;
|
||||
|
||||
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 */
|
||||
|
@ -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)));
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
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) {
|
||||
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) {
|
||||
r = &dev->resource[PCI_ROM_RESOURCE];
|
||||
r->end -= r->start;
|
||||
r->start = 0;
|
||||
if (r->end)
|
||||
pci_assign_resource(dev, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pci_assign_unassigned_resources();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/rse.h>
|
||||
#include <asm/sigcontext.h>
|
||||
#include <asm/segment.h>
|
||||
|
||||
#include "ia32priv.h"
|
||||
|
||||
|
@ -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
|
||||
|
29
arch/ia64/kernel/cpufreq/Kconfig
Normal file
29
arch/ia64/kernel/cpufreq/Kconfig
Normal 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
|
||||
|
1
arch/ia64/kernel/cpufreq/Makefile
Normal file
1
arch/ia64/kernel/cpufreq/Makefile
Normal file
@ -0,0 +1 @@
|
||||
obj-$(CONFIG_IA64_ACPI_CPUFREQ) += acpi-cpufreq.o
|
499
arch/ia64/kernel/cpufreq/acpi-cpufreq.c
Normal file
499
arch/ia64/kernel/cpufreq/acpi-cpufreq.c
Normal 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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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), \
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,16 +76,14 @@ 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),
|
||||
mask);
|
||||
HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS),
|
||||
mask);
|
||||
__set_bit(irq, (volatile void *)pda->sn_in_service_ivecs);
|
||||
|
||||
move_irq(irq);
|
||||
@ -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);
|
||||
}
|
||||
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);
|
||||
sn_call_force_intr_provider(sn_irq_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -404,13 +413,7 @@ 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);
|
||||
sn_check_intr(i, sn_irq_info);
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
@ -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]);
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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')))
|
||||
break;
|
||||
*p2 = '\0';
|
||||
seq_printf(s, "pcibus %d %s-%s\n",
|
||||
*ordinal, obj->location, p1);
|
||||
(*ordinal)++;
|
||||
p1 = p2 + 1;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
free_page((unsigned long)pg);
|
||||
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++) {
|
||||
seq_printf(s, i ? ":%d" : ", dist %d",
|
||||
node_distance(ordinal, 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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,14 +50,16 @@ void sn_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
LED_CPU_HEARTBEAT, LED_CPU_HEARTBEAT);
|
||||
}
|
||||
|
||||
if (enable_shub_wars_1_1()) {
|
||||
/* Bugfix code for SHUB 1.1 */
|
||||
if (pda->pio_shub_war_cam_addr)
|
||||
*pda->pio_shub_war_cam_addr = 0x8000000000000010UL;
|
||||
if (is_shub1()) {
|
||||
if (enable_shub_wars_1_1()) {
|
||||
/* Bugfix code for SHUB 1.1 */
|
||||
if (pda->pio_shub_war_cam_addr)
|
||||
*pda->pio_shub_war_cam_addr = 0x8000000000000010UL;
|
||||
}
|
||||
if (pda->sn_lb_int_war_ticks == 0)
|
||||
sn_lb_int_war_check();
|
||||
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;
|
||||
}
|
||||
if (pda->sn_lb_int_war_ticks == 0)
|
||||
sn_lb_int_war_check();
|
||||
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;
|
||||
}
|
||||
|
@ -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/
|
||||
|
@ -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];
|
||||
|
||||
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;
|
||||
}
|
||||
is_tio = (nasid & 1);
|
||||
if (is_tio) {
|
||||
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 == NULL)
|
||||
return;
|
||||
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);
|
||||
|
@ -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->
|
||||
sfdl_persistent_busnum ==
|
||||
soft->pbi_buscommon.bs_persist_busnum)
|
||||
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))
|
||||
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
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
771
arch/ia64/sn/pci/tioce_provider.c
Normal file
771
arch/ia64/sn/pci/tioce_provider.c
Normal 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;
|
||||
}
|
@ -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.
|
||||
|
||||
@ -343,6 +369,12 @@ config COBRA5282
|
||||
depends on M528x
|
||||
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"
|
||||
@ -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
|
||||
@ -441,6 +479,11 @@ config senTec
|
||||
bool
|
||||
default y
|
||||
depends on (COBRA5272 || COBRA5282)
|
||||
|
||||
config EMAC_INC
|
||||
bool
|
||||
default y
|
||||
depends on (SOM5282EM)
|
||||
|
||||
config SNEHA
|
||||
bool
|
||||
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Copyleft ()) 2000 James D. Schettine {james@telos-systems.com}
|
||||
* Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>
|
||||
* Copyright (C) 1995 Hamish Macdonald
|
||||
* Copyright (C) 2000 Lineo Inc. (www.lineo.com)
|
||||
* Copyright (C) 2000 Lineo Inc. (www.lineo.com)
|
||||
* Copyright (C) 2001 Lineo, Inc. <www.lineo.com>
|
||||
*
|
||||
* 68VZ328 Fixes/support Evan Stawnyczy <e@lineo.ca>
|
||||
@ -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
|
||||
@ -152,7 +162,7 @@ void setup_arch(char **cmdline_p)
|
||||
init_mm.start_code = (unsigned long) &_stext;
|
||||
init_mm.end_code = (unsigned long) &_etext;
|
||||
init_mm.end_data = (unsigned long) &_edata;
|
||||
init_mm.brk = (unsigned long) 0;
|
||||
init_mm.brk = (unsigned long) 0;
|
||||
|
||||
config_BSP(&command_line[0], sizeof(command_line));
|
||||
|
||||
@ -171,7 +181,7 @@ void setup_arch(char **cmdline_p)
|
||||
#endif
|
||||
#ifdef CONFIG_ELITE
|
||||
printk(KERN_INFO "Modified for M5206eLITE by Rob Scott, rscott@mtrob.fdns.net\n");
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_TELOS
|
||||
printk(KERN_INFO "Modified for Omnia ToolVox by James D. Schettine, james@telos-systems.com\n");
|
||||
#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 "
|
||||
@ -223,7 +236,7 @@ void setup_arch(char **cmdline_p)
|
||||
saved_command_line[COMMAND_LINE_SIZE-1] = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (strlen(*cmdline_p))
|
||||
if (strlen(*cmdline_p))
|
||||
printk(KERN_DEBUG "Command line: '%s'\n", *cmdline_p);
|
||||
#endif
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
82
arch/m68knommu/platform/523x/config.c
Normal file
82
arch/m68knommu/platform/523x/config.c
Normal 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;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
@ -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 */
|
||||
#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 */
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
@ -230,7 +250,16 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
|
||||
oris r3,r3,0x8000
|
||||
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 */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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,'
|
||||
|
@ -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
|
||||
|
||||
|
@ -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]);
|
||||
|
@ -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
|
||||
|
@ -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
149
arch/ppc64/boot/elf.h
Normal 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_ */
|
@ -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
34
arch/ppc64/boot/page.h
Normal 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 */
|
@ -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
62
arch/ppc64/boot/ppc_asm.h
Normal 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 */
|
@ -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
18
arch/ppc64/boot/prom.h
Normal 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
16
arch/ppc64/boot/stdio.h
Normal 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_ */
|
@ -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
16
arch/ppc64/boot/string.h
Normal 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_ */
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user