Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6

This commit is contained in:
Paul Mundt 2009-04-02 11:17:41 +09:00
commit c4361bb64b
732 changed files with 22433 additions and 15088 deletions

View File

@ -495,6 +495,11 @@ S: Kopmansg 2
S: 411 13 Goteborg S: 411 13 Goteborg
S: Sweden S: Sweden
N: Paul Bristow
E: paul@paulbristow.net
W: http://paulbristow.net/linux/idefloppy.html
D: Maintainer of IDE/ATAPI floppy driver
N: Dominik Brodowski N: Dominik Brodowski
E: linux@brodo.de E: linux@brodo.de
W: http://www.brodo.de/ W: http://www.brodo.de/
@ -2642,6 +2647,10 @@ S: C/ Mieses 20, 9-B
S: Valladolid 47009 S: Valladolid 47009
S: Spain S: Spain
N: Gadi Oxman
E: gadio@netvision.net.il
D: Original author and maintainer of IDE/ATAPI floppy/tape drivers
N: Greg Page N: Greg Page
E: gpage@sovereign.org E: gpage@sovereign.org
D: IPX development and support D: IPX development and support

View File

@ -41,6 +41,49 @@ Description:
for the device and attempt to bind to it. For example: for the device and attempt to bind to it. For example:
# echo "8086 10f5" > /sys/bus/pci/drivers/foo/new_id # echo "8086 10f5" > /sys/bus/pci/drivers/foo/new_id
What: /sys/bus/pci/drivers/.../remove_id
Date: February 2009
Contact: Chris Wright <chrisw@sous-sol.org>
Description:
Writing a device ID to this file will remove an ID
that was dynamically added via the new_id sysfs entry.
The format for the device ID is:
VVVV DDDD SVVV SDDD CCCC MMMM. That is Vendor ID, Device
ID, Subsystem Vendor ID, Subsystem Device ID, Class,
and Class Mask. The Vendor ID and Device ID fields are
required, the rest are optional. After successfully
removing an ID, the driver will no longer support the
device. This is useful to ensure auto probing won't
match the driver to the device. For example:
# echo "8086 10f5" > /sys/bus/pci/drivers/foo/remove_id
What: /sys/bus/pci/rescan
Date: January 2009
Contact: Linux PCI developers <linux-pci@vger.kernel.org>
Description:
Writing a non-zero value to this attribute will
force a rescan of all PCI buses in the system, and
re-discover previously removed devices.
Depends on CONFIG_HOTPLUG.
What: /sys/bus/pci/devices/.../remove
Date: January 2009
Contact: Linux PCI developers <linux-pci@vger.kernel.org>
Description:
Writing a non-zero value to this attribute will
hot-remove the PCI device and any of its children.
Depends on CONFIG_HOTPLUG.
What: /sys/bus/pci/devices/.../rescan
Date: January 2009
Contact: Linux PCI developers <linux-pci@vger.kernel.org>
Description:
Writing a non-zero value to this attribute will
force a rescan of the device's parent bus and all
child buses, and re-discover devices removed earlier
from this part of the device tree.
Depends on CONFIG_HOTPLUG.
What: /sys/bus/pci/devices/.../vpd What: /sys/bus/pci/devices/.../vpd
Date: February 2008 Date: February 2008
Contact: Ben Hutchings <bhutchings@solarflare.com> Contact: Ben Hutchings <bhutchings@solarflare.com>
@ -52,3 +95,30 @@ Description:
that some devices may have malformatted data. If the that some devices may have malformatted data. If the
underlying VPD has a writable section then the underlying VPD has a writable section then the
corresponding section of this file will be writable. corresponding section of this file will be writable.
What: /sys/bus/pci/devices/.../virtfnN
Date: March 2009
Contact: Yu Zhao <yu.zhao@intel.com>
Description:
This symbolic link appears when hardware supports the SR-IOV
capability and the Physical Function driver has enabled it.
The symbolic link points to the PCI device sysfs entry of the
Virtual Function whose index is N (0...MaxVFs-1).
What: /sys/bus/pci/devices/.../dep_link
Date: March 2009
Contact: Yu Zhao <yu.zhao@intel.com>
Description:
This symbolic link appears when hardware supports the SR-IOV
capability and the Physical Function driver has enabled it,
and this device has vendor specific dependencies with others.
The symbolic link points to the PCI device sysfs entry of
Physical Function this device depends on.
What: /sys/bus/pci/devices/.../physfn
Date: March 2009
Contact: Yu Zhao <yu.zhao@intel.com>
Description:
This symbolic link appears when a device is a Virtual Function.
The symbolic link points to the PCI device sysfs entry of the
Physical Function this device associates with.

View File

@ -0,0 +1,81 @@
What: /sys/fs/ext4/<disk>/mb_stats
Date: March 2008
Contact: "Theodore Ts'o" <tytso@mit.edu>
Description:
Controls whether the multiblock allocator should
collect statistics, which are shown during the unmount.
1 means to collect statistics, 0 means not to collect
statistics
What: /sys/fs/ext4/<disk>/mb_group_prealloc
Date: March 2008
Contact: "Theodore Ts'o" <tytso@mit.edu>
Description:
The multiblock allocator will round up allocation
requests to a multiple of this tuning parameter if the
stripe size is not set in the ext4 superblock
What: /sys/fs/ext4/<disk>/mb_max_to_scan
Date: March 2008
Contact: "Theodore Ts'o" <tytso@mit.edu>
Description:
The maximum number of extents the multiblock allocator
will search to find the best extent
What: /sys/fs/ext4/<disk>/mb_min_to_scan
Date: March 2008
Contact: "Theodore Ts'o" <tytso@mit.edu>
Description:
The minimum number of extents the multiblock allocator
will search to find the best extent
What: /sys/fs/ext4/<disk>/mb_order2_req
Date: March 2008
Contact: "Theodore Ts'o" <tytso@mit.edu>
Description:
Tuning parameter which controls the minimum size for
requests (as a power of 2) where the buddy cache is
used
What: /sys/fs/ext4/<disk>/mb_stream_req
Date: March 2008
Contact: "Theodore Ts'o" <tytso@mit.edu>
Description:
Files which have fewer blocks than this tunable
parameter will have their blocks allocated out of a
block group specific preallocation pool, so that small
files are packed closely together. Each large file
will have its blocks allocated out of its own unique
preallocation pool.
What: /sys/fs/ext4/<disk>/inode_readahead
Date: March 2008
Contact: "Theodore Ts'o" <tytso@mit.edu>
Description:
Tuning parameter which controls the maximum number of
inode table blocks that ext4's inode table readahead
algorithm will pre-read into the buffer cache
What: /sys/fs/ext4/<disk>/delayed_allocation_blocks
Date: March 2008
Contact: "Theodore Ts'o" <tytso@mit.edu>
Description:
This file is read-only and shows the number of blocks
that are dirty in the page cache, but which do not
have their location in the filesystem allocated yet.
What: /sys/fs/ext4/<disk>/lifetime_write_kbytes
Date: March 2008
Contact: "Theodore Ts'o" <tytso@mit.edu>
Description:
This file is read-only and shows the number of kilobytes
of data that have been written to this filesystem since it was
created.
What: /sys/fs/ext4/<disk>/session_write_kbytes
Date: March 2008
Contact: "Theodore Ts'o" <tytso@mit.edu>
Description:
This file is read-only and shows the number of
kilobytes of data that have been written to this
filesystem since it was mounted.

View File

@ -199,6 +199,7 @@ X!Edrivers/pci/hotplug.c
--> -->
!Edrivers/pci/probe.c !Edrivers/pci/probe.c
!Edrivers/pci/rom.c !Edrivers/pci/rom.c
!Edrivers/pci/iov.c
</sect1> </sect1>
<sect1><title>PCI Hotplug Support Library</title> <sect1><title>PCI Hotplug Support Library</title>
!Edrivers/pci/hotplug/pci_hotplug_core.c !Edrivers/pci/hotplug/pci_hotplug_core.c

View File

@ -117,9 +117,6 @@ static int __init init_procfs_example(void)
rv = -ENOMEM; rv = -ENOMEM;
goto out; goto out;
} }
example_dir->owner = THIS_MODULE;
/* create jiffies using convenience function */ /* create jiffies using convenience function */
jiffies_file = create_proc_read_entry("jiffies", jiffies_file = create_proc_read_entry("jiffies",
0444, example_dir, 0444, example_dir,
@ -130,8 +127,6 @@ static int __init init_procfs_example(void)
goto no_jiffies; goto no_jiffies;
} }
jiffies_file->owner = THIS_MODULE;
/* create foo and bar files using same callback /* create foo and bar files using same callback
* functions * functions
*/ */
@ -146,7 +141,6 @@ static int __init init_procfs_example(void)
foo_file->data = &foo_data; foo_file->data = &foo_data;
foo_file->read_proc = proc_read_foobar; foo_file->read_proc = proc_read_foobar;
foo_file->write_proc = proc_write_foobar; foo_file->write_proc = proc_write_foobar;
foo_file->owner = THIS_MODULE;
bar_file = create_proc_entry("bar", 0644, example_dir); bar_file = create_proc_entry("bar", 0644, example_dir);
if(bar_file == NULL) { if(bar_file == NULL) {
@ -159,7 +153,6 @@ static int __init init_procfs_example(void)
bar_file->data = &bar_data; bar_file->data = &bar_data;
bar_file->read_proc = proc_read_foobar; bar_file->read_proc = proc_read_foobar;
bar_file->write_proc = proc_write_foobar; bar_file->write_proc = proc_write_foobar;
bar_file->owner = THIS_MODULE;
/* create symlink */ /* create symlink */
symlink = proc_symlink("jiffies_too", example_dir, symlink = proc_symlink("jiffies_too", example_dir,
@ -169,8 +162,6 @@ static int __init init_procfs_example(void)
goto no_symlink; goto no_symlink;
} }
symlink->owner = THIS_MODULE;
/* everything OK */ /* everything OK */
printk(KERN_INFO "%s %s initialised\n", printk(KERN_INFO "%s %s initialised\n",
MODULE_NAME, MODULE_VERS); MODULE_NAME, MODULE_VERS);

View File

@ -4,506 +4,356 @@
Revised Feb 12, 2004 by Martine Silbermann Revised Feb 12, 2004 by Martine Silbermann
email: Martine.Silbermann@hp.com email: Martine.Silbermann@hp.com
Revised Jun 25, 2004 by Tom L Nguyen Revised Jun 25, 2004 by Tom L Nguyen
Revised Jul 9, 2008 by Matthew Wilcox <willy@linux.intel.com>
Copyright 2003, 2008 Intel Corporation
1. About this guide 1. About this guide
This guide describes the basics of Message Signaled Interrupts (MSI), This guide describes the basics of Message Signaled Interrupts (MSIs),
the advantages of using MSI over traditional interrupt mechanisms, the advantages of using MSI over traditional interrupt mechanisms, how
and how to enable your driver to use MSI or MSI-X. Also included is to change your driver to use MSI or MSI-X and some basic diagnostics to
a Frequently Asked Questions (FAQ) section. try if a device doesn't support MSIs.
1.1 Terminology
PCI devices can be single-function or multi-function. In either case, 2. What are MSIs?
when this text talks about enabling or disabling MSI on a "device
function," it is referring to one specific PCI device and function and
not to all functions on a PCI device (unless the PCI device has only
one function).
2. Copyright 2003 Intel Corporation A Message Signaled Interrupt is a write from the device to a special
address which causes an interrupt to be received by the CPU.
3. What is MSI/MSI-X? The MSI capability was first specified in PCI 2.2 and was later enhanced
in PCI 3.0 to allow each interrupt to be masked individually. The MSI-X
capability was also introduced with PCI 3.0. It supports more interrupts
per device than MSI and allows interrupts to be independently configured.
Message Signaled Interrupt (MSI), as described in the PCI Local Bus Devices may support both MSI and MSI-X, but only one can be enabled at
Specification Revision 2.3 or later, is an optional feature, and a a time.
required feature for PCI Express devices. MSI enables a device function
to request service by sending an Inbound Memory Write on its PCI bus to
the FSB as a Message Signal Interrupt transaction. Because MSI is
generated in the form of a Memory Write, all transaction conditions,
such as a Retry, Master-Abort, Target-Abort or normal completion, are
supported.
A PCI device that supports MSI must also support pin IRQ assertion
interrupt mechanism to provide backward compatibility for systems that
do not support MSI. In systems which support MSI, the bus driver is
responsible for initializing the message address and message data of
the device function's MSI/MSI-X capability structure during device
initial configuration.
An MSI capable device function indicates MSI support by implementing 3. Why use MSIs?
the MSI/MSI-X capability structure in its PCI capability list. The
device function may implement both the MSI capability structure and
the MSI-X capability structure; however, the bus driver should not
enable both.
The MSI capability structure contains Message Control register, There are three reasons why using MSIs can give an advantage over
Message Address register and Message Data register. These registers traditional pin-based interrupts.
provide the bus driver control over MSI. The Message Control register
indicates the MSI capability supported by the device. The Message
Address register specifies the target address and the Message Data
register specifies the characteristics of the message. To request
service, the device function writes the content of the Message Data
register to the target address. The device and its software driver
are prohibited from writing to these registers.
The MSI-X capability structure is an optional extension to MSI. It Pin-based PCI interrupts are often shared amongst several devices.
uses an independent and separate capability structure. There are To support this, the kernel must call each interrupt handler associated
some key advantages to implementing the MSI-X capability structure with an interrupt, which leads to reduced performance for the system as
over the MSI capability structure as described below. a whole. MSIs are never shared, so this problem cannot arise.
- Support a larger maximum number of vectors per function. When a device writes data to memory, then raises a pin-based interrupt,
it is possible that the interrupt may arrive before all the data has
arrived in memory (this becomes more likely with devices behind PCI-PCI
bridges). In order to ensure that all the data has arrived in memory,
the interrupt handler must read a register on the device which raised
the interrupt. PCI transaction ordering rules require that all the data
arrives in memory before the value can be returned from the register.
Using MSIs avoids this problem as the interrupt-generating write cannot
pass the data writes, so by the time the interrupt is raised, the driver
knows that all the data has arrived in memory.
- Provide the ability for system software to configure PCI devices can only support a single pin-based interrupt per function.
each vector with an independent message address and message Often drivers have to query the device to find out what event has
data, specified by a table that resides in Memory Space. occurred, slowing down interrupt handling for the common case. With
MSIs, a device can support more interrupts, allowing each interrupt
to be specialised to a different purpose. One possible design gives
infrequent conditions (such as errors) their own interrupt which allows
the driver to handle the normal interrupt handling path more efficiently.
Other possible designs include giving one interrupt to each packet queue
in a network card or each port in a storage controller.
- MSI and MSI-X both support per-vector masking. Per-vector
masking is an optional extension of MSI but a required
feature for MSI-X. Per-vector masking provides the kernel the
ability to mask/unmask a single MSI while running its
interrupt service routine. If per-vector masking is
not supported, then the device driver should provide the
hardware/software synchronization to ensure that the device
generates MSI when the driver wants it to do so.
4. Why use MSI? 4. How to use MSIs
As a benefit to the simplification of board design, MSI allows board PCI devices are initialised to use pin-based interrupts. The device
designers to remove out-of-band interrupt routing. MSI is another driver has to set up the device to use MSI or MSI-X. Not all machines
step towards a legacy-free environment. support MSIs correctly, and for those machines, the APIs described below
will simply fail and the device will continue to use pin-based interrupts.
Due to increasing pressure on chipset and processor packages to 4.1 Include kernel support for MSIs
reduce pin count, the need for interrupt pins is expected to
diminish over time. Devices, due to pin constraints, may implement
messages to increase performance.
PCI Express endpoints uses INTx emulation (in-band messages) instead To support MSI or MSI-X, the kernel must be built with the CONFIG_PCI_MSI
of IRQ pin assertion. Using INTx emulation requires interrupt option enabled. This option is only available on some architectures,
sharing among devices connected to the same node (PCI bridge) while and it may depend on some other options also being set. For example,
MSI is unique (non-shared) and does not require BIOS configuration on x86, you must also enable X86_UP_APIC or SMP in order to see the
support. As a result, the PCI Express technology requires MSI CONFIG_PCI_MSI option.
support for better interrupt performance.
Using MSI enables the device functions to support two or more 4.2 Using MSI
vectors, which can be configured to target different CPUs to
increase scalability.
5. Configuring a driver to use MSI/MSI-X Most of the hard work is done for the driver in the PCI layer. It simply
has to request that the PCI layer set up the MSI capability for this
device.
By default, the kernel will not enable MSI/MSI-X on all devices that 4.2.1 pci_enable_msi
support this capability. The CONFIG_PCI_MSI kernel option
must be selected to enable MSI/MSI-X support.
5.1 Including MSI/MSI-X support into the kernel
To allow MSI/MSI-X capable device drivers to selectively enable
MSI/MSI-X (using pci_enable_msi()/pci_enable_msix() as described
below), the VECTOR based scheme needs to be enabled by setting
CONFIG_PCI_MSI during kernel config.
Since the target of the inbound message is the local APIC, providing
CONFIG_X86_LOCAL_APIC must be enabled as well as CONFIG_PCI_MSI.
5.2 Configuring for MSI support
Due to the non-contiguous fashion in vector assignment of the
existing Linux kernel, this version does not support multiple
messages regardless of a device function is capable of supporting
more than one vector. To enable MSI on a device function's MSI
capability structure requires a device driver to call the function
pci_enable_msi() explicitly.
5.2.1 API pci_enable_msi
int pci_enable_msi(struct pci_dev *dev) int pci_enable_msi(struct pci_dev *dev)
With this new API, a device driver that wants to have MSI A successful call will allocate ONE interrupt to the device, regardless
enabled on its device function must call this API to enable MSI. of how many MSIs the device supports. The device will be switched from
A successful call will initialize the MSI capability structure pin-based interrupt mode to MSI mode. The dev->irq number is changed
with ONE vector, regardless of whether a device function is to a new number which represents the message signaled interrupt.
capable of supporting multiple messages. This vector replaces the This function should be called before the driver calls request_irq()
pre-assigned dev->irq with a new MSI vector. To avoid a conflict since enabling MSIs disables the pin-based IRQ and the driver will not
of the new assigned vector with existing pre-assigned vector requires receive interrupts on the old interrupt.
a device driver to call this API before calling request_irq().
5.2.2 API pci_disable_msi 4.2.2 pci_enable_msi_block
int pci_enable_msi_block(struct pci_dev *dev, int count)
This variation on the above call allows a device driver to request multiple
MSIs. The MSI specification only allows interrupts to be allocated in
powers of two, up to a maximum of 2^5 (32).
If this function returns 0, it has succeeded in allocating at least as many
interrupts as the driver requested (it may have allocated more in order
to satisfy the power-of-two requirement). In this case, the function
enables MSI on this device and updates dev->irq to be the lowest of
the new interrupts assigned to it. The other interrupts assigned to
the device are in the range dev->irq to dev->irq + count - 1.
If this function returns a negative number, it indicates an error and
the driver should not attempt to request any more MSI interrupts for
this device. If this function returns a positive number, it will be
less than 'count' and indicate the number of interrupts that could have
been allocated. In neither case will the irq value have been
updated, nor will the device have been switched into MSI mode.
The device driver must decide what action to take if
pci_enable_msi_block() returns a value less than the number asked for.
Some devices can make use of fewer interrupts than the maximum they
request; in this case the driver should call pci_enable_msi_block()
again. Note that it is not guaranteed to succeed, even when the
'count' has been reduced to the value returned from a previous call to
pci_enable_msi_block(). This is because there are multiple constraints
on the number of vectors that can be allocated; pci_enable_msi_block()
will return as soon as it finds any constraint that doesn't allow the
call to succeed.
4.2.3 pci_disable_msi
void pci_disable_msi(struct pci_dev *dev) void pci_disable_msi(struct pci_dev *dev)
This API should always be used to undo the effect of pci_enable_msi() This function should be used to undo the effect of pci_enable_msi() or
when a device driver is unloading. This API restores dev->irq with pci_enable_msi_block(). Calling it restores dev->irq to the pin-based
the pre-assigned IOAPIC vector and switches a device's interrupt interrupt number and frees the previously allocated message signaled
mode to PCI pin-irq assertion/INTx emulation mode. interrupt(s). The interrupt may subsequently be assigned to another
device, so drivers should not cache the value of dev->irq.
Note that a device driver should always call free_irq() on the MSI vector A device driver must always call free_irq() on the interrupt(s)
that it has done request_irq() on before calling this API. Failure to do for which it has called request_irq() before calling this function.
so results in a BUG_ON() and a device will be left with MSI enabled and Failure to do so will result in a BUG_ON(), the device will be left with
leaks its vector. MSI enabled and will leak its vector.
5.2.3 MSI mode vs. legacy mode diagram 4.3 Using MSI-X
The below diagram shows the events which switch the interrupt The MSI-X capability is much more flexible than the MSI capability.
mode on the MSI-capable device function between MSI mode and It supports up to 2048 interrupts, each of which can be controlled
PIN-IRQ assertion mode. independently. To support this flexibility, drivers must use an array of
`struct msix_entry':
------------ pci_enable_msi ------------------------
| | <=============== | |
| MSI MODE | | PIN-IRQ ASSERTION MODE |
| | ===============> | |
------------ pci_disable_msi ------------------------
Figure 1. MSI Mode vs. Legacy Mode
In Figure 1, a device operates by default in legacy mode. Legacy
in this context means PCI pin-irq assertion or PCI-Express INTx
emulation. A successful MSI request (using pci_enable_msi()) switches
a device's interrupt mode to MSI mode. A pre-assigned IOAPIC vector
stored in dev->irq will be saved by the PCI subsystem and a new
assigned MSI vector will replace dev->irq.
To return back to its default mode, a device driver should always call
pci_disable_msi() to undo the effect of pci_enable_msi(). Note that a
device driver should always call free_irq() on the MSI vector it has
done request_irq() on before calling pci_disable_msi(). Failure to do
so results in a BUG_ON() and a device will be left with MSI enabled and
leaks its vector. Otherwise, the PCI subsystem restores a device's
dev->irq with a pre-assigned IOAPIC vector and marks the released
MSI vector as unused.
Once being marked as unused, there is no guarantee that the PCI
subsystem will reserve this MSI vector for a device. Depending on
the availability of current PCI vector resources and the number of
MSI/MSI-X requests from other drivers, this MSI may be re-assigned.
For the case where the PCI subsystem re-assigns this MSI vector to
another driver, a request to switch back to MSI mode may result
in being assigned a different MSI vector or a failure if no more
vectors are available.
5.3 Configuring for MSI-X support
Due to the ability of the system software to configure each vector of
the MSI-X capability structure with an independent message address
and message data, the non-contiguous fashion in vector assignment of
the existing Linux kernel has no impact on supporting multiple
messages on an MSI-X capable device functions. To enable MSI-X on
a device function's MSI-X capability structure requires its device
driver to call the function pci_enable_msix() explicitly.
The function pci_enable_msix(), once invoked, enables either
all or nothing, depending on the current availability of PCI vector
resources. If the PCI vector resources are available for the number
of vectors requested by a device driver, this function will configure
the MSI-X table of the MSI-X capability structure of a device with
requested messages. To emphasize this reason, for example, a device
may be capable for supporting the maximum of 32 vectors while its
software driver usually may request 4 vectors. It is recommended
that the device driver should call this function once during the
initialization phase of the device driver.
Unlike the function pci_enable_msi(), the function pci_enable_msix()
does not replace the pre-assigned IOAPIC dev->irq with a new MSI
vector because the PCI subsystem writes the 1:1 vector-to-entry mapping
into the field vector of each element contained in a second argument.
Note that the pre-assigned IOAPIC dev->irq is valid only if the device
operates in PIN-IRQ assertion mode. In MSI-X mode, any attempt at
using dev->irq by the device driver to request for interrupt service
may result in unpredictable behavior.
For each MSI-X vector granted, a device driver is responsible for calling
other functions like request_irq(), enable_irq(), etc. to enable
this vector with its corresponding interrupt service handler. It is
a device driver's choice to assign all vectors with the same
interrupt service handler or each vector with a unique interrupt
service handler.
5.3.1 Handling MMIO address space of MSI-X Table
The PCI 3.0 specification has implementation notes that MMIO address
space for a device's MSI-X structure should be isolated so that the
software system can set different pages for controlling accesses to the
MSI-X structure. The implementation of MSI support requires the PCI
subsystem, not a device driver, to maintain full control of the MSI-X
table/MSI-X PBA (Pending Bit Array) and MMIO address space of the MSI-X
table/MSI-X PBA. A device driver should not access the MMIO address
space of the MSI-X table/MSI-X PBA.
5.3.2 API pci_enable_msix
int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
This API enables a device driver to request the PCI subsystem
to enable MSI-X messages on its hardware device. Depending on
the availability of PCI vectors resources, the PCI subsystem enables
either all or none of the requested vectors.
Argument 'dev' points to the device (pci_dev) structure.
Argument 'entries' is a pointer to an array of msix_entry structs.
The number of entries is indicated in argument 'nvec'.
struct msix_entry is defined in /driver/pci/msi.h:
struct msix_entry { struct msix_entry {
u16 vector; /* kernel uses to write alloc vector */ u16 vector; /* kernel uses to write alloc vector */
u16 entry; /* driver uses to specify entry */ u16 entry; /* driver uses to specify entry */
}; };
A device driver is responsible for initializing the field 'entry' of This allows for the device to use these interrupts in a sparse fashion;
each element with a unique entry supported by MSI-X table. Otherwise, for example it could use interrupts 3 and 1027 and allocate only a
-EINVAL will be returned as a result. A successful return of zero two-element array. The driver is expected to fill in the 'entry' value
indicates the PCI subsystem completed initializing each of the requested in each element of the array to indicate which entries it wants the kernel
entries of the MSI-X table with message address and message data. to assign interrupts for. It is invalid to fill in two entries with the
Last but not least, the PCI subsystem will write the 1:1 same number.
vector-to-entry mapping into the field 'vector' of each element. A
device driver is responsible for keeping track of allocated MSI-X
vectors in its internal data structure.
A return of zero indicates that the number of MSI-X vectors was 4.3.1 pci_enable_msix
successfully allocated. A return of greater than zero indicates
MSI-X vector shortage. Or a return of less than zero indicates
a failure. This failure may be a result of duplicate entries
specified in second argument, or a result of no available vector,
or a result of failing to initialize MSI-X table entries.
5.3.3 API pci_disable_msix int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
Calling this function asks the PCI subsystem to allocate 'nvec' MSIs.
The 'entries' argument is a pointer to an array of msix_entry structs
which should be at least 'nvec' entries in size. On success, the
function will return 0 and the device will have been switched into
MSI-X interrupt mode. The 'vector' elements in each entry will have
been filled in with the interrupt number. The driver should then call
request_irq() for each 'vector' that it decides to use.
If this function returns a negative number, it indicates an error and
the driver should not attempt to allocate any more MSI-X interrupts for
this device. If it returns a positive number, it indicates the maximum
number of interrupt vectors that could have been allocated. See example
below.
This function, in contrast with pci_enable_msi(), does not adjust
dev->irq. The device will not generate interrupts for this interrupt
number once MSI-X is enabled. The device driver is responsible for
keeping track of the interrupts assigned to the MSI-X vectors so it can
free them again later.
Device drivers should normally call this function once per device
during the initialization phase.
It is ideal if drivers can cope with a variable number of MSI-X interrupts,
there are many reasons why the platform may not be able to provide the
exact number a driver asks for.
A request loop to achieve that might look like:
static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec)
{
while (nvec >= FOO_DRIVER_MINIMUM_NVEC) {
rc = pci_enable_msix(adapter->pdev,
adapter->msix_entries, nvec);
if (rc > 0)
nvec = rc;
else
return rc;
}
return -ENOSPC;
}
4.3.2 pci_disable_msix
void pci_disable_msix(struct pci_dev *dev) void pci_disable_msix(struct pci_dev *dev)
This API should always be used to undo the effect of pci_enable_msix() This API should be used to undo the effect of pci_enable_msix(). It frees
when a device driver is unloading. Note that a device driver should the previously allocated message signaled interrupts. The interrupts may
always call free_irq() on all MSI-X vectors it has done request_irq() subsequently be assigned to another device, so drivers should not cache
on before calling this API. Failure to do so results in a BUG_ON() and the value of the 'vector' elements over a call to pci_disable_msix().
a device will be left with MSI-X enabled and leaks its vectors.
5.3.4 MSI-X mode vs. legacy mode diagram A device driver must always call free_irq() on the interrupt(s)
for which it has called request_irq() before calling this function.
Failure to do so will result in a BUG_ON(), the device will be left with
MSI enabled and will leak its vector.
The below diagram shows the events which switch the interrupt 4.3.3 The MSI-X Table
mode on the MSI-X capable device function between MSI-X mode and
PIN-IRQ assertion mode (legacy).
------------ pci_enable_msix(,,n) ------------------------ The MSI-X capability specifies a BAR and offset within that BAR for the
| | <=============== | | MSI-X Table. This address is mapped by the PCI subsystem, and should not
| MSI-X MODE | | PIN-IRQ ASSERTION MODE | be accessed directly by the device driver. If the driver wishes to
| | ===============> | | mask or unmask an interrupt, it should call disable_irq() / enable_irq().
------------ pci_disable_msix ------------------------
Figure 2. MSI-X Mode vs. Legacy Mode 4.4 Handling devices implementing both MSI and MSI-X capabilities
In Figure 2, a device operates by default in legacy mode. A If a device implements both MSI and MSI-X capabilities, it can
successful MSI-X request (using pci_enable_msix()) switches a run in either MSI mode or MSI-X mode but not both simultaneously.
device's interrupt mode to MSI-X mode. A pre-assigned IOAPIC vector This is a requirement of the PCI spec, and it is enforced by the
stored in dev->irq will be saved by the PCI subsystem; however, PCI layer. Calling pci_enable_msi() when MSI-X is already enabled or
unlike MSI mode, the PCI subsystem will not replace dev->irq with pci_enable_msix() when MSI is already enabled will result in an error.
assigned MSI-X vector because the PCI subsystem already writes the 1:1 If a device driver wishes to switch between MSI and MSI-X at runtime,
vector-to-entry mapping into the field 'vector' of each element it must first quiesce the device, then switch it back to pin-interrupt
specified in second argument. mode, before calling pci_enable_msi() or pci_enable_msix() and resuming
operation. This is not expected to be a common operation but may be
useful for debugging or testing during development.
To return back to its default mode, a device driver should always call 4.5 Considerations when using MSIs
pci_disable_msix() to undo the effect of pci_enable_msix(). Note that
a device driver should always call free_irq() on all MSI-X vectors it
has done request_irq() on before calling pci_disable_msix(). Failure
to do so results in a BUG_ON() and a device will be left with MSI-X
enabled and leaks its vectors. Otherwise, the PCI subsystem switches a
device function's interrupt mode from MSI-X mode to legacy mode and
marks all allocated MSI-X vectors as unused.
Once being marked as unused, there is no guarantee that the PCI 4.5.1 Choosing between MSI-X and MSI
subsystem will reserve these MSI-X vectors for a device. Depending on
the availability of current PCI vector resources and the number of
MSI/MSI-X requests from other drivers, these MSI-X vectors may be
re-assigned.
For the case where the PCI subsystem re-assigned these MSI-X vectors If your device supports both MSI-X and MSI capabilities, you should use
to other drivers, a request to switch back to MSI-X mode may result the MSI-X facilities in preference to the MSI facilities. As mentioned
being assigned with another set of MSI-X vectors or a failure if no above, MSI-X supports any number of interrupts between 1 and 2048.
more vectors are available. In constrast, MSI is restricted to a maximum of 32 interrupts (and
must be a power of two). In addition, the MSI interrupt vectors must
be allocated consecutively, so the system may not be able to allocate
as many vectors for MSI as it could for MSI-X. On some platforms, MSI
interrupts must all be targetted at the same set of CPUs whereas MSI-X
interrupts can all be targetted at different CPUs.
5.4 Handling function implementing both MSI and MSI-X capabilities 4.5.2 Spinlocks
For the case where a function implements both MSI and MSI-X Most device drivers have a per-device spinlock which is taken in the
capabilities, the PCI subsystem enables a device to run either in MSI interrupt handler. With pin-based interrupts or a single MSI, it is not
mode or MSI-X mode but not both. A device driver determines whether it necessary to disable interrupts (Linux guarantees the same interrupt will
wants MSI or MSI-X enabled on its hardware device. Once a device not be re-entered). If a device uses multiple interrupts, the driver
driver requests for MSI, for example, it is prohibited from requesting must disable interrupts while the lock is held. If the device sends
MSI-X; in other words, a device driver is not permitted to ping-pong a different interrupt, the driver will deadlock trying to recursively
between MSI mod MSI-X mode during a run-time. acquire the spinlock.
5.5 Hardware requirements for MSI/MSI-X support There are two solutions. The first is to take the lock with
spin_lock_irqsave() or spin_lock_irq() (see
Documentation/DocBook/kernel-locking). The second is to specify
IRQF_DISABLED to request_irq() so that the kernel runs the entire
interrupt routine with interrupts disabled.
MSI/MSI-X support requires support from both system hardware and If your MSI interrupt routine does not hold the lock for the whole time
individual hardware device functions. it is running, the first solution may be best. The second solution is
normally preferred as it avoids making two transitions from interrupt
disabled to enabled and back again.
5.5.1 Required x86 hardware support 4.6 How to tell whether MSI/MSI-X is enabled on a device
Since the target of MSI address is the local APIC CPU, enabling Using 'lspci -v' (as root) may show some devices with "MSI", "Message
MSI/MSI-X support in the Linux kernel is dependent on whether existing Signalled Interrupts" or "MSI-X" capabilities. Each of these capabilities
system hardware supports local APIC. Users should verify that their has an 'Enable' flag which will be followed with either "+" (enabled)
system supports local APIC operation by testing that it runs when or "-" (disabled).
CONFIG_X86_LOCAL_APIC=y.
In SMP environment, CONFIG_X86_LOCAL_APIC is automatically set;
however, in UP environment, users must manually set
CONFIG_X86_LOCAL_APIC. Once CONFIG_X86_LOCAL_APIC=y, setting
CONFIG_PCI_MSI enables the VECTOR based scheme and the option for
MSI-capable device drivers to selectively enable MSI/MSI-X.
Note that CONFIG_X86_IO_APIC setting is irrelevant because MSI/MSI-X 5. MSI quirks
vector is allocated new during runtime and MSI/MSI-X support does not
depend on BIOS support. This key independency enables MSI/MSI-X
support on future IOxAPIC free platforms.
5.5.2 Device hardware support Several PCI chipsets or devices are known not to support MSIs.
The PCI stack provides three ways to disable MSIs:
The hardware device function supports MSI by indicating the 1. globally
MSI/MSI-X capability structure on its PCI capability list. By 2. on all devices behind a specific bridge
default, this capability structure will not be initialized by 3. on a single device
the kernel to enable MSI during the system boot. In other words,
the device function is running on its default pin assertion mode.
Note that in many cases the hardware supporting MSI have bugs,
which may result in system hangs. The software driver of specific
MSI-capable hardware is responsible for deciding whether to call
pci_enable_msi or not. A return of zero indicates the kernel
successfully initialized the MSI/MSI-X capability structure of the
device function. The device function is now running on MSI/MSI-X mode.
5.6 How to tell whether MSI/MSI-X is enabled on device function 5.1. Disabling MSIs globally
At the driver level, a return of zero from the function call of Some host chipsets simply don't support MSIs properly. If we're
pci_enable_msi()/pci_enable_msix() indicates to a device driver that lucky, the manufacturer knows this and has indicated it in the ACPI
its device function is initialized successfully and ready to run in FADT table. In this case, Linux will automatically disable MSIs.
MSI/MSI-X mode. Some boards don't include this information in the table and so we have
to detect them ourselves. The complete list of these is found near the
quirk_disable_all_msi() function in drivers/pci/quirks.c.
At the user level, users can use the command 'cat /proc/interrupts' If you have a board which has problems with MSIs, you can pass pci=nomsi
to display the vectors allocated for devices and their interrupt on the kernel command line to disable MSIs on all devices. It would be
MSI/MSI-X modes ("PCI-MSI"/"PCI-MSI-X"). Below shows MSI mode is in your best interests to report the problem to linux-pci@vger.kernel.org
enabled on a SCSI Adaptec 39320D Ultra320 controller. including a full 'lspci -v' so we can add the quirks to the kernel.
CPU0 CPU1 5.2. Disabling MSIs below a bridge
0: 324639 0 IO-APIC-edge timer
1: 1186 0 IO-APIC-edge i8042
2: 0 0 XT-PIC cascade
12: 2797 0 IO-APIC-edge i8042
14: 6543 0 IO-APIC-edge ide0
15: 1 0 IO-APIC-edge ide1
169: 0 0 IO-APIC-level uhci-hcd
185: 0 0 IO-APIC-level uhci-hcd
193: 138 10 PCI-MSI aic79xx
201: 30 0 PCI-MSI aic79xx
225: 30 0 IO-APIC-level aic7xxx
233: 30 0 IO-APIC-level aic7xxx
NMI: 0 0
LOC: 324553 325068
ERR: 0
MIS: 0
6. MSI quirks Some PCI bridges are not able to route MSIs between busses properly.
In this case, MSIs must be disabled on all devices behind the bridge.
Several PCI chipsets or devices are known to not support MSI. Some bridges allow you to enable MSIs by changing some bits in their
The PCI stack provides 3 possible levels of MSI disabling: PCI configuration space (especially the Hypertransport chipsets such
* on a single device as the nVidia nForce and Serverworks HT2000). As with host chipsets,
* on all devices behind a specific bridge Linux mostly knows about them and automatically enables MSIs if it can.
* globally If you have a bridge which Linux doesn't yet know about, you can enable
MSIs in configuration space using whatever method you know works, then
enable MSIs on that bridge by doing:
6.1. Disabling MSI on a single device echo 1 > /sys/bus/pci/devices/$bridge/msi_bus
Under some circumstances it might be required to disable MSI on a where $bridge is the PCI address of the bridge you've enabled (eg
single device. This may be achieved by either not calling pci_enable_msi() 0000:00:0e.0).
or all, or setting the pci_dev->no_msi flag before (most of the time
in a quirk).
6.2. Disabling MSI below a bridge To disable MSIs, echo 0 instead of 1. Changing this value should be
done with caution as it can break interrupt handling for all devices
below this bridge.
The vast majority of MSI quirks are required by PCI bridges not Again, please notify linux-pci@vger.kernel.org of any bridges that need
being able to route MSI between busses. In this case, MSI have to be special handling.
disabled on all devices behind this bridge. It is achieves by setting
the PCI_BUS_FLAGS_NO_MSI flag in the pci_bus->bus_flags of the bridge
subordinate bus. There is no need to set the same flag on bridges that
are below the broken bridge. When pci_enable_msi() is called to enable
MSI on a device, pci_msi_supported() takes care of checking the NO_MSI
flag in all parent busses of the device.
Some bridges actually support dynamic MSI support enabling/disabling 5.3. Disabling MSIs on a single device
by changing some bits in their PCI configuration space (especially
the Hypertransport chipsets such as the nVidia nForce and Serverworks
HT2000). It may then be required to update the NO_MSI flag on the
corresponding devices in the sysfs hierarchy. To enable MSI support
on device "0000:00:0e", do:
echo 1 > /sys/bus/pci/devices/0000:00:0e/msi_bus Some devices are known to have faulty MSI implementations. Usually this
is handled in the individual device driver but occasionally it's necessary
to handle this with a quirk. Some drivers have an option to disable use
of MSI. While this is a convenient workaround for the driver author,
it is not good practise, and should not be emulated.
To disable MSI support, echo 0 instead of 1. Note that it should be 5.4. Finding why MSIs are disabled on a device
used with caution since changing this value might break interrupts.
6.3. Disabling MSI globally From the above three sections, you can see that there are many reasons
why MSIs may not be enabled for a given device. Your first step should
be to examine your dmesg carefully to determine whether MSIs are enabled
for your machine. You should also check your .config to be sure you
have enabled CONFIG_PCI_MSI.
Some extreme cases may require to disable MSI globally on the system. Then, 'lspci -t' gives the list of bridges above a device. Reading
For now, the only known case is a Serverworks PCI-X chipsets (MSI are /sys/bus/pci/devices/*/msi_bus will tell you whether MSI are enabled (1)
not supported on several busses that are not all connected to the or disabled (0). If 0 is found in any of the msi_bus files belonging
chipset in the Linux PCI hierarchy). In the vast majority of other to bridges between the PCI root and the device, MSIs are disabled.
cases, disabling only behind a specific bridge is enough.
For debugging purpose, the user may also pass pci=nomsi on the kernel It is also worth checking the device driver to see whether it supports MSIs.
command-line to explicitly disable MSI globally. But, once the appro- For example, it may contain calls to pci_enable_msi(), pci_enable_msix() or
priate quirks are added to the kernel, this option should not be pci_enable_msi_block().
required anymore.
6.4. Finding why MSI cannot be enabled on a device
Assuming that MSI are not enabled on a device, you should look at
dmesg to find messages that quirks may output when disabling MSI
on some devices, some bridges or even globally.
Then, lspci -t gives the list of bridges above a device. Reading
/sys/bus/pci/devices/0000:00:0e/msi_bus will tell you whether MSI
are enabled (1) or disabled (0). In 0 is found in a single bridge
msi_bus file above the device, MSI cannot be enabled.
7. FAQ
Q1. Are there any limitations on using the MSI?
A1. If the PCI device supports MSI and conforms to the
specification and the platform supports the APIC local bus,
then using MSI should work.
Q2. Will it work on all the Pentium processors (P3, P4, Xeon,
AMD processors)? In P3 IPI's are transmitted on the APIC local
bus and in P4 and Xeon they are transmitted on the system
bus. Are there any implications with this?
A2. MSI support enables a PCI device sending an inbound
memory write (0xfeexxxxx as target address) on its PCI bus
directly to the FSB. Since the message address has a
redirection hint bit cleared, it should work.
Q3. The target address 0xfeexxxxx will be translated by the
Host Bridge into an interrupt message. Are there any
limitations on the chipsets such as Intel 8xx, Intel e7xxx,
or VIA?
A3. If these chipsets support an inbound memory write with
target address set as 0xfeexxxxx, as conformed to PCI
specification 2.3 or latest, then it should work.
Q4. From the driver point of view, if the MSI is lost because
of errors occurring during inbound memory write, then it may
wait forever. Is there a mechanism for it to recover?
A4. Since the target of the transaction is an inbound memory
write, all transaction termination conditions (Retry,
Master-Abort, Target-Abort, or normal completion) are
supported. A device sending an MSI must abide by all the PCI
rules and conditions regarding that inbound memory write. So,
if a retry is signaled it must retry, etc... We believe that
the recommendation for Abort is also a retry (refer to PCI
specification 2.3 or latest).

View File

@ -0,0 +1,99 @@
PCI Express I/O Virtualization Howto
Copyright (C) 2009 Intel Corporation
Yu Zhao <yu.zhao@intel.com>
1. Overview
1.1 What is SR-IOV
Single Root I/O Virtualization (SR-IOV) is a PCI Express Extended
capability which makes one physical device appear as multiple virtual
devices. The physical device is referred to as Physical Function (PF)
while the virtual devices are referred to as Virtual Functions (VF).
Allocation of the VF can be dynamically controlled by the PF via
registers encapsulated in the capability. By default, this feature is
not enabled and the PF behaves as traditional PCIe device. Once it's
turned on, each VF's PCI configuration space can be accessed by its own
Bus, Device and Function Number (Routing ID). And each VF also has PCI
Memory Space, which is used to map its register set. VF device driver
operates on the register set so it can be functional and appear as a
real existing PCI device.
2. User Guide
2.1 How can I enable SR-IOV capability
The device driver (PF driver) will control the enabling and disabling
of the capability via API provided by SR-IOV core. If the hardware
has SR-IOV capability, loading its PF driver would enable it and all
VFs associated with the PF.
2.2 How can I use the Virtual Functions
The VF is treated as hot-plugged PCI devices in the kernel, so they
should be able to work in the same way as real PCI devices. The VF
requires device driver that is same as a normal PCI device's.
3. Developer Guide
3.1 SR-IOV API
To enable SR-IOV capability:
int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn);
'nr_virtfn' is number of VFs to be enabled.
To disable SR-IOV capability:
void pci_disable_sriov(struct pci_dev *dev);
To notify SR-IOV core of Virtual Function Migration:
irqreturn_t pci_sriov_migration(struct pci_dev *dev);
3.2 Usage example
Following piece of code illustrates the usage of the SR-IOV API.
static int __devinit dev_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
pci_enable_sriov(dev, NR_VIRTFN);
...
return 0;
}
static void __devexit dev_remove(struct pci_dev *dev)
{
pci_disable_sriov(dev);
...
}
static int dev_suspend(struct pci_dev *dev, pm_message_t state)
{
...
return 0;
}
static int dev_resume(struct pci_dev *dev)
{
...
return 0;
}
static void dev_shutdown(struct pci_dev *dev)
{
...
}
static struct pci_driver dev_driver = {
.name = "SR-IOV Physical Function driver",
.id_table = dev_id_table,
.probe = dev_probe,
.remove = __devexit_p(dev_remove),
.suspend = dev_suspend,
.resume = dev_resume,
.shutdown = dev_shutdown,
};

View File

@ -11,8 +11,6 @@ aty128fb.txt
- info on the ATI Rage128 frame buffer driver. - info on the ATI Rage128 frame buffer driver.
cirrusfb.txt cirrusfb.txt
- info on the driver for Cirrus Logic chipsets. - info on the driver for Cirrus Logic chipsets.
cyblafb/
- directory with documentation files related to the cyblafb driver.
deferred_io.txt deferred_io.txt
- an introduction to deferred IO. - an introduction to deferred IO.
fbcon.txt fbcon.txt

View File

@ -1,13 +0,0 @@
Bugs
====
I currently don't know of any bug. Please do send reports to:
- linux-fbdev-devel@lists.sourceforge.net
- Knut_Petersen@t-online.de.
Untested features
=================
All LCD stuff is untested. If it worked in tridentfb, it should work in
cyblafb. Please test and report the results to Knut_Petersen@t-online.de.

View File

@ -1,7 +0,0 @@
Thanks to
=========
* Alan Hourihane, for writing the X trident driver
* Jani Monoses, for writing the tridentfb driver
* Antonino A. Daplas, for review of the first published
version of cyblafb and some code
* Jochen Hein, for testing and a helpfull bug report

View File

@ -1,17 +0,0 @@
Available Documentation
=======================
Apollo PLE 133 Chipset VT8601A North Bridge Datasheet, Rev. 1.82, October 22,
2001, available from VIA:
http://www.viavpsd.com/product/6/15/DS8601A182.pdf
The datasheet is incomplete, some registers that need to be programmed are not
explained at all and important bits are listed as "reserved". But you really
need the datasheet to understand the code. "p. xxx" comments refer to page
numbers of this document.
XFree/XOrg drivers are available and of good quality, looking at the code
there is a good idea if the datasheet does not provide enough information
or if the datasheet seems to be wrong.

View File

@ -1,154 +0,0 @@
#
# Sample fb.modes file
#
# Provides an incomplete list of working modes for
# the cyberblade/i1 graphics core.
#
# The value 4294967256 is used instead of -40. Of course, -40 is not
# a really reasonable value, but chip design does not always follow
# logic. Believe me, it's ok, and it's the way the BIOS does it.
#
# fbset requires 4294967256 in fb.modes and -40 as an argument to
# the -t parameter. That's also not too reasonable, and it might change
# in the future or might even be differt for your current version.
#
mode "640x480-50"
geometry 640 480 2048 4096 8
timings 47619 4294967256 24 17 0 216 3
endmode
mode "640x480-60"
geometry 640 480 2048 4096 8
timings 39682 4294967256 24 17 0 216 3
endmode
mode "640x480-70"
geometry 640 480 2048 4096 8
timings 34013 4294967256 24 17 0 216 3
endmode
mode "640x480-72"
geometry 640 480 2048 4096 8
timings 33068 4294967256 24 17 0 216 3
endmode
mode "640x480-75"
geometry 640 480 2048 4096 8
timings 31746 4294967256 24 17 0 216 3
endmode
mode "640x480-80"
geometry 640 480 2048 4096 8
timings 29761 4294967256 24 17 0 216 3
endmode
mode "640x480-85"
geometry 640 480 2048 4096 8
timings 28011 4294967256 24 17 0 216 3
endmode
mode "800x600-50"
geometry 800 600 2048 4096 8
timings 30303 96 24 14 0 136 11
endmode
mode "800x600-60"
geometry 800 600 2048 4096 8
timings 25252 96 24 14 0 136 11
endmode
mode "800x600-70"
geometry 800 600 2048 4096 8
timings 21645 96 24 14 0 136 11
endmode
mode "800x600-72"
geometry 800 600 2048 4096 8
timings 21043 96 24 14 0 136 11
endmode
mode "800x600-75"
geometry 800 600 2048 4096 8
timings 20202 96 24 14 0 136 11
endmode
mode "800x600-80"
geometry 800 600 2048 4096 8
timings 18939 96 24 14 0 136 11
endmode
mode "800x600-85"
geometry 800 600 2048 4096 8
timings 17825 96 24 14 0 136 11
endmode
mode "1024x768-50"
geometry 1024 768 2048 4096 8
timings 19054 144 24 29 0 120 3
endmode
mode "1024x768-60"
geometry 1024 768 2048 4096 8
timings 15880 144 24 29 0 120 3
endmode
mode "1024x768-70"
geometry 1024 768 2048 4096 8
timings 13610 144 24 29 0 120 3
endmode
mode "1024x768-72"
geometry 1024 768 2048 4096 8
timings 13232 144 24 29 0 120 3
endmode
mode "1024x768-75"
geometry 1024 768 2048 4096 8
timings 12703 144 24 29 0 120 3
endmode
mode "1024x768-80"
geometry 1024 768 2048 4096 8
timings 11910 144 24 29 0 120 3
endmode
mode "1024x768-85"
geometry 1024 768 2048 4096 8
timings 11209 144 24 29 0 120 3
endmode
mode "1280x1024-50"
geometry 1280 1024 2048 4096 8
timings 11114 232 16 39 0 160 3
endmode
mode "1280x1024-60"
geometry 1280 1024 2048 4096 8
timings 9262 232 16 39 0 160 3
endmode
mode "1280x1024-70"
geometry 1280 1024 2048 4096 8
timings 7939 232 16 39 0 160 3
endmode
mode "1280x1024-72"
geometry 1280 1024 2048 4096 8
timings 7719 232 16 39 0 160 3
endmode
mode "1280x1024-75"
geometry 1280 1024 2048 4096 8
timings 7410 232 16 39 0 160 3
endmode
mode "1280x1024-80"
geometry 1280 1024 2048 4096 8
timings 6946 232 16 39 0 160 3
endmode
mode "1280x1024-85"
geometry 1280 1024 2048 4096 8
timings 6538 232 16 39 0 160 3
endmode

View File

@ -1,79 +0,0 @@
Speed
=====
CyBlaFB is much faster than tridentfb and vesafb. Compare the performance data
for mode 1280x1024-[8,16,32]@61 Hz.
Test 1: Cat a file with 2000 lines of 0 characters.
Test 2: Cat a file with 2000 lines of 80 characters.
Test 3: Cat a file with 2000 lines of 160 characters.
All values show system time use in seconds, kernel 2.6.12 was used for
the measurements. 2.6.13 is a bit slower, 2.6.14 hopefully will include a
patch that speeds up kernel bitblitting a lot ( > 20%).
+-----------+-----------------------------------------------------+
| | not accelerated |
| TRIDENTFB +-----------------+-----------------+-----------------+
| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp |
| | noypan | ypan | noypan | ypan | noypan | ypan |
+-----------+--------+--------+--------+--------+--------+--------+
| Test 1 | 4.31 | 4.33 | 6.05 | 12.81 | ---- | ---- |
| Test 2 | 67.94 | 5.44 | 123.16 | 14.79 | ---- | ---- |
| Test 3 | 131.36 | 6.55 | 240.12 | 16.76 | ---- | ---- |
+-----------+--------+--------+--------+--------+--------+--------+
| Comments | | | completely bro- |
| | | | ken, monitor |
| | | | switches off |
+-----------+-----------------+-----------------+-----------------+
+-----------+-----------------------------------------------------+
| | accelerated |
| TRIDENTFB +-----------------+-----------------+-----------------+
| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp |
| | noypan | ypan | noypan | ypan | noypan | ypan |
+-----------+--------+--------+--------+--------+--------+--------+
| Test 1 | ---- | ---- | 20.62 | 1.22 | ---- | ---- |
| Test 2 | ---- | ---- | 22.61 | 3.19 | ---- | ---- |
| Test 3 | ---- | ---- | 24.59 | 5.16 | ---- | ---- |
+-----------+--------+--------+--------+--------+--------+--------+
| Comments | broken, writing | broken, ok only | completely bro- |
| | to wrong places | if bgcolor is | ken, monitor |
| | on screen + bug | black, bug in | switches off |
| | in fillrect() | fillrect() | |
+-----------+-----------------+-----------------+-----------------+
+-----------+-----------------------------------------------------+
| | not accelerated |
| VESAFB +-----------------+-----------------+-----------------+
| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp |
| | noypan | ypan | noypan | ypan | noypan | ypan |
+-----------+--------+--------+--------+--------+--------+--------+
| Test 1 | 4.26 | 3.76 | 5.99 | 7.23 | ---- | ---- |
| Test 2 | 65.65 | 4.89 | 120.88 | 9.08 | ---- | ---- |
| Test 3 | 126.91 | 5.94 | 235.77 | 11.03 | ---- | ---- |
+-----------+--------+--------+--------+--------+--------+--------+
| Comments | vga=0x307 | vga=0x31a | vga=0x31b not |
| | fh=80kHz | fh=80kHz | supported by |
| | fv=75kHz | fv=75kHz | video BIOS and |
| | | | hardware |
+-----------+-----------------+-----------------+-----------------+
+-----------+-----------------------------------------------------+
| | accelerated |
| CYBLAFB +-----------------+-----------------+-----------------+
| | 8 bpp | 16 bpp | 32 bpp |
| | noypan | ypan | noypan | ypan | noypan | ypan |
+-----------+--------+--------+--------+--------+--------+--------+
| Test 1 | 8.02 | 0.23 | 19.04 | 0.61 | 57.12 | 2.74 |
| Test 2 | 8.38 | 0.55 | 19.39 | 0.92 | 57.54 | 3.13 |
| Test 3 | 8.73 | 0.86 | 19.74 | 1.24 | 57.95 | 3.51 |
+-----------+--------+--------+--------+--------+--------+--------+
| Comments | | | |
| | | | |
| | | | |
| | | | |
+-----------+-----------------+-----------------+-----------------+

View File

@ -1,31 +0,0 @@
TODO / Missing features
=======================
Verify LCD stuff "stretch" and "center" options are
completely untested ... this code needs to be
verified. As I don't have access to such
hardware, please contact me if you are
willing run some tests.
Interlaced video modes The reason that interleaved
modes are disabled is that I do not know
the meaning of the vertical interlace
parameter. Also the datasheet mentions a
bit d8 of a horizontal interlace parameter,
but nowhere the lower 8 bits. Please help
if you can.
low-res double scan modes Who needs it?
accelerated color blitting Who needs it? The console driver does use color
blitting for nothing but drawing the penguine,
everything else is done using color expanding
blitting of 1bpp character bitmaps.
ioctls Who needs it?
TV-out Will be done later. Use "vga= " at boot time
to set a suitable video mode.
??? Feel free to contact me if you have any
feature requests

View File

@ -1,217 +0,0 @@
CyBlaFB is a framebuffer driver for the Cyberblade/i1 graphics core integrated
into the VIA Apollo PLE133 (aka vt8601) south bridge. It is developed and
tested using a VIA EPIA 5000 board.
Cyblafb - compiled into the kernel or as a module?
==================================================
You might compile cyblafb either as a module or compile it permanently into the
kernel.
Unless you have a real reason to do so you should not compile both vesafb and
cyblafb permanently into the kernel. It's possible and it helps during the
developement cycle, but it's useless and will at least block some otherwise
usefull memory for ordinary users.
Selecting Modes
===============
Startup Mode
============
First of all, you might use the "vga=???" boot parameter as it is
documented in vesafb.txt and svga.txt. Cyblafb will detect the video
mode selected and will use the geometry and timings found by
inspecting the hardware registers.
video=cyblafb vga=0x317
Alternatively you might use a combination of the mode, ref and bpp
parameters. If you compiled the driver into the kernel, add something
like this to the kernel command line:
video=cyblafb:1280x1024,bpp=16,ref=50 ...
If you compiled the driver as a module, the same mode would be
selected by the following command:
modprobe cyblafb mode=1280x1024 bpp=16 ref=50 ...
None of the modes possible to select as startup modes are affected by
the problems described at the end of the next subsection.
For all startup modes cyblafb chooses a virtual x resolution of 2048,
the only exception is mode 1280x1024 in combination with 32 bpp. This
allows ywrap scrolling for all those modes if rotation is 0 or 2, and
also fast scrolling if rotation is 1 or 3. The default virtual y reso-
lution is 4096 for bpp == 8, 2048 for bpp==16 and 1024 for bpp == 32,
again with the only exception of 1280x1024 at 32 bpp.
Please do set your video memory size to 8 Mb in the Bios setup. Other
values will work, but performace is decreased for a lot of modes.
Mode changes using fbset
========================
You might use fbset to change the video mode, see "man fbset". Cyblafb
generally does assume that you know what you are doing. But it does
some checks, especially those that are needed to prevent you from
damaging your hardware.
- only 8, 16, 24 and 32 bpp video modes are accepted
- interlaced video modes are not accepted
- double scan video modes are not accepted
- if a flat panel is found, cyblafb does not allow you
to program a resolution higher than the physical
resolution of the flat panel monitor
- cyblafb does not allow vclk to exceed 230 MHz. As 32 bpp
and (currently) 24 bit modes use a doubled vclk internally,
the dotclock limit as seen by fbset is 115 MHz for those
modes and 230 MHz for 8 and 16 bpp modes.
- cyblafb will allow you to select very high resolutions as
long as the hardware can be programmed to these modes. The
documented limit 1600x1200 is not enforced, but don't expect
perfect signal quality.
Any request that violates the rules given above will be either changed
to something the hardware supports or an error value will be returned.
If you program a virtual y resolution higher than the hardware limit,
cyblafb will silently decrease that value to the highest possible
value. The same is true for a virtual x resolution that is not
supported by the hardware. Cyblafb tries to adapt vyres first because
vxres decides if ywrap scrolling is possible or not.
Attempts to disable acceleration are ignored, I believe that this is
safe.
Some video modes that should work do not work as expected. If you use
the standard fb.modes, fbset 640x480-60 will program that mode, but
you will see a vertical area, about two characters wide, with only
much darker characters than the other characters on the screen.
Cyblafb does allow that mode to be set, as it does not violate the
official specifications. It would need a lot of code to reliably sort
out all invalid modes, playing around with the margin values will
give a valid mode quickly. And if cyblafb would detect such an invalid
mode, should it silently alter the requested values or should it
report an error? Both options have some pros and cons. As stated
above, none of the startup modes are affected, and if you set
verbosity to 1 or higher, cyblafb will print the fbset command that
would be needed to program that mode using fbset.
Other Parameters
================
crt don't autodetect, assume monitor connected to
standard VGA connector
fp don't autodetect, assume flat panel display
connected to flat panel monitor interface
nativex inform driver about native x resolution of
flat panel monitor connected to special
interface (should be autodetected)
stretch stretch image to adapt low resolution modes to
higer resolutions of flat panel monitors
connected to special interface
center center image to adapt low resolution modes to
higer resolutions of flat panel monitors
connected to special interface
memsize use if autodetected memsize is wrong ...
should never be necessary
nopcirr disable PCI read retry
nopciwr disable PCI write retry
nopcirb disable PCI read bursts
nopciwb disable PCI write bursts
bpp bpp for specified modes
valid values: 8 || 16 || 24 || 32
ref refresh rate for specified mode
valid values: 50 <= ref <= 85
mode 640x480 or 800x600 or 1024x768 or 1280x1024
if not specified, the startup mode will be detected
and used, so you might also use the vga=??? parameter
described in vesafb.txt. If you do not specify a mode,
bpp and ref parameters are ignored.
verbosity 0 is the default, increase to at least 2 for every
bug report!
Development hints
=================
It's much faster do compile a module and to load the new version after
unloading the old module than to compile a new kernel and to reboot. So if you
try to work on cyblafb, it might be a good idea to use cyblafb as a module.
In real life, fast often means dangerous, and that's also the case here. If
you introduce a serious bug when cyblafb is compiled into the kernel, the
kernel will lock or oops with a high probability before the file system is
mounted, and the danger for your data is low. If you load a broken own version
of cyblafb on a running system, the danger for the integrity of the file
system is much higher as you might need a hard reset afterwards. Decide
yourself.
Module unloading, the vfb method
================================
If you want to unload/reload cyblafb using the virtual framebuffer, you need
to enable vfb support in the kernel first. After that, load the modules as
shown below:
modprobe vfb vfb_enable=1
modprobe fbcon
modprobe cyblafb
fbset -fb /dev/fb1 1280x1024-60 -vyres 2662
con2fb /dev/fb1 /dev/tty1
...
If you now made some changes to cyblafb and want to reload it, you might do it
as show below:
con2fb /dev/fb0 /dev/tty1
...
rmmod cyblafb
modprobe cyblafb
con2fb /dev/fb1 /dev/tty1
...
Of course, you might choose another mode, and most certainly you also want to
map some other /dev/tty* to the real framebuffer device. You might also choose
to compile fbcon as a kernel module or place it permanently in the kernel.
I do not know of any way to unload fbcon, and fbcon will prevent the
framebuffer device loaded first from unloading. [If there is a way, then
please add a description here!]
Module unloading, the vesafb method
===================================
Configure the kernel:
<*> Support for frame buffer devices
[*] VESA VGA graphics support
<M> Cyberblade/i1 support
Add e.g. "video=vesafb:ypan vga=0x307" to the kernel parameters. The ypan
parameter is important, choose any vga parameter you like as long as it is
a graphics mode.
After booting, load cyblafb without any mode and bpp parameter and assign
cyblafb to individual ttys using con2fb, e.g.:
modprobe cyblafb
con2fb /dev/fb1 /dev/tty1
Unloading cyblafb works without problems after you assign vesafb to all
ttys again, e.g.:
con2fb /dev/fb0 /dev/tty1
rmmod cyblafb

View File

@ -1,29 +0,0 @@
0.62
====
- the vesafb parameter has been removed as I decided to allow the
feature without any special parameter.
- Cyblafb does not use the vga style of panning any longer, now the
"right view" register in the graphics engine IO space is used. Without
that change it was impossible to use all available memory, and without
access to all available memory it is impossible to ywrap.
- The imageblit function now uses hardware acceleration for all font
widths. Hardware blitting across pixel column 2048 is broken in the
cyberblade/i1 graphics core, but we work around that hardware bug.
- modes with vxres != xres are supported now.
- ywrap scrolling is supported now and the default. This is a big
performance gain.
- default video modes use vyres > yres and vxres > xres to allow
almost optimal scrolling speed for normal and rotated screens
- some features mainly usefull for debugging the upper layers of the
framebuffer system have been added, have a look at the code
- fixed: Oops after unloading cyblafb when reading /proc/io*
- we work around some bugs of the higher framebuffer layers.

View File

@ -1,85 +0,0 @@
I tried the following framebuffer drivers:
- TRIDENTFB is full of bugs. Acceleration is broken for Blade3D
graphics cores like the cyberblade/i1. It claims to support a great
number of devices, but documentation for most of these devices is
unfortunately not available. There is _no_ reason to use tridentfb
for cyberblade/i1 + CRT users. VESAFB is faster, and the one
advantage, mode switching, is broken in tridentfb.
- VESAFB is used by many distributions as a standard. Vesafb does
not support mode switching. VESAFB is a bit faster than the working
configurations of TRIDENTFB, but it is still too slow, even if you
use ypan.
- EPIAFB (you'll find it on sourceforge) supports the Cyberblade/i1
graphics core, but it still has serious bugs and developement seems
to have stopped. This is the one driver with TV-out support. If you
do need this feature, try epiafb.
None of these drivers was a real option for me.
I believe that is unreasonable to change code that announces to support 20
devices if I only have more or less sufficient documentation for exactly one
of these. The risk of breaking device foo while fixing device bar is too high.
So I decided to start CyBlaFB as a stripped down tridentfb.
All code specific to other Trident chips has been removed. After that there
were a lot of cosmetic changes to increase the readability of the code. All
register names were changed to those mnemonics used in the datasheet. Function
and macro names were changed if they hindered easy understanding of the code.
After that I debugged the code and implemented some new features. I'll try to
give a little summary of the main changes:
- calculation of vertical and horizontal timings was fixed
- video signal quality has been improved dramatically
- acceleration:
- fillrect and copyarea were fixed and reenabled
- color expanding imageblit was newly implemented, color
imageblit (only used to draw the penguine) still uses the
generic code.
- init of the acceleration engine was improved and moved to a
place where it really works ...
- sync function has a timeout now and tries to reset and
reinit the accel engine if necessary
- fewer slow copyarea calls when doing ypan scrolling by using
undocumented bit d21 of screen start address stored in
CR2B[5]. BIOS does use it also, so this should be safe.
- cyblafb rejects any attempt to set modes that would cause vclk
values above reasonable 230 MHz. 32bit modes use a clock
multiplicator of 2, so fbset does show the correct values for
pixclock but not for vclk in this case. The fbset limit is 115 MHz
for 32 bpp modes.
- cyblafb rejects modes known to be broken or unimplemented (all
interlaced modes, all doublescan modes for now)
- cyblafb now works independant of the video mode in effect at startup
time (tridentfb does not init all needed registers to reasonable
values)
- switching between video modes does work reliably now
- the first video mode now is the one selected on startup using the
vga=???? mechanism or any of
- 640x480, 800x600, 1024x768, 1280x1024
- 8, 16, 24 or 32 bpp
- refresh between 50 Hz and 85 Hz, 1 Hz steps (1280x1024-32
is limited to 63Hz)
- pci retry and pci burst mode are settable (try to disable if you
experience latency problems)
- built as a module cyblafb might be unloaded and reloaded using
the vfb module and con2vt or might be used together with vesafb

View File

@ -311,6 +311,18 @@ Who: Vlad Yasevich <vladislav.yasevich@hp.com>
--------------------------- ---------------------------
What: Ability for non root users to shm_get hugetlb pages based on mlock
resource limits
When: 2.6.31
Why: Non root users need to be part of /proc/sys/vm/hugetlb_shm_group or
have CAP_IPC_LOCK to be able to allocate shm segments backed by
huge pages. The mlock based rlimit check to allow shm hugetlb is
inconsistent with mmap based allocations. Hence it is being
deprecated.
Who: Ravikiran Thirumalai <kiran@scalex86.org>
---------------------------
What: CONFIG_THERMAL_HWMON What: CONFIG_THERMAL_HWMON
When: January 2009 When: January 2009
Why: This option was introduced just to allow older lm-sensors userspace Why: This option was introduced just to allow older lm-sensors userspace
@ -380,3 +392,35 @@ Why: The defines and typedefs (hw_interrupt_type, no_irq_type, irq_desc_t)
have been kept around for migration reasons. After more than two years have been kept around for migration reasons. After more than two years
it's time to remove them finally it's time to remove them finally
Who: Thomas Gleixner <tglx@linutronix.de> Who: Thomas Gleixner <tglx@linutronix.de>
---------------------------
What: fakephp and associated sysfs files in /sys/bus/pci/slots/
When: 2011
Why: In 2.6.27, the semantics of /sys/bus/pci/slots was redefined to
represent a machine's physical PCI slots. The change in semantics
had userspace implications, as the hotplug core no longer allowed
drivers to create multiple sysfs files per physical slot (required
for multi-function devices, e.g.). fakephp was seen as a developer's
tool only, and its interface changed. Too late, we learned that
there were some users of the fakephp interface.
In 2.6.30, the original fakephp interface was restored. At the same
time, the PCI core gained the ability that fakephp provided, namely
function-level hot-remove and hot-add.
Since the PCI core now provides the same functionality, exposed in:
/sys/bus/pci/rescan
/sys/bus/pci/devices/.../remove
/sys/bus/pci/devices/.../rescan
there is no functional reason to maintain fakephp as well.
We will keep the existing module so that 'modprobe fakephp' will
present the old /sys/bus/pci/slots/... interface for compatibility,
but users are urged to migrate their applications to the API above.
After a reasonable transition period, we will remove the legacy
fakephp interface.
Who: Alex Chiang <achiang@hp.com>

View File

@ -505,7 +505,7 @@ prototypes:
void (*open)(struct vm_area_struct*); void (*open)(struct vm_area_struct*);
void (*close)(struct vm_area_struct*); void (*close)(struct vm_area_struct*);
int (*fault)(struct vm_area_struct*, struct vm_fault *); int (*fault)(struct vm_area_struct*, struct vm_fault *);
int (*page_mkwrite)(struct vm_area_struct *, struct page *); int (*page_mkwrite)(struct vm_area_struct *, struct vm_fault *);
int (*access)(struct vm_area_struct *, unsigned long, void*, int, int); int (*access)(struct vm_area_struct *, unsigned long, void*, int, int);
locking rules: locking rules:

View File

@ -85,7 +85,7 @@ Note: More extensive information for getting started with ext4 can be
* extent format more robust in face of on-disk corruption due to magics, * extent format more robust in face of on-disk corruption due to magics,
* internal redundancy in tree * internal redundancy in tree
* improved file allocation (multi-block alloc) * improved file allocation (multi-block alloc)
* fix 32000 subdirectory limit * lift 32000 subdirectory limit imposed by i_links_count[1]
* nsec timestamps for mtime, atime, ctime, create time * nsec timestamps for mtime, atime, ctime, create time
* inode version field on disk (NFSv4, Lustre) * inode version field on disk (NFSv4, Lustre)
* reduced e2fsck time via uninit_bg feature * reduced e2fsck time via uninit_bg feature
@ -100,6 +100,9 @@ Note: More extensive information for getting started with ext4 can be
* efficent new ordered mode in JBD2 and ext4(avoid using buffer head to force * efficent new ordered mode in JBD2 and ext4(avoid using buffer head to force
the ordering) the ordering)
[1] Filesystems with a block size of 1k may see a limit imposed by the
directory hash tree having a maximum depth of two.
2.2 Candidate features for future inclusion 2.2 Candidate features for future inclusion
* Online defrag (patches available but not well tested) * Online defrag (patches available but not well tested)
@ -180,8 +183,8 @@ commit=nrsec (*) Ext4 can be told to sync all its data and metadata
performance. performance.
barrier=<0|1(*)> This enables/disables the use of write barriers in barrier=<0|1(*)> This enables/disables the use of write barriers in
the jbd code. barrier=0 disables, barrier=1 enables. barrier(*) the jbd code. barrier=0 disables, barrier=1 enables.
This also requires an IO stack which can support nobarrier This also requires an IO stack which can support
barriers, and if jbd gets an error on a barrier barriers, and if jbd gets an error on a barrier
write, it will disable again with a warning. write, it will disable again with a warning.
Write barriers enforce proper on-disk ordering Write barriers enforce proper on-disk ordering
@ -189,6 +192,9 @@ barrier=<0|1(*)> This enables/disables the use of write barriers in
safe to use, at some performance penalty. If safe to use, at some performance penalty. If
your disks are battery-backed in one way or another, your disks are battery-backed in one way or another,
disabling barriers may safely improve performance. disabling barriers may safely improve performance.
The mount options "barrier" and "nobarrier" can
also be used to enable or disable barriers, for
consistency with other ext4 mount options.
inode_readahead=n This tuning parameter controls the maximum inode_readahead=n This tuning parameter controls the maximum
number of inode table blocks that ext4's inode number of inode table blocks that ext4's inode
@ -310,6 +316,24 @@ journal_ioprio=prio The I/O priority (from 0 to 7, where 0 is the
a slightly higher priority than the default I/O a slightly higher priority than the default I/O
priority. priority.
auto_da_alloc(*) Many broken applications don't use fsync() when
noauto_da_alloc replacing existing files via patterns such as
fd = open("foo.new")/write(fd,..)/close(fd)/
rename("foo.new", "foo"), or worse yet,
fd = open("foo", O_TRUNC)/write(fd,..)/close(fd).
If auto_da_alloc is enabled, ext4 will detect
the replace-via-rename and replace-via-truncate
patterns and force that any delayed allocation
blocks are allocated such that at the next
journal commit, in the default data=ordered
mode, the data blocks of the new file are forced
to disk before the rename() operation is
commited. This provides roughly the same level
of guarantees as ext3, and avoids the
"zero-length" problem that can happen when a
system crashes before the delayed allocation
blocks are forced to disk.
Data Mode Data Mode
========= =========
There are 3 different data modes: There are 3 different data modes:

View File

@ -940,27 +940,6 @@ Table 1-10: Files in /proc/fs/ext4/<devname>
File Content File Content
mb_groups details of multiblock allocator buddy cache of free blocks mb_groups details of multiblock allocator buddy cache of free blocks
mb_history multiblock allocation history mb_history multiblock allocation history
stats controls whether the multiblock allocator should start
collecting statistics, which are shown during the unmount
group_prealloc the multiblock allocator will round up allocation
requests to a multiple of this tuning parameter if the
stripe size is not set in the ext4 superblock
max_to_scan The maximum number of extents the multiblock allocator
will search to find the best extent
min_to_scan The minimum number of extents the multiblock allocator
will search to find the best extent
order2_req Tuning parameter which controls the minimum size for
requests (as a power of 2) where the buddy cache is
used
stream_req Files which have fewer blocks than this tunable
parameter will have their blocks allocated out of a
block group specific preallocation pool, so that small
files are packed closely together. Each large file
will have its blocks allocated out of its own unique
preallocation pool.
inode_readahead Tuning parameter which controls the maximum number of
inode table blocks that ext4's inode table readahead
algorithm will pre-read into the buffer cache
.............................................................................. ..............................................................................

View File

@ -12,6 +12,7 @@ that support it. For example, a given bus might look like this:
| |-- enable | |-- enable
| |-- irq | |-- irq
| |-- local_cpus | |-- local_cpus
| |-- remove
| |-- resource | |-- resource
| |-- resource0 | |-- resource0
| |-- resource1 | |-- resource1
@ -36,6 +37,7 @@ files, each with their own function.
enable Whether the device is enabled (ascii, rw) enable Whether the device is enabled (ascii, rw)
irq IRQ number (ascii, ro) irq IRQ number (ascii, ro)
local_cpus nearby CPU mask (cpumask, ro) local_cpus nearby CPU mask (cpumask, ro)
remove remove device from kernel's list (ascii, wo)
resource PCI resource host addresses (ascii, ro) resource PCI resource host addresses (ascii, ro)
resource0..N PCI resource N, if present (binary, mmap) resource0..N PCI resource N, if present (binary, mmap)
resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap) resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap)
@ -46,6 +48,7 @@ files, each with their own function.
ro - read only file ro - read only file
rw - file is readable and writable rw - file is readable and writable
wo - write only file
mmap - file is mmapable mmap - file is mmapable
ascii - file contains ascii text ascii - file contains ascii text
binary - file contains binary data binary - file contains binary data
@ -73,6 +76,13 @@ that the device must be enabled for a rom read to return data succesfully.
In the event a driver is not bound to the device, it can be enabled using the In the event a driver is not bound to the device, it can be enabled using the
'enable' file, documented above. 'enable' file, documented above.
The 'remove' file is used to remove the PCI device, by writing a non-zero
integer to the file. This does not involve any kind of hot-plug functionality,
e.g. powering off the device. The device is removed from the kernel's list of
PCI devices, the sysfs directory for it is removed, and the device will be
removed from any drivers attached to it. Removal of PCI root buses is
disallowed.
Accessing legacy resources through sysfs Accessing legacy resources through sysfs
---------------------------------------- ----------------------------------------

View File

@ -49,12 +49,9 @@ of up to +/- 0.5 degrees even when compared against precise temperature
readings. Be sure to have a high vs. low temperature limit gap of al least readings. Be sure to have a high vs. low temperature limit gap of al least
1.0 degree Celsius to avoid Tout "bouncing", though! 1.0 degree Celsius to avoid Tout "bouncing", though!
As for alarms, you can read the alarm status of the DS1621 via the 'alarms' The alarm bits are set when the high or low limits are met or exceeded and
/sys file interface. The result consists mainly of bit 6 and 5 of the are reset by the module as soon as the respective temperature ranges are
configuration register of the chip; bit 6 (0x40 or 64) is the high alarm left.
bit and bit 5 (0x20 or 32) the low one. These bits are set when the high or
low limits are met or exceeded and are reset by the module as soon as the
respective temperature ranges are left.
The alarm registers are in no way suitable to find out about the actual The alarm registers are in no way suitable to find out about the actual
status of Tout. They will only tell you about its history, whether or not status of Tout. They will only tell you about its history, whether or not
@ -64,45 +61,3 @@ with neither of the alarms set.
Temperature conversion of the DS1621 takes up to 1000ms; internal access to Temperature conversion of the DS1621 takes up to 1000ms; internal access to
non-volatile registers may last for 10ms or below. non-volatile registers may last for 10ms or below.
High Accuracy Temperature Reading
---------------------------------
As said before, the temperature issued via the 9-bit i2c-bus data is
somewhat arbitrary. Internally, the temperature conversion is of a
different kind that is explained (not so...) well in the DS1621 data sheet.
To cut the long story short: Inside the DS1621 there are two oscillators,
both of them biassed by a temperature coefficient.
Higher resolution of the temperature reading can be achieved using the
internal projection, which means taking account of REG_COUNT and REG_SLOPE
(the driver manages them):
Taken from Dallas Semiconductors App Note 068: 'Increasing Temperature
Resolution on the DS1620' and App Note 105: 'High Resolution Temperature
Measurement with Dallas Direct-to-Digital Temperature Sensors'
- Read the 9-bit temperature and strip the LSB (Truncate the .5 degs)
- The resulting value is TEMP_READ.
- Then, read REG_COUNT.
- And then, REG_SLOPE.
TEMP = TEMP_READ - 0.25 + ((REG_SLOPE - REG_COUNT) / REG_SLOPE)
Note that this is what the DONE bit in the DS1621 configuration register is
good for: Internally, one temperature conversion takes up to 1000ms. Before
that conversion is complete you will not be able to read valid things out
of REG_COUNT and REG_SLOPE. The DONE bit, as you may have guessed by now,
tells you whether the conversion is complete ("done", in plain English) and
thus, whether the values you read are good or not.
The DS1621 has two modes of operation: "Continuous" conversion, which can
be understood as the default stand-alone mode where the chip gets the
temperature and controls external devices via its Tout pin or tells other
i2c's about it if they care. The other mode is called "1SHOT", that means
that it only figures out about the temperature when it is explicitly told
to do so; this can be seen as power saving mode.
Now if you want to read REG_COUNT and REG_SLOPE, you have to either stop
the continuous conversions until the contents of these registers are valid,
or, in 1SHOT mode, you have to have one conversion made.

View File

@ -1,11 +1,11 @@
Kernel driver lis3lv02d Kernel driver lis3lv02d
================== =======================
Supported chips: Supported chips:
* STMicroelectronics LIS3LV02DL and LIS3LV02DQ * STMicroelectronics LIS3LV02DL and LIS3LV02DQ
Author: Authors:
Yan Burman <burman.yan@gmail.com> Yan Burman <burman.yan@gmail.com>
Eric Piel <eric.piel@tremplin-utc.net> Eric Piel <eric.piel@tremplin-utc.net>
@ -15,7 +15,7 @@ Description
This driver provides support for the accelerometer found in various HP This driver provides support for the accelerometer found in various HP
laptops sporting the feature officially called "HP Mobile Data laptops sporting the feature officially called "HP Mobile Data
Protection System 3D" or "HP 3D DriveGuard". It detect automatically Protection System 3D" or "HP 3D DriveGuard". It detects automatically
laptops with this sensor. Known models (for now the HP 2133, nc6420, laptops with this sensor. Known models (for now the HP 2133, nc6420,
nc2510, nc8510, nc84x0, nw9440 and nx9420) will have their axis nc2510, nc8510, nc84x0, nw9440 and nx9420) will have their axis
automatically oriented on standard way (eg: you can directly play automatically oriented on standard way (eg: you can directly play
@ -27,7 +27,7 @@ position - 3D position that the accelerometer reports. Format: "(x,y,z)"
calibrate - read: values (x, y, z) that are used as the base for input calibrate - read: values (x, y, z) that are used as the base for input
class device operation. class device operation.
write: forces the base to be recalibrated with the current write: forces the base to be recalibrated with the current
position. position.
rate - reports the sampling rate of the accelerometer device in HZ rate - reports the sampling rate of the accelerometer device in HZ
This driver also provides an absolute input class device, allowing This driver also provides an absolute input class device, allowing
@ -48,7 +48,7 @@ For better compatibility between the various laptops. The values reported by
the accelerometer are converted into a "standard" organisation of the axes the accelerometer are converted into a "standard" organisation of the axes
(aka "can play neverball out of the box"): (aka "can play neverball out of the box"):
* When the laptop is horizontal the position reported is about 0 for X and Y * When the laptop is horizontal the position reported is about 0 for X and Y
and a positive value for Z and a positive value for Z
* If the left side is elevated, X increases (becomes positive) * If the left side is elevated, X increases (becomes positive)
* If the front side (where the touchpad is) is elevated, Y decreases * If the front side (where the touchpad is) is elevated, Y decreases
(becomes negative) (becomes negative)
@ -59,3 +59,13 @@ email to the authors to add it to the database. When reporting a new
laptop, please include the output of "dmidecode" plus the value of laptop, please include the output of "dmidecode" plus the value of
/sys/devices/platform/lis3lv02d/position in these four cases. /sys/devices/platform/lis3lv02d/position in these four cases.
Q&A
---
Q: How do I safely simulate freefall? I have an HP "portable
workstation" which has about 3.5kg and a plastic case, so letting it
fall to the ground is out of question...
A: The sensor is pretty sensitive, so your hands can do it. Lift it
into free space, follow the fall with your hands for like 10
centimeters. That should be enough to trigger the detection.

View File

@ -0,0 +1,50 @@
Kernel driver ltc4215
=====================
Supported chips:
* Linear Technology LTC4215
Prefix: 'ltc4215'
Addresses scanned: 0x44
Datasheet:
http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1003,C1006,C1163,P17572,D12697
Author: Ira W. Snyder <iws@ovro.caltech.edu>
Description
-----------
The LTC4215 controller allows a board to be safely inserted and removed
from a live backplane.
Usage Notes
-----------
This driver does not probe for LTC4215 devices, due to the fact that some
of the possible addresses are unfriendly to probing. You will need to use
the "force" parameter to tell the driver where to find the device.
Example: the following will load the driver for an LTC4215 at address 0x44
on I2C bus #0:
$ modprobe ltc4215 force=0,0x44
Sysfs entries
-------------
The LTC4215 has built-in limits for overvoltage, undervoltage, and
undercurrent warnings. This makes it very likely that the reference
circuit will be used.
in1_input input voltage
in2_input output voltage
in1_min_alarm input undervoltage alarm
in1_max_alarm input overvoltage alarm
curr1_input current
curr1_max_alarm overcurrent alarm
power1_input power usage
power1_alarm power bad alarm

View File

@ -365,6 +365,7 @@ energy[1-*]_input Cumulative energy use
Unit: microJoule Unit: microJoule
RO RO
********** **********
* Alarms * * Alarms *
********** **********
@ -453,6 +454,27 @@ beep_mask Bitmask for beep.
RW RW
***********************
* Intrusion detection *
***********************
intrusion[0-*]_alarm
Chassis intrusion detection
0: OK
1: intrusion detected
RW
Contrary to regular alarm flags which clear themselves
automatically when read, this one sticks until cleared by
the user. This is done by writing 0 to the file. Writing
other values is unsupported.
intrusion[0-*]_beep
Chassis intrusion beep
0: disable
1: enable
RW
sysfs attribute writes interpretation sysfs attribute writes interpretation
------------------------------------- -------------------------------------

View File

@ -2,30 +2,40 @@ Kernel driver w83627ehf
======================= =======================
Supported chips: Supported chips:
* Winbond W83627EHF/EHG/DHG (ISA access ONLY) * Winbond W83627EHF/EHG (ISA access ONLY)
Prefix: 'w83627ehf' Prefix: 'w83627ehf'
Addresses scanned: ISA address retrieved from Super I/O registers Addresses scanned: ISA address retrieved from Super I/O registers
Datasheet: Datasheet:
http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83627EHF_%20W83627EHGb.pdf http://www.nuvoton.com.tw/NR/rdonlyres/A6A258F0-F0C9-4F97-81C0-C4D29E7E943E/0/W83627EHF.pdf
DHG datasheet confidential. * Winbond W83627DHG
Prefix: 'w83627dhg'
Addresses scanned: ISA address retrieved from Super I/O registers
Datasheet:
http://www.nuvoton.com.tw/NR/rdonlyres/7885623D-A487-4CF9-A47F-30C5F73D6FE6/0/W83627DHG.pdf
* Winbond W83667HG
Prefix: 'w83667hg'
Addresses scanned: ISA address retrieved from Super I/O registers
Datasheet: not available
Authors: Authors:
Jean Delvare <khali@linux-fr.org> Jean Delvare <khali@linux-fr.org>
Yuan Mu (Winbond) Yuan Mu (Winbond)
Rudolf Marek <r.marek@assembler.cz> Rudolf Marek <r.marek@assembler.cz>
David Hubbard <david.c.hubbard@gmail.com> David Hubbard <david.c.hubbard@gmail.com>
Gong Jun <JGong@nuvoton.com>
Description Description
----------- -----------
This driver implements support for the Winbond W83627EHF, W83627EHG, and This driver implements support for the Winbond W83627EHF, W83627EHG,
W83627DHG super I/O chips. We will refer to them collectively as Winbond chips. W83627DHG and W83667HG super I/O chips. We will refer to them collectively
as Winbond chips.
The chips implement three temperature sensors, five fan rotation The chips implement three temperature sensors, five fan rotation
speed sensors, ten analog voltage sensors (only nine for the 627DHG), one speed sensors, ten analog voltage sensors (only nine for the 627DHG), one
VID (6 pins for the 627EHF/EHG, 8 pins for the 627DHG), alarms with beep VID (6 pins for the 627EHF/EHG, 8 pins for the 627DHG and 667HG), alarms
warnings (control unimplemented), and some automatic fan regulation with beep warnings (control unimplemented), and some automatic fan
strategies (plus manual fan control mode). regulation strategies (plus manual fan control mode).
Temperatures are measured in degrees Celsius and measurement resolution is 1 Temperatures are measured in degrees Celsius and measurement resolution is 1
degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when
@ -54,7 +64,8 @@ follows:
temp1 -> pwm1 temp1 -> pwm1
temp2 -> pwm2 temp2 -> pwm2
temp3 -> pwm3 temp3 -> pwm3
prog -> pwm4 (the programmable setting is not supported by the driver) prog -> pwm4 (not on 667HG; the programmable setting is not supported by
the driver)
/sys files /sys files
---------- ----------

View File

@ -1695,6 +1695,8 @@ and is between 256 and 4096 characters. It is defined in the file
See also Documentation/blockdev/paride.txt. See also Documentation/blockdev/paride.txt.
pci=option[,option...] [PCI] various PCI subsystem options: pci=option[,option...] [PCI] various PCI subsystem options:
earlydump [X86] dump PCI config space before the kernel
changes anything
off [X86] don't probe for the PCI bus off [X86] don't probe for the PCI bus
bios [X86-32] force use of PCI BIOS, don't access bios [X86-32] force use of PCI BIOS, don't access
the hardware directly. Use this if your machine the hardware directly. Use this if your machine
@ -1794,6 +1796,15 @@ and is between 256 and 4096 characters. It is defined in the file
cbmemsize=nn[KMG] The fixed amount of bus space which is cbmemsize=nn[KMG] The fixed amount of bus space which is
reserved for the CardBus bridge's memory reserved for the CardBus bridge's memory
window. The default value is 64 megabytes. window. The default value is 64 megabytes.
resource_alignment=
Format:
[<order of align>@][<domain>:]<bus>:<slot>.<func>[; ...]
Specifies alignment and device to reassign
aligned memory resources.
If <order of align> is not specified,
PAGE_SIZE is used as alignment.
PCI-PCI bridge can be specified, if resource
windows need to be expanded.
pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power
Management. Management.

View File

@ -1630,6 +1630,13 @@ static bool service_io(struct device *dev)
} }
} }
/* OK, so we noted that it was pretty poor to use an fdatasync as a
* barrier. But Christoph Hellwig points out that we need a sync
* *afterwards* as well: "Barriers specify no reordering to the front
* or the back." And Jens Axboe confirmed it, so here we are: */
if (out->type & VIRTIO_BLK_T_BARRIER)
fdatasync(vblk->fd);
/* We can't trigger an IRQ, because we're not the Launcher. It does /* We can't trigger an IRQ, because we're not the Launcher. It does
* that when we tell it we're done. */ * that when we tell it we're done. */
add_used(dev->vq, head, wlen); add_used(dev->vq, head, wlen);

View File

@ -27,33 +27,37 @@ lock-class.
State State
----- -----
The validator tracks lock-class usage history into 5 separate state bits: The validator tracks lock-class usage history into 4n + 1 separate state bits:
- 'ever held in hardirq context' [ == hardirq-safe ] - 'ever held in STATE context'
- 'ever held in softirq context' [ == softirq-safe ] - 'ever head as readlock in STATE context'
- 'ever held with hardirqs enabled' [ == hardirq-unsafe ] - 'ever head with STATE enabled'
- 'ever held with softirqs and hardirqs enabled' [ == softirq-unsafe ] - 'ever head as readlock with STATE enabled'
Where STATE can be either one of (kernel/lockdep_states.h)
- hardirq
- softirq
- reclaim_fs
- 'ever used' [ == !unused ] - 'ever used' [ == !unused ]
When locking rules are violated, these 4 state bits are presented in the When locking rules are violated, these state bits are presented in the
locking error messages, inside curlies. A contrived example: locking error messages, inside curlies. A contrived example:
modprobe/2287 is trying to acquire lock: modprobe/2287 is trying to acquire lock:
(&sio_locks[i].lock){--..}, at: [<c02867fd>] mutex_lock+0x21/0x24 (&sio_locks[i].lock){-.-...}, at: [<c02867fd>] mutex_lock+0x21/0x24
but task is already holding lock: but task is already holding lock:
(&sio_locks[i].lock){--..}, at: [<c02867fd>] mutex_lock+0x21/0x24 (&sio_locks[i].lock){-.-...}, at: [<c02867fd>] mutex_lock+0x21/0x24
The bit position indicates hardirq, softirq, hardirq-read, The bit position indicates STATE, STATE-read, for each of the states listed
softirq-read respectively, and the character displayed in each above, and the character displayed in each indicates:
indicates:
'.' acquired while irqs disabled '.' acquired while irqs disabled
'+' acquired in irq context '+' acquired in irq context
'-' acquired with irqs enabled '-' acquired with irqs enabled
'?' read acquired in irq context with irqs enabled. '?' acquired in irq context with irqs enabled.
Unused mutexes cannot be part of the cause of an error. Unused mutexes cannot be part of the cause of an error.

View File

@ -0,0 +1,62 @@
Kernel driver isl29003
=====================
Supported chips:
* Intersil ISL29003
Prefix: 'isl29003'
Addresses scanned: none
Datasheet:
http://www.intersil.com/data/fn/fn7464.pdf
Author: Daniel Mack <daniel@caiaq.de>
Description
-----------
The ISL29003 is an integrated light sensor with a 16-bit integrating type
ADC, I2C user programmable lux range select for optimized counts/lux, and
I2C multi-function control and monitoring capabilities. The internal ADC
provides 16-bit resolution while rejecting 50Hz and 60Hz flicker caused by
artificial light sources.
The driver allows to set the lux range, the bit resolution, the operational
mode (see below) and the power state of device and can read the current lux
value, of course.
Detection
---------
The ISL29003 does not have an ID register which could be used to identify
it, so the detection routine will just try to read from the configured I2C
addess and consider the device to be present as soon as it ACKs the
transfer.
Sysfs entries
-------------
range:
0: 0 lux to 1000 lux (default)
1: 0 lux to 4000 lux
2: 0 lux to 16,000 lux
3: 0 lux to 64,000 lux
resolution:
0: 2^16 cycles (default)
1: 2^12 cycles
2: 2^8 cycles
3: 2^4 cycles
mode:
0: diode1's current (unsigned 16bit) (default)
1: diode1's current (unsigned 16bit)
2: difference between diodes (l1 - l2, signed 15bit)
power_state:
0: device is disabled (default)
1: device is enabled
lux (read only):
returns the value from the last sensor reading

View File

@ -0,0 +1,23 @@
MMC/SD/SDIO slot directly connected to a SPI bus
Required properties:
- compatible : should be "mmc-spi-slot".
- reg : should specify SPI address (chip-select number).
- spi-max-frequency : maximum frequency for this device (Hz).
- voltage-ranges : two cells are required, first cell specifies minimum
slot voltage (mV), second cell specifies maximum slot voltage (mV).
Several ranges could be specified.
- gpios : (optional) may specify GPIOs in this order: Card-Detect GPIO,
Write-Protect GPIO.
Example:
mmc-slot@0 {
compatible = "fsl,mpc8323rdb-mmc-slot",
"mmc-spi-slot";
reg = <0>;
gpios = <&qe_pio_d 14 1
&qe_pio_d 15 0>;
voltage-ranges = <3300 3300>;
spi-max-frequency = <50000000>;
};

View File

@ -81,6 +81,8 @@ On all - write a character to /proc/sysrq-trigger. e.g.:
'i' - Send a SIGKILL to all processes, except for init. 'i' - Send a SIGKILL to all processes, except for init.
'j' - Forcibly "Just thaw it" - filesystems frozen by the FIFREEZE ioctl.
'k' - Secure Access Key (SAK) Kills all programs on the current virtual 'k' - Secure Access Key (SAK) Kills all programs on the current virtual
console. NOTE: See important comments below in SAK section. console. NOTE: See important comments below in SAK section.
@ -160,6 +162,9 @@ t'E'rm and k'I'll are useful if you have some sort of runaway process you
are unable to kill any other way, especially if it's spawning other are unable to kill any other way, especially if it's spawning other
processes. processes.
"'J'ust thaw it" is useful if your system becomes unresponsive due to a frozen
(probably root) filesystem via the FIFREEZE ioctl.
* Sometimes SysRq seems to get 'stuck' after using it, what can I do? * Sometimes SysRq seems to get 'stuck' after using it, what can I do?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
That happens to me, also. I've found that tapping shift, alt, and control That happens to me, also. I've found that tapping shift, alt, and control

View File

@ -357,6 +357,7 @@ S: Odd Fixes for 2.4; Maintained for 2.6.
P: Ivan Kokshaysky P: Ivan Kokshaysky
M: ink@jurassic.park.msu.ru M: ink@jurassic.park.msu.ru
S: Maintained for 2.4; PCI support for 2.6. S: Maintained for 2.4; PCI support for 2.6.
L: linux-alpha@vger.kernel.org
AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER
P: Thomas Dahlmann P: Thomas Dahlmann
@ -2201,25 +2202,12 @@ L: linux-ide@vger.kernel.org
T: quilt kernel.org/pub/linux/kernel/people/bart/pata-2.6/ T: quilt kernel.org/pub/linux/kernel/people/bart/pata-2.6/
S: Maintained S: Maintained
IDE/ATAPI CDROM DRIVER IDE/ATAPI DRIVERS
P: Borislav Petkov P: Borislav Petkov
M: petkovbb@gmail.com M: petkovbb@gmail.com
L: linux-ide@vger.kernel.org L: linux-ide@vger.kernel.org
S: Maintained S: Maintained
IDE/ATAPI FLOPPY DRIVERS
P: Paul Bristow
M: Paul Bristow <paul@paulbristow.net>
W: http://paulbristow.net/linux/idefloppy.html
L: linux-kernel@vger.kernel.org
S: Maintained
IDE/ATAPI TAPE DRIVERS
P: Gadi Oxman
M: Gadi Oxman <gadio@netvision.net.il>
L: linux-kernel@vger.kernel.org
S: Maintained
IDLE-I7300 IDLE-I7300
P: Andy Henroid P: Andy Henroid
M: andrew.d.henroid@intel.com M: andrew.d.henroid@intel.com

View File

@ -80,7 +80,7 @@ struct alpha_machine_vector
void (*update_irq_hw)(unsigned long, unsigned long, int); void (*update_irq_hw)(unsigned long, unsigned long, int);
void (*ack_irq)(unsigned long); void (*ack_irq)(unsigned long);
void (*device_interrupt)(unsigned long vector); void (*device_interrupt)(unsigned long vector);
void (*machine_check)(u64 vector, u64 la); void (*machine_check)(unsigned long vector, unsigned long la);
void (*smp_callin)(void); void (*smp_callin)(void);
void (*init_arch)(void); void (*init_arch)(void);

View File

@ -273,4 +273,18 @@ struct pci_dev *alpha_gendev_to_pci(struct device *dev);
extern struct pci_dev *isa_bridge; extern struct pci_dev *isa_bridge;
extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val,
size_t count);
extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val,
size_t count);
extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
struct vm_area_struct *vma,
enum pci_mmap_state mmap_state);
extern void pci_adjust_legacy_attr(struct pci_bus *bus,
enum pci_mmap_state mmap_type);
#define HAVE_PCI_LEGACY 1
extern int pci_create_resource_files(struct pci_dev *dev);
extern void pci_remove_resource_files(struct pci_dev *dev);
#endif /* __ALPHA_PCI_H */ #endif /* __ALPHA_PCI_H */

View File

@ -309,519 +309,72 @@ extern int __min_ipl;
#define tbia() __tbi(-2, /* no second argument */) #define tbia() __tbi(-2, /* no second argument */)
/* /*
* Atomic exchange. * Atomic exchange routines.
* Since it can be used to implement critical sections
* it must clobber "memory" (also for interrupts in UP).
*/ */
static inline unsigned long #define __ASM__MB
__xchg_u8(volatile char *m, unsigned long val) #define ____xchg(type, args...) __xchg ## type ## _local(args)
{ #define ____cmpxchg(type, args...) __cmpxchg ## type ## _local(args)
unsigned long ret, tmp, addr64; #include <asm/xchg.h>
__asm__ __volatile__( #define xchg_local(ptr,x) \
" andnot %4,7,%3\n" ({ \
" insbl %1,%4,%1\n" __typeof__(*(ptr)) _x_ = (x); \
"1: ldq_l %2,0(%3)\n" (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \
" extbl %2,%4,%0\n" sizeof(*(ptr))); \
" mskbl %2,%4,%2\n"
" or %1,%2,%2\n"
" stq_c %2,0(%3)\n"
" beq %2,2f\n"
#ifdef CONFIG_SMP
" mb\n"
#endif
".subsection 2\n"
"2: br 1b\n"
".previous"
: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
: "r" ((long)m), "1" (val) : "memory");
return ret;
}
static inline unsigned long
__xchg_u16(volatile short *m, unsigned long val)
{
unsigned long ret, tmp, addr64;
__asm__ __volatile__(
" andnot %4,7,%3\n"
" inswl %1,%4,%1\n"
"1: ldq_l %2,0(%3)\n"
" extwl %2,%4,%0\n"
" mskwl %2,%4,%2\n"
" or %1,%2,%2\n"
" stq_c %2,0(%3)\n"
" beq %2,2f\n"
#ifdef CONFIG_SMP
" mb\n"
#endif
".subsection 2\n"
"2: br 1b\n"
".previous"
: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
: "r" ((long)m), "1" (val) : "memory");
return ret;
}
static inline unsigned long
__xchg_u32(volatile int *m, unsigned long val)
{
unsigned long dummy;
__asm__ __volatile__(
"1: ldl_l %0,%4\n"
" bis $31,%3,%1\n"
" stl_c %1,%2\n"
" beq %1,2f\n"
#ifdef CONFIG_SMP
" mb\n"
#endif
".subsection 2\n"
"2: br 1b\n"
".previous"
: "=&r" (val), "=&r" (dummy), "=m" (*m)
: "rI" (val), "m" (*m) : "memory");
return val;
}
static inline unsigned long
__xchg_u64(volatile long *m, unsigned long val)
{
unsigned long dummy;
__asm__ __volatile__(
"1: ldq_l %0,%4\n"
" bis $31,%3,%1\n"
" stq_c %1,%2\n"
" beq %1,2f\n"
#ifdef CONFIG_SMP
" mb\n"
#endif
".subsection 2\n"
"2: br 1b\n"
".previous"
: "=&r" (val), "=&r" (dummy), "=m" (*m)
: "rI" (val), "m" (*m) : "memory");
return val;
}
/* This function doesn't exist, so you'll get a linker error
if something tries to do an invalid xchg(). */
extern void __xchg_called_with_bad_pointer(void);
#define __xchg(ptr, x, size) \
({ \
unsigned long __xchg__res; \
volatile void *__xchg__ptr = (ptr); \
switch (size) { \
case 1: __xchg__res = __xchg_u8(__xchg__ptr, x); break; \
case 2: __xchg__res = __xchg_u16(__xchg__ptr, x); break; \
case 4: __xchg__res = __xchg_u32(__xchg__ptr, x); break; \
case 8: __xchg__res = __xchg_u64(__xchg__ptr, x); break; \
default: __xchg_called_with_bad_pointer(); __xchg__res = x; \
} \
__xchg__res; \
})
#define xchg(ptr,x) \
({ \
__typeof__(*(ptr)) _x_ = (x); \
(__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
}) })
static inline unsigned long #define cmpxchg_local(ptr, o, n) \
__xchg_u8_local(volatile char *m, unsigned long val) ({ \
{ __typeof__(*(ptr)) _o_ = (o); \
unsigned long ret, tmp, addr64; __typeof__(*(ptr)) _n_ = (n); \
(__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \
__asm__ __volatile__( (unsigned long)_n_, \
" andnot %4,7,%3\n" sizeof(*(ptr))); \
" insbl %1,%4,%1\n"
"1: ldq_l %2,0(%3)\n"
" extbl %2,%4,%0\n"
" mskbl %2,%4,%2\n"
" or %1,%2,%2\n"
" stq_c %2,0(%3)\n"
" beq %2,2f\n"
".subsection 2\n"
"2: br 1b\n"
".previous"
: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
: "r" ((long)m), "1" (val) : "memory");
return ret;
}
static inline unsigned long
__xchg_u16_local(volatile short *m, unsigned long val)
{
unsigned long ret, tmp, addr64;
__asm__ __volatile__(
" andnot %4,7,%3\n"
" inswl %1,%4,%1\n"
"1: ldq_l %2,0(%3)\n"
" extwl %2,%4,%0\n"
" mskwl %2,%4,%2\n"
" or %1,%2,%2\n"
" stq_c %2,0(%3)\n"
" beq %2,2f\n"
".subsection 2\n"
"2: br 1b\n"
".previous"
: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
: "r" ((long)m), "1" (val) : "memory");
return ret;
}
static inline unsigned long
__xchg_u32_local(volatile int *m, unsigned long val)
{
unsigned long dummy;
__asm__ __volatile__(
"1: ldl_l %0,%4\n"
" bis $31,%3,%1\n"
" stl_c %1,%2\n"
" beq %1,2f\n"
".subsection 2\n"
"2: br 1b\n"
".previous"
: "=&r" (val), "=&r" (dummy), "=m" (*m)
: "rI" (val), "m" (*m) : "memory");
return val;
}
static inline unsigned long
__xchg_u64_local(volatile long *m, unsigned long val)
{
unsigned long dummy;
__asm__ __volatile__(
"1: ldq_l %0,%4\n"
" bis $31,%3,%1\n"
" stq_c %1,%2\n"
" beq %1,2f\n"
".subsection 2\n"
"2: br 1b\n"
".previous"
: "=&r" (val), "=&r" (dummy), "=m" (*m)
: "rI" (val), "m" (*m) : "memory");
return val;
}
#define __xchg_local(ptr, x, size) \
({ \
unsigned long __xchg__res; \
volatile void *__xchg__ptr = (ptr); \
switch (size) { \
case 1: __xchg__res = __xchg_u8_local(__xchg__ptr, x); break; \
case 2: __xchg__res = __xchg_u16_local(__xchg__ptr, x); break; \
case 4: __xchg__res = __xchg_u32_local(__xchg__ptr, x); break; \
case 8: __xchg__res = __xchg_u64_local(__xchg__ptr, x); break; \
default: __xchg_called_with_bad_pointer(); __xchg__res = x; \
} \
__xchg__res; \
})
#define xchg_local(ptr,x) \
({ \
__typeof__(*(ptr)) _x_ = (x); \
(__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \
sizeof(*(ptr))); \
}) })
/* #define cmpxchg64_local(ptr, o, n) \
* Atomic compare and exchange. Compare OLD with MEM, if identical, ({ \
* store NEW in MEM. Return the initial value in MEM. Success is BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
* indicated by comparing RETURN with OLD. cmpxchg_local((ptr), (o), (n)); \
* })
* The memory barrier should be placed in SMP only when we actually
* make the change. If we don't change anything (so if the returned #ifdef CONFIG_SMP
* prev is equal to old) then we aren't acquiring anything new and #undef __ASM__MB
* we don't need any memory barrier as far I can tell. #define __ASM__MB "\tmb\n"
*/ #endif
#undef ____xchg
#undef ____cmpxchg
#define ____xchg(type, args...) __xchg ##type(args)
#define ____cmpxchg(type, args...) __cmpxchg ##type(args)
#include <asm/xchg.h>
#define xchg(ptr,x) \
({ \
__typeof__(*(ptr)) _x_ = (x); \
(__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, \
sizeof(*(ptr))); \
})
#define cmpxchg(ptr, o, n) \
({ \
__typeof__(*(ptr)) _o_ = (o); \
__typeof__(*(ptr)) _n_ = (n); \
(__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
(unsigned long)_n_, sizeof(*(ptr)));\
})
#define cmpxchg64(ptr, o, n) \
({ \
BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
cmpxchg((ptr), (o), (n)); \
})
#undef __ASM__MB
#undef ____cmpxchg
#define __HAVE_ARCH_CMPXCHG 1 #define __HAVE_ARCH_CMPXCHG 1
static inline unsigned long
__cmpxchg_u8(volatile char *m, long old, long new)
{
unsigned long prev, tmp, cmp, addr64;
__asm__ __volatile__(
" andnot %5,7,%4\n"
" insbl %1,%5,%1\n"
"1: ldq_l %2,0(%4)\n"
" extbl %2,%5,%0\n"
" cmpeq %0,%6,%3\n"
" beq %3,2f\n"
" mskbl %2,%5,%2\n"
" or %1,%2,%2\n"
" stq_c %2,0(%4)\n"
" beq %2,3f\n"
#ifdef CONFIG_SMP
" mb\n"
#endif
"2:\n"
".subsection 2\n"
"3: br 1b\n"
".previous"
: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
return prev;
}
static inline unsigned long
__cmpxchg_u16(volatile short *m, long old, long new)
{
unsigned long prev, tmp, cmp, addr64;
__asm__ __volatile__(
" andnot %5,7,%4\n"
" inswl %1,%5,%1\n"
"1: ldq_l %2,0(%4)\n"
" extwl %2,%5,%0\n"
" cmpeq %0,%6,%3\n"
" beq %3,2f\n"
" mskwl %2,%5,%2\n"
" or %1,%2,%2\n"
" stq_c %2,0(%4)\n"
" beq %2,3f\n"
#ifdef CONFIG_SMP
" mb\n"
#endif
"2:\n"
".subsection 2\n"
"3: br 1b\n"
".previous"
: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
return prev;
}
static inline unsigned long
__cmpxchg_u32(volatile int *m, int old, int new)
{
unsigned long prev, cmp;
__asm__ __volatile__(
"1: ldl_l %0,%5\n"
" cmpeq %0,%3,%1\n"
" beq %1,2f\n"
" mov %4,%1\n"
" stl_c %1,%2\n"
" beq %1,3f\n"
#ifdef CONFIG_SMP
" mb\n"
#endif
"2:\n"
".subsection 2\n"
"3: br 1b\n"
".previous"
: "=&r"(prev), "=&r"(cmp), "=m"(*m)
: "r"((long) old), "r"(new), "m"(*m) : "memory");
return prev;
}
static inline unsigned long
__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
{
unsigned long prev, cmp;
__asm__ __volatile__(
"1: ldq_l %0,%5\n"
" cmpeq %0,%3,%1\n"
" beq %1,2f\n"
" mov %4,%1\n"
" stq_c %1,%2\n"
" beq %1,3f\n"
#ifdef CONFIG_SMP
" mb\n"
#endif
"2:\n"
".subsection 2\n"
"3: br 1b\n"
".previous"
: "=&r"(prev), "=&r"(cmp), "=m"(*m)
: "r"((long) old), "r"(new), "m"(*m) : "memory");
return prev;
}
/* This function doesn't exist, so you'll get a linker error
if something tries to do an invalid cmpxchg(). */
extern void __cmpxchg_called_with_bad_pointer(void);
static __always_inline unsigned long
__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
{
switch (size) {
case 1:
return __cmpxchg_u8(ptr, old, new);
case 2:
return __cmpxchg_u16(ptr, old, new);
case 4:
return __cmpxchg_u32(ptr, old, new);
case 8:
return __cmpxchg_u64(ptr, old, new);
}
__cmpxchg_called_with_bad_pointer();
return old;
}
#define cmpxchg(ptr, o, n) \
({ \
__typeof__(*(ptr)) _o_ = (o); \
__typeof__(*(ptr)) _n_ = (n); \
(__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
(unsigned long)_n_, sizeof(*(ptr))); \
})
#define cmpxchg64(ptr, o, n) \
({ \
BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
cmpxchg((ptr), (o), (n)); \
})
static inline unsigned long
__cmpxchg_u8_local(volatile char *m, long old, long new)
{
unsigned long prev, tmp, cmp, addr64;
__asm__ __volatile__(
" andnot %5,7,%4\n"
" insbl %1,%5,%1\n"
"1: ldq_l %2,0(%4)\n"
" extbl %2,%5,%0\n"
" cmpeq %0,%6,%3\n"
" beq %3,2f\n"
" mskbl %2,%5,%2\n"
" or %1,%2,%2\n"
" stq_c %2,0(%4)\n"
" beq %2,3f\n"
"2:\n"
".subsection 2\n"
"3: br 1b\n"
".previous"
: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
return prev;
}
static inline unsigned long
__cmpxchg_u16_local(volatile short *m, long old, long new)
{
unsigned long prev, tmp, cmp, addr64;
__asm__ __volatile__(
" andnot %5,7,%4\n"
" inswl %1,%5,%1\n"
"1: ldq_l %2,0(%4)\n"
" extwl %2,%5,%0\n"
" cmpeq %0,%6,%3\n"
" beq %3,2f\n"
" mskwl %2,%5,%2\n"
" or %1,%2,%2\n"
" stq_c %2,0(%4)\n"
" beq %2,3f\n"
"2:\n"
".subsection 2\n"
"3: br 1b\n"
".previous"
: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
return prev;
}
static inline unsigned long
__cmpxchg_u32_local(volatile int *m, int old, int new)
{
unsigned long prev, cmp;
__asm__ __volatile__(
"1: ldl_l %0,%5\n"
" cmpeq %0,%3,%1\n"
" beq %1,2f\n"
" mov %4,%1\n"
" stl_c %1,%2\n"
" beq %1,3f\n"
"2:\n"
".subsection 2\n"
"3: br 1b\n"
".previous"
: "=&r"(prev), "=&r"(cmp), "=m"(*m)
: "r"((long) old), "r"(new), "m"(*m) : "memory");
return prev;
}
static inline unsigned long
__cmpxchg_u64_local(volatile long *m, unsigned long old, unsigned long new)
{
unsigned long prev, cmp;
__asm__ __volatile__(
"1: ldq_l %0,%5\n"
" cmpeq %0,%3,%1\n"
" beq %1,2f\n"
" mov %4,%1\n"
" stq_c %1,%2\n"
" beq %1,3f\n"
"2:\n"
".subsection 2\n"
"3: br 1b\n"
".previous"
: "=&r"(prev), "=&r"(cmp), "=m"(*m)
: "r"((long) old), "r"(new), "m"(*m) : "memory");
return prev;
}
static __always_inline unsigned long
__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
int size)
{
switch (size) {
case 1:
return __cmpxchg_u8_local(ptr, old, new);
case 2:
return __cmpxchg_u16_local(ptr, old, new);
case 4:
return __cmpxchg_u32_local(ptr, old, new);
case 8:
return __cmpxchg_u64_local(ptr, old, new);
}
__cmpxchg_called_with_bad_pointer();
return old;
}
#define cmpxchg_local(ptr, o, n) \
({ \
__typeof__(*(ptr)) _o_ = (o); \
__typeof__(*(ptr)) _n_ = (n); \
(__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \
(unsigned long)_n_, sizeof(*(ptr))); \
})
#define cmpxchg64_local(ptr, o, n) \
({ \
BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
cmpxchg_local((ptr), (o), (n)); \
})
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#define arch_align_stack(x) (x) #define arch_align_stack(x) (x)

View File

@ -8,7 +8,12 @@
* not a major issue. However, for interoperability, libraries still * not a major issue. However, for interoperability, libraries still
* need to be careful to avoid a name clashes. * need to be careful to avoid a name clashes.
*/ */
#ifdef __KERNEL__
#include <asm-generic/int-ll64.h>
#else
#include <asm-generic/int-l64.h> #include <asm-generic/int-l64.h>
#endif
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__

View File

@ -498,13 +498,13 @@ struct exception_table_entry
}; };
/* Returns the new pc */ /* Returns the new pc */
#define fixup_exception(map_reg, fixup, pc) \ #define fixup_exception(map_reg, _fixup, pc) \
({ \ ({ \
if ((fixup)->fixup.bits.valreg != 31) \ if ((_fixup)->fixup.bits.valreg != 31) \
map_reg((fixup)->fixup.bits.valreg) = 0; \ map_reg((_fixup)->fixup.bits.valreg) = 0; \
if ((fixup)->fixup.bits.errreg != 31) \ if ((_fixup)->fixup.bits.errreg != 31) \
map_reg((fixup)->fixup.bits.errreg) = -EFAULT; \ map_reg((_fixup)->fixup.bits.errreg) = -EFAULT; \
(pc) + (fixup)->fixup.bits.nextinsn; \ (pc) + (_fixup)->fixup.bits.nextinsn; \
}) })

View File

@ -0,0 +1,258 @@
#ifndef __ALPHA_SYSTEM_H
#error Do not include xchg.h directly!
#else
/*
* xchg/xchg_local and cmpxchg/cmpxchg_local share the same code
* except that local version do not have the expensive memory barrier.
* So this file is included twice from asm/system.h.
*/
/*
* Atomic exchange.
* Since it can be used to implement critical sections
* it must clobber "memory" (also for interrupts in UP).
*/
static inline unsigned long
____xchg(_u8, volatile char *m, unsigned long val)
{
unsigned long ret, tmp, addr64;
__asm__ __volatile__(
" andnot %4,7,%3\n"
" insbl %1,%4,%1\n"
"1: ldq_l %2,0(%3)\n"
" extbl %2,%4,%0\n"
" mskbl %2,%4,%2\n"
" or %1,%2,%2\n"
" stq_c %2,0(%3)\n"
" beq %2,2f\n"
__ASM__MB
".subsection 2\n"
"2: br 1b\n"
".previous"
: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
: "r" ((long)m), "1" (val) : "memory");
return ret;
}
static inline unsigned long
____xchg(_u16, volatile short *m, unsigned long val)
{
unsigned long ret, tmp, addr64;
__asm__ __volatile__(
" andnot %4,7,%3\n"
" inswl %1,%4,%1\n"
"1: ldq_l %2,0(%3)\n"
" extwl %2,%4,%0\n"
" mskwl %2,%4,%2\n"
" or %1,%2,%2\n"
" stq_c %2,0(%3)\n"
" beq %2,2f\n"
__ASM__MB
".subsection 2\n"
"2: br 1b\n"
".previous"
: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
: "r" ((long)m), "1" (val) : "memory");
return ret;
}
static inline unsigned long
____xchg(_u32, volatile int *m, unsigned long val)
{
unsigned long dummy;
__asm__ __volatile__(
"1: ldl_l %0,%4\n"
" bis $31,%3,%1\n"
" stl_c %1,%2\n"
" beq %1,2f\n"
__ASM__MB
".subsection 2\n"
"2: br 1b\n"
".previous"
: "=&r" (val), "=&r" (dummy), "=m" (*m)
: "rI" (val), "m" (*m) : "memory");
return val;
}
static inline unsigned long
____xchg(_u64, volatile long *m, unsigned long val)
{
unsigned long dummy;
__asm__ __volatile__(
"1: ldq_l %0,%4\n"
" bis $31,%3,%1\n"
" stq_c %1,%2\n"
" beq %1,2f\n"
__ASM__MB
".subsection 2\n"
"2: br 1b\n"
".previous"
: "=&r" (val), "=&r" (dummy), "=m" (*m)
: "rI" (val), "m" (*m) : "memory");
return val;
}
/* This function doesn't exist, so you'll get a linker error
if something tries to do an invalid xchg(). */
extern void __xchg_called_with_bad_pointer(void);
static __always_inline unsigned long
____xchg(, volatile void *ptr, unsigned long x, int size)
{
switch (size) {
case 1:
return ____xchg(_u8, ptr, x);
case 2:
return ____xchg(_u16, ptr, x);
case 4:
return ____xchg(_u32, ptr, x);
case 8:
return ____xchg(_u64, ptr, x);
}
__xchg_called_with_bad_pointer();
return x;
}
/*
* Atomic compare and exchange. Compare OLD with MEM, if identical,
* store NEW in MEM. Return the initial value in MEM. Success is
* indicated by comparing RETURN with OLD.
*
* The memory barrier should be placed in SMP only when we actually
* make the change. If we don't change anything (so if the returned
* prev is equal to old) then we aren't acquiring anything new and
* we don't need any memory barrier as far I can tell.
*/
static inline unsigned long
____cmpxchg(_u8, volatile char *m, unsigned char old, unsigned char new)
{
unsigned long prev, tmp, cmp, addr64;
__asm__ __volatile__(
" andnot %5,7,%4\n"
" insbl %1,%5,%1\n"
"1: ldq_l %2,0(%4)\n"
" extbl %2,%5,%0\n"
" cmpeq %0,%6,%3\n"
" beq %3,2f\n"
" mskbl %2,%5,%2\n"
" or %1,%2,%2\n"
" stq_c %2,0(%4)\n"
" beq %2,3f\n"
__ASM__MB
"2:\n"
".subsection 2\n"
"3: br 1b\n"
".previous"
: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
return prev;
}
static inline unsigned long
____cmpxchg(_u16, volatile short *m, unsigned short old, unsigned short new)
{
unsigned long prev, tmp, cmp, addr64;
__asm__ __volatile__(
" andnot %5,7,%4\n"
" inswl %1,%5,%1\n"
"1: ldq_l %2,0(%4)\n"
" extwl %2,%5,%0\n"
" cmpeq %0,%6,%3\n"
" beq %3,2f\n"
" mskwl %2,%5,%2\n"
" or %1,%2,%2\n"
" stq_c %2,0(%4)\n"
" beq %2,3f\n"
__ASM__MB
"2:\n"
".subsection 2\n"
"3: br 1b\n"
".previous"
: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
return prev;
}
static inline unsigned long
____cmpxchg(_u32, volatile int *m, int old, int new)
{
unsigned long prev, cmp;
__asm__ __volatile__(
"1: ldl_l %0,%5\n"
" cmpeq %0,%3,%1\n"
" beq %1,2f\n"
" mov %4,%1\n"
" stl_c %1,%2\n"
" beq %1,3f\n"
__ASM__MB
"2:\n"
".subsection 2\n"
"3: br 1b\n"
".previous"
: "=&r"(prev), "=&r"(cmp), "=m"(*m)
: "r"((long) old), "r"(new), "m"(*m) : "memory");
return prev;
}
static inline unsigned long
____cmpxchg(_u64, volatile long *m, unsigned long old, unsigned long new)
{
unsigned long prev, cmp;
__asm__ __volatile__(
"1: ldq_l %0,%5\n"
" cmpeq %0,%3,%1\n"
" beq %1,2f\n"
" mov %4,%1\n"
" stq_c %1,%2\n"
" beq %1,3f\n"
__ASM__MB
"2:\n"
".subsection 2\n"
"3: br 1b\n"
".previous"
: "=&r"(prev), "=&r"(cmp), "=m"(*m)
: "r"((long) old), "r"(new), "m"(*m) : "memory");
return prev;
}
/* This function doesn't exist, so you'll get a linker error
if something tries to do an invalid cmpxchg(). */
extern void __cmpxchg_called_with_bad_pointer(void);
static __always_inline unsigned long
____cmpxchg(, volatile void *ptr, unsigned long old, unsigned long new,
int size)
{
switch (size) {
case 1:
return ____cmpxchg(_u8, ptr, old, new);
case 2:
return ____cmpxchg(_u16, ptr, old, new);
case 4:
return ____cmpxchg(_u32, ptr, old, new);
case 8:
return ____cmpxchg(_u64, ptr, old, new);
}
__cmpxchg_called_with_bad_pointer();
return old;
}
#endif

View File

@ -12,7 +12,7 @@ obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o \
obj-$(CONFIG_VGA_HOSE) += console.o obj-$(CONFIG_VGA_HOSE) += console.o
obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_PCI) += pci.o pci_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o pci-sysfs.o
obj-$(CONFIG_SRM_ENV) += srm_env.o obj-$(CONFIG_SRM_ENV) += srm_env.o
obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_MODULES) += module.o

View File

@ -157,8 +157,8 @@ ev6_parse_cbox(u64 c_addr, u64 c1_syn, u64 c2_syn,
err_print_prefix, err_print_prefix,
streamname[stream], bitsname[bits], sourcename[source]); streamname[stream], bitsname[bits], sourcename[source]);
printk("%s Address: 0x%016lx\n" printk("%s Address: 0x%016llx\n"
" Syndrome[upper.lower]: %02lx.%02lx\n", " Syndrome[upper.lower]: %02llx.%02llx\n",
err_print_prefix, err_print_prefix,
c_addr, c_addr,
c2_syn, c1_syn); c2_syn, c1_syn);

View File

@ -246,13 +246,13 @@ ev7_process_pal_subpacket(struct el_subpacket *header)
switch(header->type) { switch(header->type) {
case EL_TYPE__PAL__LOGOUT_FRAME: case EL_TYPE__PAL__LOGOUT_FRAME:
printk("%s*** MCHK occurred on LPID %ld (RBOX %lx)\n", printk("%s*** MCHK occurred on LPID %ld (RBOX %llx)\n",
err_print_prefix, err_print_prefix,
packet->by_type.logout.whami, packet->by_type.logout.whami,
packet->by_type.logout.rbox_whami); packet->by_type.logout.rbox_whami);
el_print_timestamp(&packet->by_type.logout.timestamp); el_print_timestamp(&packet->by_type.logout.timestamp);
printk("%s EXC_ADDR: %016lx\n" printk("%s EXC_ADDR: %016llx\n"
" HALT_CODE: %lx\n", " HALT_CODE: %llx\n",
err_print_prefix, err_print_prefix,
packet->by_type.logout.exc_addr, packet->by_type.logout.exc_addr,
packet->by_type.logout.halt_code); packet->by_type.logout.halt_code);

View File

@ -129,7 +129,7 @@ marvel_print_po7_crrct_sym(u64 crrct_sym)
printk("%s Correctable Error Symptoms:\n" printk("%s Correctable Error Symptoms:\n"
"%s Syndrome: 0x%lx\n", "%s Syndrome: 0x%llx\n",
err_print_prefix, err_print_prefix,
err_print_prefix, EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__SYN)); err_print_prefix, EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__SYN));
marvel_print_err_cyc(EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__ERR_CYC)); marvel_print_err_cyc(EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__ERR_CYC));
@ -186,7 +186,7 @@ marvel_print_po7_uncrr_sym(u64 uncrr_sym, u64 valid_mask)
uncrr_sym &= valid_mask; uncrr_sym &= valid_mask;
if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__SYN)) if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__SYN))
printk("%s Syndrome: 0x%lx\n", printk("%s Syndrome: 0x%llx\n",
err_print_prefix, err_print_prefix,
EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__SYN)); EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__SYN));
@ -307,7 +307,7 @@ marvel_print_po7_ugbge_sym(u64 ugbge_sym)
sprintf(opcode_str, "BlkIO"); sprintf(opcode_str, "BlkIO");
break; break;
default: default:
sprintf(opcode_str, "0x%lx\n", sprintf(opcode_str, "0x%llx\n",
EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE)); EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE));
break; break;
} }
@ -321,7 +321,7 @@ marvel_print_po7_ugbge_sym(u64 ugbge_sym)
opcode_str); opcode_str);
if (0xC5 != EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE)) if (0xC5 != EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE))
printk("%s Packet Offset 0x%08lx\n", printk("%s Packet Offset 0x%08llx\n",
err_print_prefix, err_print_prefix,
EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_PKT_OFF)); EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_PKT_OFF));
} }
@ -480,8 +480,8 @@ marvel_print_po7_err_sum(struct ev7_pal_io_subpacket *io)
printk("%s Lost Error\n", err_print_prefix); printk("%s Lost Error\n", err_print_prefix);
printk("%s Failing Packet:\n" printk("%s Failing Packet:\n"
"%s Cycle 1: %016lx\n" "%s Cycle 1: %016llx\n"
"%s Cycle 2: %016lx\n", "%s Cycle 2: %016llx\n",
err_print_prefix, err_print_prefix,
err_print_prefix, io->po7_err_pkt0, err_print_prefix, io->po7_err_pkt0,
err_print_prefix, io->po7_err_pkt1); err_print_prefix, io->po7_err_pkt1);
@ -515,9 +515,9 @@ marvel_print_pox_tlb_err(u64 tlb_err)
if (!(tlb_err & IO7__POX_TLBERR__ERR_VALID)) if (!(tlb_err & IO7__POX_TLBERR__ERR_VALID))
return; return;
printk("%s TLB Error on index 0x%lx:\n" printk("%s TLB Error on index 0x%llx:\n"
"%s - %s\n" "%s - %s\n"
"%s - Addr: 0x%016lx\n", "%s - Addr: 0x%016llx\n",
err_print_prefix, err_print_prefix,
EXTRACT(tlb_err, IO7__POX_TLBERR__ERR_TLB_PTR), EXTRACT(tlb_err, IO7__POX_TLBERR__ERR_TLB_PTR),
err_print_prefix, err_print_prefix,
@ -579,7 +579,7 @@ marvel_print_pox_spl_cmplt(u64 spl_cmplt)
sprintf(message, "Uncorrectable Split Write Data Error"); sprintf(message, "Uncorrectable Split Write Data Error");
break; break;
default: default:
sprintf(message, "%08lx\n", sprintf(message, "%08llx\n",
EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__MESSAGE)); EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__MESSAGE));
break; break;
} }
@ -620,9 +620,9 @@ marvel_print_pox_trans_sum(u64 trans_sum)
return; return;
printk("%s Transaction Summary:\n" printk("%s Transaction Summary:\n"
"%s Command: 0x%lx - %s\n" "%s Command: 0x%llx - %s\n"
"%s Address: 0x%016lx%s\n" "%s Address: 0x%016llx%s\n"
"%s PCI-X Master Slot: 0x%lx\n", "%s PCI-X Master Slot: 0x%llx\n",
err_print_prefix, err_print_prefix,
err_print_prefix, err_print_prefix,
EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD), EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD),
@ -964,12 +964,12 @@ marvel_process_io_error(struct ev7_lf_subpackets *lf_subpackets, int print)
#if 0 #if 0
printk("%s PORT 7 ERROR:\n" printk("%s PORT 7 ERROR:\n"
"%s PO7_ERROR_SUM: %016lx\n" "%s PO7_ERROR_SUM: %016llx\n"
"%s PO7_UNCRR_SYM: %016lx\n" "%s PO7_UNCRR_SYM: %016llx\n"
"%s PO7_CRRCT_SYM: %016lx\n" "%s PO7_CRRCT_SYM: %016llx\n"
"%s PO7_UGBGE_SYM: %016lx\n" "%s PO7_UGBGE_SYM: %016llx\n"
"%s PO7_ERR_PKT0: %016lx\n" "%s PO7_ERR_PKT0: %016llx\n"
"%s PO7_ERR_PKT1: %016lx\n", "%s PO7_ERR_PKT1: %016llx\n",
err_print_prefix, err_print_prefix,
err_print_prefix, io->po7_error_sum, err_print_prefix, io->po7_error_sum,
err_print_prefix, io->po7_uncrr_sym, err_print_prefix, io->po7_uncrr_sym,
@ -987,12 +987,12 @@ marvel_process_io_error(struct ev7_lf_subpackets *lf_subpackets, int print)
if (!MARVEL_IO_ERR_VALID(io->ports[i].pox_err_sum)) if (!MARVEL_IO_ERR_VALID(io->ports[i].pox_err_sum))
continue; continue;
printk("%s PID %u PORT %d POx_ERR_SUM: %016lx\n", printk("%s PID %u PORT %d POx_ERR_SUM: %016llx\n",
err_print_prefix, err_print_prefix,
lf_subpackets->io_pid, i, io->ports[i].pox_err_sum); lf_subpackets->io_pid, i, io->ports[i].pox_err_sum);
marvel_print_pox_err(io->ports[i].pox_err_sum, &io->ports[i]); marvel_print_pox_err(io->ports[i].pox_err_sum, &io->ports[i]);
printk("%s [ POx_FIRST_ERR: %016lx ]\n", printk("%s [ POx_FIRST_ERR: %016llx ]\n",
err_print_prefix, io->ports[i].pox_first_err); err_print_prefix, io->ports[i].pox_first_err);
marvel_print_pox_err(io->ports[i].pox_first_err, marvel_print_pox_err(io->ports[i].pox_first_err,
&io->ports[i]); &io->ports[i]);

View File

@ -107,12 +107,12 @@ titan_parse_p_serror(int which, u64 serror, int print)
if (!print) if (!print)
return status; return status;
printk("%s PChip %d SERROR: %016lx\n", printk("%s PChip %d SERROR: %016llx\n",
err_print_prefix, which, serror); err_print_prefix, which, serror);
if (serror & TITAN__PCHIP_SERROR__ECCMASK) { if (serror & TITAN__PCHIP_SERROR__ECCMASK) {
printk("%s %sorrectable ECC Error:\n" printk("%s %sorrectable ECC Error:\n"
" Source: %-6s Command: %-8s Syndrome: 0x%08x\n" " Source: %-6s Command: %-8s Syndrome: 0x%08x\n"
" Address: 0x%lx\n", " Address: 0x%llx\n",
err_print_prefix, err_print_prefix,
(serror & TITAN__PCHIP_SERROR__UECC) ? "Unc" : "C", (serror & TITAN__PCHIP_SERROR__UECC) ? "Unc" : "C",
serror_src[EXTRACT(serror, TITAN__PCHIP_SERROR__SRC)], serror_src[EXTRACT(serror, TITAN__PCHIP_SERROR__SRC)],
@ -223,7 +223,7 @@ titan_parse_p_perror(int which, int port, u64 perror, int print)
if (!print) if (!print)
return status; return status;
printk("%s PChip %d %cPERROR: %016lx\n", printk("%s PChip %d %cPERROR: %016llx\n",
err_print_prefix, which, err_print_prefix, which,
port ? 'A' : 'G', perror); port ? 'A' : 'G', perror);
if (perror & TITAN__PCHIP_PERROR__IPTPW) if (perror & TITAN__PCHIP_PERROR__IPTPW)
@ -316,7 +316,7 @@ titan_parse_p_agperror(int which, u64 agperror, int print)
addr = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__ADDR) << 3; addr = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__ADDR) << 3;
len = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__LEN); len = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__LEN);
printk("%s PChip %d AGPERROR: %016lx\n", err_print_prefix, printk("%s PChip %d AGPERROR: %016llx\n", err_print_prefix,
which, agperror); which, agperror);
if (agperror & TITAN__PCHIP_AGPERROR__NOWINDOW) if (agperror & TITAN__PCHIP_AGPERROR__NOWINDOW)
printk("%s No Window\n", err_print_prefix); printk("%s No Window\n", err_print_prefix);
@ -597,16 +597,16 @@ privateer_process_680_frame(struct el_common *mchk_header, int print)
return status; return status;
/* TODO - decode instead of just dumping... */ /* TODO - decode instead of just dumping... */
printk("%s Summary Flags: %016lx\n" printk("%s Summary Flags: %016llx\n"
" CChip DIRx: %016lx\n" " CChip DIRx: %016llx\n"
" System Management IR: %016lx\n" " System Management IR: %016llx\n"
" CPU IR: %016lx\n" " CPU IR: %016llx\n"
" Power Supply IR: %016lx\n" " Power Supply IR: %016llx\n"
" LM78 Fault Status: %016lx\n" " LM78 Fault Status: %016llx\n"
" System Doors: %016lx\n" " System Doors: %016llx\n"
" Temperature Warning: %016lx\n" " Temperature Warning: %016llx\n"
" Fan Control: %016lx\n" " Fan Control: %016llx\n"
" Fatal Power Down Code: %016lx\n", " Fatal Power Down Code: %016llx\n",
err_print_prefix, err_print_prefix,
emchk->summary, emchk->summary,
emchk->c_dirx, emchk->c_dirx,

View File

@ -0,0 +1,366 @@
/*
* arch/alpha/kernel/pci-sysfs.c
*
* Copyright (C) 2009 Ivan Kokshaysky
*
* Alpha PCI resource files.
*
* Loosely based on generic HAVE_PCI_MMAP implementation in
* drivers/pci/pci-sysfs.c
*/
#include <linux/sched.h>
#include <linux/pci.h>
static int hose_mmap_page_range(struct pci_controller *hose,
struct vm_area_struct *vma,
enum pci_mmap_state mmap_type, int sparse)
{
unsigned long base;
if (mmap_type == pci_mmap_mem)
base = sparse ? hose->sparse_mem_base : hose->dense_mem_base;
else
base = sparse ? hose->sparse_io_base : hose->dense_io_base;
vma->vm_pgoff += base >> PAGE_SHIFT;
vma->vm_flags |= (VM_IO | VM_RESERVED);
return io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
vma->vm_end - vma->vm_start,
vma->vm_page_prot);
}
static int __pci_mmap_fits(struct pci_dev *pdev, int num,
struct vm_area_struct *vma, int sparse)
{
unsigned long nr, start, size;
int shift = sparse ? 5 : 0;
nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
start = vma->vm_pgoff;
size = ((pci_resource_len(pdev, num) - 1) >> (PAGE_SHIFT - shift)) + 1;
if (start < size && size - start >= nr)
return 1;
WARN(1, "process \"%s\" tried to map%s 0x%08lx-0x%08lx on %s BAR %d "
"(size 0x%08lx)\n",
current->comm, sparse ? " sparse" : "", start, start + nr,
pci_name(pdev), num, size);
return 0;
}
/**
* pci_mmap_resource - map a PCI resource into user memory space
* @kobj: kobject for mapping
* @attr: struct bin_attribute for the file being mapped
* @vma: struct vm_area_struct passed into the mmap
* @sparse: address space type
*
* Use the bus mapping routines to map a PCI resource into userspace.
*/
static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
struct vm_area_struct *vma, int sparse)
{
struct pci_dev *pdev = to_pci_dev(container_of(kobj,
struct device, kobj));
struct resource *res = (struct resource *)attr->private;
enum pci_mmap_state mmap_type;
struct pci_bus_region bar;
int i;
for (i = 0; i < PCI_ROM_RESOURCE; i++)
if (res == &pdev->resource[i])
break;
if (i >= PCI_ROM_RESOURCE)
return -ENODEV;
if (!__pci_mmap_fits(pdev, i, vma, sparse))
return -EINVAL;
if (iomem_is_exclusive(res->start))
return -EINVAL;
pcibios_resource_to_bus(pdev, &bar, res);
vma->vm_pgoff += bar.start >> (PAGE_SHIFT - (sparse ? 5 : 0));
mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
return hose_mmap_page_range(pdev->sysdata, vma, mmap_type, sparse);
}
static int pci_mmap_resource_sparse(struct kobject *kobj,
struct bin_attribute *attr,
struct vm_area_struct *vma)
{
return pci_mmap_resource(kobj, attr, vma, 1);
}
static int pci_mmap_resource_dense(struct kobject *kobj,
struct bin_attribute *attr,
struct vm_area_struct *vma)
{
return pci_mmap_resource(kobj, attr, vma, 0);
}
/**
* pci_remove_resource_files - cleanup resource files
* @dev: dev to cleanup
*
* If we created resource files for @dev, remove them from sysfs and
* free their resources.
*/
void pci_remove_resource_files(struct pci_dev *pdev)
{
int i;
for (i = 0; i < PCI_ROM_RESOURCE; i++) {
struct bin_attribute *res_attr;
res_attr = pdev->res_attr[i];
if (res_attr) {
sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
kfree(res_attr);
}
res_attr = pdev->res_attr_wc[i];
if (res_attr) {
sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
kfree(res_attr);
}
}
}
static int sparse_mem_mmap_fits(struct pci_dev *pdev, int num)
{
struct pci_bus_region bar;
struct pci_controller *hose = pdev->sysdata;
long dense_offset;
unsigned long sparse_size;
pcibios_resource_to_bus(pdev, &bar, &pdev->resource[num]);
/* All core logic chips have 4G sparse address space, except
CIA which has 16G (see xxx_SPARSE_MEM and xxx_DENSE_MEM
definitions in asm/core_xxx.h files). This corresponds
to 128M or 512M of the bus space. */
dense_offset = (long)(hose->dense_mem_base - hose->sparse_mem_base);
sparse_size = dense_offset >= 0x400000000UL ? 0x20000000 : 0x8000000;
return bar.end < sparse_size;
}
static int pci_create_one_attr(struct pci_dev *pdev, int num, char *name,
char *suffix, struct bin_attribute *res_attr,
unsigned long sparse)
{
size_t size = pci_resource_len(pdev, num);
sprintf(name, "resource%d%s", num, suffix);
res_attr->mmap = sparse ? pci_mmap_resource_sparse :
pci_mmap_resource_dense;
res_attr->attr.name = name;
res_attr->attr.mode = S_IRUSR | S_IWUSR;
res_attr->size = sparse ? size << 5 : size;
res_attr->private = &pdev->resource[num];
return sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
}
static int pci_create_attr(struct pci_dev *pdev, int num)
{
/* allocate attribute structure, piggyback attribute name */
int retval, nlen1, nlen2 = 0, res_count = 1;
unsigned long sparse_base, dense_base;
struct bin_attribute *attr;
struct pci_controller *hose = pdev->sysdata;
char *suffix, *attr_name;
suffix = ""; /* Assume bwx machine, normal resourceN files. */
nlen1 = 10;
if (pdev->resource[num].flags & IORESOURCE_MEM) {
sparse_base = hose->sparse_mem_base;
dense_base = hose->dense_mem_base;
if (sparse_base && !sparse_mem_mmap_fits(pdev, num)) {
sparse_base = 0;
suffix = "_dense";
nlen1 = 16; /* resourceN_dense */
}
} else {
sparse_base = hose->sparse_io_base;
dense_base = hose->dense_io_base;
}
if (sparse_base) {
suffix = "_sparse";
nlen1 = 17;
if (dense_base) {
nlen2 = 16; /* resourceN_dense */
res_count = 2;
}
}
attr = kzalloc(sizeof(*attr) * res_count + nlen1 + nlen2, GFP_ATOMIC);
if (!attr)
return -ENOMEM;
/* Create bwx, sparse or single dense file */
attr_name = (char *)(attr + res_count);
pdev->res_attr[num] = attr;
retval = pci_create_one_attr(pdev, num, attr_name, suffix, attr,
sparse_base);
if (retval || res_count == 1)
return retval;
/* Create dense file */
attr_name += nlen1;
attr++;
pdev->res_attr_wc[num] = attr;
return pci_create_one_attr(pdev, num, attr_name, "_dense", attr, 0);
}
/**
* pci_create_resource_files - create resource files in sysfs for @dev
* @dev: dev in question
*
* Walk the resources in @dev creating files for each resource available.
*/
int pci_create_resource_files(struct pci_dev *pdev)
{
int i;
int retval;
/* Expose the PCI resources from this device as files */
for (i = 0; i < PCI_ROM_RESOURCE; i++) {
/* skip empty resources */
if (!pci_resource_len(pdev, i))
continue;
retval = pci_create_attr(pdev, i);
if (retval) {
pci_remove_resource_files(pdev);
return retval;
}
}
return 0;
}
/* Legacy I/O bus mapping stuff. */
static int __legacy_mmap_fits(struct pci_controller *hose,
struct vm_area_struct *vma,
unsigned long res_size, int sparse)
{
unsigned long nr, start, size;
nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
start = vma->vm_pgoff;
size = ((res_size - 1) >> PAGE_SHIFT) + 1;
if (start < size && size - start >= nr)
return 1;
WARN(1, "process \"%s\" tried to map%s 0x%08lx-0x%08lx on hose %d "
"(size 0x%08lx)\n",
current->comm, sparse ? " sparse" : "", start, start + nr,
hose->index, size);
return 0;
}
static inline int has_sparse(struct pci_controller *hose,
enum pci_mmap_state mmap_type)
{
unsigned long base;
base = (mmap_type == pci_mmap_mem) ? hose->sparse_mem_base :
hose->sparse_io_base;
return base != 0;
}
int pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma,
enum pci_mmap_state mmap_type)
{
struct pci_controller *hose = bus->sysdata;
int sparse = has_sparse(hose, mmap_type);
unsigned long res_size;
res_size = (mmap_type == pci_mmap_mem) ? bus->legacy_mem->size :
bus->legacy_io->size;
if (!__legacy_mmap_fits(hose, vma, res_size, sparse))
return -EINVAL;
return hose_mmap_page_range(hose, vma, mmap_type, sparse);
}
/**
* pci_adjust_legacy_attr - adjustment of legacy file attributes
* @b: bus to create files under
* @mmap_type: I/O port or memory
*
* Adjust file name and size for sparse mappings.
*/
void pci_adjust_legacy_attr(struct pci_bus *bus, enum pci_mmap_state mmap_type)
{
struct pci_controller *hose = bus->sysdata;
if (!has_sparse(hose, mmap_type))
return;
if (mmap_type == pci_mmap_mem) {
bus->legacy_mem->attr.name = "legacy_mem_sparse";
bus->legacy_mem->size <<= 5;
} else {
bus->legacy_io->attr.name = "legacy_io_sparse";
bus->legacy_io->size <<= 5;
}
return;
}
/* Legacy I/O bus read/write functions */
int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, size_t size)
{
struct pci_controller *hose = bus->sysdata;
port += hose->io_space->start;
switch(size) {
case 1:
*((u8 *)val) = inb(port);
return 1;
case 2:
if (port & 1)
return -EINVAL;
*((u16 *)val) = inw(port);
return 2;
case 4:
if (port & 3)
return -EINVAL;
*((u32 *)val) = inl(port);
return 4;
}
return -EINVAL;
}
int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, size_t size)
{
struct pci_controller *hose = bus->sysdata;
port += hose->io_space->start;
switch(size) {
case 1:
outb(port, val);
return 1;
case 2:
if (port & 1)
return -EINVAL;
outw(port, val);
return 2;
case 4:
if (port & 3)
return -EINVAL;
outl(port, val);
return 4;
}
return -EINVAL;
}

View File

@ -168,7 +168,7 @@ pcibios_align_resource(void *data, struct resource *res,
*/ */
/* Align to multiple of size of minimum base. */ /* Align to multiple of size of minimum base. */
alignto = max(0x1000UL, align); alignto = max_t(resource_size_t, 0x1000, align);
start = ALIGN(start, alignto); start = ALIGN(start, alignto);
if (hose->sparse_mem_base && size <= 7 * 16*MB) { if (hose->sparse_mem_base && size <= 7 * 16*MB) {
if (((start / (16*MB)) & 0x7) == 0) { if (((start / (16*MB)) & 0x7) == 0) {

View File

@ -247,7 +247,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
&& paddr + size <= __direct_map_size) { && paddr + size <= __direct_map_size) {
ret = paddr + __direct_map_base; ret = paddr + __direct_map_base;
DBGA2("pci_map_single: [%p,%lx] -> direct %lx from %p\n", DBGA2("pci_map_single: [%p,%zx] -> direct %llx from %p\n",
cpu_addr, size, ret, __builtin_return_address(0)); cpu_addr, size, ret, __builtin_return_address(0));
return ret; return ret;
@ -258,7 +258,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
if (dac_allowed) { if (dac_allowed) {
ret = paddr + alpha_mv.pci_dac_offset; ret = paddr + alpha_mv.pci_dac_offset;
DBGA2("pci_map_single: [%p,%lx] -> DAC %lx from %p\n", DBGA2("pci_map_single: [%p,%zx] -> DAC %llx from %p\n",
cpu_addr, size, ret, __builtin_return_address(0)); cpu_addr, size, ret, __builtin_return_address(0));
return ret; return ret;
@ -299,7 +299,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
ret = arena->dma_base + dma_ofs * PAGE_SIZE; ret = arena->dma_base + dma_ofs * PAGE_SIZE;
ret += (unsigned long)cpu_addr & ~PAGE_MASK; ret += (unsigned long)cpu_addr & ~PAGE_MASK;
DBGA2("pci_map_single: [%p,%lx] np %ld -> sg %lx from %p\n", DBGA2("pci_map_single: [%p,%zx] np %ld -> sg %llx from %p\n",
cpu_addr, size, npages, ret, __builtin_return_address(0)); cpu_addr, size, npages, ret, __builtin_return_address(0));
return ret; return ret;
@ -355,14 +355,14 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
&& dma_addr < __direct_map_base + __direct_map_size) { && dma_addr < __direct_map_base + __direct_map_size) {
/* Nothing to do. */ /* Nothing to do. */
DBGA2("pci_unmap_single: direct [%lx,%lx] from %p\n", DBGA2("pci_unmap_single: direct [%llx,%zx] from %p\n",
dma_addr, size, __builtin_return_address(0)); dma_addr, size, __builtin_return_address(0));
return; return;
} }
if (dma_addr > 0xffffffff) { if (dma_addr > 0xffffffff) {
DBGA2("pci64_unmap_single: DAC [%lx,%lx] from %p\n", DBGA2("pci64_unmap_single: DAC [%llx,%zx] from %p\n",
dma_addr, size, __builtin_return_address(0)); dma_addr, size, __builtin_return_address(0));
return; return;
} }
@ -373,9 +373,9 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
dma_ofs = (dma_addr - arena->dma_base) >> PAGE_SHIFT; dma_ofs = (dma_addr - arena->dma_base) >> PAGE_SHIFT;
if (dma_ofs * PAGE_SIZE >= arena->size) { if (dma_ofs * PAGE_SIZE >= arena->size) {
printk(KERN_ERR "Bogus pci_unmap_single: dma_addr %lx " printk(KERN_ERR "Bogus pci_unmap_single: dma_addr %llx "
" base %lx size %x\n", dma_addr, arena->dma_base, " base %llx size %x\n",
arena->size); dma_addr, arena->dma_base, arena->size);
return; return;
BUG(); BUG();
} }
@ -394,7 +394,7 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
spin_unlock_irqrestore(&arena->lock, flags); spin_unlock_irqrestore(&arena->lock, flags);
DBGA2("pci_unmap_single: sg [%lx,%lx] np %ld from %p\n", DBGA2("pci_unmap_single: sg [%llx,%zx] np %ld from %p\n",
dma_addr, size, npages, __builtin_return_address(0)); dma_addr, size, npages, __builtin_return_address(0));
} }
EXPORT_SYMBOL(pci_unmap_single); EXPORT_SYMBOL(pci_unmap_single);
@ -444,7 +444,7 @@ __pci_alloc_consistent(struct pci_dev *pdev, size_t size,
goto try_again; goto try_again;
} }
DBGA2("pci_alloc_consistent: %lx -> [%p,%x] from %p\n", DBGA2("pci_alloc_consistent: %zx -> [%p,%llx] from %p\n",
size, cpu_addr, *dma_addrp, __builtin_return_address(0)); size, cpu_addr, *dma_addrp, __builtin_return_address(0));
return cpu_addr; return cpu_addr;
@ -464,7 +464,7 @@ pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu_addr,
pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL); pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL);
free_pages((unsigned long)cpu_addr, get_order(size)); free_pages((unsigned long)cpu_addr, get_order(size));
DBGA2("pci_free_consistent: [%x,%lx] from %p\n", DBGA2("pci_free_consistent: [%llx,%zx] from %p\n",
dma_addr, size, __builtin_return_address(0)); dma_addr, size, __builtin_return_address(0));
} }
EXPORT_SYMBOL(pci_free_consistent); EXPORT_SYMBOL(pci_free_consistent);
@ -551,7 +551,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
out->dma_address = paddr + __direct_map_base; out->dma_address = paddr + __direct_map_base;
out->dma_length = size; out->dma_length = size;
DBGA(" sg_fill: [%p,%lx] -> direct %lx\n", DBGA(" sg_fill: [%p,%lx] -> direct %llx\n",
__va(paddr), size, out->dma_address); __va(paddr), size, out->dma_address);
return 0; return 0;
@ -563,7 +563,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
out->dma_address = paddr + alpha_mv.pci_dac_offset; out->dma_address = paddr + alpha_mv.pci_dac_offset;
out->dma_length = size; out->dma_length = size;
DBGA(" sg_fill: [%p,%lx] -> DAC %lx\n", DBGA(" sg_fill: [%p,%lx] -> DAC %llx\n",
__va(paddr), size, out->dma_address); __va(paddr), size, out->dma_address);
return 0; return 0;
@ -589,7 +589,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
out->dma_address = arena->dma_base + dma_ofs*PAGE_SIZE + paddr; out->dma_address = arena->dma_base + dma_ofs*PAGE_SIZE + paddr;
out->dma_length = size; out->dma_length = size;
DBGA(" sg_fill: [%p,%lx] -> sg %lx np %ld\n", DBGA(" sg_fill: [%p,%lx] -> sg %llx np %ld\n",
__va(paddr), size, out->dma_address, npages); __va(paddr), size, out->dma_address, npages);
/* All virtually contiguous. We need to find the length of each /* All virtually contiguous. We need to find the length of each
@ -752,7 +752,7 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
if (addr > 0xffffffff) { if (addr > 0xffffffff) {
/* It's a DAC address -- nothing to do. */ /* It's a DAC address -- nothing to do. */
DBGA(" (%ld) DAC [%lx,%lx]\n", DBGA(" (%ld) DAC [%llx,%zx]\n",
sg - end + nents, addr, size); sg - end + nents, addr, size);
continue; continue;
} }
@ -760,12 +760,12 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
if (addr >= __direct_map_base if (addr >= __direct_map_base
&& addr < __direct_map_base + __direct_map_size) { && addr < __direct_map_base + __direct_map_size) {
/* Nothing to do. */ /* Nothing to do. */
DBGA(" (%ld) direct [%lx,%lx]\n", DBGA(" (%ld) direct [%llx,%zx]\n",
sg - end + nents, addr, size); sg - end + nents, addr, size);
continue; continue;
} }
DBGA(" (%ld) sg [%lx,%lx]\n", DBGA(" (%ld) sg [%llx,%zx]\n",
sg - end + nents, addr, size); sg - end + nents, addr, size);
npages = iommu_num_pages(addr, size, PAGE_SIZE); npages = iommu_num_pages(addr, size, PAGE_SIZE);

View File

@ -20,7 +20,7 @@ struct pci_controller;
extern struct pci_ops apecs_pci_ops; extern struct pci_ops apecs_pci_ops;
extern void apecs_init_arch(void); extern void apecs_init_arch(void);
extern void apecs_pci_clr_err(void); extern void apecs_pci_clr_err(void);
extern void apecs_machine_check(u64, u64); extern void apecs_machine_check(unsigned long vector, unsigned long la_ptr);
extern void apecs_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); extern void apecs_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_cia.c */ /* core_cia.c */
@ -29,7 +29,7 @@ extern void cia_init_pci(void);
extern void cia_init_arch(void); extern void cia_init_arch(void);
extern void pyxis_init_arch(void); extern void pyxis_init_arch(void);
extern void cia_kill_arch(int); extern void cia_kill_arch(int);
extern void cia_machine_check(u64, u64); extern void cia_machine_check(unsigned long vector, unsigned long la_ptr);
extern void cia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); extern void cia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_irongate.c */ /* core_irongate.c */
@ -42,7 +42,7 @@ extern void irongate_machine_check(u64, u64);
/* core_lca.c */ /* core_lca.c */
extern struct pci_ops lca_pci_ops; extern struct pci_ops lca_pci_ops;
extern void lca_init_arch(void); extern void lca_init_arch(void);
extern void lca_machine_check(u64, u64); extern void lca_machine_check(unsigned long vector, unsigned long la_ptr);
extern void lca_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); extern void lca_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_marvel.c */ /* core_marvel.c */
@ -64,7 +64,7 @@ void io7_clear_errors(struct io7 *io7);
extern struct pci_ops mcpcia_pci_ops; extern struct pci_ops mcpcia_pci_ops;
extern void mcpcia_init_arch(void); extern void mcpcia_init_arch(void);
extern void mcpcia_init_hoses(void); extern void mcpcia_init_hoses(void);
extern void mcpcia_machine_check(u64, u64); extern void mcpcia_machine_check(unsigned long vector, unsigned long la_ptr);
extern void mcpcia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); extern void mcpcia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_polaris.c */ /* core_polaris.c */
@ -72,14 +72,14 @@ extern struct pci_ops polaris_pci_ops;
extern int polaris_read_config_dword(struct pci_dev *, int, u32 *); extern int polaris_read_config_dword(struct pci_dev *, int, u32 *);
extern int polaris_write_config_dword(struct pci_dev *, int, u32); extern int polaris_write_config_dword(struct pci_dev *, int, u32);
extern void polaris_init_arch(void); extern void polaris_init_arch(void);
extern void polaris_machine_check(u64, u64); extern void polaris_machine_check(unsigned long vector, unsigned long la_ptr);
#define polaris_pci_tbi ((void *)0) #define polaris_pci_tbi ((void *)0)
/* core_t2.c */ /* core_t2.c */
extern struct pci_ops t2_pci_ops; extern struct pci_ops t2_pci_ops;
extern void t2_init_arch(void); extern void t2_init_arch(void);
extern void t2_kill_arch(int); extern void t2_kill_arch(int);
extern void t2_machine_check(u64, u64); extern void t2_machine_check(unsigned long vector, unsigned long la_ptr);
extern void t2_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); extern void t2_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_titan.c */ /* core_titan.c */
@ -94,14 +94,14 @@ extern struct _alpha_agp_info *titan_agp_info(void);
extern struct pci_ops tsunami_pci_ops; extern struct pci_ops tsunami_pci_ops;
extern void tsunami_init_arch(void); extern void tsunami_init_arch(void);
extern void tsunami_kill_arch(int); extern void tsunami_kill_arch(int);
extern void tsunami_machine_check(u64, u64); extern void tsunami_machine_check(unsigned long vector, unsigned long la_ptr);
extern void tsunami_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); extern void tsunami_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_wildfire.c */ /* core_wildfire.c */
extern struct pci_ops wildfire_pci_ops; extern struct pci_ops wildfire_pci_ops;
extern void wildfire_init_arch(void); extern void wildfire_init_arch(void);
extern void wildfire_kill_arch(int); extern void wildfire_kill_arch(int);
extern void wildfire_machine_check(u64, u64); extern void wildfire_machine_check(unsigned long vector, unsigned long la_ptr);
extern void wildfire_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); extern void wildfire_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
extern int wildfire_pa_to_nid(unsigned long); extern int wildfire_pa_to_nid(unsigned long);
extern int wildfire_cpuid_to_nid(int); extern int wildfire_cpuid_to_nid(int);

View File

@ -1255,7 +1255,7 @@ show_cpuinfo(struct seq_file *f, void *slot)
platform_string(), nr_processors); platform_string(), nr_processors);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
seq_printf(f, "cpus active\t\t: %d\n" seq_printf(f, "cpus active\t\t: %u\n"
"cpu active mask\t\t: %016lx\n", "cpu active mask\t\t: %016lx\n",
num_online_cpus(), cpus_addr(cpu_possible_map)[0]); num_online_cpus(), cpus_addr(cpu_possible_map)[0]);
#endif #endif

View File

@ -2542,8 +2542,8 @@ void __init SMC669_Init ( int index )
SMC37c669_display_device_info( ); SMC37c669_display_device_info( );
#endif #endif
local_irq_restore(flags); local_irq_restore(flags);
printk( "SMC37c669 Super I/O Controller found @ 0x%lx\n", printk( "SMC37c669 Super I/O Controller found @ 0x%p\n",
(unsigned long) SMC_base ); SMC_base );
} }
else { else {
local_irq_restore(flags); local_irq_restore(flags);

View File

@ -218,7 +218,6 @@ srm_env_init(void)
BASE_DIR); BASE_DIR);
goto cleanup; goto cleanup;
} }
base_dir->owner = THIS_MODULE;
/* /*
* Create per-name subdirectory * Create per-name subdirectory
@ -229,7 +228,6 @@ srm_env_init(void)
BASE_DIR, NAMED_DIR); BASE_DIR, NAMED_DIR);
goto cleanup; goto cleanup;
} }
named_dir->owner = THIS_MODULE;
/* /*
* Create per-number subdirectory * Create per-number subdirectory
@ -241,7 +239,6 @@ srm_env_init(void)
goto cleanup; goto cleanup;
} }
numbered_dir->owner = THIS_MODULE;
/* /*
* Create all named nodes * Create all named nodes
@ -254,7 +251,6 @@ srm_env_init(void)
goto cleanup; goto cleanup;
entry->proc_entry->data = (void *) entry; entry->proc_entry->data = (void *) entry;
entry->proc_entry->owner = THIS_MODULE;
entry->proc_entry->read_proc = srm_env_read; entry->proc_entry->read_proc = srm_env_read;
entry->proc_entry->write_proc = srm_env_write; entry->proc_entry->write_proc = srm_env_write;
@ -275,7 +271,6 @@ srm_env_init(void)
entry->id = var_num; entry->id = var_num;
entry->proc_entry->data = (void *) entry; entry->proc_entry->data = (void *) entry;
entry->proc_entry->owner = THIS_MODULE;
entry->proc_entry->read_proc = srm_env_read; entry->proc_entry->read_proc = srm_env_read;
entry->proc_entry->write_proc = srm_env_write; entry->proc_entry->write_proc = srm_env_write;
} }

View File

@ -244,12 +244,11 @@ jensen_init_arch(void)
} }
static void static void
jensen_machine_check (u64 vector, u64 la) jensen_machine_check(unsigned long vector, unsigned long la)
{ {
printk(KERN_CRIT "Machine check\n"); printk(KERN_CRIT "Machine check\n");
} }
/* /*
* The System Vector * The System Vector
*/ */

View File

@ -453,7 +453,7 @@ sable_lynx_enable_irq(unsigned int irq)
sable_lynx_irq_swizzle->update_irq_hw(bit, mask); sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
spin_unlock(&sable_lynx_irq_lock); spin_unlock(&sable_lynx_irq_lock);
#if 0 #if 0
printk("%s: mask 0x%lx bit 0x%x irq 0x%x\n", printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n",
__func__, mask, bit, irq); __func__, mask, bit, irq);
#endif #endif
} }
@ -469,7 +469,7 @@ sable_lynx_disable_irq(unsigned int irq)
sable_lynx_irq_swizzle->update_irq_hw(bit, mask); sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
spin_unlock(&sable_lynx_irq_lock); spin_unlock(&sable_lynx_irq_lock);
#if 0 #if 0
printk("%s: mask 0x%lx bit 0x%x irq 0x%x\n", printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n",
__func__, mask, bit, irq); __func__, mask, bit, irq);
#endif #endif
} }

View File

@ -623,7 +623,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg,
} }
lock_kernel(); lock_kernel();
printk("Bad unaligned kernel access at %016lx: %p %lx %ld\n", printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n",
pc, va, opcode, reg); pc, va, opcode, reg);
do_exit(SIGSEGV); do_exit(SIGSEGV);

View File

@ -250,21 +250,3 @@ asmlinkage void do_bus_error(unsigned long addr, int write_access,
dump_dtlb(); dump_dtlb();
die("Bus Error", regs, SIGKILL); die("Bus Error", regs, SIGKILL);
} }
/*
* This functionality is currently not possible to implement because
* we're using segmentation to ensure a fixed mapping of the kernel
* virtual address space.
*
* It would be possible to implement this, but it would require us to
* disable segmentation at startup and load the kernel mappings into
* the TLB like any other pages. There will be lots of trickery to
* avoid recursive invocation of the TLB miss handler, though...
*/
#ifdef CONFIG_DEBUG_PAGEALLOC
void kernel_map_pages(struct page *page, int numpages, int enable)
{
}
EXPORT_SYMBOL(kernel_map_pages);
#endif

View File

@ -854,7 +854,6 @@ static int __init sram_proc_init(void)
printk(KERN_WARNING "unable to create /proc/sram\n"); printk(KERN_WARNING "unable to create /proc/sram\n");
return -1; return -1;
} }
ptr->owner = THIS_MODULE;
ptr->read_proc = sram_proc_read; ptr->read_proc = sram_proc_read;
return 0; return 0;
} }

View File

@ -261,7 +261,6 @@ timer_interrupt(int irq, void *dev_id)
static struct irqaction irq2 = { static struct irqaction irq2 = {
.handler = timer_interrupt, .handler = timer_interrupt,
.flags = IRQF_SHARED | IRQF_DISABLED, .flags = IRQF_SHARED | IRQF_DISABLED,
.mask = CPU_MASK_NONE,
.name = "timer", .name = "timer",
}; };

View File

@ -65,7 +65,6 @@ static int send_ipi(int vector, int wait, cpumask_t cpu_mask);
static struct irqaction irq_ipi = { static struct irqaction irq_ipi = {
.handler = crisv32_ipi_interrupt, .handler = crisv32_ipi_interrupt,
.flags = IRQF_DISABLED, .flags = IRQF_DISABLED,
.mask = CPU_MASK_NONE,
.name = "ipi", .name = "ipi",
}; };

View File

@ -267,7 +267,6 @@ timer_interrupt(int irq, void *dev_id)
static struct irqaction irq_timer = { static struct irqaction irq_timer = {
.handler = timer_interrupt, .handler = timer_interrupt,
.flags = IRQF_SHARED | IRQF_DISABLED, .flags = IRQF_SHARED | IRQF_DISABLED,
.mask = CPU_MASK_NONE,
.name = "timer" .name = "timer"
}; };

View File

@ -109,28 +109,24 @@ static struct irqaction fpga_irq[4] = {
[0] = { [0] = {
.handler = fpga_interrupt, .handler = fpga_interrupt,
.flags = IRQF_DISABLED | IRQF_SHARED, .flags = IRQF_DISABLED | IRQF_SHARED,
.mask = CPU_MASK_NONE,
.name = "fpga.0", .name = "fpga.0",
.dev_id = (void *) 0x0028UL, .dev_id = (void *) 0x0028UL,
}, },
[1] = { [1] = {
.handler = fpga_interrupt, .handler = fpga_interrupt,
.flags = IRQF_DISABLED | IRQF_SHARED, .flags = IRQF_DISABLED | IRQF_SHARED,
.mask = CPU_MASK_NONE,
.name = "fpga.1", .name = "fpga.1",
.dev_id = (void *) 0x0050UL, .dev_id = (void *) 0x0050UL,
}, },
[2] = { [2] = {
.handler = fpga_interrupt, .handler = fpga_interrupt,
.flags = IRQF_DISABLED | IRQF_SHARED, .flags = IRQF_DISABLED | IRQF_SHARED,
.mask = CPU_MASK_NONE,
.name = "fpga.2", .name = "fpga.2",
.dev_id = (void *) 0x1c00UL, .dev_id = (void *) 0x1c00UL,
}, },
[3] = { [3] = {
.handler = fpga_interrupt, .handler = fpga_interrupt,
.flags = IRQF_DISABLED | IRQF_SHARED, .flags = IRQF_DISABLED | IRQF_SHARED,
.mask = CPU_MASK_NONE,
.name = "fpga.3", .name = "fpga.3",
.dev_id = (void *) 0x6386UL, .dev_id = (void *) 0x6386UL,
} }

View File

@ -108,7 +108,6 @@ static struct irqaction fpga_irq[1] = {
[0] = { [0] = {
.handler = fpga_interrupt, .handler = fpga_interrupt,
.flags = IRQF_DISABLED, .flags = IRQF_DISABLED,
.mask = CPU_MASK_NONE,
.name = "fpga.0", .name = "fpga.0",
.dev_id = (void *) 0x0700UL, .dev_id = (void *) 0x0700UL,
} }

View File

@ -120,14 +120,12 @@ static struct irqaction mb93493_irq[2] = {
[0] = { [0] = {
.handler = mb93493_interrupt, .handler = mb93493_interrupt,
.flags = IRQF_DISABLED | IRQF_SHARED, .flags = IRQF_DISABLED | IRQF_SHARED,
.mask = CPU_MASK_NONE,
.name = "mb93493.0", .name = "mb93493.0",
.dev_id = (void *) __addr_MB93493_IQSR(0), .dev_id = (void *) __addr_MB93493_IQSR(0),
}, },
[1] = { [1] = {
.handler = mb93493_interrupt, .handler = mb93493_interrupt,
.flags = IRQF_DISABLED | IRQF_SHARED, .flags = IRQF_DISABLED | IRQF_SHARED,
.mask = CPU_MASK_NONE,
.name = "mb93493.1", .name = "mb93493.1",
.dev_id = (void *) __addr_MB93493_IQSR(1), .dev_id = (void *) __addr_MB93493_IQSR(1),
} }

View File

@ -45,7 +45,6 @@ static irqreturn_t timer_interrupt(int irq, void *dummy);
static struct irqaction timer_irq = { static struct irqaction timer_irq = {
.handler = timer_interrupt, .handler = timer_interrupt,
.flags = IRQF_DISABLED, .flags = IRQF_DISABLED,
.mask = CPU_MASK_NONE,
.name = "timer", .name = "timer",
}; };

View File

@ -60,7 +60,6 @@ static struct irqaction itu_irq = {
.name = "itu", .name = "itu",
.handler = timer_interrupt, .handler = timer_interrupt,
.flags = IRQF_DISABLED | IRQF_TIMER, .flags = IRQF_DISABLED | IRQF_TIMER,
.mask = CPU_MASK_NONE,
}; };
static const int __initdata divide_rate[] = {1, 2, 4, 8}; static const int __initdata divide_rate[] = {1, 2, 4, 8};

View File

@ -55,7 +55,6 @@ static struct irqaction timer16_irq = {
.name = "timer-16", .name = "timer-16",
.handler = timer_interrupt, .handler = timer_interrupt,
.flags = IRQF_DISABLED | IRQF_TIMER, .flags = IRQF_DISABLED | IRQF_TIMER,
.mask = CPU_MASK_NONE,
}; };
static const int __initdata divide_rate[] = {1, 2, 4, 8}; static const int __initdata divide_rate[] = {1, 2, 4, 8};

View File

@ -75,7 +75,6 @@ static struct irqaction timer8_irq = {
.name = "timer-8", .name = "timer-8",
.handler = timer_interrupt, .handler = timer_interrupt,
.flags = IRQF_DISABLED | IRQF_TIMER, .flags = IRQF_DISABLED | IRQF_TIMER,
.mask = CPU_MASK_NONE,
}; };
static const int __initdata divide_rate[] = {8, 64, 8192}; static const int __initdata divide_rate[] = {8, 64, 8192};

View File

@ -65,7 +65,6 @@ static struct irqaction tpu_irq = {
.name = "tpu", .name = "tpu",
.handler = timer_interrupt, .handler = timer_interrupt,
.flags = IRQF_DISABLED | IRQF_TIMER, .flags = IRQF_DISABLED | IRQF_TIMER,
.mask = CPU_MASK_NONE,
}; };
const static int __initdata divide_rate[] = { const static int __initdata divide_rate[] = {

View File

@ -24,6 +24,7 @@
#include <linux/major.h> #include <linux/major.h>
#include <linux/fcntl.h> #include <linux/fcntl.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/seq_file.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/capability.h> #include <linux/capability.h>
#include <linux/console.h> #include <linux/console.h>
@ -848,38 +849,36 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
* /proc fs routines.... * /proc fs routines....
*/ */
static inline int line_info(char *buf, struct serial_state *state) static inline void line_info(struct seq_file *m, struct serial_state *state)
{ {
return sprintf(buf, "%d: uart:%s port:%lX irq:%d\n", seq_printf(m, "%d: uart:%s port:%lX irq:%d\n",
state->line, uart_config[state->type].name, state->line, uart_config[state->type].name,
state->port, state->irq); state->port, state->irq);
} }
static int rs_read_proc(char *page, char **start, off_t off, int count, static int rs_proc_show(struct seq_file *m, void *v)
int *eof, void *data)
{ {
int i, len = 0, l; int i;
off_t begin = 0;
len += sprintf(page, "simserinfo:1.0 driver:%s\n", serial_version); seq_printf(m, "simserinfo:1.0 driver:%s\n", serial_version);
for (i = 0; i < NR_PORTS && len < 4000; i++) { for (i = 0; i < NR_PORTS; i++)
l = line_info(page + len, &rs_table[i]); line_info(m, &rs_table[i]);
len += l; return 0;
if (len+begin > off+count)
goto done;
if (len+begin < off) {
begin += len;
len = 0;
}
}
*eof = 1;
done:
if (off >= len+begin)
return 0;
*start = page + (begin-off);
return ((count < begin+len-off) ? count : begin+len-off);
} }
static int rs_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, rs_proc_show, NULL);
}
static const struct file_operations rs_proc_fops = {
.owner = THIS_MODULE,
.open = rs_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
/* /*
* --------------------------------------------------------------------- * ---------------------------------------------------------------------
* rs_init() and friends * rs_init() and friends
@ -917,7 +916,7 @@ static const struct tty_operations hp_ops = {
.start = rs_start, .start = rs_start,
.hangup = rs_hangup, .hangup = rs_hangup,
.wait_until_sent = rs_wait_until_sent, .wait_until_sent = rs_wait_until_sent,
.read_proc = rs_read_proc, .proc_fops = &rs_proc_fops,
}; };
/* /*

View File

@ -202,7 +202,11 @@ extern long ia64_cmpxchg_called_with_bad_pointer (void);
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#if defined(CONFIG_PARAVIRT) && defined(__KERNEL__) #if defined(CONFIG_PARAVIRT) && defined(__KERNEL__)
#define IA64_INTRINSIC_API(name) pv_cpu_ops.name #ifdef ASM_SUPPORTED
# define IA64_INTRINSIC_API(name) paravirt_ ## name
#else
# define IA64_INTRINSIC_API(name) pv_cpu_ops.name
#endif
#define IA64_INTRINSIC_MACRO(name) paravirt_ ## name #define IA64_INTRINSIC_MACRO(name) paravirt_ ## name
#else #else
#define IA64_INTRINSIC_API(name) ia64_native_ ## name #define IA64_INTRINSIC_API(name) ia64_native_ ## name

View File

@ -87,7 +87,7 @@ get_mmu_context (struct mm_struct *mm)
/* re-check, now that we've got the lock: */ /* re-check, now that we've got the lock: */
context = mm->context; context = mm->context;
if (context == 0) { if (context == 0) {
cpus_clear(mm->cpu_vm_mask); cpumask_clear(mm_cpumask(mm));
if (ia64_ctx.next >= ia64_ctx.limit) { if (ia64_ctx.next >= ia64_ctx.limit) {
ia64_ctx.next = find_next_zero_bit(ia64_ctx.bitmap, ia64_ctx.next = find_next_zero_bit(ia64_ctx.bitmap,
ia64_ctx.max_ctx, ia64_ctx.next); ia64_ctx.max_ctx, ia64_ctx.next);
@ -166,8 +166,8 @@ activate_context (struct mm_struct *mm)
do { do {
context = get_mmu_context(mm); context = get_mmu_context(mm);
if (!cpu_isset(smp_processor_id(), mm->cpu_vm_mask)) if (!cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)))
cpu_set(smp_processor_id(), mm->cpu_vm_mask); cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
reload_context(context); reload_context(context);
/* /*
* in the unlikely event of a TLB-flush by another thread, * in the unlikely event of a TLB-flush by another thread,

View File

@ -16,6 +16,12 @@ struct mod_arch_specific {
struct elf64_shdr *got; /* global offset table */ struct elf64_shdr *got; /* global offset table */
struct elf64_shdr *opd; /* official procedure descriptors */ struct elf64_shdr *opd; /* official procedure descriptors */
struct elf64_shdr *unwind; /* unwind-table section */ struct elf64_shdr *unwind; /* unwind-table section */
#ifdef CONFIG_PARAVIRT
struct elf64_shdr *paravirt_bundles;
/* paravirt_alt_bundle_patch table */
struct elf64_shdr *paravirt_insts;
/* paravirt_alt_inst_patch table */
#endif
unsigned long gp; /* global-pointer for module */ unsigned long gp; /* global-pointer for module */
void *core_unw_table; /* core unwind-table cookie returned by unwinder */ void *core_unw_table; /* core unwind-table cookie returned by unwinder */

View File

@ -30,6 +30,9 @@
#define __paravirt_work_processed_syscall_target \ #define __paravirt_work_processed_syscall_target \
ia64_work_processed_syscall ia64_work_processed_syscall
#define paravirt_fsyscall_table ia64_native_fsyscall_table
#define paravirt_fsys_bubble_down ia64_native_fsys_bubble_down
#ifdef CONFIG_PARAVIRT_GUEST_ASM_CLOBBER_CHECK #ifdef CONFIG_PARAVIRT_GUEST_ASM_CLOBBER_CHECK
# define PARAVIRT_POISON 0xdeadbeefbaadf00d # define PARAVIRT_POISON 0xdeadbeefbaadf00d
# define CLOBBER(clob) \ # define CLOBBER(clob) \
@ -74,6 +77,11 @@
(pred) mov reg = psr \ (pred) mov reg = psr \
CLOBBER(clob) CLOBBER(clob)
#define MOV_FROM_ITC(pred, pred_clob, reg, clob) \
(pred) mov reg = ar.itc \
CLOBBER(clob) \
CLOBBER_PRED(pred_clob)
#define MOV_TO_IFA(reg, clob) \ #define MOV_TO_IFA(reg, clob) \
mov cr.ifa = reg \ mov cr.ifa = reg \
CLOBBER(clob) CLOBBER(clob)
@ -158,6 +166,11 @@
#define RSM_PSR_DT \ #define RSM_PSR_DT \
rsm psr.dt rsm psr.dt
#define RSM_PSR_BE_I(clob0, clob1) \
rsm psr.be | psr.i \
CLOBBER(clob0) \
CLOBBER(clob1)
#define SSM_PSR_DT_AND_SRLZ_I \ #define SSM_PSR_DT_AND_SRLZ_I \
ssm psr.dt \ ssm psr.dt \
;; \ ;; \

View File

@ -0,0 +1,38 @@
/******************************************************************************
* arch/ia64/include/asm/native/inst.h
*
* Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#define __paravirt_start_gate_fsyscall_patchlist \
__ia64_native_start_gate_fsyscall_patchlist
#define __paravirt_end_gate_fsyscall_patchlist \
__ia64_native_end_gate_fsyscall_patchlist
#define __paravirt_start_gate_brl_fsys_bubble_down_patchlist \
__ia64_native_start_gate_brl_fsys_bubble_down_patchlist
#define __paravirt_end_gate_brl_fsys_bubble_down_patchlist \
__ia64_native_end_gate_brl_fsys_bubble_down_patchlist
#define __paravirt_start_gate_vtop_patchlist \
__ia64_native_start_gate_vtop_patchlist
#define __paravirt_end_gate_vtop_patchlist \
__ia64_native_end_gate_vtop_patchlist
#define __paravirt_start_gate_mckinley_e9_patchlist \
__ia64_native_start_gate_mckinley_e9_patchlist
#define __paravirt_end_gate_mckinley_e9_patchlist \
__ia64_native_end_gate_mckinley_e9_patchlist

View File

@ -180,6 +180,11 @@
IS_PRED_IN(pred) \ IS_PRED_IN(pred) \
IS_RREG_OUT(reg) \ IS_RREG_OUT(reg) \
IS_RREG_CLOB(clob) IS_RREG_CLOB(clob)
#define MOV_FROM_ITC(pred, pred_clob, reg, clob) \
IS_PRED_IN(pred) \
IS_PRED_CLOB(pred_clob) \
IS_RREG_OUT(reg) \
IS_RREG_CLOB(clob)
#define MOV_TO_IFA(reg, clob) \ #define MOV_TO_IFA(reg, clob) \
IS_RREG_IN(reg) \ IS_RREG_IN(reg) \
IS_RREG_CLOB(clob) IS_RREG_CLOB(clob)
@ -246,6 +251,9 @@
IS_RREG_CLOB(clob2) IS_RREG_CLOB(clob2)
#define RSM_PSR_DT \ #define RSM_PSR_DT \
nop 0 nop 0
#define RSM_PSR_BE_I(clob0, clob1) \
IS_RREG_CLOB(clob0) \
IS_RREG_CLOB(clob1)
#define SSM_PSR_DT_AND_SRLZ_I \ #define SSM_PSR_DT_AND_SRLZ_I \
nop 0 nop 0
#define BSW_0(clob0, clob1, clob2) \ #define BSW_0(clob0, clob1, clob2) \

View File

@ -22,6 +22,56 @@
#ifndef __ASM_PARAVIRT_H #ifndef __ASM_PARAVIRT_H
#define __ASM_PARAVIRT_H #define __ASM_PARAVIRT_H
#ifndef __ASSEMBLY__
/******************************************************************************
* fsys related addresses
*/
struct pv_fsys_data {
unsigned long *fsyscall_table;
void *fsys_bubble_down;
};
extern struct pv_fsys_data pv_fsys_data;
unsigned long *paravirt_get_fsyscall_table(void);
char *paravirt_get_fsys_bubble_down(void);
/******************************************************************************
* patchlist addresses for gate page
*/
enum pv_gate_patchlist {
PV_GATE_START_FSYSCALL,
PV_GATE_END_FSYSCALL,
PV_GATE_START_BRL_FSYS_BUBBLE_DOWN,
PV_GATE_END_BRL_FSYS_BUBBLE_DOWN,
PV_GATE_START_VTOP,
PV_GATE_END_VTOP,
PV_GATE_START_MCKINLEY_E9,
PV_GATE_END_MCKINLEY_E9,
};
struct pv_patchdata {
unsigned long start_fsyscall_patchlist;
unsigned long end_fsyscall_patchlist;
unsigned long start_brl_fsys_bubble_down_patchlist;
unsigned long end_brl_fsys_bubble_down_patchlist;
unsigned long start_vtop_patchlist;
unsigned long end_vtop_patchlist;
unsigned long start_mckinley_e9_patchlist;
unsigned long end_mckinley_e9_patchlist;
void *gate_section;
};
extern struct pv_patchdata pv_patchdata;
unsigned long paravirt_get_gate_patchlist(enum pv_gate_patchlist type);
void *paravirt_get_gate_section(void);
#endif
#ifdef CONFIG_PARAVIRT_GUEST #ifdef CONFIG_PARAVIRT_GUEST
#define PARAVIRT_HYPERVISOR_TYPE_DEFAULT 0 #define PARAVIRT_HYPERVISOR_TYPE_DEFAULT 0
@ -68,6 +118,14 @@ struct pv_init_ops {
int (*arch_setup_nomca)(void); int (*arch_setup_nomca)(void);
void (*post_smp_prepare_boot_cpu)(void); void (*post_smp_prepare_boot_cpu)(void);
#ifdef ASM_SUPPORTED
unsigned long (*patch_bundle)(void *sbundle, void *ebundle,
unsigned long type);
unsigned long (*patch_inst)(unsigned long stag, unsigned long etag,
unsigned long type);
#endif
void (*patch_branch)(unsigned long tag, unsigned long type);
}; };
extern struct pv_init_ops pv_init_ops; extern struct pv_init_ops pv_init_ops;
@ -210,6 +268,8 @@ struct pv_time_ops {
int (*do_steal_accounting)(unsigned long *new_itm); int (*do_steal_accounting)(unsigned long *new_itm);
void (*clocksource_resume)(void); void (*clocksource_resume)(void);
unsigned long long (*sched_clock)(void);
}; };
extern struct pv_time_ops pv_time_ops; extern struct pv_time_ops pv_time_ops;
@ -227,6 +287,11 @@ paravirt_do_steal_accounting(unsigned long *new_itm)
return pv_time_ops.do_steal_accounting(new_itm); return pv_time_ops.do_steal_accounting(new_itm);
} }
static inline unsigned long long paravirt_sched_clock(void)
{
return pv_time_ops.sched_clock();
}
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
#else #else

View File

@ -0,0 +1,143 @@
/******************************************************************************
* Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef __ASM_PARAVIRT_PATCH_H
#define __ASM_PARAVIRT_PATCH_H
#ifdef __ASSEMBLY__
.section .paravirt_branches, "a"
.previous
#define PARAVIRT_PATCH_SITE_BR(type) \
{ \
[1:] ; \
br.cond.sptk.many 2f ; \
nop.b 0 ; \
nop.b 0;; ; \
} ; \
2: \
.xdata8 ".paravirt_branches", 1b, type
#else
#include <linux/stringify.h>
#include <asm/intrinsics.h>
/* for binary patch */
struct paravirt_patch_site_bundle {
void *sbundle;
void *ebundle;
unsigned long type;
};
/* label means the beginning of new bundle */
#define paravirt_alt_bundle(instr, privop) \
"\t998:\n" \
"\t" instr "\n" \
"\t999:\n" \
"\t.pushsection .paravirt_bundles, \"a\"\n" \
"\t.popsection\n" \
"\t.xdata8 \".paravirt_bundles\", 998b, 999b, " \
__stringify(privop) "\n"
struct paravirt_patch_bundle_elem {
const void *sbundle;
const void *ebundle;
unsigned long type;
};
struct paravirt_patch_site_inst {
unsigned long stag;
unsigned long etag;
unsigned long type;
};
#define paravirt_alt_inst(instr, privop) \
"\t[998:]\n" \
"\t" instr "\n" \
"\t[999:]\n" \
"\t.pushsection .paravirt_insts, \"a\"\n" \
"\t.popsection\n" \
"\t.xdata8 \".paravirt_insts\", 998b, 999b, " \
__stringify(privop) "\n"
struct paravirt_patch_site_branch {
unsigned long tag;
unsigned long type;
};
struct paravirt_patch_branch_target {
const void *entry;
unsigned long type;
};
void
__paravirt_patch_apply_branch(
unsigned long tag, unsigned long type,
const struct paravirt_patch_branch_target *entries,
unsigned int nr_entries);
void
paravirt_patch_reloc_br(unsigned long tag, const void *target);
void
paravirt_patch_reloc_brl(unsigned long tag, const void *target);
#if defined(ASM_SUPPORTED) && defined(CONFIG_PARAVIRT)
unsigned long
ia64_native_patch_bundle(void *sbundle, void *ebundle, unsigned long type);
unsigned long
__paravirt_patch_apply_bundle(void *sbundle, void *ebundle, unsigned long type,
const struct paravirt_patch_bundle_elem *elems,
unsigned long nelems,
const struct paravirt_patch_bundle_elem **found);
void
paravirt_patch_apply_bundle(const struct paravirt_patch_site_bundle *start,
const struct paravirt_patch_site_bundle *end);
void
paravirt_patch_apply_inst(const struct paravirt_patch_site_inst *start,
const struct paravirt_patch_site_inst *end);
void paravirt_patch_apply(void);
#else
#define paravirt_patch_apply_bundle(start, end) do { } while (0)
#define paravirt_patch_apply_inst(start, end) do { } while (0)
#define paravirt_patch_apply() do { } while (0)
#endif
#endif /* !__ASSEMBLEY__ */
#endif /* __ASM_PARAVIRT_PATCH_H */
/*
* Local variables:
* mode: C
* c-set-style: "linux"
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*/

View File

@ -33,7 +33,7 @@
*/ */
struct pv_cpu_ops { struct pv_cpu_ops {
void (*fc)(unsigned long addr); void (*fc)(void *addr);
unsigned long (*thash)(unsigned long addr); unsigned long (*thash)(unsigned long addr);
unsigned long (*get_cpuid)(int index); unsigned long (*get_cpuid)(int index);
unsigned long (*get_pmd)(int index); unsigned long (*get_pmd)(int index);
@ -60,12 +60,18 @@ extern unsigned long ia64_native_getreg_func(int regnum);
/* Instructions paravirtualized for performance */ /* Instructions paravirtualized for performance */
/************************************************/ /************************************************/
#ifndef ASM_SUPPORTED
#define paravirt_ssm_i() pv_cpu_ops.ssm_i()
#define paravirt_rsm_i() pv_cpu_ops.rsm_i()
#define __paravirt_getreg() pv_cpu_ops.getreg()
#endif
/* mask for ia64_native_ssm/rsm() must be constant.("i" constraing). /* mask for ia64_native_ssm/rsm() must be constant.("i" constraing).
* static inline function doesn't satisfy it. */ * static inline function doesn't satisfy it. */
#define paravirt_ssm(mask) \ #define paravirt_ssm(mask) \
do { \ do { \
if ((mask) == IA64_PSR_I) \ if ((mask) == IA64_PSR_I) \
pv_cpu_ops.ssm_i(); \ paravirt_ssm_i(); \
else \ else \
ia64_native_ssm(mask); \ ia64_native_ssm(mask); \
} while (0) } while (0)
@ -73,7 +79,7 @@ extern unsigned long ia64_native_getreg_func(int regnum);
#define paravirt_rsm(mask) \ #define paravirt_rsm(mask) \
do { \ do { \
if ((mask) == IA64_PSR_I) \ if ((mask) == IA64_PSR_I) \
pv_cpu_ops.rsm_i(); \ paravirt_rsm_i(); \
else \ else \
ia64_native_rsm(mask); \ ia64_native_rsm(mask); \
} while (0) } while (0)
@ -86,7 +92,7 @@ extern unsigned long ia64_native_getreg_func(int regnum);
if ((reg) == _IA64_REG_IP) \ if ((reg) == _IA64_REG_IP) \
res = ia64_native_getreg(_IA64_REG_IP); \ res = ia64_native_getreg(_IA64_REG_IP); \
else \ else \
res = pv_cpu_ops.getreg(reg); \ res = __paravirt_getreg(reg); \
res; \ res; \
}) })
@ -112,6 +118,12 @@ void paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch);
#endif /* CONFIG_PARAVIRT */ #endif /* CONFIG_PARAVIRT */
#if defined(CONFIG_PARAVIRT) && defined(ASM_SUPPORTED)
#define paravirt_dv_serialize_data() ia64_dv_serialize_data()
#else
#define paravirt_dv_serialize_data() /* nothing */
#endif
/* these routines utilize privilege-sensitive or performance-sensitive /* these routines utilize privilege-sensitive or performance-sensitive
* privileged instructions so the code must be replaced with * privileged instructions so the code must be replaced with
* paravirtualized versions */ * paravirtualized versions */
@ -121,4 +133,349 @@ void paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch);
IA64_PARAVIRT_ASM_FUNC(work_processed_syscall) IA64_PARAVIRT_ASM_FUNC(work_processed_syscall)
#define ia64_leave_kernel IA64_PARAVIRT_ASM_FUNC(leave_kernel) #define ia64_leave_kernel IA64_PARAVIRT_ASM_FUNC(leave_kernel)
#if defined(CONFIG_PARAVIRT)
/******************************************************************************
* binary patching infrastructure
*/
#define PARAVIRT_PATCH_TYPE_FC 1
#define PARAVIRT_PATCH_TYPE_THASH 2
#define PARAVIRT_PATCH_TYPE_GET_CPUID 3
#define PARAVIRT_PATCH_TYPE_GET_PMD 4
#define PARAVIRT_PATCH_TYPE_PTCGA 5
#define PARAVIRT_PATCH_TYPE_GET_RR 6
#define PARAVIRT_PATCH_TYPE_SET_RR 7
#define PARAVIRT_PATCH_TYPE_SET_RR0_TO_RR4 8
#define PARAVIRT_PATCH_TYPE_SSM_I 9
#define PARAVIRT_PATCH_TYPE_RSM_I 10
#define PARAVIRT_PATCH_TYPE_GET_PSR_I 11
#define PARAVIRT_PATCH_TYPE_INTRIN_LOCAL_IRQ_RESTORE 12
/* PARAVIRT_PATY_TYPE_[GS]ETREG + _IA64_REG_xxx */
#define PARAVIRT_PATCH_TYPE_GETREG 0x10000000
#define PARAVIRT_PATCH_TYPE_SETREG 0x20000000
/*
* struct task_struct* (*ia64_switch_to)(void* next_task);
* void *ia64_leave_syscall;
* void *ia64_work_processed_syscall
* void *ia64_leave_kernel;
*/
#define PARAVIRT_PATCH_TYPE_BR_START 0x30000000
#define PARAVIRT_PATCH_TYPE_BR_SWITCH_TO \
(PARAVIRT_PATCH_TYPE_BR_START + 0)
#define PARAVIRT_PATCH_TYPE_BR_LEAVE_SYSCALL \
(PARAVIRT_PATCH_TYPE_BR_START + 1)
#define PARAVIRT_PATCH_TYPE_BR_WORK_PROCESSED_SYSCALL \
(PARAVIRT_PATCH_TYPE_BR_START + 2)
#define PARAVIRT_PATCH_TYPE_BR_LEAVE_KERNEL \
(PARAVIRT_PATCH_TYPE_BR_START + 3)
#ifdef ASM_SUPPORTED
#include <asm/paravirt_patch.h>
/*
* pv_cpu_ops calling stub.
* normal function call convension can't be written by gcc
* inline assembly.
*
* from the caller's point of view,
* the following registers will be clobbered.
* r2, r3
* r8-r15
* r16, r17
* b6, b7
* p6-p15
* ar.ccv
*
* from the callee's point of view ,
* the following registers can be used.
* r2, r3: scratch
* r8: scratch, input argument0 and return value
* r0-r15: scratch, input argument1-5
* b6: return pointer
* b7: scratch
* p6-p15: scratch
* ar.ccv: scratch
*
* other registers must not be changed. especially
* b0: rp: preserved. gcc ignores b0 in clobbered register.
* r16: saved gp
*/
/* 5 bundles */
#define __PARAVIRT_BR \
";;\n" \
"{ .mlx\n" \
"nop 0\n" \
"movl r2 = %[op_addr]\n"/* get function pointer address */ \
";;\n" \
"}\n" \
"1:\n" \
"{ .mii\n" \
"ld8 r2 = [r2]\n" /* load function descriptor address */ \
"mov r17 = ip\n" /* get ip to calc return address */ \
"mov r16 = gp\n" /* save gp */ \
";;\n" \
"}\n" \
"{ .mii\n" \
"ld8 r3 = [r2], 8\n" /* load entry address */ \
"adds r17 = 1f - 1b, r17\n" /* calculate return address */ \
";;\n" \
"mov b7 = r3\n" /* set entry address */ \
"}\n" \
"{ .mib\n" \
"ld8 gp = [r2]\n" /* load gp value */ \
"mov b6 = r17\n" /* set return address */ \
"br.cond.sptk.few b7\n" /* intrinsics are very short isns */ \
"}\n" \
"1:\n" \
"{ .mii\n" \
"mov gp = r16\n" /* restore gp value */ \
"nop 0\n" \
"nop 0\n" \
";;\n" \
"}\n"
#define PARAVIRT_OP(op) \
[op_addr] "i"(&pv_cpu_ops.op)
#define PARAVIRT_TYPE(type) \
PARAVIRT_PATCH_TYPE_ ## type
#define PARAVIRT_REG_CLOBBERS0 \
"r2", "r3", /*"r8",*/ "r9", "r10", "r11", "r14", \
"r15", "r16", "r17"
#define PARAVIRT_REG_CLOBBERS1 \
"r2","r3", /*"r8",*/ "r9", "r10", "r11", "r14", \
"r15", "r16", "r17"
#define PARAVIRT_REG_CLOBBERS2 \
"r2", "r3", /*"r8", "r9",*/ "r10", "r11", "r14", \
"r15", "r16", "r17"
#define PARAVIRT_REG_CLOBBERS5 \
"r2", "r3", /*"r8", "r9", "r10", "r11", "r14",*/ \
"r15", "r16", "r17"
#define PARAVIRT_BR_CLOBBERS \
"b6", "b7"
#define PARAVIRT_PR_CLOBBERS \
"p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15"
#define PARAVIRT_AR_CLOBBERS \
"ar.ccv"
#define PARAVIRT_CLOBBERS0 \
PARAVIRT_REG_CLOBBERS0, \
PARAVIRT_BR_CLOBBERS, \
PARAVIRT_PR_CLOBBERS, \
PARAVIRT_AR_CLOBBERS, \
"memory"
#define PARAVIRT_CLOBBERS1 \
PARAVIRT_REG_CLOBBERS1, \
PARAVIRT_BR_CLOBBERS, \
PARAVIRT_PR_CLOBBERS, \
PARAVIRT_AR_CLOBBERS, \
"memory"
#define PARAVIRT_CLOBBERS2 \
PARAVIRT_REG_CLOBBERS2, \
PARAVIRT_BR_CLOBBERS, \
PARAVIRT_PR_CLOBBERS, \
PARAVIRT_AR_CLOBBERS, \
"memory"
#define PARAVIRT_CLOBBERS5 \
PARAVIRT_REG_CLOBBERS5, \
PARAVIRT_BR_CLOBBERS, \
PARAVIRT_PR_CLOBBERS, \
PARAVIRT_AR_CLOBBERS, \
"memory"
#define PARAVIRT_BR0(op, type) \
register unsigned long ia64_clobber asm ("r8"); \
asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \
PARAVIRT_TYPE(type)) \
: "=r"(ia64_clobber) \
: PARAVIRT_OP(op) \
: PARAVIRT_CLOBBERS0)
#define PARAVIRT_BR0_RET(op, type) \
register unsigned long ia64_intri_res asm ("r8"); \
asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \
PARAVIRT_TYPE(type)) \
: "=r"(ia64_intri_res) \
: PARAVIRT_OP(op) \
: PARAVIRT_CLOBBERS0)
#define PARAVIRT_BR1(op, type, arg1) \
register unsigned long __##arg1 asm ("r8") = arg1; \
register unsigned long ia64_clobber asm ("r8"); \
asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \
PARAVIRT_TYPE(type)) \
: "=r"(ia64_clobber) \
: PARAVIRT_OP(op), "0"(__##arg1) \
: PARAVIRT_CLOBBERS1)
#define PARAVIRT_BR1_RET(op, type, arg1) \
register unsigned long ia64_intri_res asm ("r8"); \
register unsigned long __##arg1 asm ("r8") = arg1; \
asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \
PARAVIRT_TYPE(type)) \
: "=r"(ia64_intri_res) \
: PARAVIRT_OP(op), "0"(__##arg1) \
: PARAVIRT_CLOBBERS1)
#define PARAVIRT_BR1_VOID(op, type, arg1) \
register void *__##arg1 asm ("r8") = arg1; \
register unsigned long ia64_clobber asm ("r8"); \
asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \
PARAVIRT_TYPE(type)) \
: "=r"(ia64_clobber) \
: PARAVIRT_OP(op), "0"(__##arg1) \
: PARAVIRT_CLOBBERS1)
#define PARAVIRT_BR2(op, type, arg1, arg2) \
register unsigned long __##arg1 asm ("r8") = arg1; \
register unsigned long __##arg2 asm ("r9") = arg2; \
register unsigned long ia64_clobber1 asm ("r8"); \
register unsigned long ia64_clobber2 asm ("r9"); \
asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \
PARAVIRT_TYPE(type)) \
: "=r"(ia64_clobber1), "=r"(ia64_clobber2) \
: PARAVIRT_OP(op), "0"(__##arg1), "1"(__##arg2) \
: PARAVIRT_CLOBBERS2)
#define PARAVIRT_DEFINE_CPU_OP0(op, type) \
static inline void \
paravirt_ ## op (void) \
{ \
PARAVIRT_BR0(op, type); \
}
#define PARAVIRT_DEFINE_CPU_OP0_RET(op, type) \
static inline unsigned long \
paravirt_ ## op (void) \
{ \
PARAVIRT_BR0_RET(op, type); \
return ia64_intri_res; \
}
#define PARAVIRT_DEFINE_CPU_OP1_VOID(op, type) \
static inline void \
paravirt_ ## op (void *arg1) \
{ \
PARAVIRT_BR1_VOID(op, type, arg1); \
}
#define PARAVIRT_DEFINE_CPU_OP1(op, type) \
static inline void \
paravirt_ ## op (unsigned long arg1) \
{ \
PARAVIRT_BR1(op, type, arg1); \
}
#define PARAVIRT_DEFINE_CPU_OP1_RET(op, type) \
static inline unsigned long \
paravirt_ ## op (unsigned long arg1) \
{ \
PARAVIRT_BR1_RET(op, type, arg1); \
return ia64_intri_res; \
}
#define PARAVIRT_DEFINE_CPU_OP2(op, type) \
static inline void \
paravirt_ ## op (unsigned long arg1, \
unsigned long arg2) \
{ \
PARAVIRT_BR2(op, type, arg1, arg2); \
}
PARAVIRT_DEFINE_CPU_OP1_VOID(fc, FC);
PARAVIRT_DEFINE_CPU_OP1_RET(thash, THASH)
PARAVIRT_DEFINE_CPU_OP1_RET(get_cpuid, GET_CPUID)
PARAVIRT_DEFINE_CPU_OP1_RET(get_pmd, GET_PMD)
PARAVIRT_DEFINE_CPU_OP2(ptcga, PTCGA)
PARAVIRT_DEFINE_CPU_OP1_RET(get_rr, GET_RR)
PARAVIRT_DEFINE_CPU_OP2(set_rr, SET_RR)
PARAVIRT_DEFINE_CPU_OP0(ssm_i, SSM_I)
PARAVIRT_DEFINE_CPU_OP0(rsm_i, RSM_I)
PARAVIRT_DEFINE_CPU_OP0_RET(get_psr_i, GET_PSR_I)
PARAVIRT_DEFINE_CPU_OP1(intrin_local_irq_restore, INTRIN_LOCAL_IRQ_RESTORE)
static inline void
paravirt_set_rr0_to_rr4(unsigned long val0, unsigned long val1,
unsigned long val2, unsigned long val3,
unsigned long val4)
{
register unsigned long __val0 asm ("r8") = val0;
register unsigned long __val1 asm ("r9") = val1;
register unsigned long __val2 asm ("r10") = val2;
register unsigned long __val3 asm ("r11") = val3;
register unsigned long __val4 asm ("r14") = val4;
register unsigned long ia64_clobber0 asm ("r8");
register unsigned long ia64_clobber1 asm ("r9");
register unsigned long ia64_clobber2 asm ("r10");
register unsigned long ia64_clobber3 asm ("r11");
register unsigned long ia64_clobber4 asm ("r14");
asm volatile (paravirt_alt_bundle(__PARAVIRT_BR,
PARAVIRT_TYPE(SET_RR0_TO_RR4))
: "=r"(ia64_clobber0),
"=r"(ia64_clobber1),
"=r"(ia64_clobber2),
"=r"(ia64_clobber3),
"=r"(ia64_clobber4)
: PARAVIRT_OP(set_rr0_to_rr4),
"0"(__val0), "1"(__val1), "2"(__val2),
"3"(__val3), "4"(__val4)
: PARAVIRT_CLOBBERS5);
}
/* unsigned long paravirt_getreg(int reg) */
#define __paravirt_getreg(reg) \
({ \
register unsigned long ia64_intri_res asm ("r8"); \
register unsigned long __reg asm ("r8") = (reg); \
\
BUILD_BUG_ON(!__builtin_constant_p(reg)); \
asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \
PARAVIRT_TYPE(GETREG) \
+ (reg)) \
: "=r"(ia64_intri_res) \
: PARAVIRT_OP(getreg), "0"(__reg) \
: PARAVIRT_CLOBBERS1); \
\
ia64_intri_res; \
})
/* void paravirt_setreg(int reg, unsigned long val) */
#define paravirt_setreg(reg, val) \
do { \
register unsigned long __val asm ("r8") = val; \
register unsigned long __reg asm ("r9") = reg; \
register unsigned long ia64_clobber1 asm ("r8"); \
register unsigned long ia64_clobber2 asm ("r9"); \
\
BUILD_BUG_ON(!__builtin_constant_p(reg)); \
asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \
PARAVIRT_TYPE(SETREG) \
+ (reg)) \
: "=r"(ia64_clobber1), \
"=r"(ia64_clobber2) \
: PARAVIRT_OP(setreg), \
"1"(__reg), "0"(__val) \
: PARAVIRT_CLOBBERS2); \
} while (0)
#endif /* ASM_SUPPORTED */
#endif /* CONFIG_PARAVIRT && ASM_SUPPOTED */
#endif /* _ASM_IA64_PARAVIRT_PRIVOP_H */ #endif /* _ASM_IA64_PARAVIRT_PRIVOP_H */

View File

@ -126,7 +126,8 @@ extern void identify_siblings (struct cpuinfo_ia64 *);
extern int is_multithreading_enabled(void); extern int is_multithreading_enabled(void);
extern void arch_send_call_function_single_ipi(int cpu); extern void arch_send_call_function_single_ipi(int cpu);
extern void arch_send_call_function_ipi(cpumask_t mask); extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask
#else /* CONFIG_SMP */ #else /* CONFIG_SMP */

View File

@ -40,5 +40,6 @@ get_cycles (void)
} }
extern void ia64_cpu_local_tick (void); extern void ia64_cpu_local_tick (void);
extern unsigned long long ia64_native_sched_clock (void);
#endif /* _ASM_IA64_TIMEX_H */ #endif /* _ASM_IA64_TIMEX_H */

View File

@ -43,11 +43,6 @@
*/ */
#define parent_node(nid) (nid) #define parent_node(nid) (nid)
/*
* Returns the number of the first CPU on Node 'node'.
*/
#define node_to_first_cpu(node) (cpumask_first(cpumask_of_node(node)))
/* /*
* Determines the node for a given pci bus * Determines the node for a given pci bus
*/ */
@ -117,11 +112,6 @@ void build_cpu_to_node_map(void);
extern void arch_fix_phys_package_id(int num, u32 slot); extern void arch_fix_phys_package_id(int num, u32 slot);
#define pcibus_to_cpumask(bus) (pcibus_to_node(bus) == -1 ? \
CPU_MASK_ALL : \
node_to_cpumask(pcibus_to_node(bus)) \
)
#define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \ #define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \
cpu_all_mask : \ cpu_all_mask : \
cpumask_of_node(pcibus_to_node(bus))) cpumask_of_node(pcibus_to_node(bus)))

View File

@ -33,9 +33,6 @@
#ifndef _ASM_IA64_XEN_HYPERVISOR_H #ifndef _ASM_IA64_XEN_HYPERVISOR_H
#define _ASM_IA64_XEN_HYPERVISOR_H #define _ASM_IA64_XEN_HYPERVISOR_H
#ifdef CONFIG_XEN
#include <linux/init.h>
#include <xen/interface/xen.h> #include <xen/interface/xen.h>
#include <xen/interface/version.h> /* to compile feature.c */ #include <xen/interface/version.h> /* to compile feature.c */
#include <xen/features.h> /* to comiple xen-netfront.c */ #include <xen/features.h> /* to comiple xen-netfront.c */
@ -43,22 +40,32 @@
/* xen_domain_type is set before executing any C code by early_xen_setup */ /* xen_domain_type is set before executing any C code by early_xen_setup */
enum xen_domain_type { enum xen_domain_type {
XEN_NATIVE, XEN_NATIVE, /* running on bare hardware */
XEN_PV_DOMAIN, XEN_PV_DOMAIN, /* running in a PV domain */
XEN_HVM_DOMAIN, XEN_HVM_DOMAIN, /* running in a Xen hvm domain*/
}; };
#ifdef CONFIG_XEN
extern enum xen_domain_type xen_domain_type; extern enum xen_domain_type xen_domain_type;
#else
#define xen_domain_type XEN_NATIVE
#endif
#define xen_domain() (xen_domain_type != XEN_NATIVE) #define xen_domain() (xen_domain_type != XEN_NATIVE)
#define xen_pv_domain() (xen_domain_type == XEN_PV_DOMAIN) #define xen_pv_domain() (xen_domain() && \
#define xen_initial_domain() (xen_pv_domain() && \ xen_domain_type == XEN_PV_DOMAIN)
#define xen_hvm_domain() (xen_domain() && \
xen_domain_type == XEN_HVM_DOMAIN)
#ifdef CONFIG_XEN_DOM0
#define xen_initial_domain() (xen_pv_domain() && \
(xen_start_info->flags & SIF_INITDOMAIN)) (xen_start_info->flags & SIF_INITDOMAIN))
#define xen_hvm_domain() (xen_domain_type == XEN_HVM_DOMAIN) #else
#define xen_initial_domain() (0)
#endif
/* deprecated. remove this */
#define is_running_on_xen() (xen_domain_type == XEN_PV_DOMAIN)
#ifdef CONFIG_XEN
extern struct shared_info *HYPERVISOR_shared_info; extern struct shared_info *HYPERVISOR_shared_info;
extern struct start_info *xen_start_info; extern struct start_info *xen_start_info;
@ -74,16 +81,6 @@ void force_evtchn_callback(void);
/* For setup_arch() in arch/ia64/kernel/setup.c */ /* For setup_arch() in arch/ia64/kernel/setup.c */
void xen_ia64_enable_opt_feature(void); void xen_ia64_enable_opt_feature(void);
#else /* CONFIG_XEN */
#define xen_domain() (0)
#define xen_pv_domain() (0)
#define xen_initial_domain() (0)
#define xen_hvm_domain() (0)
#define is_running_on_xen() (0) /* deprecated. remove this */
#endif #endif
#define is_initial_xendomain() (0) /* deprecated. remove this */
#endif /* _ASM_IA64_XEN_HYPERVISOR_H */ #endif /* _ASM_IA64_XEN_HYPERVISOR_H */

View File

@ -33,6 +33,9 @@
#define __paravirt_work_processed_syscall_target \ #define __paravirt_work_processed_syscall_target \
xen_work_processed_syscall xen_work_processed_syscall
#define paravirt_fsyscall_table xen_fsyscall_table
#define paravirt_fsys_bubble_down xen_fsys_bubble_down
#define MOV_FROM_IFA(reg) \ #define MOV_FROM_IFA(reg) \
movl reg = XSI_IFA; \ movl reg = XSI_IFA; \
;; \ ;; \
@ -110,6 +113,27 @@
.endm .endm
#define MOV_FROM_PSR(pred, reg, clob) __MOV_FROM_PSR pred, reg, clob #define MOV_FROM_PSR(pred, reg, clob) __MOV_FROM_PSR pred, reg, clob
/* assuming ar.itc is read with interrupt disabled. */
#define MOV_FROM_ITC(pred, pred_clob, reg, clob) \
(pred) movl clob = XSI_ITC_OFFSET; \
;; \
(pred) ld8 clob = [clob]; \
(pred) mov reg = ar.itc; \
;; \
(pred) add reg = reg, clob; \
;; \
(pred) movl clob = XSI_ITC_LAST; \
;; \
(pred) ld8 clob = [clob]; \
;; \
(pred) cmp.geu.unc pred_clob, p0 = clob, reg; \
;; \
(pred_clob) add reg = 1, clob; \
;; \
(pred) movl clob = XSI_ITC_LAST; \
;; \
(pred) st8 [clob] = reg
#define MOV_TO_IFA(reg, clob) \ #define MOV_TO_IFA(reg, clob) \
movl clob = XSI_IFA; \ movl clob = XSI_IFA; \
@ -362,6 +386,10 @@
#define RSM_PSR_DT \ #define RSM_PSR_DT \
XEN_HYPER_RSM_PSR_DT XEN_HYPER_RSM_PSR_DT
#define RSM_PSR_BE_I(clob0, clob1) \
RSM_PSR_I(p0, clob0, clob1); \
rum psr.be
#define SSM_PSR_DT_AND_SRLZ_I \ #define SSM_PSR_DT_AND_SRLZ_I \
XEN_HYPER_SSM_PSR_DT XEN_HYPER_SSM_PSR_DT

View File

@ -209,6 +209,15 @@ struct mapped_regs {
unsigned long krs[8]; /* kernel registers */ unsigned long krs[8]; /* kernel registers */
unsigned long tmp[16]; /* temp registers unsigned long tmp[16]; /* temp registers
(e.g. for hyperprivops) */ (e.g. for hyperprivops) */
/* itc paravirtualization
* vAR.ITC = mAR.ITC + itc_offset
* itc_last is one which was lastly passed to
* the guest OS in order to prevent it from
* going backwords.
*/
unsigned long itc_offset;
unsigned long itc_last;
}; };
}; };
}; };

View File

@ -1,3 +1,12 @@
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
/* read ar.itc in advance, and use it before leaving bank 0 */
#define XEN_ACCOUNT_GET_STAMP \
MOV_FROM_ITC(pUStk, p6, r20, r2);
#else
#define XEN_ACCOUNT_GET_STAMP
#endif
/* /*
* DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves * DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves
* the minimum state necessary that allows us to turn psr.ic back * the minimum state necessary that allows us to turn psr.ic back
@ -123,7 +132,7 @@
;; \ ;; \
.mem.offset 0,0; st8.spill [r16]=r2,16; \ .mem.offset 0,0; st8.spill [r16]=r2,16; \
.mem.offset 8,0; st8.spill [r17]=r3,16; \ .mem.offset 8,0; st8.spill [r17]=r3,16; \
ACCOUNT_GET_STAMP \ XEN_ACCOUNT_GET_STAMP \
adds r2=IA64_PT_REGS_R16_OFFSET,r1; \ adds r2=IA64_PT_REGS_R16_OFFSET,r1; \
;; \ ;; \
EXTRA; \ EXTRA; \

View File

@ -0,0 +1,38 @@
/******************************************************************************
* arch/ia64/include/asm/xen/patchlist.h
*
* Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#define __paravirt_start_gate_fsyscall_patchlist \
__xen_start_gate_fsyscall_patchlist
#define __paravirt_end_gate_fsyscall_patchlist \
__xen_end_gate_fsyscall_patchlist
#define __paravirt_start_gate_brl_fsys_bubble_down_patchlist \
__xen_start_gate_brl_fsys_bubble_down_patchlist
#define __paravirt_end_gate_brl_fsys_bubble_down_patchlist \
__xen_end_gate_brl_fsys_bubble_down_patchlist
#define __paravirt_start_gate_vtop_patchlist \
__xen_start_gate_vtop_patchlist
#define __paravirt_end_gate_vtop_patchlist \
__xen_end_gate_vtop_patchlist
#define __paravirt_start_gate_mckinley_e9_patchlist \
__xen_start_gate_mckinley_e9_patchlist
#define __paravirt_end_gate_mckinley_e9_patchlist \
__xen_end_gate_mckinley_e9_patchlist

View File

@ -55,6 +55,8 @@
#define XSI_BANK1_R16 (XSI_BASE + XSI_BANK1_R16_OFS) #define XSI_BANK1_R16 (XSI_BASE + XSI_BANK1_R16_OFS)
#define XSI_BANKNUM (XSI_BASE + XSI_BANKNUM_OFS) #define XSI_BANKNUM (XSI_BASE + XSI_BANKNUM_OFS)
#define XSI_IHA (XSI_BASE + XSI_IHA_OFS) #define XSI_IHA (XSI_BASE + XSI_IHA_OFS)
#define XSI_ITC_OFFSET (XSI_BASE + XSI_ITC_OFFSET_OFS)
#define XSI_ITC_LAST (XSI_BASE + XSI_ITC_LAST_OFS)
#endif #endif
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
@ -67,7 +69,7 @@
* may have different semantics depending on whether they are executed * may have different semantics depending on whether they are executed
* at PL0 vs PL!=0. When paravirtualized, these instructions mustn't * at PL0 vs PL!=0. When paravirtualized, these instructions mustn't
* be allowed to execute directly, lest incorrect semantics result. */ * be allowed to execute directly, lest incorrect semantics result. */
extern void xen_fc(unsigned long addr); extern void xen_fc(void *addr);
extern unsigned long xen_thash(unsigned long addr); extern unsigned long xen_thash(unsigned long addr);
/* Note that "ttag" and "cover" are also privilege-sensitive; "ttag" /* Note that "ttag" and "cover" are also privilege-sensitive; "ttag"
@ -80,8 +82,10 @@ extern unsigned long xen_thash(unsigned long addr);
extern unsigned long xen_get_cpuid(int index); extern unsigned long xen_get_cpuid(int index);
extern unsigned long xen_get_pmd(int index); extern unsigned long xen_get_pmd(int index);
#ifndef ASM_SUPPORTED
extern unsigned long xen_get_eflag(void); /* see xen_ia64_getreg */ extern unsigned long xen_get_eflag(void); /* see xen_ia64_getreg */
extern void xen_set_eflag(unsigned long); /* see xen_ia64_setreg */ extern void xen_set_eflag(unsigned long); /* see xen_ia64_setreg */
#endif
/************************************************/ /************************************************/
/* Instructions paravirtualized for performance */ /* Instructions paravirtualized for performance */
@ -106,6 +110,7 @@ extern void xen_set_eflag(unsigned long); /* see xen_ia64_setreg */
#define xen_get_virtual_pend() \ #define xen_get_virtual_pend() \
(*(((uint8_t *)XEN_MAPPEDREGS->interrupt_mask_addr) - 1)) (*(((uint8_t *)XEN_MAPPEDREGS->interrupt_mask_addr) - 1))
#ifndef ASM_SUPPORTED
/* Although all privileged operations can be left to trap and will /* Although all privileged operations can be left to trap and will
* be properly handled by Xen, some are frequent enough that we use * be properly handled by Xen, some are frequent enough that we use
* hyperprivops for performance. */ * hyperprivops for performance. */
@ -123,6 +128,7 @@ extern void xen_set_rr0_to_rr4(unsigned long val0, unsigned long val1,
unsigned long val4); unsigned long val4);
extern void xen_set_kr(unsigned long index, unsigned long val); extern void xen_set_kr(unsigned long index, unsigned long val);
extern void xen_ptcga(unsigned long addr, unsigned long size); extern void xen_ptcga(unsigned long addr, unsigned long size);
#endif /* !ASM_SUPPORTED */
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */

View File

@ -5,7 +5,7 @@
extra-y := head.o init_task.o vmlinux.lds extra-y := head.o init_task.o vmlinux.lds
obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \ obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \
irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \ irq_lsapic.o ivt.o machvec.o pal.o paravirt_patchlist.o patch.o process.o perfmon.o ptrace.o sal.o \
salinfo.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \ salinfo.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \
unwind.o mca.o mca_asm.o topology.o dma-mapping.o unwind.o mca.o mca_asm.o topology.o dma-mapping.o
@ -36,7 +36,8 @@ obj-$(CONFIG_PCI_MSI) += msi_ia64.o
mca_recovery-y += mca_drv.o mca_drv_asm.o mca_recovery-y += mca_drv.o mca_drv_asm.o
obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o
obj-$(CONFIG_PARAVIRT) += paravirt.o paravirtentry.o obj-$(CONFIG_PARAVIRT) += paravirt.o paravirtentry.o \
paravirt_patch.o
obj-$(CONFIG_IA64_ESI) += esi.o obj-$(CONFIG_IA64_ESI) += esi.o
ifneq ($(CONFIG_IA64_ESI),) ifneq ($(CONFIG_IA64_ESI),)
@ -45,35 +46,13 @@ endif
obj-$(CONFIG_DMAR) += pci-dma.o obj-$(CONFIG_DMAR) += pci-dma.o
obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o
# The gate DSO image is built using a special linker script.
targets += gate.so gate-syms.o
extra-y += gate.so gate-syms.o gate.lds gate.o
# fp_emulate() expects f2-f5,f16-f31 to contain the user-level state. # fp_emulate() expects f2-f5,f16-f31 to contain the user-level state.
CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31 CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31
CPPFLAGS_gate.lds := -P -C -U$(ARCH) # The gate DSO image is built using a special linker script.
include $(srctree)/arch/ia64/kernel/Makefile.gate
quiet_cmd_gate = GATE $@ # tell compiled for native
cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@ CPPFLAGS_gate.lds += -D__IA64_GATE_PARAVIRTUALIZED_NATIVE
GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \
$(call ld-option, -Wl$(comma)--hash-style=sysv)
$(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE
$(call if_changed,gate)
$(obj)/built-in.o: $(obj)/gate-syms.o
$(obj)/built-in.o: ld_flags += -R $(obj)/gate-syms.o
GATECFLAGS_gate-syms.o = -r
$(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE
$(call if_changed,gate)
# gate-data.o contains the gate DSO image as data in section .data.gate.
# We must build gate.so before we can assemble it.
# Note: kbuild does not track this dependency due to usage of .incbin
$(obj)/gate-data.o: $(obj)/gate.so
# Calculate NR_IRQ = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...) based on config # Calculate NR_IRQ = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...) based on config
define sed-y define sed-y
@ -109,9 +88,9 @@ include/asm-ia64/nr-irqs.h: arch/$(SRCARCH)/kernel/nr-irqs.s
clean-files += $(objtree)/include/asm-ia64/nr-irqs.h clean-files += $(objtree)/include/asm-ia64/nr-irqs.h
# #
# native ivt.S and entry.S # native ivt.S, entry.S and fsys.S
# #
ASM_PARAVIRT_OBJS = ivt.o entry.o ASM_PARAVIRT_OBJS = ivt.o entry.o fsys.o
define paravirtualized_native define paravirtualized_native
AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_NATIVE AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_NATIVE
AFLAGS_pvchk-sed-$(1) += -D__IA64_ASM_PARAVIRTUALIZED_PVCHECK AFLAGS_pvchk-sed-$(1) += -D__IA64_ASM_PARAVIRTUALIZED_PVCHECK

View File

@ -0,0 +1,27 @@
# The gate DSO image is built using a special linker script.
targets += gate.so gate-syms.o
extra-y += gate.so gate-syms.o gate.lds gate.o
CPPFLAGS_gate.lds := -P -C -U$(ARCH)
quiet_cmd_gate = GATE $@
cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@
GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \
$(call ld-option, -Wl$(comma)--hash-style=sysv)
$(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE
$(call if_changed,gate)
$(obj)/built-in.o: $(obj)/gate-syms.o
$(obj)/built-in.o: ld_flags += -R $(obj)/gate-syms.o
GATECFLAGS_gate-syms.o = -r
$(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE
$(call if_changed,gate)
# gate-data.o contains the gate DSO image as data in section .data.gate.
# We must build gate.so before we can assemble it.
# Note: kbuild does not track this dependency due to usage of .incbin
$(obj)/gate-data.o: $(obj)/gate.so

View File

@ -890,7 +890,7 @@ __init void prefill_possible_map(void)
possible, max((possible - available_cpus), 0)); possible, max((possible - available_cpus), 0));
for (i = 0; i < possible; i++) for (i = 0; i < possible; i++)
cpu_set(i, cpu_possible_map); set_cpu_possible(i, true);
} }
int acpi_map_lsapic(acpi_handle handle, int *pcpu) int acpi_map_lsapic(acpi_handle handle, int *pcpu)
@ -928,9 +928,9 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu)
buffer.length = ACPI_ALLOCATE_BUFFER; buffer.length = ACPI_ALLOCATE_BUFFER;
buffer.pointer = NULL; buffer.pointer = NULL;
cpus_complement(tmp_map, cpu_present_map); cpumask_complement(&tmp_map, cpu_present_mask);
cpu = first_cpu(tmp_map); cpu = cpumask_first(&tmp_map);
if (cpu >= NR_CPUS) if (cpu >= nr_cpu_ids)
return -EINVAL; return -EINVAL;
acpi_map_cpu2node(handle, cpu, physid); acpi_map_cpu2node(handle, cpu, physid);

View File

@ -316,5 +316,7 @@ void foo(void)
DEFINE_MAPPED_REG_OFS(XSI_BANK1_R16_OFS, bank1_regs[0]); DEFINE_MAPPED_REG_OFS(XSI_BANK1_R16_OFS, bank1_regs[0]);
DEFINE_MAPPED_REG_OFS(XSI_B0NATS_OFS, vbnat); DEFINE_MAPPED_REG_OFS(XSI_B0NATS_OFS, vbnat);
DEFINE_MAPPED_REG_OFS(XSI_B1NATS_OFS, vnat); DEFINE_MAPPED_REG_OFS(XSI_B1NATS_OFS, vnat);
DEFINE_MAPPED_REG_OFS(XSI_ITC_OFFSET_OFS, itc_offset);
DEFINE_MAPPED_REG_OFS(XSI_ITC_LAST_OFS, itc_last);
#endif /* CONFIG_XEN */ #endif /* CONFIG_XEN */
} }

View File

@ -456,6 +456,7 @@ efi_map_pal_code (void)
GRANULEROUNDDOWN((unsigned long) pal_vaddr), GRANULEROUNDDOWN((unsigned long) pal_vaddr),
pte_val(pfn_pte(__pa(pal_vaddr) >> PAGE_SHIFT, PAGE_KERNEL)), pte_val(pfn_pte(__pa(pal_vaddr) >> PAGE_SHIFT, PAGE_KERNEL)),
IA64_GRANULE_SHIFT); IA64_GRANULE_SHIFT);
paravirt_dv_serialize_data();
ia64_set_psr(psr); /* restore psr */ ia64_set_psr(psr); /* restore psr */
} }

View File

@ -735,7 +735,7 @@ GLOBAL_ENTRY(__paravirt_leave_syscall)
__paravirt_work_processed_syscall: __paravirt_work_processed_syscall:
#ifdef CONFIG_VIRT_CPU_ACCOUNTING #ifdef CONFIG_VIRT_CPU_ACCOUNTING
adds r2=PT(LOADRS)+16,r12 adds r2=PT(LOADRS)+16,r12
(pUStk) mov.m r22=ar.itc // fetch time at leave MOV_FROM_ITC(pUStk, p9, r22, r19) // fetch time at leave
adds r18=TI_FLAGS+IA64_TASK_SIZE,r13 adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
;; ;;
(p6) ld4 r31=[r18] // load current_thread_info()->flags (p6) ld4 r31=[r18] // load current_thread_info()->flags
@ -984,7 +984,7 @@ GLOBAL_ENTRY(__paravirt_leave_kernel)
#ifdef CONFIG_VIRT_CPU_ACCOUNTING #ifdef CONFIG_VIRT_CPU_ACCOUNTING
.pred.rel.mutex pUStk,pKStk .pred.rel.mutex pUStk,pKStk
MOV_FROM_PSR(pKStk, r22, r29) // M2 read PSR now that interrupts are disabled MOV_FROM_PSR(pKStk, r22, r29) // M2 read PSR now that interrupts are disabled
(pUStk) mov.m r22=ar.itc // M fetch time at leave MOV_FROM_ITC(pUStk, p9, r22, r29) // M fetch time at leave
nop.i 0 nop.i 0
;; ;;
#else #else

View File

@ -25,6 +25,7 @@
#include <asm/unistd.h> #include <asm/unistd.h>
#include "entry.h" #include "entry.h"
#include "paravirt_inst.h"
/* /*
* See Documentation/ia64/fsys.txt for details on fsyscalls. * See Documentation/ia64/fsys.txt for details on fsyscalls.
@ -279,7 +280,7 @@ ENTRY(fsys_gettimeofday)
(p9) cmp.eq p13,p0 = 0,r30 // if mmio_ptr, clear p13 jitter control (p9) cmp.eq p13,p0 = 0,r30 // if mmio_ptr, clear p13 jitter control
;; ;;
.pred.rel.mutex p8,p9 .pred.rel.mutex p8,p9
(p8) mov r2 = ar.itc // CPU_TIMER. 36 clocks latency!!! MOV_FROM_ITC(p8, p6, r2, r10) // CPU_TIMER. 36 clocks latency!!!
(p9) ld8 r2 = [r30] // MMIO_TIMER. Could also have latency issues.. (p9) ld8 r2 = [r30] // MMIO_TIMER. Could also have latency issues..
(p13) ld8 r25 = [r19] // get itc_lastcycle value (p13) ld8 r25 = [r19] // get itc_lastcycle value
ld8 r9 = [r22],IA64_TIMESPEC_TV_NSEC_OFFSET // tv_sec ld8 r9 = [r22],IA64_TIMESPEC_TV_NSEC_OFFSET // tv_sec
@ -418,7 +419,7 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set
mov r17=(1 << (SIGKILL - 1)) | (1 << (SIGSTOP - 1)) mov r17=(1 << (SIGKILL - 1)) | (1 << (SIGSTOP - 1))
;; ;;
rsm psr.i // mask interrupt delivery RSM_PSR_I(p0, r18, r19) // mask interrupt delivery
mov ar.ccv=0 mov ar.ccv=0
andcm r14=r14,r17 // filter out SIGKILL & SIGSTOP andcm r14=r14,r17 // filter out SIGKILL & SIGSTOP
@ -491,7 +492,7 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
st4.rel [r31]=r0 // release the lock st4.rel [r31]=r0 // release the lock
#endif #endif
ssm psr.i SSM_PSR_I(p0, p9, r31)
;; ;;
srlz.d // ensure psr.i is set again srlz.d // ensure psr.i is set again
@ -513,7 +514,7 @@ EX(.fail_efault, (p15) st8 [r34]=r3)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
st4.rel [r31]=r0 // release the lock st4.rel [r31]=r0 // release the lock
#endif #endif
ssm psr.i SSM_PSR_I(p0, p9, r17)
;; ;;
srlz.d srlz.d
br.sptk.many fsys_fallback_syscall // with signal pending, do the heavy-weight syscall br.sptk.many fsys_fallback_syscall // with signal pending, do the heavy-weight syscall
@ -521,7 +522,7 @@ EX(.fail_efault, (p15) st8 [r34]=r3)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
.lock_contention: .lock_contention:
/* Rather than spinning here, fall back on doing a heavy-weight syscall. */ /* Rather than spinning here, fall back on doing a heavy-weight syscall. */
ssm psr.i SSM_PSR_I(p0, p9, r17)
;; ;;
srlz.d srlz.d
br.sptk.many fsys_fallback_syscall br.sptk.many fsys_fallback_syscall
@ -592,17 +593,17 @@ ENTRY(fsys_fallback_syscall)
adds r17=-1024,r15 adds r17=-1024,r15
movl r14=sys_call_table movl r14=sys_call_table
;; ;;
rsm psr.i RSM_PSR_I(p0, r26, r27)
shladd r18=r17,3,r14 shladd r18=r17,3,r14
;; ;;
ld8 r18=[r18] // load normal (heavy-weight) syscall entry-point ld8 r18=[r18] // load normal (heavy-weight) syscall entry-point
mov r29=psr // read psr (12 cyc load latency) MOV_FROM_PSR(p0, r29, r26) // read psr (12 cyc load latency)
mov r27=ar.rsc mov r27=ar.rsc
mov r21=ar.fpsr mov r21=ar.fpsr
mov r26=ar.pfs mov r26=ar.pfs
END(fsys_fallback_syscall) END(fsys_fallback_syscall)
/* FALL THROUGH */ /* FALL THROUGH */
GLOBAL_ENTRY(fsys_bubble_down) GLOBAL_ENTRY(paravirt_fsys_bubble_down)
.prologue .prologue
.altrp b6 .altrp b6
.body .body
@ -640,7 +641,7 @@ GLOBAL_ENTRY(fsys_bubble_down)
* *
* PSR.BE : already is turned off in __kernel_syscall_via_epc() * PSR.BE : already is turned off in __kernel_syscall_via_epc()
* PSR.AC : don't care (kernel normally turns PSR.AC on) * PSR.AC : don't care (kernel normally turns PSR.AC on)
* PSR.I : already turned off by the time fsys_bubble_down gets * PSR.I : already turned off by the time paravirt_fsys_bubble_down gets
* invoked * invoked
* PSR.DFL: always 0 (kernel never turns it on) * PSR.DFL: always 0 (kernel never turns it on)
* PSR.DFH: don't care --- kernel never touches f32-f127 on its own * PSR.DFH: don't care --- kernel never touches f32-f127 on its own
@ -650,7 +651,7 @@ GLOBAL_ENTRY(fsys_bubble_down)
* PSR.DB : don't care --- kernel never enables kernel-level * PSR.DB : don't care --- kernel never enables kernel-level
* breakpoints * breakpoints
* PSR.TB : must be 0 already; if it wasn't zero on entry to * PSR.TB : must be 0 already; if it wasn't zero on entry to
* __kernel_syscall_via_epc, the branch to fsys_bubble_down * __kernel_syscall_via_epc, the branch to paravirt_fsys_bubble_down
* will trigger a taken branch; the taken-trap-handler then * will trigger a taken branch; the taken-trap-handler then
* converts the syscall into a break-based system-call. * converts the syscall into a break-based system-call.
*/ */
@ -683,7 +684,7 @@ GLOBAL_ENTRY(fsys_bubble_down)
;; ;;
mov ar.rsc=0 // M2 set enforced lazy mode, pl 0, LE, loadrs=0 mov ar.rsc=0 // M2 set enforced lazy mode, pl 0, LE, loadrs=0
#ifdef CONFIG_VIRT_CPU_ACCOUNTING #ifdef CONFIG_VIRT_CPU_ACCOUNTING
mov.m r30=ar.itc // M get cycle for accounting MOV_FROM_ITC(p0, p6, r30, r23) // M get cycle for accounting
#else #else
nop.m 0 nop.m 0
#endif #endif
@ -734,21 +735,21 @@ GLOBAL_ENTRY(fsys_bubble_down)
mov rp=r14 // I0 set the real return addr mov rp=r14 // I0 set the real return addr
and r3=_TIF_SYSCALL_TRACEAUDIT,r3 // A and r3=_TIF_SYSCALL_TRACEAUDIT,r3 // A
;; ;;
ssm psr.i // M2 we're on kernel stacks now, reenable irqs SSM_PSR_I(p0, p6, r22) // M2 we're on kernel stacks now, reenable irqs
cmp.eq p8,p0=r3,r0 // A cmp.eq p8,p0=r3,r0 // A
(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT (p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT
nop.m 0 nop.m 0
(p8) br.call.sptk.many b6=b6 // B (ignore return address) (p8) br.call.sptk.many b6=b6 // B (ignore return address)
br.cond.spnt ia64_trace_syscall // B br.cond.spnt ia64_trace_syscall // B
END(fsys_bubble_down) END(paravirt_fsys_bubble_down)
.rodata .rodata
.align 8 .align 8
.globl fsyscall_table .globl paravirt_fsyscall_table
data8 fsys_bubble_down data8 paravirt_fsys_bubble_down
fsyscall_table: paravirt_fsyscall_table:
data8 fsys_ni_syscall data8 fsys_ni_syscall
data8 0 // exit // 1025 data8 0 // exit // 1025
data8 0 // read data8 0 // read
@ -1033,4 +1034,4 @@ fsyscall_table:
// fill in zeros for the remaining entries // fill in zeros for the remaining entries
.zero: .zero:
.space fsyscall_table + 8*NR_syscalls - .zero, 0 .space paravirt_fsyscall_table + 8*NR_syscalls - .zero, 0

View File

@ -13,6 +13,7 @@
#include <asm/sigcontext.h> #include <asm/sigcontext.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/unistd.h> #include <asm/unistd.h>
#include "paravirt_inst.h"
/* /*
* We can't easily refer to symbols inside the kernel. To avoid full runtime relocation, * We can't easily refer to symbols inside the kernel. To avoid full runtime relocation,
@ -48,87 +49,6 @@ GLOBAL_ENTRY(__kernel_syscall_via_break)
} }
END(__kernel_syscall_via_break) END(__kernel_syscall_via_break)
/*
* On entry:
* r11 = saved ar.pfs
* r15 = system call #
* b0 = saved return address
* b6 = return address
* On exit:
* r11 = saved ar.pfs
* r15 = system call #
* b0 = saved return address
* all other "scratch" registers: undefined
* all "preserved" registers: same as on entry
*/
GLOBAL_ENTRY(__kernel_syscall_via_epc)
.prologue
.altrp b6
.body
{
/*
* Note: the kernel cannot assume that the first two instructions in this
* bundle get executed. The remaining code must be safe even if
* they do not get executed.
*/
adds r17=-1024,r15 // A
mov r10=0 // A default to successful syscall execution
epc // B causes split-issue
}
;;
rsm psr.be | psr.i // M2 (5 cyc to srlz.d)
LOAD_FSYSCALL_TABLE(r14) // X
;;
mov r16=IA64_KR(CURRENT) // M2 (12 cyc)
shladd r18=r17,3,r14 // A
mov r19=NR_syscalls-1 // A
;;
lfetch [r18] // M0|1
mov r29=psr // M2 (12 cyc)
// If r17 is a NaT, p6 will be zero
cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)?
;;
mov r21=ar.fpsr // M2 (12 cyc)
tnat.nz p10,p9=r15 // I0
mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...)
;;
srlz.d // M0 (forces split-issue) ensure PSR.BE==0
(p6) ld8 r18=[r18] // M0|1
nop.i 0
;;
nop.m 0
(p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!)
nop.i 0
;;
(p8) ssm psr.i
(p6) mov b7=r18 // I0
(p8) br.dptk.many b7 // B
mov r27=ar.rsc // M2 (12 cyc)
/*
* brl.cond doesn't work as intended because the linker would convert this branch
* into a branch to a PLT. Perhaps there will be a way to avoid this with some
* future version of the linker. In the meantime, we just use an indirect branch
* instead.
*/
#ifdef CONFIG_ITANIUM
(p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry
;;
(p6) ld8 r14=[r14] // r14 <- fsys_bubble_down
;;
(p6) mov b7=r14
(p6) br.sptk.many b7
#else
BRL_COND_FSYS_BUBBLE_DOWN(p6)
#endif
ssm psr.i
mov r10=-1
(p10) mov r8=EINVAL
(p9) mov r8=ENOSYS
FSYS_RETURN
END(__kernel_syscall_via_epc)
# define ARG0_OFF (16 + IA64_SIGFRAME_ARG0_OFFSET) # define ARG0_OFF (16 + IA64_SIGFRAME_ARG0_OFFSET)
# define ARG1_OFF (16 + IA64_SIGFRAME_ARG1_OFFSET) # define ARG1_OFF (16 + IA64_SIGFRAME_ARG1_OFFSET)
# define ARG2_OFF (16 + IA64_SIGFRAME_ARG2_OFFSET) # define ARG2_OFF (16 + IA64_SIGFRAME_ARG2_OFFSET)
@ -374,3 +294,92 @@ restore_rbs:
// invala not necessary as that will happen when returning to user-mode // invala not necessary as that will happen when returning to user-mode
br.cond.sptk back_from_restore_rbs br.cond.sptk back_from_restore_rbs
END(__kernel_sigtramp) END(__kernel_sigtramp)
/*
* On entry:
* r11 = saved ar.pfs
* r15 = system call #
* b0 = saved return address
* b6 = return address
* On exit:
* r11 = saved ar.pfs
* r15 = system call #
* b0 = saved return address
* all other "scratch" registers: undefined
* all "preserved" registers: same as on entry
*/
GLOBAL_ENTRY(__kernel_syscall_via_epc)
.prologue
.altrp b6
.body
{
/*
* Note: the kernel cannot assume that the first two instructions in this
* bundle get executed. The remaining code must be safe even if
* they do not get executed.
*/
adds r17=-1024,r15 // A
mov r10=0 // A default to successful syscall execution
epc // B causes split-issue
}
;;
RSM_PSR_BE_I(r20, r22) // M2 (5 cyc to srlz.d)
LOAD_FSYSCALL_TABLE(r14) // X
;;
mov r16=IA64_KR(CURRENT) // M2 (12 cyc)
shladd r18=r17,3,r14 // A
mov r19=NR_syscalls-1 // A
;;
lfetch [r18] // M0|1
MOV_FROM_PSR(p0, r29, r8) // M2 (12 cyc)
// If r17 is a NaT, p6 will be zero
cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)?
;;
mov r21=ar.fpsr // M2 (12 cyc)
tnat.nz p10,p9=r15 // I0
mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...)
;;
srlz.d // M0 (forces split-issue) ensure PSR.BE==0
(p6) ld8 r18=[r18] // M0|1
nop.i 0
;;
nop.m 0
(p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!)
nop.i 0
;;
SSM_PSR_I(p8, p14, r25)
(p6) mov b7=r18 // I0
(p8) br.dptk.many b7 // B
mov r27=ar.rsc // M2 (12 cyc)
/*
* brl.cond doesn't work as intended because the linker would convert this branch
* into a branch to a PLT. Perhaps there will be a way to avoid this with some
* future version of the linker. In the meantime, we just use an indirect branch
* instead.
*/
#ifdef CONFIG_ITANIUM
(p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry
;;
(p6) ld8 r14=[r14] // r14 <- fsys_bubble_down
;;
(p6) mov b7=r14
(p6) br.sptk.many b7
#else
BRL_COND_FSYS_BUBBLE_DOWN(p6)
#endif
SSM_PSR_I(p0, p14, r10)
mov r10=-1
(p10) mov r8=EINVAL
(p9) mov r8=ENOSYS
FSYS_RETURN
#ifdef CONFIG_PARAVIRT
/*
* padd to make the size of this symbol constant
* independent of paravirtualization.
*/
.align PAGE_SIZE / 8
#endif
END(__kernel_syscall_via_epc)

View File

@ -7,6 +7,7 @@
#include <asm/system.h> #include <asm/system.h>
#include "paravirt_patchlist.h"
SECTIONS SECTIONS
{ {
@ -33,21 +34,21 @@ SECTIONS
. = GATE_ADDR + 0x600; . = GATE_ADDR + 0x600;
.data.patch : { .data.patch : {
__start_gate_mckinley_e9_patchlist = .; __paravirt_start_gate_mckinley_e9_patchlist = .;
*(.data.patch.mckinley_e9) *(.data.patch.mckinley_e9)
__end_gate_mckinley_e9_patchlist = .; __paravirt_end_gate_mckinley_e9_patchlist = .;
__start_gate_vtop_patchlist = .; __paravirt_start_gate_vtop_patchlist = .;
*(.data.patch.vtop) *(.data.patch.vtop)
__end_gate_vtop_patchlist = .; __paravirt_end_gate_vtop_patchlist = .;
__start_gate_fsyscall_patchlist = .; __paravirt_start_gate_fsyscall_patchlist = .;
*(.data.patch.fsyscall_table) *(.data.patch.fsyscall_table)
__end_gate_fsyscall_patchlist = .; __paravirt_end_gate_fsyscall_patchlist = .;
__start_gate_brl_fsys_bubble_down_patchlist = .; __paravirt_start_gate_brl_fsys_bubble_down_patchlist = .;
*(.data.patch.brl_fsys_bubble_down) *(.data.patch.brl_fsys_bubble_down)
__end_gate_brl_fsys_bubble_down_patchlist = .; __paravirt_end_gate_brl_fsys_bubble_down_patchlist = .;
} :readable } :readable
.IA_64.unwind_info : { *(.IA_64.unwind_info*) } .IA_64.unwind_info : { *(.IA_64.unwind_info*) }

View File

@ -1050,7 +1050,7 @@ END(ia64_delay_loop)
* except that the multiplication and the shift are done with 128-bit * except that the multiplication and the shift are done with 128-bit
* intermediate precision so that we can produce a full 64-bit result. * intermediate precision so that we can produce a full 64-bit result.
*/ */
GLOBAL_ENTRY(sched_clock) GLOBAL_ENTRY(ia64_native_sched_clock)
addl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0 addl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0
mov.m r9=ar.itc // fetch cycle-counter (35 cyc) mov.m r9=ar.itc // fetch cycle-counter (35 cyc)
;; ;;
@ -1066,7 +1066,13 @@ GLOBAL_ENTRY(sched_clock)
;; ;;
shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT
br.ret.sptk.many rp br.ret.sptk.many rp
END(sched_clock) END(ia64_native_sched_clock)
#ifndef CONFIG_PARAVIRT
//unsigned long long
//sched_clock(void) __attribute__((alias("ia64_native_sched_clock")));
.global sched_clock
sched_clock = ia64_native_sched_clock
#endif
#ifdef CONFIG_VIRT_CPU_ACCOUNTING #ifdef CONFIG_VIRT_CPU_ACCOUNTING
GLOBAL_ENTRY(cycle_to_cputime) GLOBAL_ENTRY(cycle_to_cputime)

View File

@ -804,7 +804,7 @@ ENTRY(break_fault)
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag
#ifdef CONFIG_VIRT_CPU_ACCOUNTING #ifdef CONFIG_VIRT_CPU_ACCOUNTING
mov.m r30=ar.itc // M get cycle for accounting MOV_FROM_ITC(p0, p14, r30, r18) // M get cycle for accounting
#else #else
mov b6=r30 // I0 setup syscall handler branch reg early mov b6=r30 // I0 setup syscall handler branch reg early
#endif #endif

View File

@ -1456,9 +1456,9 @@ ia64_mca_cmc_int_caller(int cmc_irq, void *arg)
ia64_mca_cmc_int_handler(cmc_irq, arg); ia64_mca_cmc_int_handler(cmc_irq, arg);
for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++); cpuid = cpumask_next(cpuid+1, cpu_online_mask);
if (cpuid < NR_CPUS) { if (cpuid < nr_cpu_ids) {
platform_send_ipi(cpuid, IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0); platform_send_ipi(cpuid, IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0);
} else { } else {
/* If no log record, switch out of polling mode */ /* If no log record, switch out of polling mode */
@ -1525,7 +1525,7 @@ ia64_mca_cpe_int_caller(int cpe_irq, void *arg)
ia64_mca_cpe_int_handler(cpe_irq, arg); ia64_mca_cpe_int_handler(cpe_irq, arg);
for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++); cpuid = cpumask_next(cpuid+1, cpu_online_mask);
if (cpuid < NR_CPUS) { if (cpuid < NR_CPUS) {
platform_send_ipi(cpuid, IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0); platform_send_ipi(cpuid, IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);

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