Merge commit 'origin/master'
Manually fixed up: drivers/net/fs_enet/fs_enet-main.c
This commit is contained in:
Коммит
8725f25acc
3
CREDITS
3
CREDITS
|
@ -3344,8 +3344,7 @@ S: Spain
|
|||
N: Linus Torvalds
|
||||
E: torvalds@linux-foundation.org
|
||||
D: Original kernel hacker
|
||||
S: 12725 SW Millikan Way, Suite 400
|
||||
S: Beaverton, Oregon 97005
|
||||
S: Portland, Oregon 97005
|
||||
S: USA
|
||||
|
||||
N: Marcelo Tosatti
|
||||
|
|
|
@ -524,6 +524,44 @@ These utilities include endpoint autoconfiguration.
|
|||
<!-- !Edrivers/usb/gadget/epautoconf.c -->
|
||||
</sect1>
|
||||
|
||||
<sect1 id="composite"><title>Composite Device Framework</title>
|
||||
|
||||
<para>The core API is sufficient for writing drivers for composite
|
||||
USB devices (with more than one function in a given configuration),
|
||||
and also multi-configuration devices (also more than one function,
|
||||
but not necessarily sharing a given configuration).
|
||||
There is however an optional framework which makes it easier to
|
||||
reuse and combine functions.
|
||||
</para>
|
||||
|
||||
<para>Devices using this framework provide a <emphasis>struct
|
||||
usb_composite_driver</emphasis>, which in turn provides one or
|
||||
more <emphasis>struct usb_configuration</emphasis> instances.
|
||||
Each such configuration includes at least one
|
||||
<emphasis>struct usb_function</emphasis>, which packages a user
|
||||
visible role such as "network link" or "mass storage device".
|
||||
Management functions may also exist, such as "Device Firmware
|
||||
Upgrade".
|
||||
</para>
|
||||
|
||||
!Iinclude/linux/usb/composite.h
|
||||
!Edrivers/usb/gadget/composite.c
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1 id="functions"><title>Composite Device Functions</title>
|
||||
|
||||
<para>At this writing, a few of the current gadget drivers have
|
||||
been converted to this framework.
|
||||
Near-term plans include converting all of them, except for "gadgetfs".
|
||||
</para>
|
||||
|
||||
!Edrivers/usb/gadget/f_acm.c
|
||||
!Edrivers/usb/gadget/f_serial.c
|
||||
|
||||
</sect1>
|
||||
|
||||
|
||||
</chapter>
|
||||
|
||||
<chapter id="controllers"><title>Peripheral Controller Drivers</title>
|
||||
|
|
|
@ -308,9 +308,41 @@ Who: Matthew Wilcox <willy@linux.intel.com>
|
|||
|
||||
---------------------------
|
||||
|
||||
What: SCTP_GET_PEER_ADDRS_NUM_OLD, SCTP_GET_PEER_ADDRS_OLD,
|
||||
SCTP_GET_LOCAL_ADDRS_NUM_OLD, SCTP_GET_LOCAL_ADDRS_OLD
|
||||
When: June 2009
|
||||
Why: A newer version of the options have been introduced in 2005 that
|
||||
removes the limitions of the old API. The sctp library has been
|
||||
converted to use these new options at the same time. Any user
|
||||
space app that directly uses the old options should convert to using
|
||||
the new options.
|
||||
Who: Vlad Yasevich <vladislav.yasevich@hp.com>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: CONFIG_THERMAL_HWMON
|
||||
When: January 2009
|
||||
Why: This option was introduced just to allow older lm-sensors userspace
|
||||
to keep working over the upgrade to 2.6.26. At the scheduled time of
|
||||
removal fixed lm-sensors (2.x or 3.x) should be readily available.
|
||||
Who: Rene Herman <rene.herman@gmail.com>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: Code that is now under CONFIG_WIRELESS_EXT_SYSFS
|
||||
(in net/core/net-sysfs.c)
|
||||
When: After the only user (hal) has seen a release with the patches
|
||||
for enough time, probably some time in 2010.
|
||||
Why: Over 1K .text/.data size reduction, data is available in other
|
||||
ways (ioctls)
|
||||
Who: Johannes Berg <johannes@sipsolutions.net>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: CONFIG_NF_CT_ACCT
|
||||
When: 2.6.29
|
||||
Why: Accounting can now be enabled/disabled without kernel recompilation.
|
||||
Currently used only to set a default value for a feature that is also
|
||||
controlled by a kernel/module/sysfs/sysctl parameter.
|
||||
Who: Krzysztof Piotr Oledzki <ole@ans.pl>
|
||||
|
||||
|
|
|
@ -279,7 +279,7 @@ static struct config_item *simple_children_make_item(struct config_group *group,
|
|||
|
||||
simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
|
||||
if (!simple_child)
|
||||
return NULL;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
|
||||
config_item_init_type_name(&simple_child->item, name,
|
||||
|
@ -366,7 +366,7 @@ static struct config_group *group_children_make_group(struct config_group *group
|
|||
simple_children = kzalloc(sizeof(struct simple_children),
|
||||
GFP_KERNEL);
|
||||
if (!simple_children)
|
||||
return NULL;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
|
||||
config_group_init_type_name(&simple_children->group, name,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
################################################################################
|
||||
|
||||
Author: NetApp and Open Grid Computing
|
||||
Date: April 15, 2008
|
||||
Date: May 29, 2008
|
||||
|
||||
Table of Contents
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
@ -60,16 +60,18 @@ Installation
|
|||
The procedures described in this document have been tested with
|
||||
distributions from Red Hat's Fedora Project (http://fedora.redhat.com/).
|
||||
|
||||
- Install nfs-utils-1.1.1 or greater on the client
|
||||
- Install nfs-utils-1.1.2 or greater on the client
|
||||
|
||||
An NFS/RDMA mount point can only be obtained by using the mount.nfs
|
||||
command in nfs-utils-1.1.1 or greater. To see which version of mount.nfs
|
||||
you are using, type:
|
||||
An NFS/RDMA mount point can be obtained by using the mount.nfs command in
|
||||
nfs-utils-1.1.2 or greater (nfs-utils-1.1.1 was the first nfs-utils
|
||||
version with support for NFS/RDMA mounts, but for various reasons we
|
||||
recommend using nfs-utils-1.1.2 or greater). To see which version of
|
||||
mount.nfs you are using, type:
|
||||
|
||||
> /sbin/mount.nfs -V
|
||||
$ /sbin/mount.nfs -V
|
||||
|
||||
If the version is less than 1.1.1 or the command does not exist,
|
||||
then you will need to install the latest version of nfs-utils.
|
||||
If the version is less than 1.1.2 or the command does not exist,
|
||||
you should install the latest version of nfs-utils.
|
||||
|
||||
Download the latest package from:
|
||||
|
||||
|
@ -77,22 +79,33 @@ Installation
|
|||
|
||||
Uncompress the package and follow the installation instructions.
|
||||
|
||||
If you will not be using GSS and NFSv4, the installation process
|
||||
can be simplified by disabling these features when running configure:
|
||||
If you will not need the idmapper and gssd executables (you do not need
|
||||
these to create an NFS/RDMA enabled mount command), the installation
|
||||
process can be simplified by disabling these features when running
|
||||
configure:
|
||||
|
||||
> ./configure --disable-gss --disable-nfsv4
|
||||
$ ./configure --disable-gss --disable-nfsv4
|
||||
|
||||
For more information on this see the package's README and INSTALL files.
|
||||
To build nfs-utils you will need the tcp_wrappers package installed. For
|
||||
more information on this see the package's README and INSTALL files.
|
||||
|
||||
After building the nfs-utils package, there will be a mount.nfs binary in
|
||||
the utils/mount directory. This binary can be used to initiate NFS v2, v3,
|
||||
or v4 mounts. To initiate a v4 mount, the binary must be called mount.nfs4.
|
||||
The standard technique is to create a symlink called mount.nfs4 to mount.nfs.
|
||||
or v4 mounts. To initiate a v4 mount, the binary must be called
|
||||
mount.nfs4. The standard technique is to create a symlink called
|
||||
mount.nfs4 to mount.nfs.
|
||||
|
||||
NOTE: mount.nfs and therefore nfs-utils-1.1.1 or greater is only needed
|
||||
This mount.nfs binary should be installed at /sbin/mount.nfs as follows:
|
||||
|
||||
$ sudo cp utils/mount/mount.nfs /sbin/mount.nfs
|
||||
|
||||
In this location, mount.nfs will be invoked automatically for NFS mounts
|
||||
by the system mount commmand.
|
||||
|
||||
NOTE: mount.nfs and therefore nfs-utils-1.1.2 or greater is only needed
|
||||
on the NFS client machine. You do not need this specific version of
|
||||
nfs-utils on the server. Furthermore, only the mount.nfs command from
|
||||
nfs-utils-1.1.1 is needed on the client.
|
||||
nfs-utils-1.1.2 is needed on the client.
|
||||
|
||||
- Install a Linux kernel with NFS/RDMA
|
||||
|
||||
|
@ -156,8 +169,8 @@ Check RDMA and NFS Setup
|
|||
this time. For example, if you are using a Mellanox Tavor/Sinai/Arbel
|
||||
card:
|
||||
|
||||
> modprobe ib_mthca
|
||||
> modprobe ib_ipoib
|
||||
$ modprobe ib_mthca
|
||||
$ modprobe ib_ipoib
|
||||
|
||||
If you are using InfiniBand, make sure there is a Subnet Manager (SM)
|
||||
running on the network. If your IB switch has an embedded SM, you can
|
||||
|
@ -166,7 +179,7 @@ Check RDMA and NFS Setup
|
|||
|
||||
If an SM is running on your network, you should see the following:
|
||||
|
||||
> cat /sys/class/infiniband/driverX/ports/1/state
|
||||
$ cat /sys/class/infiniband/driverX/ports/1/state
|
||||
4: ACTIVE
|
||||
|
||||
where driverX is mthca0, ipath5, ehca3, etc.
|
||||
|
@ -174,10 +187,10 @@ Check RDMA and NFS Setup
|
|||
To further test the InfiniBand software stack, use IPoIB (this
|
||||
assumes you have two IB hosts named host1 and host2):
|
||||
|
||||
host1> ifconfig ib0 a.b.c.x
|
||||
host2> ifconfig ib0 a.b.c.y
|
||||
host1> ping a.b.c.y
|
||||
host2> ping a.b.c.x
|
||||
host1$ ifconfig ib0 a.b.c.x
|
||||
host2$ ifconfig ib0 a.b.c.y
|
||||
host1$ ping a.b.c.y
|
||||
host2$ ping a.b.c.x
|
||||
|
||||
For other device types, follow the appropriate procedures.
|
||||
|
||||
|
@ -202,11 +215,11 @@ NFS/RDMA Setup
|
|||
/vol0 192.168.0.47(fsid=0,rw,async,insecure,no_root_squash)
|
||||
/vol0 192.168.0.0/255.255.255.0(fsid=0,rw,async,insecure,no_root_squash)
|
||||
|
||||
The IP address(es) is(are) the client's IPoIB address for an InfiniBand HCA or the
|
||||
cleint's iWARP address(es) for an RNIC.
|
||||
The IP address(es) is(are) the client's IPoIB address for an InfiniBand
|
||||
HCA or the cleint's iWARP address(es) for an RNIC.
|
||||
|
||||
NOTE: The "insecure" option must be used because the NFS/RDMA client does not
|
||||
use a reserved port.
|
||||
NOTE: The "insecure" option must be used because the NFS/RDMA client does
|
||||
not use a reserved port.
|
||||
|
||||
Each time a machine boots:
|
||||
|
||||
|
@ -214,43 +227,45 @@ NFS/RDMA Setup
|
|||
|
||||
For InfiniBand using a Mellanox adapter:
|
||||
|
||||
> modprobe ib_mthca
|
||||
> modprobe ib_ipoib
|
||||
> ifconfig ib0 a.b.c.d
|
||||
$ modprobe ib_mthca
|
||||
$ modprobe ib_ipoib
|
||||
$ ifconfig ib0 a.b.c.d
|
||||
|
||||
NOTE: use unique addresses for the client and server
|
||||
|
||||
- Start the NFS server
|
||||
|
||||
If the NFS/RDMA server was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in kernel config),
|
||||
load the RDMA transport module:
|
||||
If the NFS/RDMA server was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in
|
||||
kernel config), load the RDMA transport module:
|
||||
|
||||
> modprobe svcrdma
|
||||
$ modprobe svcrdma
|
||||
|
||||
Regardless of how the server was built (module or built-in), start the server:
|
||||
Regardless of how the server was built (module or built-in), start the
|
||||
server:
|
||||
|
||||
> /etc/init.d/nfs start
|
||||
$ /etc/init.d/nfs start
|
||||
|
||||
or
|
||||
|
||||
> service nfs start
|
||||
$ service nfs start
|
||||
|
||||
Instruct the server to listen on the RDMA transport:
|
||||
|
||||
> echo rdma 2050 > /proc/fs/nfsd/portlist
|
||||
$ echo rdma 2050 > /proc/fs/nfsd/portlist
|
||||
|
||||
- On the client system
|
||||
|
||||
If the NFS/RDMA client was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in kernel config),
|
||||
load the RDMA client module:
|
||||
If the NFS/RDMA client was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in
|
||||
kernel config), load the RDMA client module:
|
||||
|
||||
> modprobe xprtrdma.ko
|
||||
$ modprobe xprtrdma.ko
|
||||
|
||||
Regardless of how the client was built (module or built-in), issue the mount.nfs command:
|
||||
Regardless of how the client was built (module or built-in), use this
|
||||
command to mount the NFS/RDMA server:
|
||||
|
||||
> /path/to/your/mount.nfs <IPoIB-server-name-or-address>:/<export> /mnt -i -o rdma,port=2050
|
||||
$ mount -o rdma,port=2050 <IPoIB-server-name-or-address>:/<export> /mnt
|
||||
|
||||
To verify that the mount is using RDMA, run "cat /proc/mounts" and check the
|
||||
"proto" field for the given mount.
|
||||
To verify that the mount is using RDMA, run "cat /proc/mounts" and check
|
||||
the "proto" field for the given mount.
|
||||
|
||||
Congratulations! You're using NFS/RDMA!
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
Paravirt_ops on IA64
|
||||
====================
|
||||
21 May 2008, Isaku Yamahata <yamahata@valinux.co.jp>
|
||||
|
||||
|
||||
Introduction
|
||||
------------
|
||||
The aim of this documentation is to help with maintainability and/or to
|
||||
encourage people to use paravirt_ops/IA64.
|
||||
|
||||
paravirt_ops (pv_ops in short) is a way for virtualization support of
|
||||
Linux kernel on x86. Several ways for virtualization support were
|
||||
proposed, paravirt_ops is the winner.
|
||||
On the other hand, now there are also several IA64 virtualization
|
||||
technologies like kvm/IA64, xen/IA64 and many other academic IA64
|
||||
hypervisors so that it is good to add generic virtualization
|
||||
infrastructure on Linux/IA64.
|
||||
|
||||
|
||||
What is paravirt_ops?
|
||||
---------------------
|
||||
It has been developed on x86 as virtualization support via API, not ABI.
|
||||
It allows each hypervisor to override operations which are important for
|
||||
hypervisors at API level. And it allows a single kernel binary to run on
|
||||
all supported execution environments including native machine.
|
||||
Essentially paravirt_ops is a set of function pointers which represent
|
||||
operations corresponding to low level sensitive instructions and high
|
||||
level functionalities in various area. But one significant difference
|
||||
from usual function pointer table is that it allows optimization with
|
||||
binary patch. It is because some of these operations are very
|
||||
performance sensitive and indirect call overhead is not negligible.
|
||||
With binary patch, indirect C function call can be transformed into
|
||||
direct C function call or in-place execution to eliminate the overhead.
|
||||
|
||||
Thus, operations of paravirt_ops are classified into three categories.
|
||||
- simple indirect call
|
||||
These operations correspond to high level functionality so that the
|
||||
overhead of indirect call isn't very important.
|
||||
|
||||
- indirect call which allows optimization with binary patch
|
||||
Usually these operations correspond to low level instructions. They
|
||||
are called frequently and performance critical. So the overhead is
|
||||
very important.
|
||||
|
||||
- a set of macros for hand written assembly code
|
||||
Hand written assembly codes (.S files) also need paravirtualization
|
||||
because they include sensitive instructions or some of code paths in
|
||||
them are very performance critical.
|
||||
|
||||
|
||||
The relation to the IA64 machine vector
|
||||
---------------------------------------
|
||||
Linux/IA64 has the IA64 machine vector functionality which allows the
|
||||
kernel to switch implementations (e.g. initialization, ipi, dma api...)
|
||||
depending on executing platform.
|
||||
We can replace some implementations very easily defining a new machine
|
||||
vector. Thus another approach for virtualization support would be
|
||||
enhancing the machine vector functionality.
|
||||
But paravirt_ops approach was taken because
|
||||
- virtualization support needs wider support than machine vector does.
|
||||
e.g. low level instruction paravirtualization. It must be
|
||||
initialized very early before platform detection.
|
||||
|
||||
- virtualization support needs more functionality like binary patch.
|
||||
Probably the calling overhead might not be very large compared to the
|
||||
emulation overhead of virtualization. However in the native case, the
|
||||
overhead should be eliminated completely.
|
||||
A single kernel binary should run on each environment including native,
|
||||
and the overhead of paravirt_ops on native environment should be as
|
||||
small as possible.
|
||||
|
||||
- for full virtualization technology, e.g. KVM/IA64 or
|
||||
Xen/IA64 HVM domain, the result would be
|
||||
(the emulated platform machine vector. probably dig) + (pv_ops).
|
||||
This means that the virtualization support layer should be under
|
||||
the machine vector layer.
|
||||
|
||||
Possibly it might be better to move some function pointers from
|
||||
paravirt_ops to machine vector. In fact, Xen domU case utilizes both
|
||||
pv_ops and machine vector.
|
||||
|
||||
|
||||
IA64 paravirt_ops
|
||||
-----------------
|
||||
In this section, the concrete paravirt_ops will be discussed.
|
||||
Because of the architecture difference between ia64 and x86, the
|
||||
resulting set of functions is very different from x86 pv_ops.
|
||||
|
||||
- C function pointer tables
|
||||
They are not very performance critical so that simple C indirect
|
||||
function call is acceptable. The following structures are defined at
|
||||
this moment. For details see linux/include/asm-ia64/paravirt.h
|
||||
- struct pv_info
|
||||
This structure describes the execution environment.
|
||||
- struct pv_init_ops
|
||||
This structure describes the various initialization hooks.
|
||||
- struct pv_iosapic_ops
|
||||
This structure describes hooks to iosapic operations.
|
||||
- struct pv_irq_ops
|
||||
This structure describes hooks to irq related operations
|
||||
- struct pv_time_op
|
||||
This structure describes hooks to steal time accounting.
|
||||
|
||||
- a set of indirect calls which need optimization
|
||||
Currently this class of functions correspond to a subset of IA64
|
||||
intrinsics. At this moment the optimization with binary patch isn't
|
||||
implemented yet.
|
||||
struct pv_cpu_op is defined. For details see
|
||||
linux/include/asm-ia64/paravirt_privop.h
|
||||
Mostly they correspond to ia64 intrinsics 1-to-1.
|
||||
Caveat: Now they are defined as C indirect function pointers, but in
|
||||
order to support binary patch optimization, they will be changed
|
||||
using GCC extended inline assembly code.
|
||||
|
||||
- a set of macros for hand written assembly code (.S files)
|
||||
For maintenance purpose, the taken approach for .S files is single
|
||||
source code and compile multiple times with different macros definitions.
|
||||
Each pv_ops instance must define those macros to compile.
|
||||
The important thing here is that sensitive, but non-privileged
|
||||
instructions must be paravirtualized and that some privileged
|
||||
instructions also need paravirtualization for reasonable performance.
|
||||
Developers who modify .S files must be aware of that. At this moment
|
||||
an easy checker is implemented to detect paravirtualization breakage.
|
||||
But it doesn't cover all the cases.
|
||||
|
||||
Sometimes this set of macros is called pv_cpu_asm_op. But there is no
|
||||
corresponding structure in the source code.
|
||||
Those macros mostly 1:1 correspond to a subset of privileged
|
||||
instructions. See linux/include/asm-ia64/native/inst.h.
|
||||
And some functions written in assembly also need to be overrided so
|
||||
that each pv_ops instance have to define some macros. Again see
|
||||
linux/include/asm-ia64/native/inst.h.
|
||||
|
||||
|
||||
Those structures must be initialized very early before start_kernel.
|
||||
Probably initialized in head.S using multi entry point or some other trick.
|
||||
For native case implementation see linux/arch/ia64/kernel/paravirt.c.
|
|
@ -1,5 +1,3 @@
|
|||
$Id: gameport-programming.txt,v 1.3 2001/04/24 13:51:37 vojtech Exp $
|
||||
|
||||
Programming gameport drivers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
Linux Input drivers v1.0
|
||||
(c) 1999-2001 Vojtech Pavlik <vojtech@ucw.cz>
|
||||
Sponsored by SuSE
|
||||
$Id: input.txt,v 1.8 2002/05/29 03:15:01 bradleym Exp $
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
0. Disclaimer
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
7 Aug 1998
|
||||
|
||||
$Id: joystick-api.txt,v 1.2 2001/05/08 21:21:23 vojtech Exp $
|
||||
|
||||
1. Initialization
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
(c) 1998-2000 Vojtech Pavlik <vojtech@ucw.cz>
|
||||
(c) 1998 Andree Borrmann <a.borrmann@tu-bs.de>
|
||||
Sponsored by SuSE
|
||||
$Id: joystick-parport.txt,v 1.6 2001/09/25 09:31:32 vojtech Exp $
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
0. Disclaimer
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
Linux Joystick driver v2.0.0
|
||||
(c) 1996-2000 Vojtech Pavlik <vojtech@ucw.cz>
|
||||
Sponsored by SuSE
|
||||
$Id: joystick.txt,v 1.12 2002/03/03 12:13:07 jdeneux Exp $
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
0. Disclaimer
|
||||
|
|
|
@ -147,10 +147,14 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
default: 0
|
||||
|
||||
acpi_sleep= [HW,ACPI] Sleep options
|
||||
Format: { s3_bios, s3_mode, s3_beep }
|
||||
Format: { s3_bios, s3_mode, s3_beep, old_ordering }
|
||||
See Documentation/power/video.txt for s3_bios and s3_mode.
|
||||
s3_beep is for debugging; it makes the PC's speaker beep
|
||||
as soon as the kernel's real-mode entry point is called.
|
||||
old_ordering causes the ACPI 1.0 ordering of the _PTS
|
||||
control method, wrt putting devices into low power
|
||||
states, to be enforced (the ACPI 2.0 ordering of _PTS is
|
||||
used by default).
|
||||
|
||||
acpi_sci= [HW,ACPI] ACPI System Control Interrupt trigger mode
|
||||
Format: { level | edge | high | low }
|
||||
|
@ -1202,7 +1206,7 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
or
|
||||
memmap=0x10000$0x18690000
|
||||
|
||||
memtest= [KNL,X86_64] Enable memtest
|
||||
memtest= [KNL,X86] Enable memtest
|
||||
Format: <integer>
|
||||
range: 0,4 : pattern number
|
||||
default : 0 <disable>
|
||||
|
@ -1275,6 +1279,13 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
This usage is only documented in each driver source
|
||||
file if at all.
|
||||
|
||||
nf_conntrack.acct=
|
||||
[NETFILTER] Enable connection tracking flow accounting
|
||||
0 to disable accounting
|
||||
1 to enable accounting
|
||||
Default value depends on CONFIG_NF_CT_ACCT that is
|
||||
going to be removed in 2.6.29.
|
||||
|
||||
nfsaddrs= [NFS]
|
||||
See Documentation/filesystems/nfsroot.txt.
|
||||
|
||||
|
@ -1537,6 +1548,9 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
Use with caution as certain devices share
|
||||
address decoders between ROMs and other
|
||||
resources.
|
||||
norom [X86-32,X86_64] Do not assign address space to
|
||||
expansion ROMs that do not already have
|
||||
BIOS assigned address ranges.
|
||||
irqmask=0xMMMM [X86-32] Set a bit mask of IRQs allowed to be
|
||||
assigned automatically to PCI devices. You can
|
||||
make the kernel exclude IRQs of your ISA cards
|
||||
|
@ -2151,6 +2165,10 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
Note that genuine overcurrent events won't be
|
||||
reported either.
|
||||
|
||||
unknown_nmi_panic
|
||||
[X86-32,X86-64]
|
||||
Set unknown_nmi_panic=1 early on boot.
|
||||
|
||||
usbcore.autosuspend=
|
||||
[USB] The autosuspend time delay (in seconds) used
|
||||
for newly-detected USB devices (default 2). This
|
||||
|
|
|
@ -236,6 +236,11 @@ All md devices contain:
|
|||
writing the word for the desired state, however some states
|
||||
cannot be explicitly set, and some transitions are not allowed.
|
||||
|
||||
Select/poll works on this file. All changes except between
|
||||
active_idle and active (which can be frequent and are not
|
||||
very interesting) are notified. active->active_idle is
|
||||
reported if the metadata is externally managed.
|
||||
|
||||
clear
|
||||
No devices, no size, no level
|
||||
Writing is equivalent to STOP_ARRAY ioctl
|
||||
|
@ -292,6 +297,10 @@ Each directory contains:
|
|||
writemostly - device will only be subject to read
|
||||
requests if there are no other options.
|
||||
This applies only to raid1 arrays.
|
||||
blocked - device has failed, metadata is "external",
|
||||
and the failure hasn't been acknowledged yet.
|
||||
Writes that would write to this device if
|
||||
it were not faulty are blocked.
|
||||
spare - device is working, but not a full member.
|
||||
This includes spares that are in the process
|
||||
of being recovered to
|
||||
|
@ -301,6 +310,12 @@ Each directory contains:
|
|||
Writing "remove" removes the device from the array.
|
||||
Writing "writemostly" sets the writemostly flag.
|
||||
Writing "-writemostly" clears the writemostly flag.
|
||||
Writing "blocked" sets the "blocked" flag.
|
||||
Writing "-blocked" clear the "blocked" flag and allows writes
|
||||
to complete.
|
||||
|
||||
This file responds to select/poll. Any change to 'faulty'
|
||||
or 'blocked' causes an event.
|
||||
|
||||
errors
|
||||
An approximate count of read errors that have been detected on
|
||||
|
@ -332,7 +347,7 @@ Each directory contains:
|
|||
for storage of data. This will normally be the same as the
|
||||
component_size. This can be written while assembling an
|
||||
array. If a value less than the current component_size is
|
||||
written, component_size will be reduced to this value.
|
||||
written, it will be rejected.
|
||||
|
||||
|
||||
An active md device will also contain and entry for each active device
|
||||
|
@ -381,6 +396,19 @@ also have
|
|||
'check' and 'repair' will start the appropriate process
|
||||
providing the current state is 'idle'.
|
||||
|
||||
This file responds to select/poll. Any important change in the value
|
||||
triggers a poll event. Sometimes the value will briefly be
|
||||
"recover" if a recovery seems to be needed, but cannot be
|
||||
achieved. In that case, the transition to "recover" isn't
|
||||
notified, but the transition away is.
|
||||
|
||||
degraded
|
||||
This contains a count of the number of devices by which the
|
||||
arrays is degraded. So an optimal array with show '0'. A
|
||||
single failed/missing drive will show '1', etc.
|
||||
This file responds to select/poll, any increase or decrease
|
||||
in the count of missing devices will trigger an event.
|
||||
|
||||
mismatch_count
|
||||
When performing 'check' and 'repair', and possibly when
|
||||
performing 'resync', md will count the number of errors that are
|
||||
|
|
|
@ -289,35 +289,73 @@ downdelay
|
|||
fail_over_mac
|
||||
|
||||
Specifies whether active-backup mode should set all slaves to
|
||||
the same MAC address (the traditional behavior), or, when
|
||||
enabled, change the bond's MAC address when changing the
|
||||
active interface (i.e., fail over the MAC address itself).
|
||||
the same MAC address at enslavement (the traditional
|
||||
behavior), or, when enabled, perform special handling of the
|
||||
bond's MAC address in accordance with the selected policy.
|
||||
|
||||
Fail over MAC is useful for devices that cannot ever alter
|
||||
their MAC address, or for devices that refuse incoming
|
||||
broadcasts with their own source MAC (which interferes with
|
||||
the ARP monitor).
|
||||
Possible values are:
|
||||
|
||||
The down side of fail over MAC is that every device on the
|
||||
network must be updated via gratuitous ARP, vs. just updating
|
||||
a switch or set of switches (which often takes place for any
|
||||
traffic, not just ARP traffic, if the switch snoops incoming
|
||||
traffic to update its tables) for the traditional method. If
|
||||
the gratuitous ARP is lost, communication may be disrupted.
|
||||
none or 0
|
||||
|
||||
When fail over MAC is used in conjuction with the mii monitor,
|
||||
devices which assert link up prior to being able to actually
|
||||
transmit and receive are particularly susecptible to loss of
|
||||
the gratuitous ARP, and an appropriate updelay setting may be
|
||||
required.
|
||||
This setting disables fail_over_mac, and causes
|
||||
bonding to set all slaves of an active-backup bond to
|
||||
the same MAC address at enslavement time. This is the
|
||||
default.
|
||||
|
||||
A value of 0 disables fail over MAC, and is the default. A
|
||||
value of 1 enables fail over MAC. This option is enabled
|
||||
automatically if the first slave added cannot change its MAC
|
||||
address. This option may be modified via sysfs only when no
|
||||
slaves are present in the bond.
|
||||
active or 1
|
||||
|
||||
This option was added in bonding version 3.2.0.
|
||||
The "active" fail_over_mac policy indicates that the
|
||||
MAC address of the bond should always be the MAC
|
||||
address of the currently active slave. The MAC
|
||||
address of the slaves is not changed; instead, the MAC
|
||||
address of the bond changes during a failover.
|
||||
|
||||
This policy is useful for devices that cannot ever
|
||||
alter their MAC address, or for devices that refuse
|
||||
incoming broadcasts with their own source MAC (which
|
||||
interferes with the ARP monitor).
|
||||
|
||||
The down side of this policy is that every device on
|
||||
the network must be updated via gratuitous ARP,
|
||||
vs. just updating a switch or set of switches (which
|
||||
often takes place for any traffic, not just ARP
|
||||
traffic, if the switch snoops incoming traffic to
|
||||
update its tables) for the traditional method. If the
|
||||
gratuitous ARP is lost, communication may be
|
||||
disrupted.
|
||||
|
||||
When this policy is used in conjuction with the mii
|
||||
monitor, devices which assert link up prior to being
|
||||
able to actually transmit and receive are particularly
|
||||
susecptible to loss of the gratuitous ARP, and an
|
||||
appropriate updelay setting may be required.
|
||||
|
||||
follow or 2
|
||||
|
||||
The "follow" fail_over_mac policy causes the MAC
|
||||
address of the bond to be selected normally (normally
|
||||
the MAC address of the first slave added to the bond).
|
||||
However, the second and subsequent slaves are not set
|
||||
to this MAC address while they are in a backup role; a
|
||||
slave is programmed with the bond's MAC address at
|
||||
failover time (and the formerly active slave receives
|
||||
the newly active slave's MAC address).
|
||||
|
||||
This policy is useful for multiport devices that
|
||||
either become confused or incur a performance penalty
|
||||
when multiple ports are programmed with the same MAC
|
||||
address.
|
||||
|
||||
|
||||
The default policy is none, unless the first slave cannot
|
||||
change its MAC address, in which case the active policy is
|
||||
selected by default.
|
||||
|
||||
This option may be modified via sysfs only when no slaves are
|
||||
present in the bond.
|
||||
|
||||
This option was added in bonding version 3.2.0. The "follow"
|
||||
policy was added in bonding version 3.3.0.
|
||||
|
||||
lacp_rate
|
||||
|
||||
|
@ -338,7 +376,8 @@ max_bonds
|
|||
Specifies the number of bonding devices to create for this
|
||||
instance of the bonding driver. E.g., if max_bonds is 3, and
|
||||
the bonding driver is not already loaded, then bond0, bond1
|
||||
and bond2 will be created. The default value is 1.
|
||||
and bond2 will be created. The default value is 1. Specifying
|
||||
a value of 0 will load bonding, but will not create any devices.
|
||||
|
||||
miimon
|
||||
|
||||
|
@ -501,6 +540,17 @@ mode
|
|||
swapped with the new curr_active_slave that was
|
||||
chosen.
|
||||
|
||||
num_grat_arp
|
||||
|
||||
Specifies the number of gratuitous ARPs to be issued after a
|
||||
failover event. One gratuitous ARP is issued immediately after
|
||||
the failover, subsequent ARPs are sent at a rate of one per link
|
||||
monitor interval (arp_interval or miimon, whichever is active).
|
||||
|
||||
The valid range is 0 - 255; the default value is 1. This option
|
||||
affects only the active-backup mode. This option was added for
|
||||
bonding version 3.3.0.
|
||||
|
||||
primary
|
||||
|
||||
A string (eth0, eth2, etc) specifying which slave is the
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
DM9000 Network driver
|
||||
=====================
|
||||
|
||||
Copyright 2008 Simtec Electronics,
|
||||
Ben Dooks <ben@simtec.co.uk> <ben-linux@fluff.org>
|
||||
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This file describes how to use the DM9000 platform-device based network driver
|
||||
that is contained in the files drivers/net/dm9000.c and drivers/net/dm9000.h.
|
||||
|
||||
The driver supports three DM9000 variants, the DM9000E which is the first chip
|
||||
supported as well as the newer DM9000A and DM9000B devices. It is currently
|
||||
maintained and tested by Ben Dooks, who should be CC: to any patches for this
|
||||
driver.
|
||||
|
||||
|
||||
Defining the platform device
|
||||
----------------------------
|
||||
|
||||
The minimum set of resources attached to the platform device are as follows:
|
||||
|
||||
1) The physical address of the address register
|
||||
2) The physical address of the data register
|
||||
3) The IRQ line the device's interrupt pin is connected to.
|
||||
|
||||
These resources should be specified in that order, as the ordering of the
|
||||
two address regions is important (the driver expects these to be address
|
||||
and then data).
|
||||
|
||||
An example from arch/arm/mach-s3c2410/mach-bast.c is:
|
||||
|
||||
static struct resource bast_dm9k_resource[] = {
|
||||
[0] = {
|
||||
.start = S3C2410_CS5 + BAST_PA_DM9000,
|
||||
.end = S3C2410_CS5 + BAST_PA_DM9000 + 3,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = S3C2410_CS5 + BAST_PA_DM9000 + 0x40,
|
||||
.end = S3C2410_CS5 + BAST_PA_DM9000 + 0x40 + 0x3f,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_DM9000,
|
||||
.end = IRQ_DM9000,
|
||||
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device bast_device_dm9k = {
|
||||
.name = "dm9000",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(bast_dm9k_resource),
|
||||
.resource = bast_dm9k_resource,
|
||||
};
|
||||
|
||||
Note the setting of the IRQ trigger flag in bast_dm9k_resource[2].flags,
|
||||
as this will generate a warning if it is not present. The trigger from
|
||||
the flags field will be passed to request_irq() when registering the IRQ
|
||||
handler to ensure that the IRQ is setup correctly.
|
||||
|
||||
This shows a typical platform device, without the optional configuration
|
||||
platform data supplied. The next example uses the same resources, but adds
|
||||
the optional platform data to pass extra configuration data:
|
||||
|
||||
static struct dm9000_plat_data bast_dm9k_platdata = {
|
||||
.flags = DM9000_PLATF_16BITONLY,
|
||||
};
|
||||
|
||||
static struct platform_device bast_device_dm9k = {
|
||||
.name = "dm9000",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(bast_dm9k_resource),
|
||||
.resource = bast_dm9k_resource,
|
||||
.dev = {
|
||||
.platform_data = &bast_dm9k_platdata,
|
||||
}
|
||||
};
|
||||
|
||||
The platform data is defined in include/linux/dm9000.h and described below.
|
||||
|
||||
|
||||
Platform data
|
||||
-------------
|
||||
|
||||
Extra platform data for the DM9000 can describe the IO bus width to the
|
||||
device, whether or not an external PHY is attached to the device and
|
||||
the availability of an external configuration EEPROM.
|
||||
|
||||
The flags for the platform data .flags field are as follows:
|
||||
|
||||
DM9000_PLATF_8BITONLY
|
||||
|
||||
The IO should be done with 8bit operations.
|
||||
|
||||
DM9000_PLATF_16BITONLY
|
||||
|
||||
The IO should be done with 16bit operations.
|
||||
|
||||
DM9000_PLATF_32BITONLY
|
||||
|
||||
The IO should be done with 32bit operations.
|
||||
|
||||
DM9000_PLATF_EXT_PHY
|
||||
|
||||
The chip is connected to an external PHY.
|
||||
|
||||
DM9000_PLATF_NO_EEPROM
|
||||
|
||||
This can be used to signify that the board does not have an
|
||||
EEPROM, or that the EEPROM should be hidden from the user.
|
||||
|
||||
DM9000_PLATF_SIMPLE_PHY
|
||||
|
||||
Switch to using the simpler PHY polling method which does not
|
||||
try and read the MII PHY state regularly. This is only available
|
||||
when using the internal PHY. See the section on link state polling
|
||||
for more information.
|
||||
|
||||
The config symbol DM9000_FORCE_SIMPLE_PHY_POLL, Kconfig entry
|
||||
"Force simple NSR based PHY polling" allows this flag to be
|
||||
forced on at build time.
|
||||
|
||||
|
||||
PHY Link state polling
|
||||
----------------------
|
||||
|
||||
The driver keeps track of the link state and informs the network core
|
||||
about link (carrier) availablilty. This is managed by several methods
|
||||
depending on the version of the chip and on which PHY is being used.
|
||||
|
||||
For the internal PHY, the original (and currently default) method is
|
||||
to read the MII state, either when the status changes if we have the
|
||||
necessary interrupt support in the chip or every two seconds via a
|
||||
periodic timer.
|
||||
|
||||
To reduce the overhead for the internal PHY, there is now the option
|
||||
of using the DM9000_FORCE_SIMPLE_PHY_POLL config, or DM9000_PLATF_SIMPLE_PHY
|
||||
platform data option to read the summary information without the
|
||||
expensive MII accesses. This method is faster, but does not print
|
||||
as much information.
|
||||
|
||||
When using an external PHY, the driver currently has to poll the MII
|
||||
link status as there is no method for getting an interrupt on link change.
|
||||
|
||||
|
||||
DM9000A / DM9000B
|
||||
-----------------
|
||||
|
||||
These chips are functionally similar to the DM9000E and are supported easily
|
||||
by the same driver. The features are:
|
||||
|
||||
1) Interrupt on internal PHY state change. This means that the periodic
|
||||
polling of the PHY status may be disabled on these devices when using
|
||||
the internal PHY.
|
||||
|
||||
2) TCP/UDP checksum offloading, which the driver does not currently support.
|
||||
|
||||
|
||||
ethtool
|
||||
-------
|
||||
|
||||
The driver supports the ethtool interface for access to the driver
|
||||
state information, the PHY state and the EEPROM.
|
|
@ -551,8 +551,9 @@ icmp_echo_ignore_broadcasts - BOOLEAN
|
|||
icmp_ratelimit - INTEGER
|
||||
Limit the maximal rates for sending ICMP packets whose type matches
|
||||
icmp_ratemask (see below) to specific targets.
|
||||
0 to disable any limiting, otherwise the maximal rate in jiffies(1)
|
||||
Default: 100
|
||||
0 to disable any limiting,
|
||||
otherwise the minimal space between responses in milliseconds.
|
||||
Default: 1000
|
||||
|
||||
icmp_ratemask - INTEGER
|
||||
Mask made of ICMP types for which rates are being limited.
|
||||
|
@ -1023,11 +1024,23 @@ max_addresses - INTEGER
|
|||
autoconfigured addresses.
|
||||
Default: 16
|
||||
|
||||
disable_ipv6 - BOOLEAN
|
||||
Disable IPv6 operation.
|
||||
Default: FALSE (enable IPv6 operation)
|
||||
|
||||
accept_dad - INTEGER
|
||||
Whether to accept DAD (Duplicate Address Detection).
|
||||
0: Disable DAD
|
||||
1: Enable DAD (default)
|
||||
2: Enable DAD, and disable IPv6 operation if MAC-based duplicate
|
||||
link-local address has been found.
|
||||
|
||||
icmp/*:
|
||||
ratelimit - INTEGER
|
||||
Limit the maximal rates for sending ICMPv6 packets.
|
||||
0 to disable any limiting, otherwise the maximal rate in jiffies(1)
|
||||
Default: 100
|
||||
0 to disable any limiting,
|
||||
otherwise the minimal space between responses in milliseconds.
|
||||
Default: 1000
|
||||
|
||||
|
||||
IPv6 Update by:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
Linux* Base Driver for the Intel(R) PRO/10GbE Family of Adapters
|
||||
================================================================
|
||||
Linux Base Driver for 10 Gigabit Intel(R) Network Connection
|
||||
=============================================================
|
||||
|
||||
November 17, 2004
|
||||
October 9, 2007
|
||||
|
||||
|
||||
Contents
|
||||
|
@ -9,94 +9,151 @@ Contents
|
|||
|
||||
- In This Release
|
||||
- Identifying Your Adapter
|
||||
- Building and Installation
|
||||
- Command Line Parameters
|
||||
- Improving Performance
|
||||
- Additional Configurations
|
||||
- Known Issues/Troubleshooting
|
||||
- Support
|
||||
|
||||
|
||||
|
||||
In This Release
|
||||
===============
|
||||
|
||||
This file describes the Linux* Base Driver for the Intel(R) PRO/10GbE Family
|
||||
of Adapters, version 1.0.x.
|
||||
This file describes the ixgb Linux Base Driver for the 10 Gigabit Intel(R)
|
||||
Network Connection. This driver includes support for Itanium(R)2-based
|
||||
systems.
|
||||
|
||||
For questions related to hardware requirements, refer to the documentation
|
||||
supplied with your 10 Gigabit adapter. All hardware requirements listed apply
|
||||
to use with Linux.
|
||||
|
||||
The following features are available in this kernel:
|
||||
- Native VLANs
|
||||
- Channel Bonding (teaming)
|
||||
- SNMP
|
||||
|
||||
Channel Bonding documentation can be found in the Linux kernel source:
|
||||
/Documentation/networking/bonding.txt
|
||||
|
||||
The driver information previously displayed in the /proc filesystem is not
|
||||
supported in this release. Alternatively, you can use ethtool (version 1.6
|
||||
or later), lspci, and ifconfig to obtain the same information.
|
||||
|
||||
Instructions on updating ethtool can be found in the section "Additional
|
||||
Configurations" later in this document.
|
||||
|
||||
For questions related to hardware requirements, refer to the documentation
|
||||
supplied with your Intel PRO/10GbE adapter. All hardware requirements listed
|
||||
apply to use with Linux.
|
||||
|
||||
Identifying Your Adapter
|
||||
========================
|
||||
|
||||
To verify your Intel adapter is supported, find the board ID number on the
|
||||
adapter. Look for a label that has a barcode and a number in the format
|
||||
A12345-001.
|
||||
The following Intel network adapters are compatible with the drivers in this
|
||||
release:
|
||||
|
||||
Use the above information and the Adapter & Driver ID Guide at:
|
||||
Controller Adapter Name Physical Layer
|
||||
---------- ------------ --------------
|
||||
82597EX Intel(R) PRO/10GbE LR/SR/CX4 10G Base-LR (1310 nm optical fiber)
|
||||
Server Adapters 10G Base-SR (850 nm optical fiber)
|
||||
10G Base-CX4(twin-axial copper cabling)
|
||||
|
||||
http://support.intel.com/support/network/adapter/pro100/21397.htm
|
||||
For more information on how to identify your adapter, go to the Adapter &
|
||||
Driver ID Guide at:
|
||||
|
||||
For the latest Intel network drivers for Linux, go to:
|
||||
http://support.intel.com/support/network/sb/CS-012904.htm
|
||||
|
||||
|
||||
Building and Installation
|
||||
=========================
|
||||
|
||||
select m for "Intel(R) PRO/10GbE support" located at:
|
||||
Location:
|
||||
-> Device Drivers
|
||||
-> Network device support (NETDEVICES [=y])
|
||||
-> Ethernet (10000 Mbit) (NETDEV_10000 [=y])
|
||||
1. make modules && make modules_install
|
||||
|
||||
2. Load the module:
|
||||
|
||||
modprobe ixgb <parameter>=<value>
|
||||
|
||||
The insmod command can be used if the full
|
||||
path to the driver module is specified. For example:
|
||||
|
||||
insmod /lib/modules/<KERNEL VERSION>/kernel/drivers/net/ixgb/ixgb.ko
|
||||
|
||||
With 2.6 based kernels also make sure that older ixgb drivers are
|
||||
removed from the kernel, before loading the new module:
|
||||
|
||||
rmmod ixgb; modprobe ixgb
|
||||
|
||||
3. Assign an IP address to the interface by entering the following, where
|
||||
x is the interface number:
|
||||
|
||||
ifconfig ethx <IP_address>
|
||||
|
||||
4. Verify that the interface works. Enter the following, where <IP_address>
|
||||
is the IP address for another machine on the same subnet as the interface
|
||||
that is being tested:
|
||||
|
||||
ping <IP_address>
|
||||
|
||||
http://downloadfinder.intel.com/scripts-df/support_intel.asp
|
||||
|
||||
Command Line Parameters
|
||||
=======================
|
||||
|
||||
If the driver is built as a module, the following optional parameters are
|
||||
used by entering them on the command line with the modprobe or insmod command
|
||||
using this syntax:
|
||||
If the driver is built as a module, the following optional parameters are
|
||||
used by entering them on the command line with the modprobe command using
|
||||
this syntax:
|
||||
|
||||
modprobe ixgb [<option>=<VAL1>,<VAL2>,...]
|
||||
|
||||
insmod ixgb [<option>=<VAL1>,<VAL2>,...]
|
||||
For example, with two 10GbE PCI adapters, entering:
|
||||
|
||||
For example, with two PRO/10GbE PCI adapters, entering:
|
||||
modprobe ixgb TxDescriptors=80,128
|
||||
|
||||
insmod ixgb TxDescriptors=80,128
|
||||
|
||||
loads the ixgb driver with 80 TX resources for the first adapter and 128 TX
|
||||
loads the ixgb driver with 80 TX resources for the first adapter and 128 TX
|
||||
resources for the second adapter.
|
||||
|
||||
The default value for each parameter is generally the recommended setting,
|
||||
unless otherwise noted. Also, if the driver is statically built into the
|
||||
kernel, the driver is loaded with the default values for all the parameters.
|
||||
Ethtool can be used to change some of the parameters at runtime.
|
||||
unless otherwise noted.
|
||||
|
||||
FlowControl
|
||||
Valid Range: 0-3 (0=none, 1=Rx only, 2=Tx only, 3=Rx&Tx)
|
||||
Default: Read from the EEPROM
|
||||
If EEPROM is not detected, default is 3
|
||||
This parameter controls the automatic generation(Tx) and response(Rx) to
|
||||
Ethernet PAUSE frames.
|
||||
If EEPROM is not detected, default is 1
|
||||
This parameter controls the automatic generation(Tx) and response(Rx) to
|
||||
Ethernet PAUSE frames. There are hardware bugs associated with enabling
|
||||
Tx flow control so beware.
|
||||
|
||||
RxDescriptors
|
||||
Valid Range: 64-512
|
||||
Default Value: 512
|
||||
This value is the number of receive descriptors allocated by the driver.
|
||||
Increasing this value allows the driver to buffer more incoming packets.
|
||||
Each descriptor is 16 bytes. A receive buffer is also allocated for
|
||||
each descriptor and can be either 2048, 4056, 8192, or 16384 bytes,
|
||||
depending on the MTU setting. When the MTU size is 1500 or less, the
|
||||
This value is the number of receive descriptors allocated by the driver.
|
||||
Increasing this value allows the driver to buffer more incoming packets.
|
||||
Each descriptor is 16 bytes. A receive buffer is also allocated for
|
||||
each descriptor and can be either 2048, 4056, 8192, or 16384 bytes,
|
||||
depending on the MTU setting. When the MTU size is 1500 or less, the
|
||||
receive buffer size is 2048 bytes. When the MTU is greater than 1500 the
|
||||
receive buffer size will be either 4056, 8192, or 16384 bytes. The
|
||||
receive buffer size will be either 4056, 8192, or 16384 bytes. The
|
||||
maximum MTU size is 16114.
|
||||
|
||||
RxIntDelay
|
||||
Valid Range: 0-65535 (0=off)
|
||||
Default Value: 6
|
||||
This value delays the generation of receive interrupts in units of
|
||||
0.8192 microseconds. Receive interrupt reduction can improve CPU
|
||||
efficiency if properly tuned for specific network traffic. Increasing
|
||||
this value adds extra latency to frame reception and can end up
|
||||
decreasing the throughput of TCP traffic. If the system is reporting
|
||||
dropped receives, this value may be set too high, causing the driver to
|
||||
Default Value: 72
|
||||
This value delays the generation of receive interrupts in units of
|
||||
0.8192 microseconds. Receive interrupt reduction can improve CPU
|
||||
efficiency if properly tuned for specific network traffic. Increasing
|
||||
this value adds extra latency to frame reception and can end up
|
||||
decreasing the throughput of TCP traffic. If the system is reporting
|
||||
dropped receives, this value may be set too high, causing the driver to
|
||||
run out of available receive descriptors.
|
||||
|
||||
TxDescriptors
|
||||
Valid Range: 64-4096
|
||||
Default Value: 256
|
||||
This value is the number of transmit descriptors allocated by the driver.
|
||||
Increasing this value allows the driver to queue more transmits. Each
|
||||
Increasing this value allows the driver to queue more transmits. Each
|
||||
descriptor is 16 bytes.
|
||||
|
||||
XsumRX
|
||||
|
@ -105,51 +162,49 @@ Default Value: 1
|
|||
A value of '1' indicates that the driver should enable IP checksum
|
||||
offload for received packets (both UDP and TCP) to the adapter hardware.
|
||||
|
||||
XsumTX
|
||||
Valid Range: 0-1
|
||||
Default Value: 1
|
||||
A value of '1' indicates that the driver should enable IP checksum
|
||||
offload for transmitted packets (both UDP and TCP) to the adapter
|
||||
hardware.
|
||||
|
||||
Improving Performance
|
||||
=====================
|
||||
|
||||
With the Intel PRO/10 GbE adapter, the default Linux configuration will very
|
||||
likely limit the total available throughput artificially. There is a set of
|
||||
things that when applied together increase the ability of Linux to transmit
|
||||
and receive data. The following enhancements were originally acquired from
|
||||
settings published at http://www.spec.org/web99 for various submitted results
|
||||
using Linux.
|
||||
With the 10 Gigabit server adapters, the default Linux configuration will
|
||||
very likely limit the total available throughput artificially. There is a set
|
||||
of configuration changes that, when applied together, will increase the ability
|
||||
of Linux to transmit and receive data. The following enhancements were
|
||||
originally acquired from settings published at http://www.spec.org/web99/ for
|
||||
various submitted results using Linux.
|
||||
|
||||
NOTE: These changes are only suggestions, and serve as a starting point for
|
||||
tuning your network performance.
|
||||
NOTE: These changes are only suggestions, and serve as a starting point for
|
||||
tuning your network performance.
|
||||
|
||||
The changes are made in three major ways, listed in order of greatest effect:
|
||||
- Use ifconfig to modify the mtu (maximum transmission unit) and the txqueuelen
|
||||
- Use ifconfig to modify the mtu (maximum transmission unit) and the txqueuelen
|
||||
parameter.
|
||||
- Use sysctl to modify /proc parameters (essentially kernel tuning)
|
||||
- Use setpci to modify the MMRBC field in PCI-X configuration space to increase
|
||||
- Use setpci to modify the MMRBC field in PCI-X configuration space to increase
|
||||
transmit burst lengths on the bus.
|
||||
|
||||
NOTE: setpci modifies the adapter's configuration registers to allow it to read
|
||||
up to 4k bytes at a time (for transmits). However, for some systems the
|
||||
behavior after modifying this register may be undefined (possibly errors of some
|
||||
kind). A power-cycle, hard reset or explicitly setting the e6 register back to
|
||||
22 (setpci -d 8086:1048 e6.b=22) may be required to get back to a stable
|
||||
configuration.
|
||||
NOTE: setpci modifies the adapter's configuration registers to allow it to read
|
||||
up to 4k bytes at a time (for transmits). However, for some systems the
|
||||
behavior after modifying this register may be undefined (possibly errors of
|
||||
some kind). A power-cycle, hard reset or explicitly setting the e6 register
|
||||
back to 22 (setpci -d 8086:1a48 e6.b=22) may be required to get back to a
|
||||
stable configuration.
|
||||
|
||||
- COPY these lines and paste them into ixgb_perf.sh:
|
||||
#!/bin/bash
|
||||
echo "configuring network performance , edit this file to change the interface"
|
||||
echo "configuring network performance , edit this file to change the interface
|
||||
or device ID of 10GbE card"
|
||||
# set mmrbc to 4k reads, modify only Intel 10GbE device IDs
|
||||
setpci -d 8086:1048 e6.b=2e
|
||||
# set the MTU (max transmission unit) - it requires your switch and clients to change too!
|
||||
# replace 1a48 with appropriate 10GbE device's ID installed on the system,
|
||||
# if needed.
|
||||
setpci -d 8086:1a48 e6.b=2e
|
||||
# set the MTU (max transmission unit) - it requires your switch and clients
|
||||
# to change as well.
|
||||
# set the txqueuelen
|
||||
# your ixgb adapter should be loaded as eth1 for this to work, change if needed
|
||||
ifconfig eth1 mtu 9000 txqueuelen 1000 up
|
||||
# call the sysctl utility to modify /proc/sys entries
|
||||
sysctl -p ./sysctl_ixgb.conf
|
||||
# call the sysctl utility to modify /proc/sys entries
|
||||
sysctl -p ./sysctl_ixgb.conf
|
||||
- END ixgb_perf.sh
|
||||
|
||||
- COPY these lines and paste them into sysctl_ixgb.conf:
|
||||
|
@ -159,54 +214,220 @@ sysctl -p ./sysctl_ixgb.conf
|
|||
# several network benchmark tests, your mileage may vary
|
||||
|
||||
### IPV4 specific settings
|
||||
net.ipv4.tcp_timestamps = 0 # turns TCP timestamp support off, default 1, reduces CPU use
|
||||
net.ipv4.tcp_sack = 0 # turn SACK support off, default on
|
||||
# on systems with a VERY fast bus -> memory interface this is the big gainer
|
||||
net.ipv4.tcp_rmem = 10000000 10000000 10000000 # sets min/default/max TCP read buffer, default 4096 87380 174760
|
||||
net.ipv4.tcp_wmem = 10000000 10000000 10000000 # sets min/pressure/max TCP write buffer, default 4096 16384 131072
|
||||
net.ipv4.tcp_mem = 10000000 10000000 10000000 # sets min/pressure/max TCP buffer space, default 31744 32256 32768
|
||||
# turn TCP timestamp support off, default 1, reduces CPU use
|
||||
net.ipv4.tcp_timestamps = 0
|
||||
# turn SACK support off, default on
|
||||
# on systems with a VERY fast bus -> memory interface this is the big gainer
|
||||
net.ipv4.tcp_sack = 0
|
||||
# set min/default/max TCP read buffer, default 4096 87380 174760
|
||||
net.ipv4.tcp_rmem = 10000000 10000000 10000000
|
||||
# set min/pressure/max TCP write buffer, default 4096 16384 131072
|
||||
net.ipv4.tcp_wmem = 10000000 10000000 10000000
|
||||
# set min/pressure/max TCP buffer space, default 31744 32256 32768
|
||||
net.ipv4.tcp_mem = 10000000 10000000 10000000
|
||||
|
||||
### CORE settings (mostly for socket and UDP effect)
|
||||
net.core.rmem_max = 524287 # maximum receive socket buffer size, default 131071
|
||||
net.core.wmem_max = 524287 # maximum send socket buffer size, default 131071
|
||||
net.core.rmem_default = 524287 # default receive socket buffer size, default 65535
|
||||
net.core.wmem_default = 524287 # default send socket buffer size, default 65535
|
||||
net.core.optmem_max = 524287 # maximum amount of option memory buffers, default 10240
|
||||
net.core.netdev_max_backlog = 300000 # number of unprocessed input packets before kernel starts dropping them, default 300
|
||||
# set maximum receive socket buffer size, default 131071
|
||||
net.core.rmem_max = 524287
|
||||
# set maximum send socket buffer size, default 131071
|
||||
net.core.wmem_max = 524287
|
||||
# set default receive socket buffer size, default 65535
|
||||
net.core.rmem_default = 524287
|
||||
# set default send socket buffer size, default 65535
|
||||
net.core.wmem_default = 524287
|
||||
# set maximum amount of option memory buffers, default 10240
|
||||
net.core.optmem_max = 524287
|
||||
# set number of unprocessed input packets before kernel starts dropping them; default 300
|
||||
net.core.netdev_max_backlog = 300000
|
||||
- END sysctl_ixgb.conf
|
||||
|
||||
Edit the ixgb_perf.sh script if necessary to change eth1 to whatever interface
|
||||
your ixgb driver is using.
|
||||
Edit the ixgb_perf.sh script if necessary to change eth1 to whatever interface
|
||||
your ixgb driver is using and/or replace '1a48' with appropriate 10GbE device's
|
||||
ID installed on the system.
|
||||
|
||||
NOTE: Unless these scripts are added to the boot process, these changes will
|
||||
only last only until the next system reboot.
|
||||
NOTE: Unless these scripts are added to the boot process, these changes will
|
||||
only last only until the next system reboot.
|
||||
|
||||
|
||||
Resolving Slow UDP Traffic
|
||||
--------------------------
|
||||
If your server does not seem to be able to receive UDP traffic as fast as it
|
||||
can receive TCP traffic, it could be because Linux, by default, does not set
|
||||
the network stack buffers as large as they need to be to support high UDP
|
||||
transfer rates. One way to alleviate this problem is to allow more memory to
|
||||
be used by the IP stack to store incoming data.
|
||||
|
||||
If your server does not seem to be able to receive UDP traffic as fast as it
|
||||
can receive TCP traffic, it could be because Linux, by default, does not set
|
||||
the network stack buffers as large as they need to be to support high UDP
|
||||
transfer rates. One way to alleviate this problem is to allow more memory to
|
||||
be used by the IP stack to store incoming data.
|
||||
|
||||
For instance, use the commands:
|
||||
For instance, use the commands:
|
||||
sysctl -w net.core.rmem_max=262143
|
||||
and
|
||||
sysctl -w net.core.rmem_default=262143
|
||||
to increase the read buffer memory max and default to 262143 (256k - 1) from
|
||||
defaults of max=131071 (128k - 1) and default=65535 (64k - 1). These variables
|
||||
will increase the amount of memory used by the network stack for receives, and
|
||||
to increase the read buffer memory max and default to 262143 (256k - 1) from
|
||||
defaults of max=131071 (128k - 1) and default=65535 (64k - 1). These variables
|
||||
will increase the amount of memory used by the network stack for receives, and
|
||||
can be increased significantly more if necessary for your application.
|
||||
|
||||
|
||||
Additional Configurations
|
||||
=========================
|
||||
|
||||
Configuring the Driver on Different Distributions
|
||||
-------------------------------------------------
|
||||
Configuring a network driver to load properly when the system is started is
|
||||
distribution dependent. Typically, the configuration process involves adding
|
||||
an alias line to /etc/modprobe.conf as well as editing other system startup
|
||||
scripts and/or configuration files. Many popular Linux distributions ship
|
||||
with tools to make these changes for you. To learn the proper way to
|
||||
configure a network device for your system, refer to your distribution
|
||||
documentation. If during this process you are asked for the driver or module
|
||||
name, the name for the Linux Base Driver for the Intel 10GbE Family of
|
||||
Adapters is ixgb.
|
||||
|
||||
Viewing Link Messages
|
||||
---------------------
|
||||
Link messages will not be displayed to the console if the distribution is
|
||||
restricting system messages. In order to see network driver link messages on
|
||||
your console, set dmesg to eight by entering the following:
|
||||
|
||||
dmesg -n 8
|
||||
|
||||
NOTE: This setting is not saved across reboots.
|
||||
|
||||
|
||||
Jumbo Frames
|
||||
------------
|
||||
The driver supports Jumbo Frames for all adapters. Jumbo Frames support is
|
||||
enabled by changing the MTU to a value larger than the default of 1500.
|
||||
The maximum value for the MTU is 16114. Use the ifconfig command to
|
||||
increase the MTU size. For example:
|
||||
|
||||
ifconfig ethx mtu 9000 up
|
||||
|
||||
The maximum MTU setting for Jumbo Frames is 16114. This value coincides
|
||||
with the maximum Jumbo Frames size of 16128.
|
||||
|
||||
|
||||
Ethtool
|
||||
-------
|
||||
The driver utilizes the ethtool interface for driver configuration and
|
||||
diagnostics, as well as displaying statistical information. Ethtool
|
||||
version 1.6 or later is required for this functionality.
|
||||
|
||||
The latest release of ethtool can be found from
|
||||
http://sourceforge.net/projects/gkernel
|
||||
|
||||
NOTE: Ethtool 1.6 only supports a limited set of ethtool options. Support
|
||||
for a more complete ethtool feature set can be enabled by upgrading
|
||||
to the latest version.
|
||||
|
||||
|
||||
NAPI
|
||||
----
|
||||
|
||||
NAPI (Rx polling mode) is supported in the ixgb driver. NAPI is enabled
|
||||
or disabled based on the configuration of the kernel. see CONFIG_IXGB_NAPI
|
||||
|
||||
See www.cyberus.ca/~hadi/usenix-paper.tgz for more information on NAPI.
|
||||
|
||||
|
||||
Known Issues/Troubleshooting
|
||||
============================
|
||||
|
||||
NOTE: After installing the driver, if your Intel Network Connection is not
|
||||
working, verify in the "In This Release" section of the readme that you have
|
||||
installed the correct driver.
|
||||
|
||||
Intel(R) PRO/10GbE CX4 Server Adapter Cable Interoperability Issue with
|
||||
Fujitsu XENPAK Module in SmartBits Chassis
|
||||
---------------------------------------------------------------------
|
||||
Excessive CRC errors may be observed if the Intel(R) PRO/10GbE CX4
|
||||
Server adapter is connected to a Fujitsu XENPAK CX4 module in a SmartBits
|
||||
chassis using 15 m/24AWG cable assemblies manufactured by Fujitsu or Leoni.
|
||||
The CRC errors may be received either by the Intel(R) PRO/10GbE CX4
|
||||
Server adapter or the SmartBits. If this situation occurs using a different
|
||||
cable assembly may resolve the issue.
|
||||
|
||||
CX4 Server Adapter Cable Interoperability Issues with HP Procurve 3400cl
|
||||
Switch Port
|
||||
------------------------------------------------------------------------
|
||||
Excessive CRC errors may be observed if the Intel(R) PRO/10GbE CX4 Server
|
||||
adapter is connected to an HP Procurve 3400cl switch port using short cables
|
||||
(1 m or shorter). If this situation occurs, using a longer cable may resolve
|
||||
the issue.
|
||||
|
||||
Excessive CRC errors may be observed using Fujitsu 24AWG cable assemblies that
|
||||
Are 10 m or longer or where using a Leoni 15 m/24AWG cable assembly. The CRC
|
||||
errors may be received either by the CX4 Server adapter or at the switch. If
|
||||
this situation occurs, using a different cable assembly may resolve the issue.
|
||||
|
||||
|
||||
Jumbo Frames System Requirement
|
||||
-------------------------------
|
||||
Memory allocation failures have been observed on Linux systems with 64 MB
|
||||
of RAM or less that are running Jumbo Frames. If you are using Jumbo
|
||||
Frames, your system may require more than the advertised minimum
|
||||
requirement of 64 MB of system memory.
|
||||
|
||||
|
||||
Performance Degradation with Jumbo Frames
|
||||
-----------------------------------------
|
||||
Degradation in throughput performance may be observed in some Jumbo frames
|
||||
environments. If this is observed, increasing the application's socket buffer
|
||||
size and/or increasing the /proc/sys/net/ipv4/tcp_*mem entry values may help.
|
||||
See the specific application manual and /usr/src/linux*/Documentation/
|
||||
networking/ip-sysctl.txt for more details.
|
||||
|
||||
|
||||
Allocating Rx Buffers when Using Jumbo Frames
|
||||
---------------------------------------------
|
||||
Allocating Rx buffers when using Jumbo Frames on 2.6.x kernels may fail if
|
||||
the available memory is heavily fragmented. This issue may be seen with PCI-X
|
||||
adapters or with packet split disabled. This can be reduced or eliminated
|
||||
by changing the amount of available memory for receive buffer allocation, by
|
||||
increasing /proc/sys/vm/min_free_kbytes.
|
||||
|
||||
|
||||
Multiple Interfaces on Same Ethernet Broadcast Network
|
||||
------------------------------------------------------
|
||||
Due to the default ARP behavior on Linux, it is not possible to have
|
||||
one system on two IP networks in the same Ethernet broadcast domain
|
||||
(non-partitioned switch) behave as expected. All Ethernet interfaces
|
||||
will respond to IP traffic for any IP address assigned to the system.
|
||||
This results in unbalanced receive traffic.
|
||||
|
||||
If you have multiple interfaces in a server, do either of the following:
|
||||
|
||||
- Turn on ARP filtering by entering:
|
||||
echo 1 > /proc/sys/net/ipv4/conf/all/arp_filter
|
||||
|
||||
- Install the interfaces in separate broadcast domains - either in
|
||||
different switches or in a switch partitioned to VLANs.
|
||||
|
||||
|
||||
UDP Stress Test Dropped Packet Issue
|
||||
--------------------------------------
|
||||
Under small packets UDP stress test with 10GbE driver, the Linux system
|
||||
may drop UDP packets due to the fullness of socket buffers. You may want
|
||||
to change the driver's Flow Control variables to the minimum value for
|
||||
controlling packet reception.
|
||||
|
||||
|
||||
Tx Hangs Possible Under Stress
|
||||
------------------------------
|
||||
Under stress conditions, if TX hangs occur, turning off TSO
|
||||
"ethtool -K eth0 tso off" may resolve the problem.
|
||||
|
||||
|
||||
Support
|
||||
=======
|
||||
|
||||
For general information and support, go to the Intel support website at:
|
||||
For general information, go to the Intel support website at:
|
||||
|
||||
http://support.intel.com
|
||||
|
||||
or the Intel Wired Networking project hosted by Sourceforge at:
|
||||
|
||||
http://sourceforge.net/projects/e1000
|
||||
|
||||
If an issue is identified with the released source code on the supported
|
||||
kernel with a supported adapter, email the specific information related to
|
||||
the issue to linux.nics@intel.com.
|
||||
kernel with a supported adapter, email the specific information related
|
||||
to the issue to e1000-devel@lists.sf.net
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
|
||||
Copyright (c) 2008, Jouni Malinen <j@w1.fi>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
|
||||
Introduction
|
||||
|
||||
mac80211_hwsim is a Linux kernel module that can be used to simulate
|
||||
arbitrary number of IEEE 802.11 radios for mac80211. It can be used to
|
||||
test most of the mac80211 functionality and user space tools (e.g.,
|
||||
hostapd and wpa_supplicant) in a way that matches very closely with
|
||||
the normal case of using real WLAN hardware. From the mac80211 view
|
||||
point, mac80211_hwsim is yet another hardware driver, i.e., no changes
|
||||
to mac80211 are needed to use this testing tool.
|
||||
|
||||
The main goal for mac80211_hwsim is to make it easier for developers
|
||||
to test their code and work with new features to mac80211, hostapd,
|
||||
and wpa_supplicant. The simulated radios do not have the limitations
|
||||
of real hardware, so it is easy to generate an arbitrary test setup
|
||||
and always reproduce the same setup for future tests. In addition,
|
||||
since all radio operation is simulated, any channel can be used in
|
||||
tests regardless of regulatory rules.
|
||||
|
||||
mac80211_hwsim kernel module has a parameter 'radios' that can be used
|
||||
to select how many radios are simulated (default 2). This allows
|
||||
configuration of both very simply setups (e.g., just a single access
|
||||
point and a station) or large scale tests (multiple access points with
|
||||
hundreds of stations).
|
||||
|
||||
mac80211_hwsim works by tracking the current channel of each virtual
|
||||
radio and copying all transmitted frames to all other radios that are
|
||||
currently enabled and on the same channel as the transmitting
|
||||
radio. Software encryption in mac80211 is used so that the frames are
|
||||
actually encrypted over the virtual air interface to allow more
|
||||
complete testing of encryption.
|
||||
|
||||
A global monitoring netdev, hwsim#, is created independent of
|
||||
mac80211. This interface can be used to monitor all transmitted frames
|
||||
regardless of channel.
|
||||
|
||||
|
||||
Simple example
|
||||
|
||||
This example shows how to use mac80211_hwsim to simulate two radios:
|
||||
one to act as an access point and the other as a station that
|
||||
associates with the AP. hostapd and wpa_supplicant are used to take
|
||||
care of WPA2-PSK authentication. In addition, hostapd is also
|
||||
processing access point side of association.
|
||||
|
||||
Please note that the current Linux kernel does not enable AP mode, so a
|
||||
simple patch is needed to enable AP mode selection:
|
||||
http://johannes.sipsolutions.net/patches/kernel/all/LATEST/006-allow-ap-vlan-modes.patch
|
||||
|
||||
|
||||
# Build mac80211_hwsim as part of kernel configuration
|
||||
|
||||
# Load the module
|
||||
modprobe mac80211_hwsim
|
||||
|
||||
# Run hostapd (AP) for wlan0
|
||||
hostapd hostapd.conf
|
||||
|
||||
# Run wpa_supplicant (station) for wlan1
|
||||
wpa_supplicant -Dwext -iwlan1 -c wpa_supplicant.conf
|
|
@ -0,0 +1,11 @@
|
|||
interface=wlan0
|
||||
driver=nl80211
|
||||
|
||||
hw_mode=g
|
||||
channel=1
|
||||
ssid=mac80211 test
|
||||
|
||||
wpa=2
|
||||
wpa_key_mgmt=WPA-PSK
|
||||
wpa_pairwise=CCMP
|
||||
wpa_passphrase=12345678
|
|
@ -0,0 +1,10 @@
|
|||
ctrl_interface=/var/run/wpa_supplicant
|
||||
|
||||
network={
|
||||
ssid="mac80211 test"
|
||||
psk="12345678"
|
||||
key_mgmt=WPA-PSK
|
||||
proto=WPA2
|
||||
pairwise=CCMP
|
||||
group=CCMP
|
||||
}
|
|
@ -3,19 +3,11 @@
|
|||
===========================================
|
||||
|
||||
Section 1: Base driver requirements for implementing multiqueue support
|
||||
Section 2: Qdisc support for multiqueue devices
|
||||
Section 3: Brief howto using PRIO or RR for multiqueue devices
|
||||
|
||||
|
||||
Intro: Kernel support for multiqueue devices
|
||||
---------------------------------------------------------
|
||||
|
||||
Kernel support for multiqueue devices is only an API that is presented to the
|
||||
netdevice layer for base drivers to implement. This feature is part of the
|
||||
core networking stack, and all network devices will be running on the
|
||||
multiqueue-aware stack. If a base driver only has one queue, then these
|
||||
changes are transparent to that driver.
|
||||
|
||||
Kernel support for multiqueue devices is always present.
|
||||
|
||||
Section 1: Base driver requirements for implementing multiqueue support
|
||||
-----------------------------------------------------------------------
|
||||
|
@ -32,84 +24,4 @@ netif_{start|stop|wake}_subqueue() functions to manage each queue while the
|
|||
device is still operational. netdev->queue_lock is still used when the device
|
||||
comes online or when it's completely shut down (unregister_netdev(), etc.).
|
||||
|
||||
Finally, the base driver should indicate that it is a multiqueue device. The
|
||||
feature flag NETIF_F_MULTI_QUEUE should be added to the netdev->features
|
||||
bitmap on device initialization. Below is an example from e1000:
|
||||
|
||||
#ifdef CONFIG_E1000_MQ
|
||||
if ( (adapter->hw.mac.type == e1000_82571) ||
|
||||
(adapter->hw.mac.type == e1000_82572) ||
|
||||
(adapter->hw.mac.type == e1000_80003es2lan))
|
||||
netdev->features |= NETIF_F_MULTI_QUEUE;
|
||||
#endif
|
||||
|
||||
|
||||
Section 2: Qdisc support for multiqueue devices
|
||||
-----------------------------------------------
|
||||
|
||||
Currently two qdiscs support multiqueue devices. A new round-robin qdisc,
|
||||
sch_rr, and sch_prio. The qdisc is responsible for classifying the skb's to
|
||||
bands and queues, and will store the queue mapping into skb->queue_mapping.
|
||||
Use this field in the base driver to determine which queue to send the skb
|
||||
to.
|
||||
|
||||
sch_rr has been added for hardware that doesn't want scheduling policies from
|
||||
software, so it's a straight round-robin qdisc. It uses the same syntax and
|
||||
classification priomap that sch_prio uses, so it should be intuitive to
|
||||
configure for people who've used sch_prio.
|
||||
|
||||
In order to utilitize the multiqueue features of the qdiscs, the network
|
||||
device layer needs to enable multiple queue support. This can be done by
|
||||
selecting NETDEVICES_MULTIQUEUE under Drivers.
|
||||
|
||||
The PRIO qdisc naturally plugs into a multiqueue device. If
|
||||
NETDEVICES_MULTIQUEUE is selected, then on qdisc load, the number of
|
||||
bands requested is compared to the number of queues on the hardware. If they
|
||||
are equal, it sets a one-to-one mapping up between the queues and bands. If
|
||||
they're not equal, it will not load the qdisc. This is the same behavior
|
||||
for RR. Once the association is made, any skb that is classified will have
|
||||
skb->queue_mapping set, which will allow the driver to properly queue skb's
|
||||
to multiple queues.
|
||||
|
||||
|
||||
Section 3: Brief howto using PRIO and RR for multiqueue devices
|
||||
---------------------------------------------------------------
|
||||
|
||||
The userspace command 'tc,' part of the iproute2 package, is used to configure
|
||||
qdiscs. To add the PRIO qdisc to your network device, assuming the device is
|
||||
called eth0, run the following command:
|
||||
|
||||
# tc qdisc add dev eth0 root handle 1: prio bands 4 multiqueue
|
||||
|
||||
This will create 4 bands, 0 being highest priority, and associate those bands
|
||||
to the queues on your NIC. Assuming eth0 has 4 Tx queues, the band mapping
|
||||
would look like:
|
||||
|
||||
band 0 => queue 0
|
||||
band 1 => queue 1
|
||||
band 2 => queue 2
|
||||
band 3 => queue 3
|
||||
|
||||
Traffic will begin flowing through each queue if your TOS values are assigning
|
||||
traffic across the various bands. For example, ssh traffic will always try to
|
||||
go out band 0 based on TOS -> Linux priority conversion (realtime traffic),
|
||||
so it will be sent out queue 0. ICMP traffic (pings) fall into the "normal"
|
||||
traffic classification, which is band 1. Therefore pings will be send out
|
||||
queue 1 on the NIC.
|
||||
|
||||
Note the use of the multiqueue keyword. This is only in versions of iproute2
|
||||
that support multiqueue networking devices; if this is omitted when loading
|
||||
a qdisc onto a multiqueue device, the qdisc will load and operate the same
|
||||
if it were loaded onto a single-queue device (i.e. - sends all traffic to
|
||||
queue 0).
|
||||
|
||||
Another alternative to multiqueue band allocation can be done by using the
|
||||
multiqueue option and specify 0 bands. If this is the case, the qdisc will
|
||||
allocate the number of bands to equal the number of queues that the device
|
||||
reports, and bring the qdisc online.
|
||||
|
||||
The behavior of tc filters remains the same, where it will override TOS priority
|
||||
classification.
|
||||
|
||||
|
||||
Author: Peter P. Waskiewicz Jr. <peter.p.waskiewicz.jr@intel.com>
|
||||
|
|
|
@ -52,13 +52,10 @@ d. MSI/MSI-X. Can be enabled on platforms which support this feature
|
|||
(IA64, Xeon) resulting in noticeable performance improvement(upto 7%
|
||||
on certain platforms).
|
||||
|
||||
e. NAPI. Compile-time option(CONFIG_S2IO_NAPI) for better Rx interrupt
|
||||
moderation.
|
||||
|
||||
f. Statistics. Comprehensive MAC-level and software statistics displayed
|
||||
e. Statistics. Comprehensive MAC-level and software statistics displayed
|
||||
using "ethtool -S" option.
|
||||
|
||||
g. Multi-FIFO/Ring. Supports up to 8 transmit queues and receive rings,
|
||||
f. Multi-FIFO/Ring. Supports up to 8 transmit queues and receive rings,
|
||||
with multiple steering options.
|
||||
|
||||
4. Command line parameters
|
||||
|
|
|
@ -41,12 +41,24 @@ Table of Contents
|
|||
VI - System-on-a-chip devices and nodes
|
||||
1) Defining child nodes of an SOC
|
||||
2) Representing devices without a current OF specification
|
||||
a) PHY nodes
|
||||
b) Interrupt controllers
|
||||
c) CFI or JEDEC memory-mapped NOR flash
|
||||
d) 4xx/Axon EMAC ethernet nodes
|
||||
e) Xilinx IP cores
|
||||
f) USB EHCI controllers
|
||||
a) MDIO IO device
|
||||
b) Gianfar-compatible ethernet nodes
|
||||
c) PHY nodes
|
||||
d) Interrupt controllers
|
||||
e) I2C
|
||||
f) Freescale SOC USB controllers
|
||||
g) Freescale SOC SEC Security Engines
|
||||
h) Board Control and Status (BCSR)
|
||||
i) Freescale QUICC Engine module (QE)
|
||||
j) CFI or JEDEC memory-mapped NOR flash
|
||||
k) Global Utilities Block
|
||||
l) Freescale Communications Processor Module
|
||||
m) Chipselect/Local Bus
|
||||
n) 4xx/Axon EMAC ethernet nodes
|
||||
o) Xilinx IP cores
|
||||
p) Freescale Synchronous Serial Interface
|
||||
q) USB EHCI controllers
|
||||
r) MDIO on GPIOs
|
||||
|
||||
VII - Marvell Discovery mv64[345]6x System Controller chips
|
||||
1) The /system-controller node
|
||||
|
@ -1817,6 +1829,60 @@ platforms are moved over to use the flattened-device-tree model.
|
|||
big-endian;
|
||||
};
|
||||
|
||||
r) Freescale Display Interface Unit
|
||||
|
||||
The Freescale DIU is a LCD controller, with proper hardware, it can also
|
||||
drive DVI monitors.
|
||||
|
||||
Required properties:
|
||||
- compatible : should be "fsl-diu".
|
||||
- reg : should contain at least address and length of the DIU register
|
||||
set.
|
||||
- Interrupts : one DIU interrupt should be describe here.
|
||||
|
||||
Example (MPC8610HPCD)
|
||||
display@2c000 {
|
||||
compatible = "fsl,diu";
|
||||
reg = <0x2c000 100>;
|
||||
interrupts = <72 2>;
|
||||
interrupt-parent = <&mpic>;
|
||||
};
|
||||
|
||||
s) Freescale on board FPGA
|
||||
|
||||
This is the memory-mapped registers for on board FPGA.
|
||||
|
||||
Required properities:
|
||||
- compatible : should be "fsl,fpga-pixis".
|
||||
- reg : should contain the address and the lenght of the FPPGA register
|
||||
set.
|
||||
|
||||
Example (MPC8610HPCD)
|
||||
board-control@e8000000 {
|
||||
compatible = "fsl,fpga-pixis";
|
||||
reg = <0xe8000000 32>;
|
||||
};
|
||||
|
||||
r) MDIO on GPIOs
|
||||
|
||||
Currently defined compatibles:
|
||||
- virtual,gpio-mdio
|
||||
|
||||
MDC and MDIO lines connected to GPIO controllers are listed in the
|
||||
gpios property as described in section VIII.1 in the following order:
|
||||
|
||||
MDC, MDIO.
|
||||
|
||||
Example:
|
||||
|
||||
mdio {
|
||||
compatible = "virtual,mdio-gpio";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
gpios = <&qe_pio_a 11
|
||||
&qe_pio_c 6>;
|
||||
};
|
||||
|
||||
VII - Marvell Discovery mv64[345]6x System Controller chips
|
||||
===========================================================
|
||||
|
||||
|
|
|
@ -1,89 +1,528 @@
|
|||
rfkill - RF switch subsystem support
|
||||
====================================
|
||||
|
||||
1 Implementation details
|
||||
2 Driver support
|
||||
3 Userspace support
|
||||
1 Introduction
|
||||
2 Implementation details
|
||||
3 Kernel driver guidelines
|
||||
3.1 wireless device drivers
|
||||
3.2 platform/switch drivers
|
||||
3.3 input device drivers
|
||||
4 Kernel API
|
||||
5 Userspace support
|
||||
|
||||
|
||||
1. Introduction:
|
||||
|
||||
The rfkill switch subsystem exists to add a generic interface to circuitry that
|
||||
can enable or disable the signal output of a wireless *transmitter* of any
|
||||
type. By far, the most common use is to disable radio-frequency transmitters.
|
||||
|
||||
Note that disabling the signal output means that the the transmitter is to be
|
||||
made to not emit any energy when "blocked". rfkill is not about blocking data
|
||||
transmissions, it is about blocking energy emission.
|
||||
|
||||
The rfkill subsystem offers support for keys and switches often found on
|
||||
laptops to enable wireless devices like WiFi and Bluetooth, so that these keys
|
||||
and switches actually perform an action in all wireless devices of a given type
|
||||
attached to the system.
|
||||
|
||||
The buttons to enable and disable the wireless transmitters are important in
|
||||
situations where the user is for example using his laptop on a location where
|
||||
radio-frequency transmitters _must_ be disabled (e.g. airplanes).
|
||||
|
||||
Because of this requirement, userspace support for the keys should not be made
|
||||
mandatory. Because userspace might want to perform some additional smarter
|
||||
tasks when the key is pressed, rfkill provides userspace the possibility to
|
||||
take over the task to handle the key events.
|
||||
|
||||
===============================================================================
|
||||
1: Implementation details
|
||||
2: Implementation details
|
||||
|
||||
The rfkill switch subsystem offers support for keys often found on laptops
|
||||
to enable wireless devices like WiFi and Bluetooth.
|
||||
The rfkill subsystem is composed of various components: the rfkill class, the
|
||||
rfkill-input module (an input layer handler), and some specific input layer
|
||||
events.
|
||||
|
||||
This is done by providing the user 3 possibilities:
|
||||
1 - The rfkill system handles all events; userspace is not aware of events.
|
||||
2 - The rfkill system handles all events; userspace is informed about the events.
|
||||
3 - The rfkill system does not handle events; userspace handles all events.
|
||||
The rfkill class provides kernel drivers with an interface that allows them to
|
||||
know when they should enable or disable a wireless network device transmitter.
|
||||
This is enabled by the CONFIG_RFKILL Kconfig option.
|
||||
|
||||
The buttons to enable and disable the wireless radios are important in
|
||||
situations where the user is for example using his laptop on a location where
|
||||
wireless radios _must_ be disabled (e.g. airplanes).
|
||||
Because of this requirement, userspace support for the keys should not be
|
||||
made mandatory. Because userspace might want to perform some additional smarter
|
||||
tasks when the key is pressed, rfkill still provides userspace the possibility
|
||||
to take over the task to handle the key events.
|
||||
The rfkill class support makes sure userspace will be notified of all state
|
||||
changes on rfkill devices through uevents. It provides a notification chain
|
||||
for interested parties in the kernel to also get notified of rfkill state
|
||||
changes in other drivers. It creates several sysfs entries which can be used
|
||||
by userspace. See section "Userspace support".
|
||||
|
||||
The system inside the kernel has been split into 2 separate sections:
|
||||
1 - RFKILL
|
||||
2 - RFKILL_INPUT
|
||||
The rfkill-input module provides the kernel with the ability to implement a
|
||||
basic response when the user presses a key or button (or toggles a switch)
|
||||
related to rfkill functionality. It is an in-kernel implementation of default
|
||||
policy of reacting to rfkill-related input events and neither mandatory nor
|
||||
required for wireless drivers to operate. It is enabled by the
|
||||
CONFIG_RFKILL_INPUT Kconfig option.
|
||||
|
||||
The first option enables rfkill support and will make sure userspace will
|
||||
be notified of any events through the input device. It also creates several
|
||||
sysfs entries which can be used by userspace. See section "Userspace support".
|
||||
rfkill-input is a rfkill-related events input layer handler. This handler will
|
||||
listen to all rfkill key events and will change the rfkill state of the
|
||||
wireless devices accordingly. With this option enabled userspace could either
|
||||
do nothing or simply perform monitoring tasks.
|
||||
|
||||
The second option provides an rfkill input handler. This handler will
|
||||
listen to all rfkill key events and will toggle the radio accordingly.
|
||||
With this option enabled userspace could either do nothing or simply
|
||||
perform monitoring tasks.
|
||||
The rfkill-input module also provides EPO (emergency power-off) functionality
|
||||
for all wireless transmitters. This function cannot be overridden, and it is
|
||||
always active. rfkill EPO is related to *_RFKILL_ALL input layer events.
|
||||
|
||||
|
||||
Important terms for the rfkill subsystem:
|
||||
|
||||
In order to avoid confusion, we avoid the term "switch" in rfkill when it is
|
||||
referring to an electronic control circuit that enables or disables a
|
||||
transmitter. We reserve it for the physical device a human manipulates
|
||||
(which is an input device, by the way):
|
||||
|
||||
rfkill switch:
|
||||
|
||||
A physical device a human manipulates. Its state can be perceived by
|
||||
the kernel either directly (through a GPIO pin, ACPI GPE) or by its
|
||||
effect on a rfkill line of a wireless device.
|
||||
|
||||
rfkill controller:
|
||||
|
||||
A hardware circuit that controls the state of a rfkill line, which a
|
||||
kernel driver can interact with *to modify* that state (i.e. it has
|
||||
either write-only or read/write access).
|
||||
|
||||
rfkill line:
|
||||
|
||||
An input channel (hardware or software) of a wireless device, which
|
||||
causes a wireless transmitter to stop emitting energy (BLOCK) when it
|
||||
is active. Point of view is extremely important here: rfkill lines are
|
||||
always seen from the PoV of a wireless device (and its driver).
|
||||
|
||||
soft rfkill line/software rfkill line:
|
||||
|
||||
A rfkill line the wireless device driver can directly change the state
|
||||
of. Related to rfkill_state RFKILL_STATE_SOFT_BLOCKED.
|
||||
|
||||
hard rfkill line/hardware rfkill line:
|
||||
|
||||
A rfkill line that works fully in hardware or firmware, and that cannot
|
||||
be overridden by the kernel driver. The hardware device or the
|
||||
firmware just exports its status to the driver, but it is read-only.
|
||||
Related to rfkill_state RFKILL_STATE_HARD_BLOCKED.
|
||||
|
||||
The enum rfkill_state describes the rfkill state of a transmitter:
|
||||
|
||||
When a rfkill line or rfkill controller is in the RFKILL_STATE_UNBLOCKED state,
|
||||
the wireless transmitter (radio TX circuit for example) is *enabled*. When the
|
||||
it is in the RFKILL_STATE_SOFT_BLOCKED or RFKILL_STATE_HARD_BLOCKED, the
|
||||
wireless transmitter is to be *blocked* from operating.
|
||||
|
||||
RFKILL_STATE_SOFT_BLOCKED indicates that a call to toggle_radio() can change
|
||||
that state. RFKILL_STATE_HARD_BLOCKED indicates that a call to toggle_radio()
|
||||
will not be able to change the state and will return with a suitable error if
|
||||
attempts are made to set the state to RFKILL_STATE_UNBLOCKED.
|
||||
|
||||
RFKILL_STATE_HARD_BLOCKED is used by drivers to signal that the device is
|
||||
locked in the BLOCKED state by a hardwire rfkill line (typically an input pin
|
||||
that, when active, forces the transmitter to be disabled) which the driver
|
||||
CANNOT override.
|
||||
|
||||
Full rfkill functionality requires two different subsystems to cooperate: the
|
||||
input layer and the rfkill class. The input layer issues *commands* to the
|
||||
entire system requesting that devices registered to the rfkill class change
|
||||
state. The way this interaction happens is not complex, but it is not obvious
|
||||
either:
|
||||
|
||||
Kernel Input layer:
|
||||
|
||||
* Generates KEY_WWAN, KEY_WLAN, KEY_BLUETOOTH, SW_RFKILL_ALL, and
|
||||
other such events when the user presses certain keys, buttons, or
|
||||
toggles certain physical switches.
|
||||
|
||||
THE INPUT LAYER IS NEVER USED TO PROPAGATE STATUS, NOTIFICATIONS OR THE
|
||||
KIND OF STUFF AN ON-SCREEN-DISPLAY APPLICATION WOULD REPORT. It is
|
||||
used to issue *commands* for the system to change behaviour, and these
|
||||
commands may or may not be carried out by some kernel driver or
|
||||
userspace application. It follows that doing user feedback based only
|
||||
on input events is broken, as there is no guarantee that an input event
|
||||
will be acted upon.
|
||||
|
||||
Most wireless communication device drivers implementing rfkill
|
||||
functionality MUST NOT generate these events, and have no reason to
|
||||
register themselves with the input layer. Doing otherwise is a common
|
||||
misconception. There is an API to propagate rfkill status change
|
||||
information, and it is NOT the input layer.
|
||||
|
||||
rfkill class:
|
||||
|
||||
* Calls a hook in a driver to effectively change the wireless
|
||||
transmitter state;
|
||||
* Keeps track of the wireless transmitter state (with help from
|
||||
the driver);
|
||||
* Generates userspace notifications (uevents) and a call to a
|
||||
notification chain (kernel) when there is a wireless transmitter
|
||||
state change;
|
||||
* Connects a wireless communications driver with the common rfkill
|
||||
control system, which, for example, allows actions such as
|
||||
"switch all bluetooth devices offline" to be carried out by
|
||||
userspace or by rfkill-input.
|
||||
|
||||
THE RFKILL CLASS NEVER ISSUES INPUT EVENTS. THE RFKILL CLASS DOES
|
||||
NOT LISTEN TO INPUT EVENTS. NO DRIVER USING THE RFKILL CLASS SHALL
|
||||
EVER LISTEN TO, OR ACT ON RFKILL INPUT EVENTS. Doing otherwise is
|
||||
a layering violation.
|
||||
|
||||
Most wireless data communication drivers in the kernel have just to
|
||||
implement the rfkill class API to work properly. Interfacing to the
|
||||
input layer is not often required (and is very often a *bug*) on
|
||||
wireless drivers.
|
||||
|
||||
Platform drivers often have to attach to the input layer to *issue*
|
||||
(but never to listen to) rfkill events for rfkill switches, and also to
|
||||
the rfkill class to export a control interface for the platform rfkill
|
||||
controllers to the rfkill subsystem. This does NOT mean the rfkill
|
||||
switch is attached to a rfkill class (doing so is almost always wrong).
|
||||
It just means the same kernel module is the driver for different
|
||||
devices (rfkill switches and rfkill controllers).
|
||||
|
||||
|
||||
Userspace input handlers (uevents) or kernel input handlers (rfkill-input):
|
||||
|
||||
* Implements the policy of what should happen when one of the input
|
||||
layer events related to rfkill operation is received.
|
||||
* Uses the sysfs interface (userspace) or private rfkill API calls
|
||||
to tell the devices registered with the rfkill class to change
|
||||
their state (i.e. translates the input layer event into real
|
||||
action).
|
||||
* rfkill-input implements EPO by handling EV_SW SW_RFKILL_ALL 0
|
||||
(power off all transmitters) in a special way: it ignores any
|
||||
overrides and local state cache and forces all transmitters to the
|
||||
RFKILL_STATE_SOFT_BLOCKED state (including those which are already
|
||||
supposed to be BLOCKED). Note that the opposite event (power on all
|
||||
transmitters) is handled normally.
|
||||
|
||||
Userspace uevent handler or kernel platform-specific drivers hooked to the
|
||||
rfkill notifier chain:
|
||||
|
||||
* Taps into the rfkill notifier chain or to KOBJ_CHANGE uevents,
|
||||
in order to know when a device that is registered with the rfkill
|
||||
class changes state;
|
||||
* Issues feedback notifications to the user;
|
||||
* In the rare platforms where this is required, synthesizes an input
|
||||
event to command all *OTHER* rfkill devices to also change their
|
||||
statues when a specific rfkill device changes state.
|
||||
|
||||
|
||||
===============================================================================
|
||||
3: Kernel driver guidelines
|
||||
|
||||
Remember: point-of-view is everything for a driver that connects to the rfkill
|
||||
subsystem. All the details below must be measured/perceived from the point of
|
||||
view of the specific driver being modified.
|
||||
|
||||
The first thing one needs to know is whether his driver should be talking to
|
||||
the rfkill class or to the input layer. In rare cases (platform drivers), it
|
||||
could happen that you need to do both, as platform drivers often handle a
|
||||
variety of devices in the same driver.
|
||||
|
||||
Do not mistake input devices for rfkill controllers. The only type of "rfkill
|
||||
switch" device that is to be registered with the rfkill class are those
|
||||
directly controlling the circuits that cause a wireless transmitter to stop
|
||||
working (or the software equivalent of them), i.e. what we call a rfkill
|
||||
controller. Every other kind of "rfkill switch" is just an input device and
|
||||
MUST NOT be registered with the rfkill class.
|
||||
|
||||
A driver should register a device with the rfkill class when ALL of the
|
||||
following conditions are met (they define a rfkill controller):
|
||||
|
||||
1. The device is/controls a data communications wireless transmitter;
|
||||
|
||||
2. The kernel can interact with the hardware/firmware to CHANGE the wireless
|
||||
transmitter state (block/unblock TX operation);
|
||||
|
||||
3. The transmitter can be made to not emit any energy when "blocked":
|
||||
rfkill is not about blocking data transmissions, it is about blocking
|
||||
energy emission;
|
||||
|
||||
A driver should register a device with the input subsystem to issue
|
||||
rfkill-related events (KEY_WLAN, KEY_BLUETOOTH, KEY_WWAN, KEY_WIMAX,
|
||||
SW_RFKILL_ALL, etc) when ALL of the folowing conditions are met:
|
||||
|
||||
1. It is directly related to some physical device the user interacts with, to
|
||||
command the O.S./firmware/hardware to enable/disable a data communications
|
||||
wireless transmitter.
|
||||
|
||||
Examples of the physical device are: buttons, keys and switches the user
|
||||
will press/touch/slide/switch to enable or disable the wireless
|
||||
communication device.
|
||||
|
||||
2. It is NOT slaved to another device, i.e. there is no other device that
|
||||
issues rfkill-related input events in preference to this one.
|
||||
|
||||
Please refer to the corner cases and examples section for more details.
|
||||
|
||||
When in doubt, do not issue input events. For drivers that should generate
|
||||
input events in some platforms, but not in others (e.g. b43), the best solution
|
||||
is to NEVER generate input events in the first place. That work should be
|
||||
deferred to a platform-specific kernel module (which will know when to generate
|
||||
events through the rfkill notifier chain) or to userspace. This avoids the
|
||||
usual maintenance problems with DMI whitelisting.
|
||||
|
||||
|
||||
Corner cases and examples:
|
||||
====================================
|
||||
2: Driver support
|
||||
|
||||
To build a driver with rfkill subsystem support, the driver should
|
||||
depend on the Kconfig symbol RFKILL; it should _not_ depend on
|
||||
RKFILL_INPUT.
|
||||
1. If the device is an input device that, because of hardware or firmware,
|
||||
causes wireless transmitters to be blocked regardless of the kernel's will, it
|
||||
is still just an input device, and NOT to be registered with the rfkill class.
|
||||
|
||||
Unless key events trigger an interrupt to which the driver listens, polling
|
||||
will be required to determine the key state changes. For this the input
|
||||
layer providers the input-polldev handler.
|
||||
2. If the wireless transmitter switch control is read-only, it is an input
|
||||
device and not to be registered with the rfkill class (and maybe not to be made
|
||||
an input layer event source either, see below).
|
||||
|
||||
A driver should implement a few steps to correctly make use of the
|
||||
rfkill subsystem. First for non-polling drivers:
|
||||
3. If there is some other device driver *closer* to the actual hardware the
|
||||
user interacted with (the button/switch/key) to issue an input event, THAT is
|
||||
the device driver that should be issuing input events.
|
||||
|
||||
- rfkill_allocate()
|
||||
- input_allocate_device()
|
||||
- rfkill_register()
|
||||
- input_register_device()
|
||||
E.g:
|
||||
[RFKILL slider switch] -- [GPIO hardware] -- [WLAN card rf-kill input]
|
||||
(platform driver) (wireless card driver)
|
||||
|
||||
For polling drivers:
|
||||
The user is closer to the RFKILL slide switch plaform driver, so the driver
|
||||
which must issue input events is the platform driver looking at the GPIO
|
||||
hardware, and NEVER the wireless card driver (which is just a slave). It is
|
||||
very likely that there are other leaves than just the WLAN card rf-kill input
|
||||
(e.g. a bluetooth card, etc)...
|
||||
|
||||
- rfkill_allocate()
|
||||
- input_allocate_polled_device()
|
||||
- rfkill_register()
|
||||
- input_register_polled_device()
|
||||
On the other hand, some embedded devices do this:
|
||||
|
||||
When a key event has been detected, the correct event should be
|
||||
sent over the input device which has been registered by the driver.
|
||||
[RFKILL slider switch] -- [WLAN card rf-kill input]
|
||||
(wireless card driver)
|
||||
|
||||
In this situation, the wireless card driver *could* register itself as an input
|
||||
device and issue rf-kill related input events... but in order to AVOID the need
|
||||
for DMI whitelisting, the wireless card driver does NOT do it. Userspace (HAL)
|
||||
or a platform driver (that exists only on these embedded devices) will do the
|
||||
dirty job of issuing the input events.
|
||||
|
||||
|
||||
COMMON MISTAKES in kernel drivers, related to rfkill:
|
||||
====================================
|
||||
3: Userspace support
|
||||
|
||||
For each key an input device will be created which will send out the correct
|
||||
key event when the rfkill key has been pressed.
|
||||
1. NEVER confuse input device keys and buttons with input device switches.
|
||||
|
||||
1a. Switches are always set or reset. They report the current state
|
||||
(on position or off position).
|
||||
|
||||
1b. Keys and buttons are either in the pressed or not-pressed state, and
|
||||
that's it. A "button" that latches down when you press it, and
|
||||
unlatches when you press it again is in fact a switch as far as input
|
||||
devices go.
|
||||
|
||||
Add the SW_* events you need for switches, do NOT try to emulate a button using
|
||||
KEY_* events just because there is no such SW_* event yet. Do NOT try to use,
|
||||
for example, KEY_BLUETOOTH when you should be using SW_BLUETOOTH instead.
|
||||
|
||||
2. Input device switches (sources of EV_SW events) DO store their current state
|
||||
(so you *must* initialize it by issuing a gratuitous input layer event on
|
||||
driver start-up and also when resuming from sleep), and that state CAN be
|
||||
queried from userspace through IOCTLs. There is no sysfs interface for this,
|
||||
but that doesn't mean you should break things trying to hook it to the rfkill
|
||||
class to get a sysfs interface :-)
|
||||
|
||||
3. Do not issue *_RFKILL_ALL events by default, unless you are sure it is the
|
||||
correct event for your switch/button. These events are emergency power-off
|
||||
events when they are trying to turn the transmitters off. An example of an
|
||||
input device which SHOULD generate *_RFKILL_ALL events is the wireless-kill
|
||||
switch in a laptop which is NOT a hotkey, but a real switch that kills radios
|
||||
in hardware, even if the O.S. has gone to lunch. An example of an input device
|
||||
which SHOULD NOT generate *_RFKILL_ALL events by default, is any sort of hot
|
||||
key that does nothing by itself, as well as any hot key that is type-specific
|
||||
(e.g. the one for WLAN).
|
||||
|
||||
|
||||
3.1 Guidelines for wireless device drivers
|
||||
------------------------------------------
|
||||
|
||||
1. Each independent transmitter in a wireless device (usually there is only one
|
||||
transmitter per device) should have a SINGLE rfkill class attached to it.
|
||||
|
||||
2. If the device does not have any sort of hardware assistance to allow the
|
||||
driver to rfkill the device, the driver should emulate it by taking all actions
|
||||
required to silence the transmitter.
|
||||
|
||||
3. If it is impossible to silence the transmitter (i.e. it still emits energy,
|
||||
even if it is just in brief pulses, when there is no data to transmit and there
|
||||
is no hardware support to turn it off) do NOT lie to the users. Do not attach
|
||||
it to a rfkill class. The rfkill subsystem does not deal with data
|
||||
transmission, it deals with energy emission. If the transmitter is emitting
|
||||
energy, it is not blocked in rfkill terms.
|
||||
|
||||
4. It doesn't matter if the device has multiple rfkill input lines affecting
|
||||
the same transmitter, their combined state is to be exported as a single state
|
||||
per transmitter (see rule 1).
|
||||
|
||||
This rule exists because users of the rfkill subsystem expect to get (and set,
|
||||
when possible) the overall transmitter rfkill state, not of a particular rfkill
|
||||
line.
|
||||
|
||||
Example of a WLAN wireless driver connected to the rfkill subsystem:
|
||||
--------------------------------------------------------------------
|
||||
|
||||
A certain WLAN card has one input pin that causes it to block the transmitter
|
||||
and makes the status of that input pin available (only for reading!) to the
|
||||
kernel driver. This is a hard rfkill input line (it cannot be overridden by
|
||||
the kernel driver).
|
||||
|
||||
The card also has one PCI register that, if manipulated by the driver, causes
|
||||
it to block the transmitter. This is a soft rfkill input line.
|
||||
|
||||
It has also a thermal protection circuitry that shuts down its transmitter if
|
||||
the card overheats, and makes the status of that protection available (only for
|
||||
reading!) to the kernel driver. This is also a hard rfkill input line.
|
||||
|
||||
If either one of these rfkill lines are active, the transmitter is blocked by
|
||||
the hardware and forced offline.
|
||||
|
||||
The driver should allocate and attach to its struct device *ONE* instance of
|
||||
the rfkill class (there is only one transmitter).
|
||||
|
||||
It can implement the get_state() hook, and return RFKILL_STATE_HARD_BLOCKED if
|
||||
either one of its two hard rfkill input lines are active. If the two hard
|
||||
rfkill lines are inactive, it must return RFKILL_STATE_SOFT_BLOCKED if its soft
|
||||
rfkill input line is active. Only if none of the rfkill input lines are
|
||||
active, will it return RFKILL_STATE_UNBLOCKED.
|
||||
|
||||
If it doesn't implement the get_state() hook, it must make sure that its calls
|
||||
to rfkill_force_state() are enough to keep the status always up-to-date, and it
|
||||
must do a rfkill_force_state() on resume from sleep.
|
||||
|
||||
Every time the driver gets a notification from the card that one of its rfkill
|
||||
lines changed state (polling might be needed on badly designed cards that don't
|
||||
generate interrupts for such events), it recomputes the rfkill state as per
|
||||
above, and calls rfkill_force_state() to update it.
|
||||
|
||||
The driver should implement the toggle_radio() hook, that:
|
||||
|
||||
1. Returns an error if one of the hardware rfkill lines are active, and the
|
||||
caller asked for RFKILL_STATE_UNBLOCKED.
|
||||
|
||||
2. Activates the soft rfkill line if the caller asked for state
|
||||
RFKILL_STATE_SOFT_BLOCKED. It should do this even if one of the hard rfkill
|
||||
lines are active, effectively double-blocking the transmitter.
|
||||
|
||||
3. Deactivates the soft rfkill line if none of the hardware rfkill lines are
|
||||
active and the caller asked for RFKILL_STATE_UNBLOCKED.
|
||||
|
||||
===============================================================================
|
||||
4: Kernel API
|
||||
|
||||
To build a driver with rfkill subsystem support, the driver should depend on
|
||||
(or select) the Kconfig symbol RFKILL; it should _not_ depend on RKFILL_INPUT.
|
||||
|
||||
The hardware the driver talks to may be write-only (where the current state
|
||||
of the hardware is unknown), or read-write (where the hardware can be queried
|
||||
about its current state).
|
||||
|
||||
The rfkill class will call the get_state hook of a device every time it needs
|
||||
to know the *real* current state of the hardware. This can happen often.
|
||||
|
||||
Some hardware provides events when its status changes. In these cases, it is
|
||||
best for the driver to not provide a get_state hook, and instead register the
|
||||
rfkill class *already* with the correct status, and keep it updated using
|
||||
rfkill_force_state() when it gets an event from the hardware.
|
||||
|
||||
There is no provision for a statically-allocated rfkill struct. You must
|
||||
use rfkill_allocate() to allocate one.
|
||||
|
||||
You should:
|
||||
- rfkill_allocate()
|
||||
- modify rfkill fields (flags, name)
|
||||
- modify state to the current hardware state (THIS IS THE ONLY TIME
|
||||
YOU CAN ACCESS state DIRECTLY)
|
||||
- rfkill_register()
|
||||
|
||||
The only way to set a device to the RFKILL_STATE_HARD_BLOCKED state is through
|
||||
a suitable return of get_state() or through rfkill_force_state().
|
||||
|
||||
When a device is in the RFKILL_STATE_HARD_BLOCKED state, the only way to switch
|
||||
it to a different state is through a suitable return of get_state() or through
|
||||
rfkill_force_state().
|
||||
|
||||
If toggle_radio() is called to set a device to state RFKILL_STATE_SOFT_BLOCKED
|
||||
when that device is already at the RFKILL_STATE_HARD_BLOCKED state, it should
|
||||
not return an error. Instead, it should try to double-block the transmitter,
|
||||
so that its state will change from RFKILL_STATE_HARD_BLOCKED to
|
||||
RFKILL_STATE_SOFT_BLOCKED should the hardware blocking cease.
|
||||
|
||||
Please refer to the source for more documentation.
|
||||
|
||||
===============================================================================
|
||||
5: Userspace support
|
||||
|
||||
rfkill devices issue uevents (with an action of "change"), with the following
|
||||
environment variables set:
|
||||
|
||||
RFKILL_NAME
|
||||
RFKILL_STATE
|
||||
RFKILL_TYPE
|
||||
|
||||
The ABI for these variables is defined by the sysfs attributes. It is best
|
||||
to take a quick look at the source to make sure of the possible values.
|
||||
|
||||
It is expected that HAL will trap those, and bridge them to DBUS, etc. These
|
||||
events CAN and SHOULD be used to give feedback to the user about the rfkill
|
||||
status of the system.
|
||||
|
||||
Input devices may issue events that are related to rfkill. These are the
|
||||
various KEY_* events and SW_* events supported by rfkill-input.c.
|
||||
|
||||
******IMPORTANT******
|
||||
When rfkill-input is ACTIVE, userspace is NOT TO CHANGE THE STATE OF AN RFKILL
|
||||
SWITCH IN RESPONSE TO AN INPUT EVENT also handled by rfkill-input, unless it
|
||||
has set to true the user_claim attribute for that particular switch. This rule
|
||||
is *absolute*; do NOT violate it.
|
||||
******IMPORTANT******
|
||||
|
||||
Userspace must not assume it is the only source of control for rfkill switches.
|
||||
Their state CAN and WILL change due to firmware actions, direct user actions,
|
||||
and the rfkill-input EPO override for *_RFKILL_ALL.
|
||||
|
||||
When rfkill-input is not active, userspace must initiate a rfkill status
|
||||
change by writing to the "state" attribute in order for anything to happen.
|
||||
|
||||
Take particular care to implement EV_SW SW_RFKILL_ALL properly. When that
|
||||
switch is set to OFF, *every* rfkill device *MUST* be immediately put into the
|
||||
RFKILL_STATE_SOFT_BLOCKED state, no questions asked.
|
||||
|
||||
The following sysfs entries will be created:
|
||||
|
||||
name: Name assigned by driver to this key (interface or driver name).
|
||||
type: Name of the key type ("wlan", "bluetooth", etc).
|
||||
state: Current state of the key. 1: On, 0: Off.
|
||||
state: Current state of the transmitter
|
||||
0: RFKILL_STATE_SOFT_BLOCKED
|
||||
transmitter is forced off, but one can override it
|
||||
by a write to the state attribute;
|
||||
1: RFKILL_STATE_UNBLOCKED
|
||||
transmiter is NOT forced off, and may operate if
|
||||
all other conditions for such operation are met
|
||||
(such as interface is up and configured, etc);
|
||||
2: RFKILL_STATE_HARD_BLOCKED
|
||||
transmitter is forced off by something outside of
|
||||
the driver's control. One cannot set a device to
|
||||
this state through writes to the state attribute;
|
||||
claim: 1: Userspace handles events, 0: Kernel handles events
|
||||
|
||||
Both the "state" and "claim" entries are also writable. For the "state" entry
|
||||
this means that when 1 or 0 is written all radios, not yet in the requested
|
||||
state, will be will be toggled accordingly.
|
||||
this means that when 1 or 0 is written, the device rfkill state (if not yet in
|
||||
the requested state), will be will be toggled accordingly.
|
||||
|
||||
For the "claim" entry writing 1 to it means that the kernel no longer handles
|
||||
key events even though RFKILL_INPUT input was enabled. When "claim" has been
|
||||
set to 0, userspace should make sure that it listens for the input events or
|
||||
check the sysfs "state" entry regularly to correctly perform the required
|
||||
tasks when the rkfill key is pressed.
|
||||
check the sysfs "state" entry regularly to correctly perform the required tasks
|
||||
when the rkfill key is pressed.
|
||||
|
||||
A note about input devices and EV_SW events:
|
||||
|
||||
In order to know the current state of an input device switch (like
|
||||
SW_RFKILL_ALL), you will need to use an IOCTL. That information is not
|
||||
available through sysfs in a generic way at this time, and it is not available
|
||||
through the rfkill class AT ALL.
|
||||
|
|
|
@ -186,6 +186,17 @@ hardware.
|
|||
Locking: port_sem taken.
|
||||
Interrupts: caller dependent.
|
||||
|
||||
flush_buffer(port)
|
||||
Flush any write buffers, reset any DMA state and stop any
|
||||
ongoing DMA transfers.
|
||||
|
||||
This will be called whenever the port->info->xmit circular
|
||||
buffer is cleared.
|
||||
|
||||
Locking: port->lock taken.
|
||||
Interrupts: locally disabled.
|
||||
This call must not sleep
|
||||
|
||||
set_termios(port,termios,oldtermios)
|
||||
Change the port parameters, including word length, parity, stop
|
||||
bits. Update read_status_mask and ignore_status_mask to indicate
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
Linux Gadget Serial Driver v2.0
|
||||
11/20/2004
|
||||
(updated 8-May-2008 for v2.3)
|
||||
|
||||
|
||||
License and Disclaimer
|
||||
|
@ -31,7 +32,7 @@ Prerequisites
|
|||
-------------
|
||||
Versions of the gadget serial driver are available for the
|
||||
2.4 Linux kernels, but this document assumes you are using
|
||||
version 2.0 or later of the gadget serial driver in a 2.6
|
||||
version 2.3 or later of the gadget serial driver in a 2.6
|
||||
Linux kernel.
|
||||
|
||||
This document assumes that you are familiar with Linux and
|
||||
|
@ -40,6 +41,12 @@ standard utilities, use minicom and HyperTerminal, and work with
|
|||
USB and serial devices. It also assumes you configure the Linux
|
||||
gadget and usb drivers as modules.
|
||||
|
||||
With version 2.3 of the driver, major and minor device nodes are
|
||||
no longer statically defined. Your Linux based system should mount
|
||||
sysfs in /sys, and use "mdev" (in Busybox) or "udev" to make the
|
||||
/dev nodes matching the sysfs /sys/class/tty files.
|
||||
|
||||
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
@ -104,15 +111,8 @@ driver. All this are listed under "USB Gadget Support" when
|
|||
configuring the kernel. Then rebuild and install the kernel or
|
||||
modules.
|
||||
|
||||
The gadget serial driver uses major number 127, for now. So you
|
||||
will need to create a device node for it, like this:
|
||||
|
||||
mknod /dev/ttygserial c 127 0
|
||||
|
||||
You only need to do this once.
|
||||
|
||||
Then you must load the gadget serial driver. To load it as an
|
||||
ACM device, do this:
|
||||
ACM device (recommended for interoperability), do this:
|
||||
|
||||
modprobe g_serial use_acm=1
|
||||
|
||||
|
@ -125,6 +125,23 @@ controller driver. This must be done each time you reboot the gadget
|
|||
side Linux system. You can add this to the start up scripts, if
|
||||
desired.
|
||||
|
||||
Your system should use mdev (from busybox) or udev to make the
|
||||
device nodes. After this gadget driver has been set up you should
|
||||
then see a /dev/ttyGS0 node:
|
||||
|
||||
# ls -l /dev/ttyGS0 | cat
|
||||
crw-rw---- 1 root root 253, 0 May 8 14:10 /dev/ttyGS0
|
||||
#
|
||||
|
||||
Note that the major number (253, above) is system-specific. If
|
||||
you need to create /dev nodes by hand, the right numbers to use
|
||||
will be in the /sys/class/tty/ttyGS0/dev file.
|
||||
|
||||
When you link this gadget driver early, perhaps even statically,
|
||||
you may want to set up an /etc/inittab entry to run "getty" on it.
|
||||
The /dev/ttyGS0 line should work like most any other serial port.
|
||||
|
||||
|
||||
If gadget serial is loaded as an ACM device you will want to use
|
||||
either the Windows or Linux ACM driver on the host side. If gadget
|
||||
serial is loaded as a bulk in/out device, you will want to use the
|
||||
|
|
|
@ -81,8 +81,11 @@ re-enumeration shows that the device now attached to that port has the
|
|||
same descriptors as before, including the Vendor and Product IDs, then
|
||||
the kernel continues to use the same device structure. In effect, the
|
||||
kernel treats the device as though it had merely been reset instead of
|
||||
unplugged. The same thing happens if the host controller is in the
|
||||
expected state but a USB device was unplugged and then replugged.
|
||||
unplugged.
|
||||
|
||||
The same thing happens if the host controller is in the expected state
|
||||
but a USB device was unplugged and then replugged, or if a USB device
|
||||
fails to carry out a normal resume.
|
||||
|
||||
If no device is now attached to the port, or if the descriptors are
|
||||
different from what the kernel remembers, then the treatment is what
|
||||
|
|
|
@ -1,165 +0,0 @@
|
|||
Specification and Internals for the New UHCI Driver (Whitepaper...)
|
||||
|
||||
brought to you by
|
||||
|
||||
Georg Acher, acher@in.tum.de (executive slave) (base guitar)
|
||||
Deti Fliegl, deti@fliegl.de (executive slave) (lead voice)
|
||||
Thomas Sailer, sailer@ife.ee.ethz.ch (chief consultant) (cheer leader)
|
||||
|
||||
$Id: README.uhci,v 1.1 1999/12/14 14:03:02 fliegl Exp $
|
||||
|
||||
This document and the new uhci sources can be found on
|
||||
http://hotswap.in.tum.de/usb
|
||||
|
||||
1. General issues
|
||||
|
||||
1.1 Why a new UHCI driver, we already have one?!?
|
||||
|
||||
Correct, but its internal structure got more and more mixed up by the (still
|
||||
ongoing) efforts to get isochronous transfers (ISO) to work.
|
||||
Since there is an increasing need for reliable ISO-transfers (especially
|
||||
for USB-audio needed by TS and for a DAB-USB-Receiver build by GA and DF),
|
||||
this state was a bit unsatisfying in our opinion, so we've decided (based
|
||||
on knowledge and experiences with the old UHCI driver) to start
|
||||
from scratch with a new approach, much simpler but at the same time more
|
||||
powerful.
|
||||
It is inspired by the way Win98/Win2000 handles USB requests via URBs,
|
||||
but it's definitely 100% free of MS-code and doesn't crash while
|
||||
unplugging an used ISO-device like Win98 ;-)
|
||||
Some code for HW setup and root hub management was taken from the
|
||||
original UHCI driver, but heavily modified to fit into the new code.
|
||||
The invention of the basic concept, and major coding were completed in two
|
||||
days (and nights) on the 16th and 17th of October 1999, now known as the
|
||||
great USB-October-Revolution started by GA, DF, and TS ;-)
|
||||
|
||||
Since the concept is in no way UHCI dependent, we hope that it will also be
|
||||
transferred to the OHCI-driver, so both drivers share a common API.
|
||||
|
||||
1.2. Advantages and disadvantages
|
||||
|
||||
+ All USB transfer types work now!
|
||||
+ Asynchronous operation
|
||||
+ Simple, but powerful interface (only two calls for start and cancel)
|
||||
+ Easy migration to the new API, simplified by a compatibility API
|
||||
+ Simple usage of ISO transfers
|
||||
+ Automatic linking of requests
|
||||
+ ISO transfers allow variable length for each frame and striping
|
||||
+ No CPU dependent and non-portable atomic memory access, no asm()-inlines
|
||||
+ Tested on x86 and Alpha
|
||||
|
||||
- Rewriting for ISO transfers needed
|
||||
|
||||
1.3. Is there some compatibility to the old API?
|
||||
|
||||
Yes, but only for control, bulk and interrupt transfers. We've implemented
|
||||
some wrapper calls for these transfer types. The usbcore works fine with
|
||||
these wrappers. For ISO there's no compatibility, because the old ISO-API
|
||||
and its semantics were unnecessary complicated in our opinion.
|
||||
|
||||
1.4. What's really working?
|
||||
|
||||
As said above, CTRL and BULK already work fine even with the wrappers,
|
||||
so legacy code wouldn't notice the change.
|
||||
Regarding to Thomas, ISO transfers now run stable with USB audio.
|
||||
INT transfers (e.g. mouse driver) work fine, too.
|
||||
|
||||
1.5. Are there any bugs?
|
||||
|
||||
No ;-)
|
||||
Hm...
|
||||
Well, of course this implementation needs extensive testing on all available
|
||||
hardware, but we believe that any fixes shouldn't harm the overall concept.
|
||||
|
||||
1.6. What should be done next?
|
||||
|
||||
A large part of the request handling seems to be identical for UHCI and
|
||||
OHCI, so it would be a good idea to extract the common parts and have only
|
||||
the HW specific stuff in uhci.c. Furthermore, all other USB device drivers
|
||||
should need URBification, if they use isochronous or interrupt transfers.
|
||||
One thing missing in the current implementation (and the old UHCI driver)
|
||||
is fair queueing for BULK transfers. Since this would need (in principle)
|
||||
the alteration of already constructed TD chains (to switch from depth to
|
||||
breadth execution), another way has to be found. Maybe some simple
|
||||
heuristics work with the same effect.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
2. Internal structure and mechanisms
|
||||
|
||||
To get quickly familiar with the internal structures, here's a short
|
||||
description how the new UHCI driver works. However, the ultimate source of
|
||||
truth is only uhci.c!
|
||||
|
||||
2.1. Descriptor structure (QHs and TDs)
|
||||
|
||||
During initialization, the following skeleton is allocated in init_skel:
|
||||
|
||||
framespecific | common chain
|
||||
|
||||
framelist[]
|
||||
[ 0 ]-----> TD --> TD -------\
|
||||
[ 1 ]-----> TD --> TD --------> TD ----> QH -------> QH -------> QH ---> NULL
|
||||
... TD --> TD -------/
|
||||
[1023]-----> TD --> TD ------/
|
||||
|
||||
^^ ^^ ^^ ^^ ^^ ^^
|
||||
1024 TDs for 7 TDs for 1 TD for Start of Start of End Chain
|
||||
ISO INT (2-128ms) 1ms-INT CTRL Chain BULK Chain
|
||||
|
||||
For each CTRL or BULK transfer a new QH is allocated and the containing data
|
||||
transfers are appended as (vertical) TDs. After building the whole QH with its
|
||||
dangling TDs, the QH is inserted before the BULK Chain QH (for CTRL) or
|
||||
before the End Chain QH (for BULK). Since only the QH->next pointers are
|
||||
affected, no atomic memory operation is required. The three QHs in the
|
||||
common chain are never equipped with TDs!
|
||||
|
||||
For ISO or INT, the TD for each frame is simply inserted into the appropriate
|
||||
ISO/INT-TD-chain for the desired frame. The 7 skeleton INT-TDs are scattered
|
||||
among the 1024 frames similar to the old UHCI driver.
|
||||
|
||||
For CTRL/BULK/ISO, the last TD in the transfer has the IOC-bit set. For INT,
|
||||
every TD (there is only one...) has the IOC-bit set.
|
||||
|
||||
Besides the data for the UHCI controller (2 or 4 32bit words), the descriptors
|
||||
are double-linked through the .vertical and .horizontal elements in the
|
||||
SW data of the descriptor (using the double-linked list structures and
|
||||
operations), but SW-linking occurs only in closed domains, i.e. for each of
|
||||
the 1024 ISO-chains and the 8 INT-chains there is a closed cycle. This
|
||||
simplifies all insertions and unlinking operations and avoids costly
|
||||
bus_to_virt()-calls.
|
||||
|
||||
2.2. URB structure and linking to QH/TDs
|
||||
|
||||
During assembly of the QH and TDs of the requested action, these descriptors
|
||||
are stored in urb->urb_list, so the allocated QH/TD descriptors are bound to
|
||||
this URB.
|
||||
If the assembly was successful and the descriptors were added to the HW chain,
|
||||
the corresponding URB is inserted into a global URB list for this controller.
|
||||
This list stores all pending URBs.
|
||||
|
||||
2.3. Interrupt processing
|
||||
|
||||
Since UHCI provides no means to directly detect completed transactions, the
|
||||
following is done in each UHCI interrupt (uhci_interrupt()):
|
||||
|
||||
For each URB in the pending queue (process_urb()), the ACTIVE-flag of the
|
||||
associated TDs are processed (depending on the transfer type
|
||||
process_{transfer|interrupt|iso}()). If the TDs are not active anymore,
|
||||
they indicate the completion of the transaction and the status is calculated.
|
||||
Inactive QH/TDs are removed from the HW chain (since the host controller
|
||||
already removed the TDs from the QH, no atomic access is needed) and
|
||||
eventually the URB is marked as completed (OK or errors) and removed from the
|
||||
pending queue. Then the next linked URB is submitted. After (or immediately
|
||||
before) that, the completion handler is called.
|
||||
|
||||
2.4. Unlinking URBs
|
||||
|
||||
First, all QH/TDs stored in the URB are unlinked from the HW chain.
|
||||
To ensure that the host controller really left a vertical TD chain, we
|
||||
wait for one frame. After that, the TDs are physically destroyed.
|
||||
|
||||
2.5. URB linking and the consequences
|
||||
|
||||
Since URBs can be linked and the corresponding submit_urb is called in
|
||||
the UHCI-interrupt, all work associated with URB/QH/TD assembly has to be
|
||||
interrupt save. This forces kmalloc to use GFP_ATOMIC in the interrupt.
|
|
@ -8,3 +8,4 @@
|
|||
7 -> Hauppauge WinTV-HVR1200 [0070:71d1,0070:71d3]
|
||||
8 -> Hauppauge WinTV-HVR1700 [0070:8101]
|
||||
9 -> Hauppauge WinTV-HVR1400 [0070:8010]
|
||||
10 -> DViCO FusionHDTV7 Dual Express [18ac:d618]
|
||||
|
|
|
@ -8,10 +8,13 @@
|
|||
7 -> Leadtek Winfast USB II (em2800)
|
||||
8 -> Kworld USB2800 (em2800)
|
||||
9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a]
|
||||
10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500,2040:6502]
|
||||
10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500]
|
||||
11 -> Terratec Hybrid XS (em2880) [0ccd:0042]
|
||||
12 -> Kworld PVR TV 2800 RF (em2820/em2840)
|
||||
13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
|
||||
14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
|
||||
15 -> V-Gear PocketTV (em2800)
|
||||
16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513,2040:6517,2040:651b,2040:651f]
|
||||
17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227]
|
||||
18 -> Hauppauge WinTV HVR 900 (R2) (em2880) [2040:6502]
|
||||
19 -> PointNix Intra-Oral Camera (em2860)
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
36 -> UPMOST PURPLE TV [12ab:0800]
|
||||
37 -> Items MuchTV Plus / IT-005
|
||||
38 -> Terratec Cinergy 200 TV [153b:1152]
|
||||
39 -> LifeView FlyTV Platinum Mini [5168:0212,4e42:0212]
|
||||
39 -> LifeView FlyTV Platinum Mini [5168:0212,4e42:0212,5169:1502]
|
||||
40 -> Compro VideoMate TV PVR/FM [185b:c100]
|
||||
41 -> Compro VideoMate TV Gold+ [185b:c100]
|
||||
42 -> Sabrent SBT-TVFM (saa7130)
|
||||
|
@ -128,7 +128,7 @@
|
|||
127 -> Beholder BeholdTV 507 FM/RDS / BeholdTV 509 FM [0000:5071,0000:507B,5ace:5070,5ace:5090]
|
||||
128 -> Beholder BeholdTV Columbus TVFM [0000:5201]
|
||||
129 -> Beholder BeholdTV 607 / BeholdTV 609 [5ace:6070,5ace:6071,5ace:6072,5ace:6073,5ace:6090,5ace:6091,5ace:6092,5ace:6093]
|
||||
130 -> Beholder BeholdTV M6 / BeholdTV M6 Extra [5ace:6190,5ace:6193,5ace:6191]
|
||||
130 -> Beholder BeholdTV M6 [5ace:6190]
|
||||
131 -> Twinhan Hybrid DTV-DVB 3056 PCI [1822:0022]
|
||||
132 -> Genius TVGO AM11MCE
|
||||
133 -> NXP Snake DVB-S reference design
|
||||
|
@ -141,3 +141,7 @@
|
|||
140 -> Avermedia DVB-S Pro A700 [1461:a7a1]
|
||||
141 -> Avermedia DVB-S Hybrid+FM A700 [1461:a7a2]
|
||||
142 -> Beholder BeholdTV H6 [5ace:6290]
|
||||
143 -> Beholder BeholdTV M63 [5ace:6191]
|
||||
144 -> Beholder BeholdTV M6 Extra [5ace:6193]
|
||||
145 -> AVerMedia MiniPCI DVB-T Hybrid M103 [1461:f636]
|
||||
146 -> ASUSTeK P7131 Analog
|
||||
|
|
|
@ -1,36 +1,30 @@
|
|||
Some notes regarding the cx18 driver for the Conexant CX23418 MPEG
|
||||
encoder chip:
|
||||
|
||||
1) The only hardware currently supported is the Hauppauge HVR-1600
|
||||
card and the Compro VideoMate H900 (note that this card only
|
||||
supports analog input, it has no digital tuner!).
|
||||
1) Currently supported are:
|
||||
|
||||
2) Some people have problems getting the i2c bus to work. Cause unknown.
|
||||
- Hauppauge HVR-1600
|
||||
- Compro VideoMate H900
|
||||
- Yuan MPC718
|
||||
- Conexant Raptor PAL/SECAM devkit
|
||||
|
||||
2) Some people have problems getting the i2c bus to work.
|
||||
The symptom is that the eeprom cannot be read and the card is
|
||||
unusable.
|
||||
unusable. This is probably fixed, but if you have problems
|
||||
then post to the video4linux or ivtv-users mailinglist.
|
||||
|
||||
3) The audio from the analog tuner is mono only. Probably caused by
|
||||
incorrect audio register information in the datasheet. We are
|
||||
waiting for updated information from Conexant.
|
||||
3) VBI (raw or sliced) has not yet been implemented.
|
||||
|
||||
4) VBI (raw or sliced) has not yet been implemented.
|
||||
4) MPEG indexing is not yet implemented.
|
||||
|
||||
5) MPEG indexing is not yet implemented.
|
||||
|
||||
6) The driver is still a bit rough around the edges, this should
|
||||
5) The driver is still a bit rough around the edges, this should
|
||||
improve over time.
|
||||
|
||||
|
||||
Firmware:
|
||||
|
||||
The firmware needs to be extracted from the Windows Hauppauge HVR-1600
|
||||
driver, available here:
|
||||
You can obtain the firmware files here:
|
||||
|
||||
http://hauppauge.lightpath.net/software/install_cd/hauppauge_cd_3.4d1.zip
|
||||
http://dl.ivtvdriver.org/ivtv/firmware/cx18-firmware.tar.gz
|
||||
|
||||
Unzip, then copy the following files to the firmware directory
|
||||
and rename them as follows:
|
||||
|
||||
Drivers/Driver18/hcw18apu.rom -> v4l-cx23418-apu.fw
|
||||
Drivers/Driver18/hcw18enc.rom -> v4l-cx23418-cpu.fw
|
||||
Drivers/Driver18/hcw18mlC.rom -> v4l-cx23418-dig.fw
|
||||
Untar and copy the .fw files to your firmware directory.
|
||||
|
|
|
@ -0,0 +1,243 @@
|
|||
List of the webcams know by gspca.
|
||||
|
||||
The modules are:
|
||||
gspca_main main driver
|
||||
gspca_xxxx subdriver module with xxxx as follows
|
||||
|
||||
xxxx vend:prod
|
||||
----
|
||||
spca501 0000:0000 MystFromOri Unknow Camera
|
||||
spca501 040a:0002 Kodak DVC-325
|
||||
spca500 040a:0300 Kodak EZ200
|
||||
zc3xx 041e:041e Creative WebCam Live!
|
||||
spca500 041e:400a Creative PC-CAM 300
|
||||
sunplus 041e:400b Creative PC-CAM 600
|
||||
sunplus 041e:4012 PC-Cam350
|
||||
sunplus 041e:4013 Creative Pccam750
|
||||
zc3xx 041e:4017 Creative Webcam Mobile PD1090
|
||||
spca508 041e:4018 Creative Webcam Vista (PD1100)
|
||||
spca561 041e:401a Creative Webcam Vista (PD1100)
|
||||
zc3xx 041e:401c Creative NX
|
||||
spca505 041e:401d Creative Webcam NX ULTRA
|
||||
zc3xx 041e:401e Creative Nx Pro
|
||||
zc3xx 041e:401f Creative Webcam Notebook PD1171
|
||||
pac207 041e:4028 Creative Webcam Vista Plus
|
||||
zc3xx 041e:4029 Creative WebCam Vista Pro
|
||||
zc3xx 041e:4034 Creative Instant P0620
|
||||
zc3xx 041e:4035 Creative Instant P0620D
|
||||
zc3xx 041e:4036 Creative Live !
|
||||
zc3xx 041e:403a Creative Nx Pro 2
|
||||
spca561 041e:403b Creative Webcam Vista (VF0010)
|
||||
zc3xx 041e:4051 Creative Live!Cam Notebook Pro (VF0250)
|
||||
ov519 041e:4052 Creative Live! VISTA IM
|
||||
zc3xx 041e:4053 Creative Live!Cam Video IM
|
||||
ov519 041e:405f Creative Live! VISTA VF0330
|
||||
ov519 041e:4060 Creative Live! VISTA VF0350
|
||||
ov519 041e:4061 Creative Live! VISTA VF0400
|
||||
ov519 041e:4064 Creative Live! VISTA VF0420
|
||||
ov519 041e:4068 Creative Live! VISTA VF0470
|
||||
spca561 0458:7004 Genius VideoCAM Express V2
|
||||
sunplus 0458:7006 Genius Dsc 1.3 Smart
|
||||
zc3xx 0458:7007 Genius VideoCam V2
|
||||
zc3xx 0458:700c Genius VideoCam V3
|
||||
zc3xx 0458:700f Genius VideoCam Web V2
|
||||
sonixj 0458:7025 Genius Eye 311Q
|
||||
sonixj 045e:00f5 MicroSoft VX3000
|
||||
sonixj 045e:00f7 MicroSoft VX1000
|
||||
ov519 045e:028c Micro$oft xbox cam
|
||||
spca508 0461:0815 Micro Innovation IC200
|
||||
sunplus 0461:0821 Fujifilm MV-1
|
||||
zc3xx 0461:0a00 MicroInnovation WebCam320
|
||||
spca500 046d:0890 Logitech QuickCam traveler
|
||||
vc032x 046d:0892 Logitech Orbicam
|
||||
vc032x 046d:0896 Logitech Orbicam
|
||||
zc3xx 046d:08a0 Logitech QC IM
|
||||
zc3xx 046d:08a1 Logitech QC IM 0x08A1 +sound
|
||||
zc3xx 046d:08a2 Labtec Webcam Pro
|
||||
zc3xx 046d:08a3 Logitech QC Chat
|
||||
zc3xx 046d:08a6 Logitech QCim
|
||||
zc3xx 046d:08a7 Logitech QuickCam Image
|
||||
zc3xx 046d:08a9 Logitech Notebook Deluxe
|
||||
zc3xx 046d:08aa Labtec Webcam Notebook
|
||||
zc3xx 046d:08ac Logitech QuickCam Cool
|
||||
zc3xx 046d:08ad Logitech QCCommunicate STX
|
||||
zc3xx 046d:08ae Logitech QuickCam for Notebooks
|
||||
zc3xx 046d:08af Logitech QuickCam Cool
|
||||
zc3xx 046d:08b9 Logitech QC IM ???
|
||||
zc3xx 046d:08d7 Logitech QCam STX
|
||||
zc3xx 046d:08d9 Logitech QuickCam IM/Connect
|
||||
zc3xx 046d:08d8 Logitech Notebook Deluxe
|
||||
zc3xx 046d:08da Logitech QuickCam Messenger
|
||||
zc3xx 046d:08dd Logitech QuickCam for Notebooks
|
||||
spca500 046d:0900 Logitech Inc. ClickSmart 310
|
||||
spca500 046d:0901 Logitech Inc. ClickSmart 510
|
||||
sunplus 046d:0905 Logitech ClickSmart 820
|
||||
tv8532 046d:0920 QC Express
|
||||
tv8532 046d:0921 Labtec Webcam
|
||||
spca561 046d:0928 Logitech QC Express Etch2
|
||||
spca561 046d:0929 Labtec Webcam Elch2
|
||||
spca561 046d:092a Logitech QC for Notebook
|
||||
spca561 046d:092b Labtec Webcam Plus
|
||||
spca561 046d:092c Logitech QC chat Elch2
|
||||
spca561 046d:092d Logitech QC Elch2
|
||||
spca561 046d:092e Logitech QC Elch2
|
||||
spca561 046d:092f Logitech QC Elch2
|
||||
sunplus 046d:0960 Logitech ClickSmart 420
|
||||
sunplus 0471:0322 Philips DMVC1300K
|
||||
zc3xx 0471:0325 Philips SPC 200 NC
|
||||
zc3xx 0471:0326 Philips SPC 300 NC
|
||||
sonixj 0471:0327 Philips SPC 600 NC
|
||||
sonixj 0471:0328 Philips SPC 700 NC
|
||||
zc3xx 0471:032d Philips spc210nc
|
||||
zc3xx 0471:032e Philips spc315nc
|
||||
sonixj 0471:0330 Philips SPC 710NC
|
||||
spca501 0497:c001 Smile International
|
||||
sunplus 04a5:3003 Benq DC 1300
|
||||
sunplus 04a5:3008 Benq DC 1500
|
||||
sunplus 04a5:300a Benq DC3410
|
||||
spca500 04a5:300c Benq DC1016
|
||||
sunplus 04f1:1001 JVC GC A50
|
||||
spca561 04fc:0561 Flexcam 100
|
||||
sunplus 04fc:500c Sunplus CA500C
|
||||
sunplus 04fc:504a Aiptek Mini PenCam 1.3
|
||||
sunplus 04fc:504b Maxell MaxPocket LE 1.3
|
||||
sunplus 04fc:5330 Digitrex 2110
|
||||
sunplus 04fc:5360 Sunplus Generic
|
||||
spca500 04fc:7333 PalmPixDC85
|
||||
sunplus 04fc:ffff Pure DigitalDakota
|
||||
spca501 0506:00df 3Com HomeConnect Lite
|
||||
sunplus 052b:1513 Megapix V4
|
||||
tv8532 0545:808b Veo Stingray
|
||||
tv8532 0545:8333 Veo Stingray
|
||||
sunplus 0546:3155 Polaroid PDC3070
|
||||
sunplus 0546:3191 Polaroid Ion 80
|
||||
sunplus 0546:3273 Polaroid PDC2030
|
||||
ov519 054c:0154 Sonny toy4
|
||||
ov519 054c:0155 Sonny toy5
|
||||
zc3xx 055f:c005 Mustek Wcam300A
|
||||
spca500 055f:c200 Mustek Gsmart 300
|
||||
sunplus 055f:c211 Kowa Bs888e Microcamera
|
||||
spca500 055f:c220 Gsmart Mini
|
||||
sunplus 055f:c230 Mustek Digicam 330K
|
||||
sunplus 055f:c232 Mustek MDC3500
|
||||
sunplus 055f:c360 Mustek DV4000 Mpeg4
|
||||
sunplus 055f:c420 Mustek gSmart Mini 2
|
||||
sunplus 055f:c430 Mustek Gsmart LCD 2
|
||||
sunplus 055f:c440 Mustek DV 3000
|
||||
sunplus 055f:c520 Mustek gSmart Mini 3
|
||||
sunplus 055f:c530 Mustek Gsmart LCD 3
|
||||
sunplus 055f:c540 Gsmart D30
|
||||
sunplus 055f:c630 Mustek MDC4000
|
||||
sunplus 055f:c650 Mustek MDC5500Z
|
||||
zc3xx 055f:d003 Mustek WCam300A
|
||||
zc3xx 055f:d004 Mustek WCam300 AN
|
||||
conex 0572:0041 Creative Notebook cx11646
|
||||
ov519 05a9:0519 OmniVision
|
||||
ov519 05a9:0530 OmniVision
|
||||
ov519 05a9:4519 OmniVision
|
||||
ov519 05a9:8519 OmniVision
|
||||
sunplus 05da:1018 Digital Dream Enigma 1.3
|
||||
stk014 05e1:0893 Syntek DV4000
|
||||
spca561 060b:a001 Maxell Compact Pc PM3
|
||||
zc3xx 0698:2003 CTX M730V built in
|
||||
spca500 06bd:0404 Agfa CL20
|
||||
spca500 06be:0800 Optimedia
|
||||
sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom
|
||||
spca506 06e1:a190 ADS Instant VCD
|
||||
spca508 0733:0110 ViewQuest VQ110
|
||||
spca508 0130:0130 Clone Digital Webcam 11043
|
||||
spca501 0733:0401 Intel Create and Share
|
||||
spca501 0733:0402 ViewQuest M318B
|
||||
spca505 0733:0430 Intel PC Camera Pro
|
||||
sunplus 0733:1311 Digital Dream Epsilon 1.3
|
||||
sunplus 0733:1314 Mercury 2.1MEG Deluxe Classic Cam
|
||||
sunplus 0733:2211 Jenoptik jdc 21 LCD
|
||||
sunplus 0733:2221 Mercury Digital Pro 3.1p
|
||||
sunplus 0733:3261 Concord 3045 spca536a
|
||||
sunplus 0733:3281 Cyberpix S550V
|
||||
spca506 0734:043b 3DeMon USB Capture aka
|
||||
spca500 084d:0003 D-Link DSC-350
|
||||
spca500 08ca:0103 Aiptek PocketDV
|
||||
sunplus 08ca:0104 Aiptek PocketDVII 1.3
|
||||
sunplus 08ca:0106 Aiptek Pocket DV3100+
|
||||
sunplus 08ca:2008 Aiptek Mini PenCam 2 M
|
||||
sunplus 08ca:2010 Aiptek PocketCam 3M
|
||||
sunplus 08ca:2016 Aiptek PocketCam 2 Mega
|
||||
sunplus 08ca:2018 Aiptek Pencam SD 2M
|
||||
sunplus 08ca:2020 Aiptek Slim 3000F
|
||||
sunplus 08ca:2022 Aiptek Slim 3200
|
||||
sunplus 08ca:2024 Aiptek DV3500 Mpeg4
|
||||
sunplus 08ca:2028 Aiptek PocketCam4M
|
||||
sunplus 08ca:2040 Aiptek PocketDV4100M
|
||||
sunplus 08ca:2042 Aiptek PocketDV5100
|
||||
sunplus 08ca:2050 Medion MD 41437
|
||||
sunplus 08ca:2060 Aiptek PocketDV5300
|
||||
tv8532 0923:010f ICM532 cams
|
||||
mars 093a:050f Mars-Semi Pc-Camera
|
||||
pac207 093a:2460 PAC207 Qtec Webcam 100
|
||||
pac207 093a:2463 Philips spc200nc pac207
|
||||
pac207 093a:2464 Labtec Webcam 1200
|
||||
pac207 093a:2468 PAC207
|
||||
pac207 093a:2470 Genius GF112
|
||||
pac207 093a:2471 PAC207 Genius VideoCam ge111
|
||||
pac207 093a:2472 PAC207 Genius VideoCam ge110
|
||||
pac7311 093a:2600 PAC7311 Typhoon
|
||||
pac7311 093a:2601 PAC7311 Phillips SPC610NC
|
||||
pac7311 093a:2603 PAC7312
|
||||
pac7311 093a:2608 PAC7311 Trust WB-3300p
|
||||
pac7311 093a:260e PAC7311 Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350
|
||||
pac7311 093a:260f PAC7311 SnakeCam
|
||||
pac7311 093a:2621 PAC731x
|
||||
zc3xx 0ac8:0302 Z-star Vimicro zc0302
|
||||
vc032x 0ac8:0321 Vimicro generic vc0321
|
||||
vc032x 0ac8:0323 Vimicro Vc0323
|
||||
vc032x 0ac8:0328 A4Tech PK-130MG
|
||||
zc3xx 0ac8:301b Z-Star zc301b
|
||||
zc3xx 0ac8:303b Vimicro 0x303b
|
||||
zc3xx 0ac8:305b Z-star Vimicro zc0305b
|
||||
zc3xx 0ac8:307b Ldlc VC302+Ov7620
|
||||
vc032x 0ac8:c001 Sony embedded vimicro
|
||||
vc032x 0ac8:c002 Sony embedded vimicro
|
||||
spca508 0af9:0010 Hama USB Sightcam 100
|
||||
spca508 0af9:0011 Hama USB Sightcam 100
|
||||
sonixb 0c45:6001 Genius VideoCAM NB
|
||||
sonixb 0c45:6005 Microdia Sweex Mini Webcam
|
||||
sonixb 0c45:6007 Sonix sn9c101 + Tas5110D
|
||||
sonixb 0c45:6009 spcaCam@120
|
||||
sonixb 0c45:600d spcaCam@120
|
||||
sonixb 0c45:6011 Microdia PC Camera (SN9C102)
|
||||
sonixb 0c45:6019 Generic Sonix OV7630
|
||||
sonixb 0c45:6024 Generic Sonix Tas5130c
|
||||
sonixb 0c45:6025 Xcam Shanga
|
||||
sonixb 0c45:6028 Sonix Btc Pc380
|
||||
sonixb 0c45:6029 spcaCam@150
|
||||
sonixb 0c45:602c Generic Sonix OV7630
|
||||
sonixb 0c45:602d LIC-200 LG
|
||||
sonixb 0c45:602e Genius VideoCam Messenger
|
||||
sonixj 0c45:6040 Speed NVC 350K
|
||||
sonixj 0c45:607c Sonix sn9c102p Hv7131R
|
||||
sonixj 0c45:60c0 Sangha Sn535
|
||||
sonixj 0c45:60ec SN9C105+MO4000
|
||||
sonixj 0c45:60fb Surfer NoName
|
||||
sonixj 0c45:60fc LG-LIC300
|
||||
sonixj 0c45:612a Avant Camera
|
||||
sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix
|
||||
sonixj 0c45:6130 Sonix Pccam
|
||||
sonixj 0c45:6138 Sn9c120 Mo4000
|
||||
sonixj 0c45:613b Surfer SN-206
|
||||
sonixj 0c45:613c Sonix Pccam168
|
||||
sunplus 0d64:0303 Sunplus FashionCam DXG
|
||||
etoms 102c:6151 Qcam Sangha CIF
|
||||
etoms 102c:6251 Qcam xxxxxx VGA
|
||||
zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128
|
||||
spca561 10fd:7e50 FlyCam Usb 100
|
||||
zc3xx 10fd:8050 Typhoon Webshot II USB 300k
|
||||
spca501 1776:501c Arowana 300K CMOS Camera
|
||||
t613 17a1:0128 T613/TAS5130A
|
||||
vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC
|
||||
pac207 2001:f115 D-Link DSB-C120
|
||||
spca500 2899:012c Toptro Industrial
|
||||
spca508 8086:0110 Intel Easy PC Camera
|
||||
spca500 8086:0630 Intel Pocket PC Camera
|
||||
spca506 99fa:8988 Grandtec V.cap
|
||||
spca561 abcd:cdee Petcam
|
36
MAINTAINERS
36
MAINTAINERS
|
@ -248,7 +248,7 @@ S: Supported
|
|||
ACPI PCI HOTPLUG DRIVER
|
||||
P: Kristen Carlson Accardi
|
||||
M: kristen.c.accardi@intel.com
|
||||
L: pcihpd-discuss@lists.sourceforge.net
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Supported
|
||||
|
||||
ACPI THERMAL DRIVER
|
||||
|
@ -1145,21 +1145,21 @@ COMPACTPCI HOTPLUG CORE
|
|||
P: Scott Murray
|
||||
M: scottm@somanetworks.com
|
||||
M: scott@spiteful.org
|
||||
L: pcihpd-discuss@lists.sourceforge.net
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Supported
|
||||
|
||||
COMPACTPCI HOTPLUG ZIATECH ZT5550 DRIVER
|
||||
P: Scott Murray
|
||||
M: scottm@somanetworks.com
|
||||
M: scott@spiteful.org
|
||||
L: pcihpd-discuss@lists.sourceforge.net
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Supported
|
||||
|
||||
COMPACTPCI HOTPLUG GENERIC DRIVER
|
||||
P: Scott Murray
|
||||
M: scottm@somanetworks.com
|
||||
M: scott@spiteful.org
|
||||
L: pcihpd-discuss@lists.sourceforge.net
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Supported
|
||||
|
||||
COMPAL LAPTOP SUPPORT
|
||||
|
@ -1988,6 +1988,12 @@ M: mikulas@artax.karlin.mff.cuni.cz
|
|||
W: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
|
||||
S: Maintained
|
||||
|
||||
HTCPEN TOUCHSCREEN DRIVER
|
||||
P: Pau Oliva Fora
|
||||
M: pof@eslack.org
|
||||
L: linux-input@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
HUGETLB FILESYSTEM
|
||||
P: William Irwin
|
||||
M: wli@holomorphy.com
|
||||
|
@ -2189,6 +2195,8 @@ P: Jesse Brandeburg
|
|||
M: jesse.brandeburg@intel.com
|
||||
P: Bruce Allan
|
||||
M: bruce.w.allan@intel.com
|
||||
P: PJ Waskiewicz
|
||||
M: peter.p.waskiewicz.jr@intel.com
|
||||
P: John Ronciak
|
||||
M: john.ronciak@intel.com
|
||||
L: e1000-devel@lists.sourceforge.net
|
||||
|
@ -2725,12 +2733,10 @@ L: libertas-dev@lists.infradead.org
|
|||
S: Maintained
|
||||
|
||||
MARVELL MV643XX ETHERNET DRIVER
|
||||
P: Dale Farnsworth
|
||||
M: dale@farnsworth.org
|
||||
P: Manish Lachwani
|
||||
M: mlachwani@mvista.com
|
||||
P: Lennert Buytenhek
|
||||
M: buytenh@marvell.com
|
||||
L: netdev@vger.kernel.org
|
||||
S: Odd Fixes for 2.4; Maintained for 2.6.
|
||||
S: Supported
|
||||
|
||||
MATROX FRAMEBUFFER DRIVER
|
||||
P: Petr Vandrovec
|
||||
|
@ -3219,7 +3225,7 @@ S: Supported
|
|||
PCIE HOTPLUG DRIVER
|
||||
P: Kristen Carlson Accardi
|
||||
M: kristen.c.accardi@intel.com
|
||||
L: pcihpd-discuss@lists.sourceforge.net
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Supported
|
||||
|
||||
PCMCIA SUBSYSTEM
|
||||
|
@ -3274,14 +3280,6 @@ L: linux-kernel@vger.kernel.org
|
|||
T: git git.infradead.org/battery-2.6.git
|
||||
S: Maintained
|
||||
|
||||
POWERPC 4xx EMAC DRIVER
|
||||
P: Eugene Surovegin
|
||||
M: ebs@ebshome.net
|
||||
W: http://kernel.ebshome.net/emac/
|
||||
L: linuxppc-dev@ozlabs.org
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
PNP SUPPORT
|
||||
P: Adam Belay
|
||||
M: ambx1@neo.rr.com
|
||||
|
@ -3865,7 +3863,7 @@ S: Maintained
|
|||
SHPC HOTPLUG DRIVER
|
||||
P: Kristen Carlson Accardi
|
||||
M: kristen.c.accardi@intel.com
|
||||
L: pcihpd-discuss@lists.sourceforge.net
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Supported
|
||||
|
||||
SECURE DIGITAL HOST CONTROLLER INTERFACE DRIVER
|
||||
|
|
1
Makefile
1
Makefile
|
@ -1,4 +1,3 @@
|
|||
FRED=42
|
||||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 26
|
||||
|
|
|
@ -323,10 +323,15 @@ static struct platform_device smc91x_device = {
|
|||
static struct resource dm9000_resources[] = {
|
||||
[0] = {
|
||||
.start = 0x203FB800,
|
||||
.end = 0x203FB800 + 8,
|
||||
.end = 0x203FB800 + 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = 0x203FB800 + 4,
|
||||
.end = 0x203FB800 + 5,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_PF9,
|
||||
.end = IRQ_PF9,
|
||||
.flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
|
||||
|
|
|
@ -65,10 +65,15 @@ static struct platform_device rtc_device = {
|
|||
static struct resource dm9000_resources[] = {
|
||||
[0] = {
|
||||
.start = 0x20300000,
|
||||
.end = 0x20300000 + 8,
|
||||
.end = 0x20300000 + 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = 0x20300000 + 4,
|
||||
.end = 0x20300000 + 5,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_PF10,
|
||||
.end = IRQ_PF10,
|
||||
.flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
|
||||
|
|
|
@ -166,10 +166,15 @@ static struct platform_device smc91x_device = {
|
|||
static struct resource dm9000_resources[] = {
|
||||
[0] = {
|
||||
.start = 0x203FB800,
|
||||
.end = 0x203FB800 + 8,
|
||||
.end = 0x203FB800 + 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = 0x203FB800 + 4,
|
||||
.end = 0x203FB800 + 5,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_PF9,
|
||||
.end = IRQ_PF9,
|
||||
.flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
# arch/cris/arch-v10/boot/Makefile
|
||||
#
|
||||
|
||||
OBJCOPY = objcopy-cris
|
||||
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
||||
|
||||
subdir- := compressed rescue
|
||||
|
|
|
@ -2,12 +2,10 @@
|
|||
# arch/cris/arch-v10/boot/compressed/Makefile
|
||||
#
|
||||
|
||||
CC = gcc-cris -melf $(LINUXINCLUDE)
|
||||
ccflags-y += -O2
|
||||
LD = ld-cris
|
||||
ldflags-y += -T $(obj)/decompress.ld
|
||||
asflags-y += $(LINUXINCLUDE)
|
||||
ccflags-y += -O2 $(LINUXINCLUDE)
|
||||
ldflags-y += -T $(srctree)/$(obj)/decompress.ld
|
||||
OBJECTS = $(obj)/head.o $(obj)/misc.o
|
||||
OBJCOPY = objcopy-cris
|
||||
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
||||
|
||||
quiet_cmd_image = BUILD $@
|
||||
|
@ -21,12 +19,6 @@ $(obj)/decompress.o: $(OBJECTS) FORCE
|
|||
$(obj)/decompress.bin: $(obj)/decompress.o FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
$(obj)/head.o: $(obj)/head.S .config
|
||||
@$(CC) -D__ASSEMBLY__ -traditional -c $< -o $@
|
||||
|
||||
$(obj)/misc.o: $(obj)/misc.c .config
|
||||
@$(CC) -D__KERNEL__ -c $< -o $@
|
||||
|
||||
$(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
|
||||
$(call if_changed,image)
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
OUTPUT_FORMAT(elf32-us-cris)
|
||||
/* OUTPUT_FORMAT(elf32-us-cris) */
|
||||
OUTPUT_FORMAT(elf32-cris)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
|
|
|
@ -15,77 +15,77 @@
|
|||
#define COMMAND_LINE_MAGIC 0x87109563
|
||||
|
||||
;; Exported symbols
|
||||
|
||||
.globl _input_data
|
||||
|
||||
|
||||
.globl input_data
|
||||
|
||||
|
||||
.text
|
||||
|
||||
nop
|
||||
di
|
||||
|
||||
;; We need to initialze DRAM registers before we start using the DRAM
|
||||
|
||||
cmp.d RAM_INIT_MAGIC, r8 ; Already initialized?
|
||||
|
||||
cmp.d RAM_INIT_MAGIC, $r8 ; Already initialized?
|
||||
beq dram_init_finished
|
||||
nop
|
||||
|
||||
|
||||
#include "../../lib/dram_init.S"
|
||||
|
||||
dram_init_finished:
|
||||
|
||||
|
||||
dram_init_finished:
|
||||
|
||||
;; Initiate the PA and PB ports
|
||||
|
||||
move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, r0
|
||||
move.b r0, [R_PORT_PA_DATA]
|
||||
move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
|
||||
move.b $r0, [R_PORT_PA_DATA]
|
||||
|
||||
move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, r0
|
||||
move.b r0, [R_PORT_PA_DIR]
|
||||
move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
|
||||
move.b $r0, [R_PORT_PA_DIR]
|
||||
|
||||
move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, r0
|
||||
move.b r0, [R_PORT_PB_DATA]
|
||||
move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
|
||||
move.b $r0, [R_PORT_PB_DATA]
|
||||
|
||||
move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, r0
|
||||
move.b r0, [R_PORT_PB_DIR]
|
||||
move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
|
||||
move.b $r0, [R_PORT_PB_DIR]
|
||||
|
||||
;; Setup the stack to a suitably high address.
|
||||
;; We assume 8 MB is the minimum DRAM in an eLinux
|
||||
;; product and put the sp at the top for now.
|
||||
|
||||
move.d 0x40800000, sp
|
||||
move.d 0x40800000, $sp
|
||||
|
||||
;; Figure out where the compressed piggyback image is
|
||||
;; in the flash (since we wont try to copy it to DRAM
|
||||
;; before unpacking). It is at _edata, but in flash.
|
||||
;; Use (_edata - basse) as offset to the current PC.
|
||||
|
||||
basse: move.d pc, r5
|
||||
and.d 0x7fffffff, r5 ; strip any non-cache bit
|
||||
subq 2, r5 ; compensate for the move.d pc instr
|
||||
move.d r5, r0 ; save for later - flash address of 'basse'
|
||||
add.d _edata, r5
|
||||
sub.d basse, r5 ; r5 = flash address of '_edata'
|
||||
|
||||
|
||||
basse: move.d $pc, $r5
|
||||
and.d 0x7fffffff, $r5 ; strip any non-cache bit
|
||||
subq 2, $r5 ; compensate for the move.d $pc instr
|
||||
move.d $r5, $r0 ; save for later - flash address of 'basse'
|
||||
add.d _edata, $r5
|
||||
sub.d basse, $r5 ; $r5 = flash address of '_edata'
|
||||
|
||||
;; Copy text+data to DRAM
|
||||
|
||||
move.d basse, r1 ; destination
|
||||
move.d _edata, r2 ; end destination
|
||||
1: move.w [r0+], r3
|
||||
move.w r3, [r1+]
|
||||
cmp.d r2, r1
|
||||
|
||||
move.d basse, $r1 ; destination
|
||||
move.d _edata, $r2 ; end destination
|
||||
1: move.w [$r0+], $r3
|
||||
move.w $r3, [$r1+]
|
||||
cmp.d $r2, $r1
|
||||
bcs 1b
|
||||
nop
|
||||
|
||||
move.d r5, [_input_data] ; for the decompressor
|
||||
move.d $r5, [input_data] ; for the decompressor
|
||||
|
||||
|
||||
;; Clear the decompressors BSS (between _edata and _end)
|
||||
|
||||
moveq 0, r0
|
||||
move.d _edata, r1
|
||||
move.d _end, r2
|
||||
1: move.w r0, [r1+]
|
||||
cmp.d r2, r1
|
||||
|
||||
moveq 0, $r0
|
||||
move.d _edata, $r1
|
||||
move.d _end, $r2
|
||||
1: move.w $r0, [$r1+]
|
||||
cmp.d $r2, $r1
|
||||
bcs 1b
|
||||
nop
|
||||
|
||||
|
@ -94,16 +94,16 @@ basse: move.d pc, r5
|
|||
move.d $r10, [$r12]
|
||||
move.d _cmd_line_addr, $r12
|
||||
move.d $r11, [$r12]
|
||||
|
||||
;; Do the decompression and save compressed size in _inptr
|
||||
|
||||
jsr _decompress_kernel
|
||||
|
||||
;; Put start address of root partition in r9 so the kernel can use it
|
||||
;; Do the decompression and save compressed size in inptr
|
||||
|
||||
jsr decompress_kernel
|
||||
|
||||
;; Put start address of root partition in $r9 so the kernel can use it
|
||||
;; when mounting from flash
|
||||
|
||||
move.d [_input_data], r9 ; flash address of compressed kernel
|
||||
add.d [_inptr], r9 ; size of compressed kernel
|
||||
move.d [input_data], $r9 ; flash address of compressed kernel
|
||||
add.d [inptr], $r9 ; size of compressed kernel
|
||||
|
||||
;; Restore command line magic and address.
|
||||
move.d _cmd_line_magic, $r10
|
||||
|
@ -112,12 +112,12 @@ basse: move.d pc, r5
|
|||
move.d [$r11], $r11
|
||||
|
||||
;; Enter the decompressed kernel
|
||||
move.d RAM_INIT_MAGIC, r8 ; Tell kernel that DRAM is initialized
|
||||
move.d RAM_INIT_MAGIC, $r8 ; Tell kernel that DRAM is initialized
|
||||
jump 0x40004000 ; kernel is linked to this address
|
||||
|
||||
|
||||
.data
|
||||
|
||||
_input_data:
|
||||
input_data:
|
||||
.dword 0 ; used by the decompressor
|
||||
_cmd_line_magic:
|
||||
.dword 0
|
||||
|
|
|
@ -29,12 +29,10 @@
|
|||
#define OF(args) args
|
||||
#define STATIC static
|
||||
|
||||
void* memset(void* s, int c, size_t n);
|
||||
void* memcpy(void* __dest, __const void* __src,
|
||||
size_t __n);
|
||||
|
||||
#define memzero(s, n) memset ((s), 0, (n))
|
||||
void *memset(void *s, int c, size_t n);
|
||||
void *memcpy(void *__dest, __const void *__src, size_t __n);
|
||||
|
||||
#define memzero(s, n) memset((s), 0, (n))
|
||||
|
||||
typedef unsigned char uch;
|
||||
typedef unsigned short ush;
|
||||
|
@ -62,57 +60,69 @@ static unsigned outcnt = 0; /* bytes in output buffer */
|
|||
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
|
||||
#define RESERVED 0xC0 /* bit 6,7: reserved */
|
||||
|
||||
#define get_byte() inbuf[inptr++]
|
||||
|
||||
#define get_byte() (inbuf[inptr++])
|
||||
|
||||
/* Diagnostic functions */
|
||||
#ifdef DEBUG
|
||||
# define Assert(cond,msg) {if(!(cond)) error(msg);}
|
||||
# define Assert(cond, msg) do { \
|
||||
if (!(cond)) \
|
||||
error(msg); \
|
||||
} while (0)
|
||||
# define Trace(x) fprintf x
|
||||
# define Tracev(x) {if (verbose) fprintf x ;}
|
||||
# define Tracevv(x) {if (verbose>1) fprintf x ;}
|
||||
# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
|
||||
# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
|
||||
# define Tracev(x) do { \
|
||||
if (verbose) \
|
||||
fprintf x; \
|
||||
} while (0)
|
||||
# define Tracevv(x) do { \
|
||||
if (verbose > 1) \
|
||||
fprintf x; \
|
||||
} while (0)
|
||||
# define Tracec(c, x) do { \
|
||||
if (verbose && (c)) \
|
||||
fprintf x; \
|
||||
} while (0)
|
||||
# define Tracecv(c, x) do { \
|
||||
if (verbose > 1 && (c)) \
|
||||
fprintf x; \
|
||||
} while (0)
|
||||
#else
|
||||
# define Assert(cond,msg)
|
||||
# define Assert(cond, msg)
|
||||
# define Trace(x)
|
||||
# define Tracev(x)
|
||||
# define Tracevv(x)
|
||||
# define Tracec(c,x)
|
||||
# define Tracecv(c,x)
|
||||
# define Tracec(c, x)
|
||||
# define Tracecv(c, x)
|
||||
#endif
|
||||
|
||||
static int fill_inbuf(void);
|
||||
static void flush_window(void);
|
||||
static void error(char *m);
|
||||
static void gzip_mark(void **);
|
||||
static void gzip_release(void **);
|
||||
|
||||
extern char *input_data; /* lives in head.S */
|
||||
|
||||
static long bytes_out = 0;
|
||||
static uch *output_data;
|
||||
static unsigned long output_ptr = 0;
|
||||
|
||||
|
||||
static void *malloc(int size);
|
||||
static void free(void *where);
|
||||
static void error(char *m);
|
||||
static void gzip_mark(void **);
|
||||
static void gzip_release(void **);
|
||||
|
||||
|
||||
static void puts(const char *);
|
||||
|
||||
/* the "heap" is put directly after the BSS ends, at end */
|
||||
|
||||
extern int end;
|
||||
static long free_mem_ptr = (long)&end;
|
||||
|
||||
|
||||
extern int _end;
|
||||
static long free_mem_ptr = (long)&_end;
|
||||
|
||||
#include "../../../../../lib/inflate.c"
|
||||
|
||||
static void *malloc(int size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if (size <0) error("Malloc error");
|
||||
if (size < 0)
|
||||
error("Malloc error");
|
||||
|
||||
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
|
||||
|
||||
|
@ -142,44 +152,47 @@ static void
|
|||
puts(const char *s)
|
||||
{
|
||||
#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
|
||||
while(*s) {
|
||||
while (*s) {
|
||||
#ifdef CONFIG_ETRAX_DEBUG_PORT0
|
||||
while(!(*R_SERIAL0_STATUS & (1 << 5))) ;
|
||||
while (!(*R_SERIAL0_STATUS & (1 << 5))) ;
|
||||
*R_SERIAL0_TR_DATA = *s++;
|
||||
#endif
|
||||
#ifdef CONFIG_ETRAX_DEBUG_PORT1
|
||||
while(!(*R_SERIAL1_STATUS & (1 << 5))) ;
|
||||
while (!(*R_SERIAL1_STATUS & (1 << 5))) ;
|
||||
*R_SERIAL1_TR_DATA = *s++;
|
||||
#endif
|
||||
#ifdef CONFIG_ETRAX_DEBUG_PORT2
|
||||
while(!(*R_SERIAL2_STATUS & (1 << 5))) ;
|
||||
while (!(*R_SERIAL2_STATUS & (1 << 5))) ;
|
||||
*R_SERIAL2_TR_DATA = *s++;
|
||||
#endif
|
||||
#ifdef CONFIG_ETRAX_DEBUG_PORT3
|
||||
while(!(*R_SERIAL3_STATUS & (1 << 5))) ;
|
||||
while (!(*R_SERIAL3_STATUS & (1 << 5))) ;
|
||||
*R_SERIAL3_TR_DATA = *s++;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void*
|
||||
memset(void* s, int c, size_t n)
|
||||
void *memset(void *s, int c, size_t n)
|
||||
{
|
||||
int i;
|
||||
char *ss = (char*)s;
|
||||
char *ss = (char *)s;
|
||||
|
||||
for (i=0;i<n;i++) ss[i] = c;
|
||||
for (i = 0; i < n; i++)
|
||||
ss[i] = c;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void*
|
||||
memcpy(void* __dest, __const void* __src,
|
||||
size_t __n)
|
||||
void *memcpy(void *__dest, __const void *__src, size_t __n)
|
||||
{
|
||||
int i;
|
||||
char *d = (char *)__dest, *s = (char *)__src;
|
||||
|
||||
for (i=0;i<__n;i++) d[i] = s[i];
|
||||
for (i = 0; i < __n; i++)
|
||||
d[i] = s[i];
|
||||
|
||||
return __dest;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
|
@ -187,46 +200,44 @@ memcpy(void* __dest, __const void* __src,
|
|||
* (Used for the decompressed data only.)
|
||||
*/
|
||||
|
||||
static void
|
||||
flush_window()
|
||||
static void flush_window(void)
|
||||
{
|
||||
ulg c = crc; /* temporary variable */
|
||||
unsigned n;
|
||||
uch *in, *out, ch;
|
||||
|
||||
in = window;
|
||||
out = &output_data[output_ptr];
|
||||
for (n = 0; n < outcnt; n++) {
|
||||
ch = *out++ = *in++;
|
||||
c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
|
||||
}
|
||||
crc = c;
|
||||
bytes_out += (ulg)outcnt;
|
||||
output_ptr += (ulg)outcnt;
|
||||
outcnt = 0;
|
||||
ulg c = crc; /* temporary variable */
|
||||
unsigned n;
|
||||
uch *in, *out, ch;
|
||||
|
||||
in = window;
|
||||
out = &output_data[output_ptr];
|
||||
for (n = 0; n < outcnt; n++) {
|
||||
ch = *out = *in;
|
||||
out++;
|
||||
in++;
|
||||
c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
|
||||
}
|
||||
crc = c;
|
||||
bytes_out += (ulg)outcnt;
|
||||
output_ptr += (ulg)outcnt;
|
||||
outcnt = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
error(char *x)
|
||||
static void error(char *x)
|
||||
{
|
||||
puts("\n\n");
|
||||
puts(x);
|
||||
puts("\n\n -- System halted\n");
|
||||
|
||||
while(1); /* Halt */
|
||||
while (1); /* Halt */
|
||||
}
|
||||
|
||||
void
|
||||
setup_normal_output_buffer()
|
||||
void setup_normal_output_buffer(void)
|
||||
{
|
||||
output_data = (char *)KERNEL_LOAD_ADR;
|
||||
}
|
||||
|
||||
void
|
||||
decompress_kernel()
|
||||
void decompress_kernel(void)
|
||||
{
|
||||
char revision;
|
||||
|
||||
|
||||
/* input_data is set in head.S */
|
||||
inbuf = input_data;
|
||||
|
||||
|
@ -257,11 +268,10 @@ decompress_kernel()
|
|||
|
||||
makecrc();
|
||||
|
||||
__asm__ volatile ("move vr,%0" : "=rm" (revision));
|
||||
if (revision < 10)
|
||||
{
|
||||
__asm__ volatile ("move $vr,%0" : "=rm" (revision));
|
||||
if (revision < 10) {
|
||||
puts("You need an ETRAX 100LX to run linux 2.6\n");
|
||||
while(1);
|
||||
while (1);
|
||||
}
|
||||
|
||||
puts("Uncompressing Linux...\n");
|
||||
|
|
|
@ -2,12 +2,9 @@
|
|||
# Makefile for rescue (bootstrap) code
|
||||
#
|
||||
|
||||
CC = gcc-cris -mlinux $(LINUXINCLUDE)
|
||||
ccflags-y += -O2
|
||||
asflags-y += -traditional
|
||||
LD = gcc-cris -mlinux -nostdlib
|
||||
ldflags-y += -T $(obj)/rescue.ld
|
||||
OBJCOPY = objcopy-cris
|
||||
ccflags-y += -O2 $(LINUXINCLUDE)
|
||||
asflags-y += $(LINUXINCLUDE)
|
||||
ldflags-y += -T $(srctree)/$(obj)/rescue.ld
|
||||
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
||||
obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o
|
||||
OBJECT := $(obj)/head.o
|
||||
|
|
|
@ -233,7 +233,7 @@ int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
|
||||
if (copy_to_user((struct rtc_time *) arg, &tm,
|
||||
sizeof tm)) {
|
||||
spin_unlock(&rtc_lock);
|
||||
mutex_unlock(&rtc_lock);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
|
|
@ -426,12 +426,18 @@ static int dummy_write(struct tty_struct * tty,
|
|||
return count;
|
||||
}
|
||||
|
||||
static int
|
||||
dummy_write_room(struct tty_struct *tty)
|
||||
static int dummy_write_room(struct tty_struct *tty)
|
||||
{
|
||||
return 8192;
|
||||
}
|
||||
|
||||
static const struct tty_operations dummy_ops = {
|
||||
.open = dummy_open,
|
||||
.close = dummy_close,
|
||||
.write = dummy_write,
|
||||
.write_room = dummy_write_room,
|
||||
};
|
||||
|
||||
void __init
|
||||
init_dummy_console(void)
|
||||
{
|
||||
|
@ -444,14 +450,14 @@ init_dummy_console(void)
|
|||
dummy_driver.type = TTY_DRIVER_TYPE_SERIAL;
|
||||
dummy_driver.subtype = SERIAL_TYPE_NORMAL;
|
||||
dummy_driver.init_termios = tty_std_termios;
|
||||
/* Normally B9600 default... */
|
||||
dummy_driver.init_termios.c_cflag =
|
||||
B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
|
||||
B115200 | CS8 | CREAD | HUPCL | CLOCAL;
|
||||
dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
|
||||
dummy_driver.init_termios.c_ispeed = 115200;
|
||||
dummy_driver.init_termios.c_ospeed = 115200;
|
||||
|
||||
dummy_driver.open = dummy_open;
|
||||
dummy_driver.close = dummy_close;
|
||||
dummy_driver.write = dummy_write;
|
||||
dummy_driver.write_room = dummy_write_room;
|
||||
dummy_driver.ops = &dummy_ops;
|
||||
if (tty_register_driver(&dummy_driver))
|
||||
panic("Couldn't register dummy serial driver\n");
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
# arch/cris/arch-v32/boot/Makefile
|
||||
#
|
||||
|
||||
OBJCOPY = objcopy-cris
|
||||
OBJCOPYFLAGS = -O binary -R .note -R .comment
|
||||
|
||||
subdir- := compressed rescue
|
||||
|
|
|
@ -2,14 +2,10 @@
|
|||
# arch/cris/arch-v32/boot/compressed/Makefile
|
||||
#
|
||||
|
||||
CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE)
|
||||
asflags-y += -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch
|
||||
ccflags-y += -O2 -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch
|
||||
LD = gcc-cris -mlinux -march=v32 -nostdlib
|
||||
ldflags-y += -T $(obj)/decompress.ld
|
||||
obj-y = head.o misc.o
|
||||
ldflags-y += -T $(srctree)/$(obj)/decompress.ld
|
||||
OBJECTS = $(obj)/head.o $(obj)/misc.o
|
||||
OBJCOPY = objcopy-cris
|
||||
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
||||
|
||||
quiet_cmd_image = BUILD $@
|
||||
|
|
|
@ -7,9 +7,8 @@ ccflags-y += -O2 -I $(srctree)/include/asm/arch/mach/ \
|
|||
-I $(srctree)/include/asm/arch
|
||||
asflags-y += -I $(srctree)/include/asm/arch/mach/ -I $(srctree)/include/asm/arch
|
||||
LD = gcc-cris -mlinux -march=v32 -nostdlib
|
||||
ldflags-y += -T $(obj)/rescue.ld
|
||||
ldflags-y += -T $(srctree)/$(obj)/rescue.ld
|
||||
LDPOSTFLAGS = -lgcc
|
||||
OBJCOPY = objcopy-cris
|
||||
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
||||
obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o
|
||||
OBJECT := $(obj)/head.o
|
||||
|
|
|
@ -229,7 +229,7 @@ int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
|
||||
if (copy_to_user((struct rtc_time *) arg, &tm,
|
||||
sizeof tm)) {
|
||||
spin_unlock(&rtc_lock);
|
||||
mutex_unlock(&rtc_lock);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,36 +19,6 @@
|
|||
|
||||
#include "pci-frv.h"
|
||||
|
||||
#if 0
|
||||
void
|
||||
pcibios_update_resource(struct pci_dev *dev, struct resource *root,
|
||||
struct resource *res, int resource)
|
||||
{
|
||||
u32 new, check;
|
||||
int reg;
|
||||
|
||||
new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
|
||||
if (resource < 6) {
|
||||
reg = PCI_BASE_ADDRESS_0 + 4*resource;
|
||||
} else if (resource == PCI_ROM_RESOURCE) {
|
||||
res->flags |= IORESOURCE_ROM_ENABLE;
|
||||
new |= PCI_ROM_ADDRESS_ENABLE;
|
||||
reg = dev->rom_base_reg;
|
||||
} else {
|
||||
/* Somebody might have asked allocation of a non-standard resource */
|
||||
return;
|
||||
}
|
||||
|
||||
pci_write_config_dword(dev, reg, new);
|
||||
pci_read_config_dword(dev, reg, &check);
|
||||
if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
|
||||
printk(KERN_ERR "PCI: Error while updating region "
|
||||
"%s/%d (%08x != %08x)\n", pci_name(dev), resource,
|
||||
new, check);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We need to avoid collisions with `mirrored' VGA ports
|
||||
* and other strange ISA hardware, so we always want the
|
||||
|
|
|
@ -540,8 +540,8 @@ config KEXEC
|
|||
strongly in flux, so no good recommendation can be made.
|
||||
|
||||
config CRASH_DUMP
|
||||
bool "kernel crash dumps (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL && IA64_MCA_RECOVERY && !IA64_HP_SIM && (!SMP || HOTPLUG_CPU)
|
||||
bool "kernel crash dumps"
|
||||
depends on IA64_MCA_RECOVERY && !IA64_HP_SIM && (!SMP || HOTPLUG_CPU)
|
||||
help
|
||||
Generate crash dump after being started by kexec.
|
||||
|
||||
|
|
|
@ -100,3 +100,9 @@ define archhelp
|
|||
echo ' boot - Build vmlinux and bootloader for Ski simulator'
|
||||
echo '* unwcheck - Check vmlinux for invalid unwind info'
|
||||
endef
|
||||
|
||||
archprepare: make_nr_irqs_h FORCE
|
||||
PHONY += make_nr_irqs_h FORCE
|
||||
|
||||
make_nr_irqs_h: FORCE
|
||||
$(Q)$(MAKE) $(build)=arch/ia64/kernel include/asm-ia64/nr-irqs.h
|
||||
|
|
|
@ -193,18 +193,6 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
|
|||
* -------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* not really used in our situation so keep them commented out for now
|
||||
*/
|
||||
static DECLARE_TASK_QUEUE(tq_serial); /* used to be at the top of the file */
|
||||
static void do_serial_bh(void)
|
||||
{
|
||||
run_task_queue(&tq_serial);
|
||||
printk(KERN_ERR "do_serial_bh: called\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void do_softint(struct work_struct *private_)
|
||||
{
|
||||
printk(KERN_ERR "simserial: do_softint called\n");
|
||||
|
@ -351,11 +339,7 @@ static void rs_flush_buffer(struct tty_struct *tty)
|
|||
info->xmit.head = info->xmit.tail = 0;
|
||||
local_irq_restore(flags);
|
||||
|
||||
wake_up_interruptible(&tty->write_wait);
|
||||
|
||||
if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
|
||||
tty->ldisc.write_wakeup)
|
||||
(tty->ldisc.write_wakeup)(tty);
|
||||
tty_wakeup(tty);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -404,12 +388,6 @@ static void rs_unthrottle(struct tty_struct * tty)
|
|||
printk(KERN_INFO "simrs_unthrottle called\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* rs_break() --- routine which turns the break handling on or off
|
||||
*/
|
||||
static void rs_break(struct tty_struct *tty, int break_state)
|
||||
{
|
||||
}
|
||||
|
||||
static int rs_ioctl(struct tty_struct *tty, struct file * file,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
|
@ -422,14 +400,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
|
|||
}
|
||||
|
||||
switch (cmd) {
|
||||
case TIOCMGET:
|
||||
printk(KERN_INFO "rs_ioctl: TIOCMGET called\n");
|
||||
return -EINVAL;
|
||||
case TIOCMBIS:
|
||||
case TIOCMBIC:
|
||||
case TIOCMSET:
|
||||
printk(KERN_INFO "rs_ioctl: TIOCMBIS/BIC/SET called\n");
|
||||
return -EINVAL;
|
||||
case TIOCGSERIAL:
|
||||
printk(KERN_INFO "simrs_ioctl TIOCGSERIAL called\n");
|
||||
return 0;
|
||||
|
@ -488,14 +458,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
|
|||
|
||||
static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
|
||||
{
|
||||
unsigned int cflag = tty->termios->c_cflag;
|
||||
|
||||
if ( (cflag == old_termios->c_cflag)
|
||||
&& ( RELEVANT_IFLAG(tty->termios->c_iflag)
|
||||
== RELEVANT_IFLAG(old_termios->c_iflag)))
|
||||
return;
|
||||
|
||||
|
||||
/* Handle turning off CRTSCTS */
|
||||
if ((old_termios->c_cflag & CRTSCTS) &&
|
||||
!(tty->termios->c_cflag & CRTSCTS)) {
|
||||
|
@ -623,9 +585,8 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
|
|||
* the line discipline to only process XON/XOFF characters.
|
||||
*/
|
||||
shutdown(info);
|
||||
if (tty->ops->flush_buffer)
|
||||
tty->ops->flush_buffer(tty);
|
||||
if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty);
|
||||
rs_flush_buffer(tty);
|
||||
tty_ldisc_flush(tty);
|
||||
info->event = 0;
|
||||
info->tty = NULL;
|
||||
if (info->blocked_open) {
|
||||
|
@ -955,7 +916,6 @@ static const struct tty_operations hp_ops = {
|
|||
.stop = rs_stop,
|
||||
.start = rs_start,
|
||||
.hangup = rs_hangup,
|
||||
.break_ctl = rs_break,
|
||||
.wait_until_sent = rs_wait_until_sent,
|
||||
.read_proc = rs_read_proc,
|
||||
};
|
||||
|
|
|
@ -36,6 +36,8 @@ obj-$(CONFIG_PCI_MSI) += msi_ia64.o
|
|||
mca_recovery-y += mca_drv.o mca_drv_asm.o
|
||||
obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o
|
||||
|
||||
obj-$(CONFIG_PARAVIRT) += paravirt.o paravirtentry.o
|
||||
|
||||
obj-$(CONFIG_IA64_ESI) += esi.o
|
||||
ifneq ($(CONFIG_IA64_ESI),)
|
||||
obj-y += esi_stub.o # must be in kernel proper
|
||||
|
@ -70,3 +72,45 @@ $(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE
|
|||
# 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
|
||||
define sed-y
|
||||
"/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}"
|
||||
endef
|
||||
quiet_cmd_nr_irqs = GEN $@
|
||||
define cmd_nr_irqs
|
||||
(set -e; \
|
||||
echo "#ifndef __ASM_NR_IRQS_H__"; \
|
||||
echo "#define __ASM_NR_IRQS_H__"; \
|
||||
echo "/*"; \
|
||||
echo " * DO NOT MODIFY."; \
|
||||
echo " *"; \
|
||||
echo " * This file was generated by Kbuild"; \
|
||||
echo " *"; \
|
||||
echo " */"; \
|
||||
echo ""; \
|
||||
sed -ne $(sed-y) $<; \
|
||||
echo ""; \
|
||||
echo "#endif" ) > $@
|
||||
endef
|
||||
|
||||
# We use internal kbuild rules to avoid the "is up to date" message from make
|
||||
arch/$(SRCARCH)/kernel/nr-irqs.s: $(srctree)/arch/$(SRCARCH)/kernel/nr-irqs.c \
|
||||
$(wildcard $(srctree)/include/asm-ia64/*/irq.h)
|
||||
$(Q)mkdir -p $(dir $@)
|
||||
$(call if_changed_dep,cc_s_c)
|
||||
|
||||
include/asm-ia64/nr-irqs.h: arch/$(SRCARCH)/kernel/nr-irqs.s
|
||||
$(Q)mkdir -p $(dir $@)
|
||||
$(call cmd,nr_irqs)
|
||||
|
||||
clean-files += $(objtree)/include/asm-ia64/nr-irqs.h
|
||||
|
||||
#
|
||||
# native ivt.S and entry.S
|
||||
#
|
||||
ASM_PARAVIRT_OBJS = ivt.o entry.o
|
||||
define paravirtualized_native
|
||||
AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_NATIVE
|
||||
endef
|
||||
$(foreach obj,$(ASM_PARAVIRT_OBJS),$(eval $(call paravirtualized_native,$(obj))))
|
||||
|
|
|
@ -774,7 +774,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
|
|||
*/
|
||||
#ifdef CONFIG_ACPI_HOTPLUG_CPU
|
||||
static
|
||||
int acpi_map_cpu2node(acpi_handle handle, int cpu, long physid)
|
||||
int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
|
||||
{
|
||||
#ifdef CONFIG_ACPI_NUMA
|
||||
int pxm_id;
|
||||
|
@ -854,8 +854,7 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu)
|
|||
union acpi_object *obj;
|
||||
struct acpi_madt_local_sapic *lsapic;
|
||||
cpumask_t tmp_map;
|
||||
long physid;
|
||||
int cpu;
|
||||
int cpu, physid;
|
||||
|
||||
if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
|
||||
return -EINVAL;
|
||||
|
|
|
@ -51,7 +51,7 @@ processor_set_pstate (
|
|||
retval = ia64_pal_set_pstate((u64)value);
|
||||
|
||||
if (retval) {
|
||||
dprintk("Failed to set freq to 0x%x, with error 0x%x\n",
|
||||
dprintk("Failed to set freq to 0x%x, with error 0x%lx\n",
|
||||
value, retval);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ processor_get_pstate (
|
|||
|
||||
if (retval)
|
||||
dprintk("Failed to get current freq with "
|
||||
"error 0x%x, idx 0x%x\n", retval, *value);
|
||||
"error 0x%lx, idx 0x%x\n", retval, *value);
|
||||
|
||||
return (int)retval;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
* Patrick O'Rourke <orourke@missioncriticallinux.com>
|
||||
* 11/07/2000
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
|
||||
* VA Linux Systems Japan K.K.
|
||||
* pv_ops.
|
||||
*/
|
||||
/*
|
||||
* Global (preserved) predicate usage on syscall entry/exit path:
|
||||
*
|
||||
|
@ -45,6 +50,7 @@
|
|||
|
||||
#include "minstate.h"
|
||||
|
||||
#ifdef __IA64_ASM_PARAVIRTUALIZED_NATIVE
|
||||
/*
|
||||
* execve() is special because in case of success, we need to
|
||||
* setup a null register window frame.
|
||||
|
@ -173,6 +179,7 @@ GLOBAL_ENTRY(sys_clone)
|
|||
mov rp=loc0
|
||||
br.ret.sptk.many rp
|
||||
END(sys_clone)
|
||||
#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
|
||||
|
||||
/*
|
||||
* prev_task <- ia64_switch_to(struct task_struct *next)
|
||||
|
@ -180,7 +187,7 @@ END(sys_clone)
|
|||
* called. The code starting at .map relies on this. The rest of the code
|
||||
* doesn't care about the interrupt masking status.
|
||||
*/
|
||||
GLOBAL_ENTRY(ia64_switch_to)
|
||||
GLOBAL_ENTRY(__paravirt_switch_to)
|
||||
.prologue
|
||||
alloc r16=ar.pfs,1,0,0,0
|
||||
DO_SAVE_SWITCH_STACK
|
||||
|
@ -204,7 +211,7 @@ GLOBAL_ENTRY(ia64_switch_to)
|
|||
;;
|
||||
.done:
|
||||
ld8 sp=[r21] // load kernel stack pointer of new task
|
||||
mov IA64_KR(CURRENT)=in0 // update "current" application register
|
||||
MOV_TO_KR(CURRENT, in0, r8, r9) // update "current" application register
|
||||
mov r8=r13 // return pointer to previously running task
|
||||
mov r13=in0 // set "current" pointer
|
||||
;;
|
||||
|
@ -216,26 +223,25 @@ GLOBAL_ENTRY(ia64_switch_to)
|
|||
br.ret.sptk.many rp // boogie on out in new context
|
||||
|
||||
.map:
|
||||
rsm psr.ic // interrupts (psr.i) are already disabled here
|
||||
RSM_PSR_IC(r25) // interrupts (psr.i) are already disabled here
|
||||
movl r25=PAGE_KERNEL
|
||||
;;
|
||||
srlz.d
|
||||
or r23=r25,r20 // construct PA | page properties
|
||||
mov r25=IA64_GRANULE_SHIFT<<2
|
||||
;;
|
||||
mov cr.itir=r25
|
||||
mov cr.ifa=in0 // VA of next task...
|
||||
MOV_TO_ITIR(p0, r25, r8)
|
||||
MOV_TO_IFA(in0, r8) // VA of next task...
|
||||
;;
|
||||
mov r25=IA64_TR_CURRENT_STACK
|
||||
mov IA64_KR(CURRENT_STACK)=r26 // remember last page we mapped...
|
||||
MOV_TO_KR(CURRENT_STACK, r26, r8, r9) // remember last page we mapped...
|
||||
;;
|
||||
itr.d dtr[r25]=r23 // wire in new mapping...
|
||||
ssm psr.ic // reenable the psr.ic bit
|
||||
;;
|
||||
srlz.d
|
||||
SSM_PSR_IC_AND_SRLZ_D(r8, r9) // reenable the psr.ic bit
|
||||
br.cond.sptk .done
|
||||
END(ia64_switch_to)
|
||||
END(__paravirt_switch_to)
|
||||
|
||||
#ifdef __IA64_ASM_PARAVIRTUALIZED_NATIVE
|
||||
/*
|
||||
* Note that interrupts are enabled during save_switch_stack and load_switch_stack. This
|
||||
* means that we may get an interrupt with "sp" pointing to the new kernel stack while
|
||||
|
@ -375,7 +381,7 @@ END(save_switch_stack)
|
|||
* - b7 holds address to return to
|
||||
* - must not touch r8-r11
|
||||
*/
|
||||
ENTRY(load_switch_stack)
|
||||
GLOBAL_ENTRY(load_switch_stack)
|
||||
.prologue
|
||||
.altrp b7
|
||||
|
||||
|
@ -571,7 +577,7 @@ GLOBAL_ENTRY(ia64_trace_syscall)
|
|||
.ret3:
|
||||
(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk
|
||||
(pUStk) rsm psr.i // disable interrupts
|
||||
br.cond.sptk .work_pending_syscall_end
|
||||
br.cond.sptk ia64_work_pending_syscall_end
|
||||
|
||||
strace_error:
|
||||
ld8 r3=[r2] // load pt_regs.r8
|
||||
|
@ -636,8 +642,17 @@ GLOBAL_ENTRY(ia64_ret_from_syscall)
|
|||
adds r2=PT(R8)+16,sp // r2 = &pt_regs.r8
|
||||
mov r10=r0 // clear error indication in r10
|
||||
(p7) br.cond.spnt handle_syscall_error // handle potential syscall failure
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
;;
|
||||
br.cond.sptk.few ia64_leave_syscall
|
||||
;;
|
||||
#endif /* CONFIG_PARAVIRT */
|
||||
END(ia64_ret_from_syscall)
|
||||
#ifndef CONFIG_PARAVIRT
|
||||
// fall through
|
||||
#endif
|
||||
#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
|
||||
|
||||
/*
|
||||
* ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't
|
||||
* need to switch to bank 0 and doesn't restore the scratch registers.
|
||||
|
@ -682,7 +697,7 @@ END(ia64_ret_from_syscall)
|
|||
* ar.csd: cleared
|
||||
* ar.ssd: cleared
|
||||
*/
|
||||
ENTRY(ia64_leave_syscall)
|
||||
GLOBAL_ENTRY(__paravirt_leave_syscall)
|
||||
PT_REGS_UNWIND_INFO(0)
|
||||
/*
|
||||
* work.need_resched etc. mustn't get changed by this CPU before it returns to
|
||||
|
@ -692,11 +707,11 @@ ENTRY(ia64_leave_syscall)
|
|||
* extra work. We always check for extra work when returning to user-level.
|
||||
* With CONFIG_PREEMPT, we also check for extra work when the preempt_count
|
||||
* is 0. After extra work processing has been completed, execution
|
||||
* resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check
|
||||
* resumes at ia64_work_processed_syscall with p6 set to 1 if the extra-work-check
|
||||
* needs to be redone.
|
||||
*/
|
||||
#ifdef CONFIG_PREEMPT
|
||||
rsm psr.i // disable interrupts
|
||||
RSM_PSR_I(p0, r2, r18) // disable interrupts
|
||||
cmp.eq pLvSys,p0=r0,r0 // pLvSys=1: leave from syscall
|
||||
(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
|
||||
;;
|
||||
|
@ -706,11 +721,12 @@ ENTRY(ia64_leave_syscall)
|
|||
;;
|
||||
cmp.eq p6,p0=r21,r0 // p6 <- pUStk || (preempt_count == 0)
|
||||
#else /* !CONFIG_PREEMPT */
|
||||
(pUStk) rsm psr.i
|
||||
RSM_PSR_I(pUStk, r2, r18)
|
||||
cmp.eq pLvSys,p0=r0,r0 // pLvSys=1: leave from syscall
|
||||
(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk
|
||||
#endif
|
||||
.work_processed_syscall:
|
||||
.global __paravirt_work_processed_syscall;
|
||||
__paravirt_work_processed_syscall:
|
||||
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
|
||||
adds r2=PT(LOADRS)+16,r12
|
||||
(pUStk) mov.m r22=ar.itc // fetch time at leave
|
||||
|
@ -744,7 +760,7 @@ ENTRY(ia64_leave_syscall)
|
|||
(pNonSys) break 0 // bug check: we shouldn't be here if pNonSys is TRUE!
|
||||
;;
|
||||
invala // M0|1 invalidate ALAT
|
||||
rsm psr.i | psr.ic // M2 turn off interrupts and interruption collection
|
||||
RSM_PSR_I_IC(r28, r29, r30) // M2 turn off interrupts and interruption collection
|
||||
cmp.eq p9,p0=r0,r0 // A set p9 to indicate that we should restore cr.ifs
|
||||
|
||||
ld8 r29=[r2],16 // M0|1 load cr.ipsr
|
||||
|
@ -765,7 +781,7 @@ ENTRY(ia64_leave_syscall)
|
|||
;;
|
||||
#endif
|
||||
ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs
|
||||
(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled
|
||||
MOV_FROM_PSR(pKStk, r22, r21) // M2 read PSR now that interrupts are disabled
|
||||
nop 0
|
||||
;;
|
||||
ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0
|
||||
|
@ -798,7 +814,7 @@ ENTRY(ia64_leave_syscall)
|
|||
|
||||
srlz.d // M0 ensure interruption collection is off (for cover)
|
||||
shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition
|
||||
cover // B add current frame into dirty partition & set cr.ifs
|
||||
COVER // B add current frame into dirty partition & set cr.ifs
|
||||
;;
|
||||
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
|
||||
mov r19=ar.bsp // M2 get new backing store pointer
|
||||
|
@ -823,8 +839,9 @@ ENTRY(ia64_leave_syscall)
|
|||
mov.m ar.ssd=r0 // M2 clear ar.ssd
|
||||
mov f11=f0 // F clear f11
|
||||
br.cond.sptk.many rbs_switch // B
|
||||
END(ia64_leave_syscall)
|
||||
END(__paravirt_leave_syscall)
|
||||
|
||||
#ifdef __IA64_ASM_PARAVIRTUALIZED_NATIVE
|
||||
#ifdef CONFIG_IA32_SUPPORT
|
||||
GLOBAL_ENTRY(ia64_ret_from_ia32_execve)
|
||||
PT_REGS_UNWIND_INFO(0)
|
||||
|
@ -835,10 +852,20 @@ GLOBAL_ENTRY(ia64_ret_from_ia32_execve)
|
|||
st8.spill [r2]=r8 // store return value in slot for r8 and set unat bit
|
||||
.mem.offset 8,0
|
||||
st8.spill [r3]=r0 // clear error indication in slot for r10 and set unat bit
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
;;
|
||||
// don't fall through, ia64_leave_kernel may be #define'd
|
||||
br.cond.sptk.few ia64_leave_kernel
|
||||
;;
|
||||
#endif /* CONFIG_PARAVIRT */
|
||||
END(ia64_ret_from_ia32_execve)
|
||||
#ifndef CONFIG_PARAVIRT
|
||||
// fall through
|
||||
#endif
|
||||
#endif /* CONFIG_IA32_SUPPORT */
|
||||
GLOBAL_ENTRY(ia64_leave_kernel)
|
||||
#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
|
||||
|
||||
GLOBAL_ENTRY(__paravirt_leave_kernel)
|
||||
PT_REGS_UNWIND_INFO(0)
|
||||
/*
|
||||
* work.need_resched etc. mustn't get changed by this CPU before it returns to
|
||||
|
@ -852,7 +879,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
|
|||
* needs to be redone.
|
||||
*/
|
||||
#ifdef CONFIG_PREEMPT
|
||||
rsm psr.i // disable interrupts
|
||||
RSM_PSR_I(p0, r17, r31) // disable interrupts
|
||||
cmp.eq p0,pLvSys=r0,r0 // pLvSys=0: leave from kernel
|
||||
(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
|
||||
;;
|
||||
|
@ -862,7 +889,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
|
|||
;;
|
||||
cmp.eq p6,p0=r21,r0 // p6 <- pUStk || (preempt_count == 0)
|
||||
#else
|
||||
(pUStk) rsm psr.i
|
||||
RSM_PSR_I(pUStk, r17, r31)
|
||||
cmp.eq p0,pLvSys=r0,r0 // pLvSys=0: leave from kernel
|
||||
(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk
|
||||
#endif
|
||||
|
@ -910,7 +937,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
|
|||
mov ar.csd=r30
|
||||
mov ar.ssd=r31
|
||||
;;
|
||||
rsm psr.i | psr.ic // initiate turning off of interrupt and interruption collection
|
||||
RSM_PSR_I_IC(r23, r22, r25) // initiate turning off of interrupt and interruption collection
|
||||
invala // invalidate ALAT
|
||||
;;
|
||||
ld8.fill r22=[r2],24
|
||||
|
@ -942,7 +969,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
|
|||
mov ar.ccv=r15
|
||||
;;
|
||||
ldf.fill f11=[r2]
|
||||
bsw.0 // switch back to bank 0 (no stop bit required beforehand...)
|
||||
BSW_0(r2, r3, r15) // switch back to bank 0 (no stop bit required beforehand...)
|
||||
;;
|
||||
(pUStk) mov r18=IA64_KR(CURRENT)// M2 (12 cycle read latency)
|
||||
adds r16=PT(CR_IPSR)+16,r12
|
||||
|
@ -950,12 +977,12 @@ GLOBAL_ENTRY(ia64_leave_kernel)
|
|||
|
||||
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
|
||||
.pred.rel.mutex pUStk,pKStk
|
||||
(pKStk) mov r22=psr // 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
|
||||
nop.i 0
|
||||
;;
|
||||
#else
|
||||
(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled
|
||||
MOV_FROM_PSR(pKStk, r22, r29) // M2 read PSR now that interrupts are disabled
|
||||
nop.i 0
|
||||
nop.i 0
|
||||
;;
|
||||
|
@ -1027,7 +1054,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
|
|||
* NOTE: alloc, loadrs, and cover can't be predicated.
|
||||
*/
|
||||
(pNonSys) br.cond.dpnt dont_preserve_current_frame
|
||||
cover // add current frame into dirty partition and set cr.ifs
|
||||
COVER // add current frame into dirty partition and set cr.ifs
|
||||
;;
|
||||
mov r19=ar.bsp // get new backing store pointer
|
||||
rbs_switch:
|
||||
|
@ -1130,16 +1157,16 @@ skip_rbs_switch:
|
|||
(pKStk) dep r29=r22,r29,21,1 // I0 update ipsr.pp with psr.pp
|
||||
(pLvSys)mov r16=r0 // A clear r16 for leave_syscall, no-op otherwise
|
||||
;;
|
||||
mov cr.ipsr=r29 // M2
|
||||
MOV_TO_IPSR(p0, r29, r25) // M2
|
||||
mov ar.pfs=r26 // I0
|
||||
(pLvSys)mov r17=r0 // A clear r17 for leave_syscall, no-op otherwise
|
||||
|
||||
(p9) mov cr.ifs=r30 // M2
|
||||
MOV_TO_IFS(p9, r30, r25)// M2
|
||||
mov b0=r21 // I0
|
||||
(pLvSys)mov r18=r0 // A clear r18 for leave_syscall, no-op otherwise
|
||||
|
||||
mov ar.fpsr=r20 // M2
|
||||
mov cr.iip=r28 // M2
|
||||
MOV_TO_IIP(r28, r25) // M2
|
||||
nop 0
|
||||
;;
|
||||
(pUStk) mov ar.rnat=r24 // M2 must happen with RSE in lazy mode
|
||||
|
@ -1148,7 +1175,7 @@ skip_rbs_switch:
|
|||
|
||||
mov ar.rsc=r27 // M2
|
||||
mov pr=r31,-1 // I0
|
||||
rfi // B
|
||||
RFI // B
|
||||
|
||||
/*
|
||||
* On entry:
|
||||
|
@ -1174,35 +1201,36 @@ skip_rbs_switch:
|
|||
;;
|
||||
(pKStk) st4 [r20]=r21
|
||||
#endif
|
||||
ssm psr.i // enable interrupts
|
||||
SSM_PSR_I(p0, p6, r2) // enable interrupts
|
||||
br.call.spnt.many rp=schedule
|
||||
.ret9: cmp.eq p6,p0=r0,r0 // p6 <- 1 (re-check)
|
||||
rsm psr.i // disable interrupts
|
||||
RSM_PSR_I(p0, r2, r20) // disable interrupts
|
||||
;;
|
||||
#ifdef CONFIG_PREEMPT
|
||||
(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
|
||||
;;
|
||||
(pKStk) st4 [r20]=r0 // preempt_count() <- 0
|
||||
#endif
|
||||
(pLvSys)br.cond.sptk.few .work_pending_syscall_end
|
||||
(pLvSys)br.cond.sptk.few __paravirt_pending_syscall_end
|
||||
br.cond.sptk.many .work_processed_kernel
|
||||
|
||||
.notify:
|
||||
(pUStk) br.call.spnt.many rp=notify_resume_user
|
||||
.ret10: cmp.ne p6,p0=r0,r0 // p6 <- 0 (don't re-check)
|
||||
(pLvSys)br.cond.sptk.few .work_pending_syscall_end
|
||||
(pLvSys)br.cond.sptk.few __paravirt_pending_syscall_end
|
||||
br.cond.sptk.many .work_processed_kernel
|
||||
|
||||
.work_pending_syscall_end:
|
||||
.global __paravirt_pending_syscall_end;
|
||||
__paravirt_pending_syscall_end:
|
||||
adds r2=PT(R8)+16,r12
|
||||
adds r3=PT(R10)+16,r12
|
||||
;;
|
||||
ld8 r8=[r2]
|
||||
ld8 r10=[r3]
|
||||
br.cond.sptk.many .work_processed_syscall
|
||||
|
||||
END(ia64_leave_kernel)
|
||||
br.cond.sptk.many __paravirt_work_processed_syscall_target
|
||||
END(__paravirt_leave_kernel)
|
||||
|
||||
#ifdef __IA64_ASM_PARAVIRTUALIZED_NATIVE
|
||||
ENTRY(handle_syscall_error)
|
||||
/*
|
||||
* Some system calls (e.g., ptrace, mmap) can return arbitrary values which could
|
||||
|
@ -1244,7 +1272,7 @@ END(ia64_invoke_schedule_tail)
|
|||
* We declare 8 input registers so the system call args get preserved,
|
||||
* in case we need to restart a system call.
|
||||
*/
|
||||
ENTRY(notify_resume_user)
|
||||
GLOBAL_ENTRY(notify_resume_user)
|
||||
.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
|
||||
alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall restart!
|
||||
mov r9=ar.unat
|
||||
|
@ -1306,7 +1334,7 @@ ENTRY(sys_rt_sigreturn)
|
|||
adds sp=16,sp
|
||||
;;
|
||||
ld8 r9=[sp] // load new ar.unat
|
||||
mov.sptk b7=r8,ia64_leave_kernel
|
||||
mov.sptk b7=r8,ia64_native_leave_kernel
|
||||
;;
|
||||
mov ar.unat=r9
|
||||
br.many b7
|
||||
|
@ -1665,3 +1693,4 @@ sys_call_table:
|
|||
data8 sys_timerfd_gettime
|
||||
|
||||
.org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
|
||||
#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
|
||||
|
|
|
@ -26,11 +26,14 @@
|
|||
#include <asm/mmu_context.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/pal.h>
|
||||
#include <asm/paravirt.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/mca_asm.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
#define SAL_PSR_BITS_TO_SET \
|
||||
|
@ -367,6 +370,44 @@ start_ap:
|
|||
;;
|
||||
(isBP) st8 [r2]=r28 // save the address of the boot param area passed by the bootloader
|
||||
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
|
||||
movl r14=hypervisor_setup_hooks
|
||||
movl r15=hypervisor_type
|
||||
mov r16=num_hypervisor_hooks
|
||||
;;
|
||||
ld8 r2=[r15]
|
||||
;;
|
||||
cmp.ltu p7,p0=r2,r16 // array size check
|
||||
shladd r8=r2,3,r14
|
||||
;;
|
||||
(p7) ld8 r9=[r8]
|
||||
;;
|
||||
(p7) mov b1=r9
|
||||
(p7) cmp.ne.unc p7,p0=r9,r0 // no actual branch to NULL
|
||||
;;
|
||||
(p7) br.call.sptk.many rp=b1
|
||||
|
||||
__INITDATA
|
||||
|
||||
default_setup_hook = 0 // Currently nothing needs to be done.
|
||||
|
||||
.weak xen_setup_hook
|
||||
|
||||
.global hypervisor_type
|
||||
hypervisor_type:
|
||||
data8 PARAVIRT_HYPERVISOR_TYPE_DEFAULT
|
||||
|
||||
// must have the same order with PARAVIRT_HYPERVISOR_TYPE_xxx
|
||||
|
||||
hypervisor_setup_hooks:
|
||||
data8 default_setup_hook
|
||||
data8 xen_setup_hook
|
||||
num_hypervisor_hooks = (. - hypervisor_setup_hooks) / 8
|
||||
.previous
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
(isAP) br.call.sptk.many rp=start_secondary
|
||||
.ret0:
|
||||
|
|
|
@ -585,6 +585,15 @@ static inline int irq_is_shared (int irq)
|
|||
return (iosapic_intr_info[irq].count > 1);
|
||||
}
|
||||
|
||||
struct irq_chip*
|
||||
ia64_native_iosapic_get_irq_chip(unsigned long trigger)
|
||||
{
|
||||
if (trigger == IOSAPIC_EDGE)
|
||||
return &irq_type_iosapic_edge;
|
||||
else
|
||||
return &irq_type_iosapic_level;
|
||||
}
|
||||
|
||||
static int
|
||||
register_intr (unsigned int gsi, int irq, unsigned char delivery,
|
||||
unsigned long polarity, unsigned long trigger)
|
||||
|
@ -635,13 +644,10 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery,
|
|||
iosapic_intr_info[irq].dmode = delivery;
|
||||
iosapic_intr_info[irq].trigger = trigger;
|
||||
|
||||
if (trigger == IOSAPIC_EDGE)
|
||||
irq_type = &irq_type_iosapic_edge;
|
||||
else
|
||||
irq_type = &irq_type_iosapic_level;
|
||||
irq_type = iosapic_get_irq_chip(trigger);
|
||||
|
||||
idesc = irq_desc + irq;
|
||||
if (idesc->chip != irq_type) {
|
||||
if (irq_type != NULL && idesc->chip != irq_type) {
|
||||
if (idesc->chip != &no_irq_type)
|
||||
printk(KERN_WARNING
|
||||
"%s: changing vector %d from %s to %s\n",
|
||||
|
@ -973,6 +979,22 @@ iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
|
|||
set_rte(gsi, irq, dest, 1);
|
||||
}
|
||||
|
||||
void __init
|
||||
ia64_native_iosapic_pcat_compat_init(void)
|
||||
{
|
||||
if (pcat_compat) {
|
||||
/*
|
||||
* Disable the compatibility mode interrupts (8259 style),
|
||||
* needs IN/OUT support enabled.
|
||||
*/
|
||||
printk(KERN_INFO
|
||||
"%s: Disabling PC-AT compatible 8259 interrupts\n",
|
||||
__func__);
|
||||
outb(0xff, 0xA1);
|
||||
outb(0xff, 0x21);
|
||||
}
|
||||
}
|
||||
|
||||
void __init
|
||||
iosapic_system_init (int system_pcat_compat)
|
||||
{
|
||||
|
@ -987,17 +1009,8 @@ iosapic_system_init (int system_pcat_compat)
|
|||
}
|
||||
|
||||
pcat_compat = system_pcat_compat;
|
||||
if (pcat_compat) {
|
||||
/*
|
||||
* Disable the compatibility mode interrupts (8259 style),
|
||||
* needs IN/OUT support enabled.
|
||||
*/
|
||||
printk(KERN_INFO
|
||||
"%s: Disabling PC-AT compatible 8259 interrupts\n",
|
||||
__func__);
|
||||
outb(0xff, 0xA1);
|
||||
outb(0xff, 0x21);
|
||||
}
|
||||
if (pcat_compat)
|
||||
iosapic_pcat_compat_init();
|
||||
}
|
||||
|
||||
static inline int
|
||||
|
|
|
@ -196,7 +196,7 @@ static void clear_irq_vector(int irq)
|
|||
}
|
||||
|
||||
int
|
||||
assign_irq_vector (int irq)
|
||||
ia64_native_assign_irq_vector (int irq)
|
||||
{
|
||||
unsigned long flags;
|
||||
int vector, cpu;
|
||||
|
@ -222,7 +222,7 @@ assign_irq_vector (int irq)
|
|||
}
|
||||
|
||||
void
|
||||
free_irq_vector (int vector)
|
||||
ia64_native_free_irq_vector (int vector)
|
||||
{
|
||||
if (vector < IA64_FIRST_DEVICE_VECTOR ||
|
||||
vector > IA64_LAST_DEVICE_VECTOR)
|
||||
|
@ -600,7 +600,6 @@ static irqreturn_t dummy_handler (int irq, void *dev_id)
|
|||
{
|
||||
BUG();
|
||||
}
|
||||
extern irqreturn_t handle_IPI (int irq, void *dev_id);
|
||||
|
||||
static struct irqaction ipi_irqaction = {
|
||||
.handler = handle_IPI,
|
||||
|
@ -623,7 +622,7 @@ static struct irqaction tlb_irqaction = {
|
|||
#endif
|
||||
|
||||
void
|
||||
register_percpu_irq (ia64_vector vec, struct irqaction *action)
|
||||
ia64_native_register_percpu_irq (ia64_vector vec, struct irqaction *action)
|
||||
{
|
||||
irq_desc_t *desc;
|
||||
unsigned int irq;
|
||||
|
@ -638,13 +637,21 @@ register_percpu_irq (ia64_vector vec, struct irqaction *action)
|
|||
}
|
||||
|
||||
void __init
|
||||
init_IRQ (void)
|
||||
ia64_native_register_ipi(void)
|
||||
{
|
||||
register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
|
||||
#ifdef CONFIG_SMP
|
||||
register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
|
||||
register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction);
|
||||
register_percpu_irq(IA64_IPI_LOCAL_TLB_FLUSH, &tlb_irqaction);
|
||||
#endif
|
||||
}
|
||||
|
||||
void __init
|
||||
init_IRQ (void)
|
||||
{
|
||||
ia64_register_ipi();
|
||||
register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
|
||||
#ifdef CONFIG_SMP
|
||||
#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG)
|
||||
if (vector_domain_type != VECTOR_DOMAIN_NONE) {
|
||||
BUG_ON(IA64_FIRST_DEVICE_VECTOR != IA64_IRQ_MOVE_VECTOR);
|
||||
|
|
|
@ -12,6 +12,14 @@
|
|||
*
|
||||
* 00/08/23 Asit Mallick <asit.k.mallick@intel.com> TLB handling for SMP
|
||||
* 00/12/20 David Mosberger-Tang <davidm@hpl.hp.com> DTLB/ITLB handler now uses virtual PT.
|
||||
*
|
||||
* Copyright (C) 2005 Hewlett-Packard Co
|
||||
* Dan Magenheimer <dan.magenheimer@hp.com>
|
||||
* Xen paravirtualization
|
||||
* Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
|
||||
* VA Linux Systems Japan K.K.
|
||||
* pv_ops.
|
||||
* Yaozu (Eddie) Dong <eddie.dong@intel.com>
|
||||
*/
|
||||
/*
|
||||
* This file defines the interruption vector table used by the CPU.
|
||||
|
@ -102,13 +110,13 @@ ENTRY(vhpt_miss)
|
|||
* - the faulting virtual address uses unimplemented address bits
|
||||
* - the faulting virtual address has no valid page table mapping
|
||||
*/
|
||||
mov r16=cr.ifa // get address that caused the TLB miss
|
||||
MOV_FROM_IFA(r16) // get address that caused the TLB miss
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
movl r18=PAGE_SHIFT
|
||||
mov r25=cr.itir
|
||||
MOV_FROM_ITIR(r25)
|
||||
#endif
|
||||
;;
|
||||
rsm psr.dt // use physical addressing for data
|
||||
RSM_PSR_DT // use physical addressing for data
|
||||
mov r31=pr // save the predicate registers
|
||||
mov r19=IA64_KR(PT_BASE) // get page table base address
|
||||
shl r21=r16,3 // shift bit 60 into sign bit
|
||||
|
@ -168,21 +176,21 @@ ENTRY(vhpt_miss)
|
|||
dep r21=r19,r20,3,(PAGE_SHIFT-3) // r21=pte_offset(pmd,addr)
|
||||
;;
|
||||
(p7) ld8 r18=[r21] // read *pte
|
||||
mov r19=cr.isr // cr.isr bit 32 tells us if this is an insn miss
|
||||
MOV_FROM_ISR(r19) // cr.isr bit 32 tells us if this is an insn miss
|
||||
;;
|
||||
(p7) tbit.z p6,p7=r18,_PAGE_P_BIT // page present bit cleared?
|
||||
mov r22=cr.iha // get the VHPT address that caused the TLB miss
|
||||
MOV_FROM_IHA(r22) // get the VHPT address that caused the TLB miss
|
||||
;; // avoid RAW on p7
|
||||
(p7) tbit.nz.unc p10,p11=r19,32 // is it an instruction TLB miss?
|
||||
dep r23=0,r20,0,PAGE_SHIFT // clear low bits to get page address
|
||||
;;
|
||||
(p10) itc.i r18 // insert the instruction TLB entry
|
||||
(p11) itc.d r18 // insert the data TLB entry
|
||||
ITC_I_AND_D(p10, p11, r18, r24) // insert the instruction TLB entry and
|
||||
// insert the data TLB entry
|
||||
(p6) br.cond.spnt.many page_fault // handle bad address/page not present (page fault)
|
||||
mov cr.ifa=r22
|
||||
MOV_TO_IFA(r22, r24)
|
||||
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
(p8) mov cr.itir=r25 // change to default page-size for VHPT
|
||||
MOV_TO_ITIR(p8, r25, r24) // change to default page-size for VHPT
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -192,7 +200,7 @@ ENTRY(vhpt_miss)
|
|||
*/
|
||||
adds r24=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r23
|
||||
;;
|
||||
(p7) itc.d r24
|
||||
ITC_D(p7, r24, r25)
|
||||
;;
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
|
@ -234,7 +242,7 @@ ENTRY(vhpt_miss)
|
|||
#endif
|
||||
|
||||
mov pr=r31,-1 // restore predicate registers
|
||||
rfi
|
||||
RFI
|
||||
END(vhpt_miss)
|
||||
|
||||
.org ia64_ivt+0x400
|
||||
|
@ -248,11 +256,11 @@ ENTRY(itlb_miss)
|
|||
* mode, walk the page table, and then re-execute the PTE read and
|
||||
* go on normally after that.
|
||||
*/
|
||||
mov r16=cr.ifa // get virtual address
|
||||
MOV_FROM_IFA(r16) // get virtual address
|
||||
mov r29=b0 // save b0
|
||||
mov r31=pr // save predicates
|
||||
.itlb_fault:
|
||||
mov r17=cr.iha // get virtual address of PTE
|
||||
MOV_FROM_IHA(r17) // get virtual address of PTE
|
||||
movl r30=1f // load nested fault continuation point
|
||||
;;
|
||||
1: ld8 r18=[r17] // read *pte
|
||||
|
@ -261,7 +269,7 @@ ENTRY(itlb_miss)
|
|||
tbit.z p6,p0=r18,_PAGE_P_BIT // page present bit cleared?
|
||||
(p6) br.cond.spnt page_fault
|
||||
;;
|
||||
itc.i r18
|
||||
ITC_I(p0, r18, r19)
|
||||
;;
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
|
@ -278,7 +286,7 @@ ENTRY(itlb_miss)
|
|||
(p7) ptc.l r16,r20
|
||||
#endif
|
||||
mov pr=r31,-1
|
||||
rfi
|
||||
RFI
|
||||
END(itlb_miss)
|
||||
|
||||
.org ia64_ivt+0x0800
|
||||
|
@ -292,11 +300,11 @@ ENTRY(dtlb_miss)
|
|||
* mode, walk the page table, and then re-execute the PTE read and
|
||||
* go on normally after that.
|
||||
*/
|
||||
mov r16=cr.ifa // get virtual address
|
||||
MOV_FROM_IFA(r16) // get virtual address
|
||||
mov r29=b0 // save b0
|
||||
mov r31=pr // save predicates
|
||||
dtlb_fault:
|
||||
mov r17=cr.iha // get virtual address of PTE
|
||||
MOV_FROM_IHA(r17) // get virtual address of PTE
|
||||
movl r30=1f // load nested fault continuation point
|
||||
;;
|
||||
1: ld8 r18=[r17] // read *pte
|
||||
|
@ -305,7 +313,7 @@ dtlb_fault:
|
|||
tbit.z p6,p0=r18,_PAGE_P_BIT // page present bit cleared?
|
||||
(p6) br.cond.spnt page_fault
|
||||
;;
|
||||
itc.d r18
|
||||
ITC_D(p0, r18, r19)
|
||||
;;
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
|
@ -322,7 +330,7 @@ dtlb_fault:
|
|||
(p7) ptc.l r16,r20
|
||||
#endif
|
||||
mov pr=r31,-1
|
||||
rfi
|
||||
RFI
|
||||
END(dtlb_miss)
|
||||
|
||||
.org ia64_ivt+0x0c00
|
||||
|
@ -330,9 +338,9 @@ END(dtlb_miss)
|
|||
// 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19)
|
||||
ENTRY(alt_itlb_miss)
|
||||
DBG_FAULT(3)
|
||||
mov r16=cr.ifa // get address that caused the TLB miss
|
||||
MOV_FROM_IFA(r16) // get address that caused the TLB miss
|
||||
movl r17=PAGE_KERNEL
|
||||
mov r21=cr.ipsr
|
||||
MOV_FROM_IPSR(p0, r21)
|
||||
movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
|
||||
mov r31=pr
|
||||
;;
|
||||
|
@ -341,9 +349,9 @@ ENTRY(alt_itlb_miss)
|
|||
;;
|
||||
cmp.gt p8,p0=6,r22 // user mode
|
||||
;;
|
||||
(p8) thash r17=r16
|
||||
THASH(p8, r17, r16, r23)
|
||||
;;
|
||||
(p8) mov cr.iha=r17
|
||||
MOV_TO_IHA(p8, r17, r23)
|
||||
(p8) mov r29=b0 // save b0
|
||||
(p8) br.cond.dptk .itlb_fault
|
||||
#endif
|
||||
|
@ -358,9 +366,9 @@ ENTRY(alt_itlb_miss)
|
|||
or r19=r19,r18 // set bit 4 (uncached) if the access was to region 6
|
||||
(p8) br.cond.spnt page_fault
|
||||
;;
|
||||
itc.i r19 // insert the TLB entry
|
||||
ITC_I(p0, r19, r18) // insert the TLB entry
|
||||
mov pr=r31,-1
|
||||
rfi
|
||||
RFI
|
||||
END(alt_itlb_miss)
|
||||
|
||||
.org ia64_ivt+0x1000
|
||||
|
@ -368,11 +376,11 @@ END(alt_itlb_miss)
|
|||
// 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46)
|
||||
ENTRY(alt_dtlb_miss)
|
||||
DBG_FAULT(4)
|
||||
mov r16=cr.ifa // get address that caused the TLB miss
|
||||
MOV_FROM_IFA(r16) // get address that caused the TLB miss
|
||||
movl r17=PAGE_KERNEL
|
||||
mov r20=cr.isr
|
||||
MOV_FROM_ISR(r20)
|
||||
movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
|
||||
mov r21=cr.ipsr
|
||||
MOV_FROM_IPSR(p0, r21)
|
||||
mov r31=pr
|
||||
mov r24=PERCPU_ADDR
|
||||
;;
|
||||
|
@ -381,9 +389,9 @@ ENTRY(alt_dtlb_miss)
|
|||
;;
|
||||
cmp.gt p8,p0=6,r22 // access to region 0-5
|
||||
;;
|
||||
(p8) thash r17=r16
|
||||
THASH(p8, r17, r16, r25)
|
||||
;;
|
||||
(p8) mov cr.iha=r17
|
||||
MOV_TO_IHA(p8, r17, r25)
|
||||
(p8) mov r29=b0 // save b0
|
||||
(p8) br.cond.dptk dtlb_fault
|
||||
#endif
|
||||
|
@ -402,7 +410,7 @@ ENTRY(alt_dtlb_miss)
|
|||
tbit.nz p9,p0=r20,IA64_ISR_NA_BIT // is non-access bit on?
|
||||
;;
|
||||
(p10) sub r19=r19,r26
|
||||
(p10) mov cr.itir=r25
|
||||
MOV_TO_ITIR(p10, r25, r24)
|
||||
cmp.ne p8,p0=r0,r23
|
||||
(p9) cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22 // check isr.code field
|
||||
(p12) dep r17=-1,r17,4,1 // set ma=UC for region 6 addr
|
||||
|
@ -411,11 +419,11 @@ ENTRY(alt_dtlb_miss)
|
|||
dep r21=-1,r21,IA64_PSR_ED_BIT,1
|
||||
;;
|
||||
or r19=r19,r17 // insert PTE control bits into r19
|
||||
(p6) mov cr.ipsr=r21
|
||||
MOV_TO_IPSR(p6, r21, r24)
|
||||
;;
|
||||
(p7) itc.d r19 // insert the TLB entry
|
||||
ITC_D(p7, r19, r18) // insert the TLB entry
|
||||
mov pr=r31,-1
|
||||
rfi
|
||||
RFI
|
||||
END(alt_dtlb_miss)
|
||||
|
||||
.org ia64_ivt+0x1400
|
||||
|
@ -444,10 +452,10 @@ ENTRY(nested_dtlb_miss)
|
|||
*
|
||||
* Clobbered: b0, r18, r19, r21, r22, psr.dt (cleared)
|
||||
*/
|
||||
rsm psr.dt // switch to using physical data addressing
|
||||
RSM_PSR_DT // switch to using physical data addressing
|
||||
mov r19=IA64_KR(PT_BASE) // get the page table base address
|
||||
shl r21=r16,3 // shift bit 60 into sign bit
|
||||
mov r18=cr.itir
|
||||
MOV_FROM_ITIR(r18)
|
||||
;;
|
||||
shr.u r17=r16,61 // get the region number into r17
|
||||
extr.u r18=r18,2,6 // get the faulting page size
|
||||
|
@ -507,33 +515,6 @@ ENTRY(ikey_miss)
|
|||
FAULT(6)
|
||||
END(ikey_miss)
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
// call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address)
|
||||
ENTRY(page_fault)
|
||||
ssm psr.dt
|
||||
;;
|
||||
srlz.i
|
||||
;;
|
||||
SAVE_MIN_WITH_COVER
|
||||
alloc r15=ar.pfs,0,0,3,0
|
||||
mov out0=cr.ifa
|
||||
mov out1=cr.isr
|
||||
adds r3=8,r2 // set up second base pointer
|
||||
;;
|
||||
ssm psr.ic | PSR_DEFAULT_BITS
|
||||
;;
|
||||
srlz.i // guarantee that interruption collectin is on
|
||||
;;
|
||||
(p15) ssm psr.i // restore psr.i
|
||||
movl r14=ia64_leave_kernel
|
||||
;;
|
||||
SAVE_REST
|
||||
mov rp=r14
|
||||
;;
|
||||
adds out2=16,r12 // out2 = pointer to pt_regs
|
||||
br.call.sptk.many b6=ia64_do_page_fault // ignore return address
|
||||
END(page_fault)
|
||||
|
||||
.org ia64_ivt+0x1c00
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
|
||||
|
@ -556,10 +537,10 @@ ENTRY(dirty_bit)
|
|||
* page table TLB entry isn't present, we take a nested TLB miss hit where we look
|
||||
* up the physical address of the L3 PTE and then continue at label 1 below.
|
||||
*/
|
||||
mov r16=cr.ifa // get the address that caused the fault
|
||||
MOV_FROM_IFA(r16) // get the address that caused the fault
|
||||
movl r30=1f // load continuation point in case of nested fault
|
||||
;;
|
||||
thash r17=r16 // compute virtual address of L3 PTE
|
||||
THASH(p0, r17, r16, r18) // compute virtual address of L3 PTE
|
||||
mov r29=b0 // save b0 in case of nested fault
|
||||
mov r31=pr // save pr
|
||||
#ifdef CONFIG_SMP
|
||||
|
@ -576,7 +557,7 @@ ENTRY(dirty_bit)
|
|||
;;
|
||||
(p6) cmp.eq p6,p7=r26,r18 // Only compare if page is present
|
||||
;;
|
||||
(p6) itc.d r25 // install updated PTE
|
||||
ITC_D(p6, r25, r18) // install updated PTE
|
||||
;;
|
||||
/*
|
||||
* Tell the assemblers dependency-violation checker that the above "itc" instructions
|
||||
|
@ -602,7 +583,7 @@ ENTRY(dirty_bit)
|
|||
itc.d r18 // install updated PTE
|
||||
#endif
|
||||
mov pr=r31,-1 // restore pr
|
||||
rfi
|
||||
RFI
|
||||
END(dirty_bit)
|
||||
|
||||
.org ia64_ivt+0x2400
|
||||
|
@ -611,22 +592,22 @@ END(dirty_bit)
|
|||
ENTRY(iaccess_bit)
|
||||
DBG_FAULT(9)
|
||||
// Like Entry 8, except for instruction access
|
||||
mov r16=cr.ifa // get the address that caused the fault
|
||||
MOV_FROM_IFA(r16) // get the address that caused the fault
|
||||
movl r30=1f // load continuation point in case of nested fault
|
||||
mov r31=pr // save predicates
|
||||
#ifdef CONFIG_ITANIUM
|
||||
/*
|
||||
* Erratum 10 (IFA may contain incorrect address) has "NoFix" status.
|
||||
*/
|
||||
mov r17=cr.ipsr
|
||||
MOV_FROM_IPSR(p0, r17)
|
||||
;;
|
||||
mov r18=cr.iip
|
||||
MOV_FROM_IIP(r18)
|
||||
tbit.z p6,p0=r17,IA64_PSR_IS_BIT // IA64 instruction set?
|
||||
;;
|
||||
(p6) mov r16=r18 // if so, use cr.iip instead of cr.ifa
|
||||
#endif /* CONFIG_ITANIUM */
|
||||
;;
|
||||
thash r17=r16 // compute virtual address of L3 PTE
|
||||
THASH(p0, r17, r16, r18) // compute virtual address of L3 PTE
|
||||
mov r29=b0 // save b0 in case of nested fault)
|
||||
#ifdef CONFIG_SMP
|
||||
mov r28=ar.ccv // save ar.ccv
|
||||
|
@ -642,7 +623,7 @@ ENTRY(iaccess_bit)
|
|||
;;
|
||||
(p6) cmp.eq p6,p7=r26,r18 // Only if page present
|
||||
;;
|
||||
(p6) itc.i r25 // install updated PTE
|
||||
ITC_I(p6, r25, r26) // install updated PTE
|
||||
;;
|
||||
/*
|
||||
* Tell the assemblers dependency-violation checker that the above "itc" instructions
|
||||
|
@ -668,7 +649,7 @@ ENTRY(iaccess_bit)
|
|||
itc.i r18 // install updated PTE
|
||||
#endif /* !CONFIG_SMP */
|
||||
mov pr=r31,-1
|
||||
rfi
|
||||
RFI
|
||||
END(iaccess_bit)
|
||||
|
||||
.org ia64_ivt+0x2800
|
||||
|
@ -677,10 +658,10 @@ END(iaccess_bit)
|
|||
ENTRY(daccess_bit)
|
||||
DBG_FAULT(10)
|
||||
// Like Entry 8, except for data access
|
||||
mov r16=cr.ifa // get the address that caused the fault
|
||||
MOV_FROM_IFA(r16) // get the address that caused the fault
|
||||
movl r30=1f // load continuation point in case of nested fault
|
||||
;;
|
||||
thash r17=r16 // compute virtual address of L3 PTE
|
||||
THASH(p0, r17, r16, r18) // compute virtual address of L3 PTE
|
||||
mov r31=pr
|
||||
mov r29=b0 // save b0 in case of nested fault)
|
||||
#ifdef CONFIG_SMP
|
||||
|
@ -697,7 +678,7 @@ ENTRY(daccess_bit)
|
|||
;;
|
||||
(p6) cmp.eq p6,p7=r26,r18 // Only if page is present
|
||||
;;
|
||||
(p6) itc.d r25 // install updated PTE
|
||||
ITC_D(p6, r25, r26) // install updated PTE
|
||||
/*
|
||||
* Tell the assemblers dependency-violation checker that the above "itc" instructions
|
||||
* cannot possibly affect the following loads:
|
||||
|
@ -721,7 +702,7 @@ ENTRY(daccess_bit)
|
|||
#endif
|
||||
mov b0=r29 // restore b0
|
||||
mov pr=r31,-1
|
||||
rfi
|
||||
RFI
|
||||
END(daccess_bit)
|
||||
|
||||
.org ia64_ivt+0x2c00
|
||||
|
@ -745,10 +726,10 @@ ENTRY(break_fault)
|
|||
*/
|
||||
DBG_FAULT(11)
|
||||
mov.m r16=IA64_KR(CURRENT) // M2 r16 <- current task (12 cyc)
|
||||
mov r29=cr.ipsr // M2 (12 cyc)
|
||||
MOV_FROM_IPSR(p0, r29) // M2 (12 cyc)
|
||||
mov r31=pr // I0 (2 cyc)
|
||||
|
||||
mov r17=cr.iim // M2 (2 cyc)
|
||||
MOV_FROM_IIM(r17) // M2 (2 cyc)
|
||||
mov.m r27=ar.rsc // M2 (12 cyc)
|
||||
mov r18=__IA64_BREAK_SYSCALL // A
|
||||
|
||||
|
@ -767,7 +748,7 @@ ENTRY(break_fault)
|
|||
nop.m 0
|
||||
movl r30=sys_call_table // X
|
||||
|
||||
mov r28=cr.iip // M2 (2 cyc)
|
||||
MOV_FROM_IIP(r28) // M2 (2 cyc)
|
||||
cmp.eq p0,p7=r18,r17 // I0 is this a system call?
|
||||
(p7) br.cond.spnt non_syscall // B no ->
|
||||
//
|
||||
|
@ -864,18 +845,17 @@ ENTRY(break_fault)
|
|||
#endif
|
||||
mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0
|
||||
nop 0
|
||||
bsw.1 // B (6 cyc) regs are saved, switch to bank 1
|
||||
BSW_1(r2, r14) // B (6 cyc) regs are saved, switch to bank 1
|
||||
;;
|
||||
|
||||
ssm psr.ic | PSR_DEFAULT_BITS // M2 now it's safe to re-enable intr.-collection
|
||||
SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r16) // M2 now it's safe to re-enable intr.-collection
|
||||
// M0 ensure interruption collection is on
|
||||
movl r3=ia64_ret_from_syscall // X
|
||||
;;
|
||||
|
||||
srlz.i // M0 ensure interruption collection is on
|
||||
mov rp=r3 // I0 set the real return addr
|
||||
(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT
|
||||
|
||||
(p15) ssm psr.i // M2 restore psr.i
|
||||
SSM_PSR_I(p15, p15, r16) // M2 restore psr.i
|
||||
(p14) br.call.sptk.many b6=b6 // B invoke syscall-handker (ignore return addr)
|
||||
br.cond.spnt.many ia64_trace_syscall // B do syscall-tracing thingamagic
|
||||
// NOT REACHED
|
||||
|
@ -895,27 +875,8 @@ END(break_fault)
|
|||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 0x3000 Entry 12 (size 64 bundles) External Interrupt (4)
|
||||
ENTRY(interrupt)
|
||||
DBG_FAULT(12)
|
||||
mov r31=pr // prepare to save predicates
|
||||
;;
|
||||
SAVE_MIN_WITH_COVER // uses r31; defines r2 and r3
|
||||
ssm psr.ic | PSR_DEFAULT_BITS
|
||||
;;
|
||||
adds r3=8,r2 // set up second base pointer for SAVE_REST
|
||||
srlz.i // ensure everybody knows psr.ic is back on
|
||||
;;
|
||||
SAVE_REST
|
||||
;;
|
||||
MCA_RECOVER_RANGE(interrupt)
|
||||
alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
|
||||
mov out0=cr.ivr // pass cr.ivr as first arg
|
||||
add out1=16,sp // pass pointer to pt_regs as second arg
|
||||
;;
|
||||
srlz.d // make sure we see the effect of cr.ivr
|
||||
movl r14=ia64_leave_kernel
|
||||
;;
|
||||
mov rp=r14
|
||||
br.call.sptk.many b6=ia64_handle_irq
|
||||
/* interrupt handler has become too big to fit this area. */
|
||||
br.sptk.many __interrupt
|
||||
END(interrupt)
|
||||
|
||||
.org ia64_ivt+0x3400
|
||||
|
@ -978,6 +939,7 @@ END(interrupt)
|
|||
* - ar.fpsr: set to kernel settings
|
||||
* - b6: preserved (same as on entry)
|
||||
*/
|
||||
#ifdef __IA64_ASM_PARAVIRTUALIZED_NATIVE
|
||||
GLOBAL_ENTRY(ia64_syscall_setup)
|
||||
#if PT(B6) != 0
|
||||
# error This code assumes that b6 is the first field in pt_regs.
|
||||
|
@ -1069,6 +1031,7 @@ GLOBAL_ENTRY(ia64_syscall_setup)
|
|||
(p10) mov r8=-EINVAL
|
||||
br.ret.sptk.many b7
|
||||
END(ia64_syscall_setup)
|
||||
#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
|
||||
|
||||
.org ia64_ivt+0x3c00
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1082,7 +1045,7 @@ END(ia64_syscall_setup)
|
|||
DBG_FAULT(16)
|
||||
FAULT(16)
|
||||
|
||||
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
|
||||
#if defined(CONFIG_VIRT_CPU_ACCOUNTING) && defined(__IA64_ASM_PARAVIRTUALIZED_NATIVE)
|
||||
/*
|
||||
* There is no particular reason for this code to be here, other than
|
||||
* that there happens to be space here that would go unused otherwise.
|
||||
|
@ -1092,7 +1055,7 @@ END(ia64_syscall_setup)
|
|||
* account_sys_enter is called from SAVE_MIN* macros if accounting is
|
||||
* enabled and if the macro is entered from user mode.
|
||||
*/
|
||||
ENTRY(account_sys_enter)
|
||||
GLOBAL_ENTRY(account_sys_enter)
|
||||
// mov.m r20=ar.itc is called in advance, and r13 is current
|
||||
add r16=TI_AC_STAMP+IA64_TASK_SIZE,r13
|
||||
add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r13
|
||||
|
@ -1123,110 +1086,18 @@ END(account_sys_enter)
|
|||
DBG_FAULT(17)
|
||||
FAULT(17)
|
||||
|
||||
ENTRY(non_syscall)
|
||||
mov ar.rsc=r27 // restore ar.rsc before SAVE_MIN_WITH_COVER
|
||||
;;
|
||||
SAVE_MIN_WITH_COVER
|
||||
|
||||
// There is no particular reason for this code to be here, other than that
|
||||
// there happens to be space here that would go unused otherwise. If this
|
||||
// fault ever gets "unreserved", simply moved the following code to a more
|
||||
// suitable spot...
|
||||
|
||||
alloc r14=ar.pfs,0,0,2,0
|
||||
mov out0=cr.iim
|
||||
add out1=16,sp
|
||||
adds r3=8,r2 // set up second base pointer for SAVE_REST
|
||||
|
||||
ssm psr.ic | PSR_DEFAULT_BITS
|
||||
;;
|
||||
srlz.i // guarantee that interruption collection is on
|
||||
;;
|
||||
(p15) ssm psr.i // restore psr.i
|
||||
movl r15=ia64_leave_kernel
|
||||
;;
|
||||
SAVE_REST
|
||||
mov rp=r15
|
||||
;;
|
||||
br.call.sptk.many b6=ia64_bad_break // avoid WAW on CFM and ignore return addr
|
||||
END(non_syscall)
|
||||
|
||||
.org ia64_ivt+0x4800
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 0x4800 Entry 18 (size 64 bundles) Reserved
|
||||
DBG_FAULT(18)
|
||||
FAULT(18)
|
||||
|
||||
/*
|
||||
* There is no particular reason for this code to be here, other than that
|
||||
* there happens to be space here that would go unused otherwise. If this
|
||||
* fault ever gets "unreserved", simply moved the following code to a more
|
||||
* suitable spot...
|
||||
*/
|
||||
|
||||
ENTRY(dispatch_unaligned_handler)
|
||||
SAVE_MIN_WITH_COVER
|
||||
;;
|
||||
alloc r14=ar.pfs,0,0,2,0 // now it's safe (must be first in insn group!)
|
||||
mov out0=cr.ifa
|
||||
adds out1=16,sp
|
||||
|
||||
ssm psr.ic | PSR_DEFAULT_BITS
|
||||
;;
|
||||
srlz.i // guarantee that interruption collection is on
|
||||
;;
|
||||
(p15) ssm psr.i // restore psr.i
|
||||
adds r3=8,r2 // set up second base pointer
|
||||
;;
|
||||
SAVE_REST
|
||||
movl r14=ia64_leave_kernel
|
||||
;;
|
||||
mov rp=r14
|
||||
br.sptk.many ia64_prepare_handle_unaligned
|
||||
END(dispatch_unaligned_handler)
|
||||
|
||||
.org ia64_ivt+0x4c00
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 0x4c00 Entry 19 (size 64 bundles) Reserved
|
||||
DBG_FAULT(19)
|
||||
FAULT(19)
|
||||
|
||||
/*
|
||||
* There is no particular reason for this code to be here, other than that
|
||||
* there happens to be space here that would go unused otherwise. If this
|
||||
* fault ever gets "unreserved", simply moved the following code to a more
|
||||
* suitable spot...
|
||||
*/
|
||||
|
||||
ENTRY(dispatch_to_fault_handler)
|
||||
/*
|
||||
* Input:
|
||||
* psr.ic: off
|
||||
* r19: fault vector number (e.g., 24 for General Exception)
|
||||
* r31: contains saved predicates (pr)
|
||||
*/
|
||||
SAVE_MIN_WITH_COVER_R19
|
||||
alloc r14=ar.pfs,0,0,5,0
|
||||
mov out0=r15
|
||||
mov out1=cr.isr
|
||||
mov out2=cr.ifa
|
||||
mov out3=cr.iim
|
||||
mov out4=cr.itir
|
||||
;;
|
||||
ssm psr.ic | PSR_DEFAULT_BITS
|
||||
;;
|
||||
srlz.i // guarantee that interruption collection is on
|
||||
;;
|
||||
(p15) ssm psr.i // restore psr.i
|
||||
adds r3=8,r2 // set up second base pointer for SAVE_REST
|
||||
;;
|
||||
SAVE_REST
|
||||
movl r14=ia64_leave_kernel
|
||||
;;
|
||||
mov rp=r14
|
||||
br.call.sptk.many b6=ia64_fault
|
||||
END(dispatch_to_fault_handler)
|
||||
|
||||
//
|
||||
// --- End of long entries, Beginning of short entries
|
||||
//
|
||||
|
@ -1236,8 +1107,8 @@ END(dispatch_to_fault_handler)
|
|||
// 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49)
|
||||
ENTRY(page_not_present)
|
||||
DBG_FAULT(20)
|
||||
mov r16=cr.ifa
|
||||
rsm psr.dt
|
||||
MOV_FROM_IFA(r16)
|
||||
RSM_PSR_DT
|
||||
/*
|
||||
* The Linux page fault handler doesn't expect non-present pages to be in
|
||||
* the TLB. Flush the existing entry now, so we meet that expectation.
|
||||
|
@ -1256,8 +1127,8 @@ END(page_not_present)
|
|||
// 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52)
|
||||
ENTRY(key_permission)
|
||||
DBG_FAULT(21)
|
||||
mov r16=cr.ifa
|
||||
rsm psr.dt
|
||||
MOV_FROM_IFA(r16)
|
||||
RSM_PSR_DT
|
||||
mov r31=pr
|
||||
;;
|
||||
srlz.d
|
||||
|
@ -1269,8 +1140,8 @@ END(key_permission)
|
|||
// 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26)
|
||||
ENTRY(iaccess_rights)
|
||||
DBG_FAULT(22)
|
||||
mov r16=cr.ifa
|
||||
rsm psr.dt
|
||||
MOV_FROM_IFA(r16)
|
||||
RSM_PSR_DT
|
||||
mov r31=pr
|
||||
;;
|
||||
srlz.d
|
||||
|
@ -1282,8 +1153,8 @@ END(iaccess_rights)
|
|||
// 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53)
|
||||
ENTRY(daccess_rights)
|
||||
DBG_FAULT(23)
|
||||
mov r16=cr.ifa
|
||||
rsm psr.dt
|
||||
MOV_FROM_IFA(r16)
|
||||
RSM_PSR_DT
|
||||
mov r31=pr
|
||||
;;
|
||||
srlz.d
|
||||
|
@ -1295,7 +1166,7 @@ END(daccess_rights)
|
|||
// 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39)
|
||||
ENTRY(general_exception)
|
||||
DBG_FAULT(24)
|
||||
mov r16=cr.isr
|
||||
MOV_FROM_ISR(r16)
|
||||
mov r31=pr
|
||||
;;
|
||||
cmp4.eq p6,p0=0,r16
|
||||
|
@ -1324,8 +1195,8 @@ END(disabled_fp_reg)
|
|||
ENTRY(nat_consumption)
|
||||
DBG_FAULT(26)
|
||||
|
||||
mov r16=cr.ipsr
|
||||
mov r17=cr.isr
|
||||
MOV_FROM_IPSR(p0, r16)
|
||||
MOV_FROM_ISR(r17)
|
||||
mov r31=pr // save PR
|
||||
;;
|
||||
and r18=0xf,r17 // r18 = cr.ipsr.code{3:0}
|
||||
|
@ -1335,10 +1206,10 @@ ENTRY(nat_consumption)
|
|||
dep r16=-1,r16,IA64_PSR_ED_BIT,1
|
||||
(p6) br.cond.spnt 1f // branch if (cr.ispr.na == 0 || cr.ipsr.code{3:0} != LFETCH)
|
||||
;;
|
||||
mov cr.ipsr=r16 // set cr.ipsr.na
|
||||
MOV_TO_IPSR(p0, r16, r18)
|
||||
mov pr=r31,-1
|
||||
;;
|
||||
rfi
|
||||
RFI
|
||||
|
||||
1: mov pr=r31,-1
|
||||
;;
|
||||
|
@ -1360,26 +1231,26 @@ ENTRY(speculation_vector)
|
|||
*
|
||||
* cr.imm contains zero_ext(imm21)
|
||||
*/
|
||||
mov r18=cr.iim
|
||||
MOV_FROM_IIM(r18)
|
||||
;;
|
||||
mov r17=cr.iip
|
||||
MOV_FROM_IIP(r17)
|
||||
shl r18=r18,43 // put sign bit in position (43=64-21)
|
||||
;;
|
||||
|
||||
mov r16=cr.ipsr
|
||||
MOV_FROM_IPSR(p0, r16)
|
||||
shr r18=r18,39 // sign extend (39=43-4)
|
||||
;;
|
||||
|
||||
add r17=r17,r18 // now add the offset
|
||||
;;
|
||||
mov cr.iip=r17
|
||||
MOV_FROM_IIP(r17)
|
||||
dep r16=0,r16,41,2 // clear EI
|
||||
;;
|
||||
|
||||
mov cr.ipsr=r16
|
||||
MOV_FROM_IPSR(p0, r16)
|
||||
;;
|
||||
|
||||
rfi // and go back
|
||||
RFI
|
||||
END(speculation_vector)
|
||||
|
||||
.org ia64_ivt+0x5800
|
||||
|
@ -1517,11 +1388,11 @@ ENTRY(ia32_intercept)
|
|||
DBG_FAULT(46)
|
||||
#ifdef CONFIG_IA32_SUPPORT
|
||||
mov r31=pr
|
||||
mov r16=cr.isr
|
||||
MOV_FROM_ISR(r16)
|
||||
;;
|
||||
extr.u r17=r16,16,8 // get ISR.code
|
||||
mov r18=ar.eflag
|
||||
mov r19=cr.iim // old eflag value
|
||||
MOV_FROM_IIM(r19) // old eflag value
|
||||
;;
|
||||
cmp.ne p6,p0=2,r17
|
||||
(p6) br.cond.spnt 1f // not a system flag fault
|
||||
|
@ -1533,7 +1404,7 @@ ENTRY(ia32_intercept)
|
|||
(p6) br.cond.spnt 1f // eflags.ac bit didn't change
|
||||
;;
|
||||
mov pr=r31,-1 // restore predicate registers
|
||||
rfi
|
||||
RFI
|
||||
|
||||
1:
|
||||
#endif // CONFIG_IA32_SUPPORT
|
||||
|
@ -1673,6 +1544,137 @@ END(ia32_interrupt)
|
|||
DBG_FAULT(67)
|
||||
FAULT(67)
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
// call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address)
|
||||
ENTRY(page_fault)
|
||||
SSM_PSR_DT_AND_SRLZ_I
|
||||
;;
|
||||
SAVE_MIN_WITH_COVER
|
||||
alloc r15=ar.pfs,0,0,3,0
|
||||
MOV_FROM_IFA(out0)
|
||||
MOV_FROM_ISR(out1)
|
||||
SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r14, r3)
|
||||
adds r3=8,r2 // set up second base pointer
|
||||
SSM_PSR_I(p15, p15, r14) // restore psr.i
|
||||
movl r14=ia64_leave_kernel
|
||||
;;
|
||||
SAVE_REST
|
||||
mov rp=r14
|
||||
;;
|
||||
adds out2=16,r12 // out2 = pointer to pt_regs
|
||||
br.call.sptk.many b6=ia64_do_page_fault // ignore return address
|
||||
END(page_fault)
|
||||
|
||||
ENTRY(non_syscall)
|
||||
mov ar.rsc=r27 // restore ar.rsc before SAVE_MIN_WITH_COVER
|
||||
;;
|
||||
SAVE_MIN_WITH_COVER
|
||||
|
||||
// There is no particular reason for this code to be here, other than that
|
||||
// there happens to be space here that would go unused otherwise. If this
|
||||
// fault ever gets "unreserved", simply moved the following code to a more
|
||||
// suitable spot...
|
||||
|
||||
alloc r14=ar.pfs,0,0,2,0
|
||||
MOV_FROM_IIM(out0)
|
||||
add out1=16,sp
|
||||
adds r3=8,r2 // set up second base pointer for SAVE_REST
|
||||
|
||||
SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r15, r24)
|
||||
// guarantee that interruption collection is on
|
||||
SSM_PSR_I(p15, p15, r15) // restore psr.i
|
||||
movl r15=ia64_leave_kernel
|
||||
;;
|
||||
SAVE_REST
|
||||
mov rp=r15
|
||||
;;
|
||||
br.call.sptk.many b6=ia64_bad_break // avoid WAW on CFM and ignore return addr
|
||||
END(non_syscall)
|
||||
|
||||
ENTRY(__interrupt)
|
||||
DBG_FAULT(12)
|
||||
mov r31=pr // prepare to save predicates
|
||||
;;
|
||||
SAVE_MIN_WITH_COVER // uses r31; defines r2 and r3
|
||||
SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r14)
|
||||
// ensure everybody knows psr.ic is back on
|
||||
adds r3=8,r2 // set up second base pointer for SAVE_REST
|
||||
;;
|
||||
SAVE_REST
|
||||
;;
|
||||
MCA_RECOVER_RANGE(interrupt)
|
||||
alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
|
||||
MOV_FROM_IVR(out0, r8) // pass cr.ivr as first arg
|
||||
add out1=16,sp // pass pointer to pt_regs as second arg
|
||||
;;
|
||||
srlz.d // make sure we see the effect of cr.ivr
|
||||
movl r14=ia64_leave_kernel
|
||||
;;
|
||||
mov rp=r14
|
||||
br.call.sptk.many b6=ia64_handle_irq
|
||||
END(__interrupt)
|
||||
|
||||
/*
|
||||
* There is no particular reason for this code to be here, other than that
|
||||
* there happens to be space here that would go unused otherwise. If this
|
||||
* fault ever gets "unreserved", simply moved the following code to a more
|
||||
* suitable spot...
|
||||
*/
|
||||
|
||||
ENTRY(dispatch_unaligned_handler)
|
||||
SAVE_MIN_WITH_COVER
|
||||
;;
|
||||
alloc r14=ar.pfs,0,0,2,0 // now it's safe (must be first in insn group!)
|
||||
MOV_FROM_IFA(out0)
|
||||
adds out1=16,sp
|
||||
|
||||
SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24)
|
||||
// guarantee that interruption collection is on
|
||||
SSM_PSR_I(p15, p15, r3) // restore psr.i
|
||||
adds r3=8,r2 // set up second base pointer
|
||||
;;
|
||||
SAVE_REST
|
||||
movl r14=ia64_leave_kernel
|
||||
;;
|
||||
mov rp=r14
|
||||
br.sptk.many ia64_prepare_handle_unaligned
|
||||
END(dispatch_unaligned_handler)
|
||||
|
||||
/*
|
||||
* There is no particular reason for this code to be here, other than that
|
||||
* there happens to be space here that would go unused otherwise. If this
|
||||
* fault ever gets "unreserved", simply moved the following code to a more
|
||||
* suitable spot...
|
||||
*/
|
||||
|
||||
ENTRY(dispatch_to_fault_handler)
|
||||
/*
|
||||
* Input:
|
||||
* psr.ic: off
|
||||
* r19: fault vector number (e.g., 24 for General Exception)
|
||||
* r31: contains saved predicates (pr)
|
||||
*/
|
||||
SAVE_MIN_WITH_COVER_R19
|
||||
alloc r14=ar.pfs,0,0,5,0
|
||||
MOV_FROM_ISR(out1)
|
||||
MOV_FROM_IFA(out2)
|
||||
MOV_FROM_IIM(out3)
|
||||
MOV_FROM_ITIR(out4)
|
||||
;;
|
||||
SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, out0)
|
||||
// guarantee that interruption collection is on
|
||||
mov out0=r15
|
||||
;;
|
||||
SSM_PSR_I(p15, p15, r3) // restore psr.i
|
||||
adds r3=8,r2 // set up second base pointer for SAVE_REST
|
||||
;;
|
||||
SAVE_REST
|
||||
movl r14=ia64_leave_kernel
|
||||
;;
|
||||
mov rp=r14
|
||||
br.call.sptk.many b6=ia64_fault
|
||||
END(dispatch_to_fault_handler)
|
||||
|
||||
/*
|
||||
* Squatting in this space ...
|
||||
*
|
||||
|
@ -1686,11 +1688,10 @@ ENTRY(dispatch_illegal_op_fault)
|
|||
.prologue
|
||||
.body
|
||||
SAVE_MIN_WITH_COVER
|
||||
ssm psr.ic | PSR_DEFAULT_BITS
|
||||
SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24)
|
||||
// guarantee that interruption collection is on
|
||||
;;
|
||||
srlz.i // guarantee that interruption collection is on
|
||||
;;
|
||||
(p15) ssm psr.i // restore psr.i
|
||||
SSM_PSR_I(p15, p15, r3) // restore psr.i
|
||||
adds r3=8,r2 // set up second base pointer for SAVE_REST
|
||||
;;
|
||||
alloc r14=ar.pfs,0,0,1,0 // must be first in insn group
|
||||
|
@ -1729,12 +1730,11 @@ END(dispatch_illegal_op_fault)
|
|||
ENTRY(dispatch_to_ia32_handler)
|
||||
SAVE_MIN
|
||||
;;
|
||||
mov r14=cr.isr
|
||||
ssm psr.ic | PSR_DEFAULT_BITS
|
||||
MOV_FROM_ISR(r14)
|
||||
SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24)
|
||||
// guarantee that interruption collection is on
|
||||
;;
|
||||
srlz.i // guarantee that interruption collection is on
|
||||
;;
|
||||
(p15) ssm psr.i
|
||||
SSM_PSR_I(p15, p15, r3)
|
||||
adds r3=8,r2 // Base pointer for SAVE_REST
|
||||
;;
|
||||
SAVE_REST
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <asm/cache.h>
|
||||
|
||||
#include "entry.h"
|
||||
#include "paravirt_inst.h"
|
||||
|
||||
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
|
||||
/* read ar.itc in advance, and use it before leaving bank 0 */
|
||||
|
@ -43,16 +44,16 @@
|
|||
* Note that psr.ic is NOT turned on by this macro. This is so that
|
||||
* we can pass interruption state as arguments to a handler.
|
||||
*/
|
||||
#define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA,WORKAROUND) \
|
||||
#define IA64_NATIVE_DO_SAVE_MIN(__COVER,SAVE_IFS,EXTRA,WORKAROUND) \
|
||||
mov r16=IA64_KR(CURRENT); /* M */ \
|
||||
mov r27=ar.rsc; /* M */ \
|
||||
mov r20=r1; /* A */ \
|
||||
mov r25=ar.unat; /* M */ \
|
||||
mov r29=cr.ipsr; /* M */ \
|
||||
MOV_FROM_IPSR(p0,r29); /* M */ \
|
||||
mov r26=ar.pfs; /* I */ \
|
||||
mov r28=cr.iip; /* M */ \
|
||||
MOV_FROM_IIP(r28); /* M */ \
|
||||
mov r21=ar.fpsr; /* M */ \
|
||||
COVER; /* B;; (or nothing) */ \
|
||||
__COVER; /* B;; (or nothing) */ \
|
||||
;; \
|
||||
adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16; \
|
||||
;; \
|
||||
|
@ -244,6 +245,6 @@
|
|||
1: \
|
||||
.pred.rel "mutex", pKStk, pUStk
|
||||
|
||||
#define SAVE_MIN_WITH_COVER DO_SAVE_MIN(cover, mov r30=cr.ifs, , RSE_WORKAROUND)
|
||||
#define SAVE_MIN_WITH_COVER_R19 DO_SAVE_MIN(cover, mov r30=cr.ifs, mov r15=r19, RSE_WORKAROUND)
|
||||
#define SAVE_MIN_WITH_COVER DO_SAVE_MIN(COVER, mov r30=cr.ifs, , RSE_WORKAROUND)
|
||||
#define SAVE_MIN_WITH_COVER_R19 DO_SAVE_MIN(COVER, mov r30=cr.ifs, mov r15=r19, RSE_WORKAROUND)
|
||||
#define SAVE_MIN DO_SAVE_MIN( , mov r30=r0, , )
|
||||
|
|
|
@ -321,7 +321,8 @@ module_alloc (unsigned long size)
|
|||
void
|
||||
module_free (struct module *mod, void *module_region)
|
||||
{
|
||||
if (mod->arch.init_unw_table && module_region == mod->module_init) {
|
||||
if (mod && mod->arch.init_unw_table &&
|
||||
module_region == mod->module_init) {
|
||||
unw_remove_unwind_table(mod->arch.init_unw_table);
|
||||
mod->arch.init_unw_table = NULL;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* calculate
|
||||
* NR_IRQS = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, FOO_NR_IRQS...)
|
||||
* depending on config.
|
||||
* This must be calculated before processing asm-offset.c.
|
||||
*/
|
||||
|
||||
#define ASM_OFFSETS_C 1
|
||||
|
||||
#include <linux/kbuild.h>
|
||||
#include <linux/threads.h>
|
||||
#include <asm-ia64/native/irq.h>
|
||||
|
||||
void foo(void)
|
||||
{
|
||||
union paravirt_nr_irqs_max {
|
||||
char ia64_native_nr_irqs[IA64_NATIVE_NR_IRQS];
|
||||
#ifdef CONFIG_XEN
|
||||
char xen_nr_irqs[XEN_NR_IRQS];
|
||||
#endif
|
||||
};
|
||||
|
||||
DEFINE(NR_IRQS, sizeof (union paravirt_nr_irqs_max));
|
||||
}
|
|
@ -0,0 +1,369 @@
|
|||
/******************************************************************************
|
||||
* arch/ia64/kernel/paravirt.c
|
||||
*
|
||||
* Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
|
||||
* VA Linux Systems Japan K.K.
|
||||
* Yaozu (Eddie) Dong <eddie.dong@intel.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <asm/iosapic.h>
|
||||
#include <asm/paravirt.h>
|
||||
|
||||
/***************************************************************************
|
||||
* general info
|
||||
*/
|
||||
struct pv_info pv_info = {
|
||||
.kernel_rpl = 0,
|
||||
.paravirt_enabled = 0,
|
||||
.name = "bare hardware"
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
* pv_init_ops
|
||||
* initialization hooks.
|
||||
*/
|
||||
|
||||
struct pv_init_ops pv_init_ops;
|
||||
|
||||
/***************************************************************************
|
||||
* pv_cpu_ops
|
||||
* intrinsics hooks.
|
||||
*/
|
||||
|
||||
/* ia64_native_xxx are macros so that we have to make them real functions */
|
||||
|
||||
#define DEFINE_VOID_FUNC1(name) \
|
||||
static void \
|
||||
ia64_native_ ## name ## _func(unsigned long arg) \
|
||||
{ \
|
||||
ia64_native_ ## name(arg); \
|
||||
} \
|
||||
|
||||
#define DEFINE_VOID_FUNC2(name) \
|
||||
static void \
|
||||
ia64_native_ ## name ## _func(unsigned long arg0, \
|
||||
unsigned long arg1) \
|
||||
{ \
|
||||
ia64_native_ ## name(arg0, arg1); \
|
||||
} \
|
||||
|
||||
#define DEFINE_FUNC0(name) \
|
||||
static unsigned long \
|
||||
ia64_native_ ## name ## _func(void) \
|
||||
{ \
|
||||
return ia64_native_ ## name(); \
|
||||
}
|
||||
|
||||
#define DEFINE_FUNC1(name, type) \
|
||||
static unsigned long \
|
||||
ia64_native_ ## name ## _func(type arg) \
|
||||
{ \
|
||||
return ia64_native_ ## name(arg); \
|
||||
} \
|
||||
|
||||
DEFINE_VOID_FUNC1(fc);
|
||||
DEFINE_VOID_FUNC1(intrin_local_irq_restore);
|
||||
|
||||
DEFINE_VOID_FUNC2(ptcga);
|
||||
DEFINE_VOID_FUNC2(set_rr);
|
||||
|
||||
DEFINE_FUNC0(get_psr_i);
|
||||
|
||||
DEFINE_FUNC1(thash, unsigned long);
|
||||
DEFINE_FUNC1(get_cpuid, int);
|
||||
DEFINE_FUNC1(get_pmd, int);
|
||||
DEFINE_FUNC1(get_rr, unsigned long);
|
||||
|
||||
static void
|
||||
ia64_native_ssm_i_func(void)
|
||||
{
|
||||
ia64_native_ssm(IA64_PSR_I);
|
||||
}
|
||||
|
||||
static void
|
||||
ia64_native_rsm_i_func(void)
|
||||
{
|
||||
ia64_native_rsm(IA64_PSR_I);
|
||||
}
|
||||
|
||||
static void
|
||||
ia64_native_set_rr0_to_rr4_func(unsigned long val0, unsigned long val1,
|
||||
unsigned long val2, unsigned long val3,
|
||||
unsigned long val4)
|
||||
{
|
||||
ia64_native_set_rr0_to_rr4(val0, val1, val2, val3, val4);
|
||||
}
|
||||
|
||||
#define CASE_GET_REG(id) \
|
||||
case _IA64_REG_ ## id: \
|
||||
res = ia64_native_getreg(_IA64_REG_ ## id); \
|
||||
break;
|
||||
#define CASE_GET_AR(id) CASE_GET_REG(AR_ ## id)
|
||||
#define CASE_GET_CR(id) CASE_GET_REG(CR_ ## id)
|
||||
|
||||
unsigned long
|
||||
ia64_native_getreg_func(int regnum)
|
||||
{
|
||||
unsigned long res = -1;
|
||||
switch (regnum) {
|
||||
CASE_GET_REG(GP);
|
||||
CASE_GET_REG(IP);
|
||||
CASE_GET_REG(PSR);
|
||||
CASE_GET_REG(TP);
|
||||
CASE_GET_REG(SP);
|
||||
|
||||
CASE_GET_AR(KR0);
|
||||
CASE_GET_AR(KR1);
|
||||
CASE_GET_AR(KR2);
|
||||
CASE_GET_AR(KR3);
|
||||
CASE_GET_AR(KR4);
|
||||
CASE_GET_AR(KR5);
|
||||
CASE_GET_AR(KR6);
|
||||
CASE_GET_AR(KR7);
|
||||
CASE_GET_AR(RSC);
|
||||
CASE_GET_AR(BSP);
|
||||
CASE_GET_AR(BSPSTORE);
|
||||
CASE_GET_AR(RNAT);
|
||||
CASE_GET_AR(FCR);
|
||||
CASE_GET_AR(EFLAG);
|
||||
CASE_GET_AR(CSD);
|
||||
CASE_GET_AR(SSD);
|
||||
CASE_GET_AR(CFLAG);
|
||||
CASE_GET_AR(FSR);
|
||||
CASE_GET_AR(FIR);
|
||||
CASE_GET_AR(FDR);
|
||||
CASE_GET_AR(CCV);
|
||||
CASE_GET_AR(UNAT);
|
||||
CASE_GET_AR(FPSR);
|
||||
CASE_GET_AR(ITC);
|
||||
CASE_GET_AR(PFS);
|
||||
CASE_GET_AR(LC);
|
||||
CASE_GET_AR(EC);
|
||||
|
||||
CASE_GET_CR(DCR);
|
||||
CASE_GET_CR(ITM);
|
||||
CASE_GET_CR(IVA);
|
||||
CASE_GET_CR(PTA);
|
||||
CASE_GET_CR(IPSR);
|
||||
CASE_GET_CR(ISR);
|
||||
CASE_GET_CR(IIP);
|
||||
CASE_GET_CR(IFA);
|
||||
CASE_GET_CR(ITIR);
|
||||
CASE_GET_CR(IIPA);
|
||||
CASE_GET_CR(IFS);
|
||||
CASE_GET_CR(IIM);
|
||||
CASE_GET_CR(IHA);
|
||||
CASE_GET_CR(LID);
|
||||
CASE_GET_CR(IVR);
|
||||
CASE_GET_CR(TPR);
|
||||
CASE_GET_CR(EOI);
|
||||
CASE_GET_CR(IRR0);
|
||||
CASE_GET_CR(IRR1);
|
||||
CASE_GET_CR(IRR2);
|
||||
CASE_GET_CR(IRR3);
|
||||
CASE_GET_CR(ITV);
|
||||
CASE_GET_CR(PMV);
|
||||
CASE_GET_CR(CMCV);
|
||||
CASE_GET_CR(LRR0);
|
||||
CASE_GET_CR(LRR1);
|
||||
|
||||
default:
|
||||
printk(KERN_CRIT "wrong_getreg %d\n", regnum);
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#define CASE_SET_REG(id) \
|
||||
case _IA64_REG_ ## id: \
|
||||
ia64_native_setreg(_IA64_REG_ ## id, val); \
|
||||
break;
|
||||
#define CASE_SET_AR(id) CASE_SET_REG(AR_ ## id)
|
||||
#define CASE_SET_CR(id) CASE_SET_REG(CR_ ## id)
|
||||
|
||||
void
|
||||
ia64_native_setreg_func(int regnum, unsigned long val)
|
||||
{
|
||||
switch (regnum) {
|
||||
case _IA64_REG_PSR_L:
|
||||
ia64_native_setreg(_IA64_REG_PSR_L, val);
|
||||
ia64_dv_serialize_data();
|
||||
break;
|
||||
CASE_SET_REG(SP);
|
||||
CASE_SET_REG(GP);
|
||||
|
||||
CASE_SET_AR(KR0);
|
||||
CASE_SET_AR(KR1);
|
||||
CASE_SET_AR(KR2);
|
||||
CASE_SET_AR(KR3);
|
||||
CASE_SET_AR(KR4);
|
||||
CASE_SET_AR(KR5);
|
||||
CASE_SET_AR(KR6);
|
||||
CASE_SET_AR(KR7);
|
||||
CASE_SET_AR(RSC);
|
||||
CASE_SET_AR(BSP);
|
||||
CASE_SET_AR(BSPSTORE);
|
||||
CASE_SET_AR(RNAT);
|
||||
CASE_SET_AR(FCR);
|
||||
CASE_SET_AR(EFLAG);
|
||||
CASE_SET_AR(CSD);
|
||||
CASE_SET_AR(SSD);
|
||||
CASE_SET_AR(CFLAG);
|
||||
CASE_SET_AR(FSR);
|
||||
CASE_SET_AR(FIR);
|
||||
CASE_SET_AR(FDR);
|
||||
CASE_SET_AR(CCV);
|
||||
CASE_SET_AR(UNAT);
|
||||
CASE_SET_AR(FPSR);
|
||||
CASE_SET_AR(ITC);
|
||||
CASE_SET_AR(PFS);
|
||||
CASE_SET_AR(LC);
|
||||
CASE_SET_AR(EC);
|
||||
|
||||
CASE_SET_CR(DCR);
|
||||
CASE_SET_CR(ITM);
|
||||
CASE_SET_CR(IVA);
|
||||
CASE_SET_CR(PTA);
|
||||
CASE_SET_CR(IPSR);
|
||||
CASE_SET_CR(ISR);
|
||||
CASE_SET_CR(IIP);
|
||||
CASE_SET_CR(IFA);
|
||||
CASE_SET_CR(ITIR);
|
||||
CASE_SET_CR(IIPA);
|
||||
CASE_SET_CR(IFS);
|
||||
CASE_SET_CR(IIM);
|
||||
CASE_SET_CR(IHA);
|
||||
CASE_SET_CR(LID);
|
||||
CASE_SET_CR(IVR);
|
||||
CASE_SET_CR(TPR);
|
||||
CASE_SET_CR(EOI);
|
||||
CASE_SET_CR(IRR0);
|
||||
CASE_SET_CR(IRR1);
|
||||
CASE_SET_CR(IRR2);
|
||||
CASE_SET_CR(IRR3);
|
||||
CASE_SET_CR(ITV);
|
||||
CASE_SET_CR(PMV);
|
||||
CASE_SET_CR(CMCV);
|
||||
CASE_SET_CR(LRR0);
|
||||
CASE_SET_CR(LRR1);
|
||||
default:
|
||||
printk(KERN_CRIT "wrong setreg %d\n", regnum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct pv_cpu_ops pv_cpu_ops = {
|
||||
.fc = ia64_native_fc_func,
|
||||
.thash = ia64_native_thash_func,
|
||||
.get_cpuid = ia64_native_get_cpuid_func,
|
||||
.get_pmd = ia64_native_get_pmd_func,
|
||||
.ptcga = ia64_native_ptcga_func,
|
||||
.get_rr = ia64_native_get_rr_func,
|
||||
.set_rr = ia64_native_set_rr_func,
|
||||
.set_rr0_to_rr4 = ia64_native_set_rr0_to_rr4_func,
|
||||
.ssm_i = ia64_native_ssm_i_func,
|
||||
.getreg = ia64_native_getreg_func,
|
||||
.setreg = ia64_native_setreg_func,
|
||||
.rsm_i = ia64_native_rsm_i_func,
|
||||
.get_psr_i = ia64_native_get_psr_i_func,
|
||||
.intrin_local_irq_restore
|
||||
= ia64_native_intrin_local_irq_restore_func,
|
||||
};
|
||||
EXPORT_SYMBOL(pv_cpu_ops);
|
||||
|
||||
/******************************************************************************
|
||||
* replacement of hand written assembly codes.
|
||||
*/
|
||||
|
||||
void
|
||||
paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch)
|
||||
{
|
||||
extern unsigned long paravirt_switch_to_targ;
|
||||
extern unsigned long paravirt_leave_syscall_targ;
|
||||
extern unsigned long paravirt_work_processed_syscall_targ;
|
||||
extern unsigned long paravirt_leave_kernel_targ;
|
||||
|
||||
paravirt_switch_to_targ = cpu_asm_switch->switch_to;
|
||||
paravirt_leave_syscall_targ = cpu_asm_switch->leave_syscall;
|
||||
paravirt_work_processed_syscall_targ =
|
||||
cpu_asm_switch->work_processed_syscall;
|
||||
paravirt_leave_kernel_targ = cpu_asm_switch->leave_kernel;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* pv_iosapic_ops
|
||||
* iosapic read/write hooks.
|
||||
*/
|
||||
|
||||
static unsigned int
|
||||
ia64_native_iosapic_read(char __iomem *iosapic, unsigned int reg)
|
||||
{
|
||||
return __ia64_native_iosapic_read(iosapic, reg);
|
||||
}
|
||||
|
||||
static void
|
||||
ia64_native_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
|
||||
{
|
||||
__ia64_native_iosapic_write(iosapic, reg, val);
|
||||
}
|
||||
|
||||
struct pv_iosapic_ops pv_iosapic_ops = {
|
||||
.pcat_compat_init = ia64_native_iosapic_pcat_compat_init,
|
||||
.get_irq_chip = ia64_native_iosapic_get_irq_chip,
|
||||
|
||||
.__read = ia64_native_iosapic_read,
|
||||
.__write = ia64_native_iosapic_write,
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
* pv_irq_ops
|
||||
* irq operations
|
||||
*/
|
||||
|
||||
struct pv_irq_ops pv_irq_ops = {
|
||||
.register_ipi = ia64_native_register_ipi,
|
||||
|
||||
.assign_irq_vector = ia64_native_assign_irq_vector,
|
||||
.free_irq_vector = ia64_native_free_irq_vector,
|
||||
.register_percpu_irq = ia64_native_register_percpu_irq,
|
||||
|
||||
.resend_irq = ia64_native_resend_irq,
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
* pv_time_ops
|
||||
* time operations
|
||||
*/
|
||||
|
||||
static int
|
||||
ia64_native_do_steal_accounting(unsigned long *new_itm)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct pv_time_ops pv_time_ops = {
|
||||
.do_steal_accounting = ia64_native_do_steal_accounting,
|
||||
};
|
|
@ -0,0 +1,29 @@
|
|||
/******************************************************************************
|
||||
* linux/arch/ia64/xen/paravirt_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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __IA64_ASM_PARAVIRTUALIZED_XEN
|
||||
#include <asm/xen/inst.h>
|
||||
#include <asm/xen/minstate.h>
|
||||
#else
|
||||
#include <asm/native/inst.h>
|
||||
#endif
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/******************************************************************************
|
||||
* linux/arch/ia64/xen/paravirtentry.S
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include <asm/asmmacro.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include "entry.h"
|
||||
|
||||
#define DATA8(sym, init_value) \
|
||||
.pushsection .data.read_mostly ; \
|
||||
.align 8 ; \
|
||||
.global sym ; \
|
||||
sym: ; \
|
||||
data8 init_value ; \
|
||||
.popsection
|
||||
|
||||
#define BRANCH(targ, reg, breg) \
|
||||
movl reg=targ ; \
|
||||
;; \
|
||||
ld8 reg=[reg] ; \
|
||||
;; \
|
||||
mov breg=reg ; \
|
||||
br.cond.sptk.many breg
|
||||
|
||||
#define BRANCH_PROC(sym, reg, breg) \
|
||||
DATA8(paravirt_ ## sym ## _targ, ia64_native_ ## sym) ; \
|
||||
GLOBAL_ENTRY(paravirt_ ## sym) ; \
|
||||
BRANCH(paravirt_ ## sym ## _targ, reg, breg) ; \
|
||||
END(paravirt_ ## sym)
|
||||
|
||||
#define BRANCH_PROC_UNWINFO(sym, reg, breg) \
|
||||
DATA8(paravirt_ ## sym ## _targ, ia64_native_ ## sym) ; \
|
||||
GLOBAL_ENTRY(paravirt_ ## sym) ; \
|
||||
PT_REGS_UNWIND_INFO(0) ; \
|
||||
BRANCH(paravirt_ ## sym ## _targ, reg, breg) ; \
|
||||
END(paravirt_ ## sym)
|
||||
|
||||
|
||||
BRANCH_PROC(switch_to, r22, b7)
|
||||
BRANCH_PROC_UNWINFO(leave_syscall, r22, b7)
|
||||
BRANCH_PROC(work_processed_syscall, r2, b7)
|
||||
BRANCH_PROC_UNWINFO(leave_kernel, r22, b7)
|
|
@ -51,6 +51,7 @@
|
|||
#include <asm/mca.h>
|
||||
#include <asm/meminit.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/paravirt.h>
|
||||
#include <asm/patch.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/processor.h>
|
||||
|
@ -341,6 +342,8 @@ reserve_memory (void)
|
|||
rsvd_region[n].end = (unsigned long) ia64_imva(_end);
|
||||
n++;
|
||||
|
||||
n += paravirt_reserve_memory(&rsvd_region[n]);
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
if (ia64_boot_param->initrd_start) {
|
||||
rsvd_region[n].start = (unsigned long)__va(ia64_boot_param->initrd_start);
|
||||
|
@ -519,6 +522,8 @@ setup_arch (char **cmdline_p)
|
|||
{
|
||||
unw_init();
|
||||
|
||||
paravirt_arch_setup_early();
|
||||
|
||||
ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist);
|
||||
|
||||
*cmdline_p = __va(ia64_boot_param->command_line);
|
||||
|
@ -583,6 +588,9 @@ setup_arch (char **cmdline_p)
|
|||
acpi_boot_init();
|
||||
#endif
|
||||
|
||||
paravirt_banner();
|
||||
paravirt_arch_setup_console(cmdline_p);
|
||||
|
||||
#ifdef CONFIG_VT
|
||||
if (!conswitchp) {
|
||||
# if defined(CONFIG_DUMMY_CONSOLE)
|
||||
|
@ -602,6 +610,8 @@ setup_arch (char **cmdline_p)
|
|||
#endif
|
||||
|
||||
/* enable IA-64 Machine Check Abort Handling unless disabled */
|
||||
if (paravirt_arch_setup_nomca())
|
||||
nomca = 1;
|
||||
if (!nomca)
|
||||
ia64_mca_init();
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include <asm/machvec.h>
|
||||
#include <asm/mca.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/paravirt.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/processor.h>
|
||||
|
@ -642,6 +643,7 @@ void __devinit smp_prepare_boot_cpu(void)
|
|||
cpu_set(smp_processor_id(), cpu_online_map);
|
||||
cpu_set(smp_processor_id(), cpu_callin_map);
|
||||
per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
|
||||
paravirt_post_smp_prepare_boot_cpu();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <asm/machvec.h>
|
||||
#include <asm/delay.h>
|
||||
#include <asm/hw_irq.h>
|
||||
#include <asm/paravirt.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/sal.h>
|
||||
#include <asm/sections.h>
|
||||
|
@ -48,6 +49,15 @@ EXPORT_SYMBOL(last_cli_ip);
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
static void
|
||||
paravirt_clocksource_resume(void)
|
||||
{
|
||||
if (pv_time_ops.clocksource_resume)
|
||||
pv_time_ops.clocksource_resume();
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct clocksource clocksource_itc = {
|
||||
.name = "itc",
|
||||
.rating = 350,
|
||||
|
@ -56,6 +66,9 @@ static struct clocksource clocksource_itc = {
|
|||
.mult = 0, /*to be calculated*/
|
||||
.shift = 16,
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
.resume = paravirt_clocksource_resume,
|
||||
#endif
|
||||
};
|
||||
static struct clocksource *itc_clocksource;
|
||||
|
||||
|
@ -157,6 +170,9 @@ timer_interrupt (int irq, void *dev_id)
|
|||
|
||||
profile_tick(CPU_PROFILING);
|
||||
|
||||
if (paravirt_do_steal_accounting(&new_itm))
|
||||
goto skip_process_time_accounting;
|
||||
|
||||
while (1) {
|
||||
update_process_times(user_mode(get_irq_regs()));
|
||||
|
||||
|
@ -186,6 +202,8 @@ timer_interrupt (int irq, void *dev_id)
|
|||
local_irq_disable();
|
||||
}
|
||||
|
||||
skip_process_time_accounting:
|
||||
|
||||
do {
|
||||
/*
|
||||
* If we're too close to the next clock tick for
|
||||
|
@ -335,6 +353,11 @@ ia64_init_itm (void)
|
|||
*/
|
||||
clocksource_itc.rating = 50;
|
||||
|
||||
paravirt_init_missing_ticks_accounting(smp_processor_id());
|
||||
|
||||
/* avoid softlock up message when cpu is unplug and plugged again. */
|
||||
touch_softlockup_watchdog();
|
||||
|
||||
/* Setup the CPU local timer tick */
|
||||
ia64_cpu_local_tick();
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include <asm/system.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
#define LOAD_OFFSET (KERNEL_START - KERNEL_TR_PAGE_SIZE)
|
||||
#include <asm-generic/vmlinux.lds.h>
|
||||
|
||||
#define IVT_TEXT \
|
||||
|
|
|
@ -43,7 +43,8 @@ $(obj)/$(offsets-file): arch/ia64/kvm/asm-offsets.s
|
|||
EXTRA_CFLAGS += -Ivirt/kvm -Iarch/ia64/kvm/
|
||||
EXTRA_AFLAGS += -Ivirt/kvm -Iarch/ia64/kvm/
|
||||
|
||||
common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o)
|
||||
common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \
|
||||
coalesced_mmio.o)
|
||||
|
||||
kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o
|
||||
obj-$(CONFIG_KVM) += kvm.o
|
||||
|
|
|
@ -187,6 +187,9 @@ int kvm_dev_ioctl_check_extension(long ext)
|
|||
|
||||
r = 1;
|
||||
break;
|
||||
case KVM_CAP_COALESCED_MMIO:
|
||||
r = KVM_COALESCED_MMIO_PAGE_OFFSET;
|
||||
break;
|
||||
default:
|
||||
r = 0;
|
||||
}
|
||||
|
@ -195,11 +198,11 @@ int kvm_dev_ioctl_check_extension(long ext)
|
|||
}
|
||||
|
||||
static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
|
||||
gpa_t addr)
|
||||
gpa_t addr, int len, int is_write)
|
||||
{
|
||||
struct kvm_io_device *dev;
|
||||
|
||||
dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr);
|
||||
dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr, len, is_write);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
@ -231,7 +234,7 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
|||
kvm_run->exit_reason = KVM_EXIT_MMIO;
|
||||
return 0;
|
||||
mmio:
|
||||
mmio_dev = vcpu_find_mmio_dev(vcpu, p->addr);
|
||||
mmio_dev = vcpu_find_mmio_dev(vcpu, p->addr, p->size, !p->dir);
|
||||
if (mmio_dev) {
|
||||
if (!p->dir)
|
||||
kvm_iodevice_write(mmio_dev, p->addr, p->size,
|
||||
|
@ -395,7 +398,7 @@ static int handle_global_purge(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
|||
if (kvm->vcpus[i]->cpu != -1) {
|
||||
call_data.vcpu = kvm->vcpus[i];
|
||||
smp_call_function_single(kvm->vcpus[i]->cpu,
|
||||
vcpu_global_purge, &call_data, 0, 1);
|
||||
vcpu_global_purge, &call_data, 1);
|
||||
} else
|
||||
printk(KERN_WARNING"kvm: Uninit vcpu received ipi!\n");
|
||||
|
||||
|
@ -1035,14 +1038,6 @@ static void kvm_free_vmm_area(void)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure that a cpu that is being hot-unplugged does not have any vcpus
|
||||
* cached on it. Leave it as blank for IA64.
|
||||
*/
|
||||
void decache_vcpus_on_cpu(int cpu)
|
||||
{
|
||||
}
|
||||
|
||||
static void vti_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
||||
{
|
||||
}
|
||||
|
@ -1460,6 +1455,9 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void kvm_arch_flush_shadow(struct kvm *kvm)
|
||||
{
|
||||
}
|
||||
|
||||
long kvm_arch_dev_ioctl(struct file *filp,
|
||||
unsigned int ioctl, unsigned long arg)
|
||||
|
@ -1693,7 +1691,7 @@ void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
|
|||
wake_up_interruptible(&vcpu->wq);
|
||||
|
||||
if (vcpu->guest_mode)
|
||||
smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0, 0);
|
||||
smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0);
|
||||
}
|
||||
|
||||
int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig)
|
||||
|
|
|
@ -130,7 +130,7 @@ static struct ia64_pal_retval pal_cache_flush(struct kvm_vcpu *vcpu)
|
|||
args.cache_type = gr29;
|
||||
args.operation = gr30;
|
||||
smp_call_function(remote_pal_cache_flush,
|
||||
(void *)&args, 1, 1);
|
||||
(void *)&args, 1);
|
||||
if (args.status != 0)
|
||||
printk(KERN_ERR"pal_cache_flush error!,"
|
||||
"status:0x%lx\n", args.status);
|
||||
|
|
|
@ -490,28 +490,6 @@ config ATARI_MFPSER
|
|||
Note for Falcon users: You also have an MFP port, it's just not
|
||||
wired to the outside... But you could use the port under Linux.
|
||||
|
||||
config ATARI_SCC
|
||||
tristate "Atari SCC serial support"
|
||||
depends on ATARI
|
||||
---help---
|
||||
If you have serial ports based on a Zilog SCC chip (Modem2, Serial2,
|
||||
LAN) and like to use them under Linux, say Y. All built-in SCC's are
|
||||
supported (TT, MegaSTE, Falcon), and also the ST-ESCC. If you have
|
||||
two connectors for channel A (Serial2 and LAN), they are visible as
|
||||
two separate devices.
|
||||
|
||||
To compile this driver as a module, choose M here.
|
||||
|
||||
config ATARI_SCC_DMA
|
||||
bool "Atari SCC serial DMA support"
|
||||
depends on ATARI_SCC
|
||||
help
|
||||
This enables DMA support for receiving data on channel A of the SCC.
|
||||
If you have a TT you may say Y here and read
|
||||
drivers/char/atari_SCC.README. All other users should say N here,
|
||||
because only the TT has SCC-DMA, even if your machine keeps claiming
|
||||
so at boot time.
|
||||
|
||||
config ATARI_MIDI
|
||||
tristate "Atari MIDI serial support"
|
||||
depends on ATARI
|
||||
|
@ -578,18 +556,6 @@ config MAC_HID
|
|||
depends on INPUT_ADBHID
|
||||
default y
|
||||
|
||||
config ADB_KEYBOARD
|
||||
bool "Support for ADB keyboard (old driver)"
|
||||
depends on MAC && !INPUT_ADBHID
|
||||
help
|
||||
This option allows you to use an ADB keyboard attached to your
|
||||
machine. Note that this disables any other (ie. PS/2) keyboard
|
||||
support, even if your machine is physically capable of using both at
|
||||
the same time.
|
||||
|
||||
If you use an ADB keyboard (4 pin connector), say Y here.
|
||||
If you use a PS/2 keyboard (6 pin connector), say N here.
|
||||
|
||||
config HPDCA
|
||||
tristate "HP DCA serial support"
|
||||
depends on DIO && SERIAL_8250
|
||||
|
@ -640,7 +606,7 @@ config DN_SERIAL
|
|||
|
||||
config SERIAL_CONSOLE
|
||||
bool "Support for serial port console"
|
||||
depends on (AMIGA || ATARI || MAC || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_SCC=y || ATARI_MIDI=y || MAC_SCC=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL)
|
||||
depends on (AMIGA || ATARI || MAC || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_MIDI=y || MAC_SCC=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL)
|
||||
---help---
|
||||
If you say Y here, it will be possible to use a serial port as the
|
||||
system console (the system console is the device which receives all
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# Copyright (C) 1994 by Hamish Macdonald
|
||||
#
|
||||
|
||||
KBUILD_DEFCONFIG := amiga_defconfig
|
||||
KBUILD_DEFCONFIG := multi_defconfig
|
||||
|
||||
# override top level makefile
|
||||
AS += -m68020
|
||||
|
|
|
@ -36,14 +36,11 @@
|
|||
#include <asm/machdep.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
unsigned long amiga_model;
|
||||
EXPORT_SYMBOL(amiga_model);
|
||||
static unsigned long amiga_model;
|
||||
|
||||
unsigned long amiga_eclock;
|
||||
EXPORT_SYMBOL(amiga_eclock);
|
||||
|
||||
unsigned long amiga_masterclock;
|
||||
|
||||
unsigned long amiga_colorclock;
|
||||
EXPORT_SYMBOL(amiga_colorclock);
|
||||
|
||||
|
@ -51,7 +48,9 @@ unsigned long amiga_chipset;
|
|||
EXPORT_SYMBOL(amiga_chipset);
|
||||
|
||||
unsigned char amiga_vblank;
|
||||
unsigned char amiga_psfreq;
|
||||
EXPORT_SYMBOL(amiga_vblank);
|
||||
|
||||
static unsigned char amiga_psfreq;
|
||||
|
||||
struct amiga_hw_present amiga_hw_present;
|
||||
EXPORT_SYMBOL(amiga_hw_present);
|
||||
|
@ -92,8 +91,6 @@ static char *amiga_models[] __initdata = {
|
|||
static char amiga_model_name[13] = "Amiga ";
|
||||
|
||||
static void amiga_sched_init(irq_handler_t handler);
|
||||
/* amiga specific irq functions */
|
||||
extern void amiga_init_IRQ(void);
|
||||
static void amiga_get_model(char *model);
|
||||
static int amiga_get_hardware_list(char *buffer);
|
||||
/* amiga specific timer functions */
|
||||
|
@ -107,8 +104,6 @@ static void amiga_reset(void);
|
|||
extern void amiga_init_sound(void);
|
||||
static void amiga_mem_console_write(struct console *co, const char *b,
|
||||
unsigned int count);
|
||||
void amiga_serial_console_write(struct console *co, const char *s,
|
||||
unsigned int count);
|
||||
#ifdef CONFIG_HEARTBEAT
|
||||
static void amiga_heartbeat(int on);
|
||||
#endif
|
||||
|
@ -418,8 +413,7 @@ void __init config_amiga(void)
|
|||
mach_heartbeat = amiga_heartbeat;
|
||||
#endif
|
||||
|
||||
/* Fill in the clock values (based on the 700 kHz E-Clock) */
|
||||
amiga_masterclock = 40*amiga_eclock; /* 28 MHz */
|
||||
/* Fill in the clock value (based on the 700 kHz E-Clock) */
|
||||
amiga_colorclock = 5*amiga_eclock; /* 3.5 MHz */
|
||||
|
||||
/* clear all DMA bits */
|
||||
|
@ -817,8 +811,8 @@ static void amiga_serial_putc(char c)
|
|||
;
|
||||
}
|
||||
|
||||
void amiga_serial_console_write(struct console *co, const char *s,
|
||||
unsigned int count)
|
||||
static void amiga_serial_console_write(struct console *co, const char *s,
|
||||
unsigned int count)
|
||||
{
|
||||
while (count--) {
|
||||
if (*s == '\n')
|
||||
|
@ -827,7 +821,7 @@ void amiga_serial_console_write(struct console *co, const char *s,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIAL_CONSOLE
|
||||
#if 0
|
||||
void amiga_serial_puts(const char *s)
|
||||
{
|
||||
amiga_serial_console_write(NULL, s, strlen(s));
|
||||
|
|
|
@ -20,14 +20,6 @@
|
|||
#include <asm/atarihw.h>
|
||||
#include <asm/atariints.h>
|
||||
|
||||
/* Flag that Modem1 port is already initialized and used */
|
||||
int atari_MFP_init_done;
|
||||
EXPORT_SYMBOL(atari_MFP_init_done);
|
||||
|
||||
/* Flag that Modem1 port is already initialized and used */
|
||||
int atari_SCC_init_done;
|
||||
EXPORT_SYMBOL(atari_SCC_init_done);
|
||||
|
||||
/* Can be set somewhere, if a SCC master reset has already be done and should
|
||||
* not be repeated; used by kgdb */
|
||||
int atari_SCC_reset_done;
|
||||
|
@ -47,8 +39,8 @@ static inline void ata_mfp_out(char c)
|
|||
mfp.usart_dta = c;
|
||||
}
|
||||
|
||||
void atari_mfp_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
static void atari_mfp_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
{
|
||||
while (count--) {
|
||||
if (*str == '\n')
|
||||
|
@ -66,8 +58,8 @@ static inline void ata_scc_out(char c)
|
|||
scc.cha_b_data = c;
|
||||
}
|
||||
|
||||
void atari_scc_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
static void atari_scc_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
{
|
||||
while (count--) {
|
||||
if (*str == '\n')
|
||||
|
@ -83,8 +75,8 @@ static inline void ata_midi_out(char c)
|
|||
acia.mid_data = c;
|
||||
}
|
||||
|
||||
void atari_midi_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
static void atari_midi_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
{
|
||||
while (count--) {
|
||||
if (*str == '\n')
|
||||
|
@ -136,7 +128,7 @@ static void atari_par_console_write(struct console *co, const char *str,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIAL_CONSOLE
|
||||
#if 0
|
||||
int atari_mfp_console_wait_key(struct console *co)
|
||||
{
|
||||
while (!(mfp.rcv_stat & 0x80)) /* wait for rx buf filled */
|
||||
|
@ -166,11 +158,7 @@ int atari_midi_console_wait_key(struct console *co)
|
|||
* SCC serial ports. They're used by the debugging interface, kgdb, and the
|
||||
* serial console code.
|
||||
*/
|
||||
#ifndef CONFIG_SERIAL_CONSOLE
|
||||
static void __init atari_init_mfp_port(int cflag)
|
||||
#else
|
||||
void atari_init_mfp_port(int cflag)
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
* timer values for 1200...115200 bps; > 38400 select 110, 134, or 150
|
||||
|
@ -193,8 +181,6 @@ void atari_init_mfp_port(int cflag)
|
|||
mfp.tim_dt_d = baud_table[baud];
|
||||
mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */
|
||||
mfp.trn_stat |= 0x01; /* enable TX */
|
||||
|
||||
atari_MFP_init_done = 1;
|
||||
}
|
||||
|
||||
#define SCC_WRITE(reg, val) \
|
||||
|
@ -214,11 +200,7 @@ void atari_init_mfp_port(int cflag)
|
|||
MFPDELAY(); \
|
||||
} while (0)
|
||||
|
||||
#ifndef CONFIG_SERIAL_CONSOLE
|
||||
static void __init atari_init_scc_port(int cflag)
|
||||
#else
|
||||
void atari_init_scc_port(int cflag)
|
||||
#endif
|
||||
{
|
||||
extern int atari_SCC_reset_done;
|
||||
static int clksrc_table[9] =
|
||||
|
@ -277,14 +259,9 @@ void atari_init_scc_port(int cflag)
|
|||
SCC_WRITE(5, reg5 | 8);
|
||||
|
||||
atari_SCC_reset_done = 1;
|
||||
atari_SCC_init_done = 1;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SERIAL_CONSOLE
|
||||
static void __init atari_init_midi_port(int cflag)
|
||||
#else
|
||||
void atari_init_midi_port(int cflag)
|
||||
#endif
|
||||
{
|
||||
int baud = cflag & CBAUD;
|
||||
int csize = ((cflag & CSIZE) == CS8) ? 0x10 : 0x00;
|
||||
|
|
|
@ -10,7 +10,6 @@ obj-y := bindec.o binstr.o decbin.o do_func.o gen_except.o get_op.o \
|
|||
x_bsun.o x_fline.o x_operr.o x_ovfl.o x_snan.o x_store.o \
|
||||
x_unfl.o x_unimp.o x_unsupp.o bugfix.o skeleton.o
|
||||
|
||||
EXTRA_AFLAGS := -traditional
|
||||
EXTRA_LDFLAGS := -x
|
||||
|
||||
$(OS_OBJS): fpsp.h
|
||||
|
|
|
@ -6,5 +6,4 @@
|
|||
|
||||
obj-y := fskeleton.o iskeleton.o os.o
|
||||
|
||||
EXTRA_AFLAGS := -traditional
|
||||
EXTRA_LDFLAGS := -x
|
||||
|
|
|
@ -16,5 +16,3 @@ devres-y = ../../../kernel/irq/devres.o
|
|||
|
||||
obj-$(CONFIG_PCI) += bios32.o
|
||||
obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo
|
||||
|
||||
EXTRA_AFLAGS := -traditional
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/fpu.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/machdep.h>
|
||||
|
@ -40,6 +41,11 @@
|
|||
#include <asm/dvma.h>
|
||||
#endif
|
||||
|
||||
#if !FPSTATESIZE || !NR_IRQS
|
||||
#warning No CPU/platform type selected, your kernel will not work!
|
||||
#warning Are you building an allnoconfig kernel?
|
||||
#endif
|
||||
|
||||
unsigned long m68k_machtype;
|
||||
EXPORT_SYMBOL(m68k_machtype);
|
||||
unsigned long m68k_cputype;
|
||||
|
@ -116,6 +122,7 @@ extern int bvme6000_parse_bootinfo(const struct bi_record *);
|
|||
extern int mvme16x_parse_bootinfo(const struct bi_record *);
|
||||
extern int mvme147_parse_bootinfo(const struct bi_record *);
|
||||
extern int hp300_parse_bootinfo(const struct bi_record *);
|
||||
extern int apollo_parse_bootinfo(const struct bi_record *);
|
||||
|
||||
extern void config_amiga(void);
|
||||
extern void config_atari(void);
|
||||
|
@ -183,6 +190,8 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
|
|||
unknown = mvme147_parse_bootinfo(record);
|
||||
else if (MACH_IS_HP300)
|
||||
unknown = hp300_parse_bootinfo(record);
|
||||
else if (MACH_IS_APOLLO)
|
||||
unknown = apollo_parse_bootinfo(record);
|
||||
else
|
||||
unknown = 1;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* ld script to make m68k Linux kernel */
|
||||
|
||||
#include <asm-generic/vmlinux.lds.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
|
||||
OUTPUT_ARCH(m68k)
|
||||
|
@ -41,7 +42,7 @@ SECTIONS
|
|||
_edata = .; /* End of data section */
|
||||
|
||||
/* will be freed after init */
|
||||
. = ALIGN(4096); /* Init code and data */
|
||||
. = ALIGN(PAGE_SIZE); /* Init code and data */
|
||||
__init_begin = .;
|
||||
.init.text : {
|
||||
_sinittext = .;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* ld script to make m68k Linux kernel */
|
||||
|
||||
#include <asm-generic/vmlinux.lds.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
|
||||
OUTPUT_ARCH(m68k)
|
||||
|
@ -34,7 +35,7 @@ SECTIONS
|
|||
_edata = .;
|
||||
|
||||
/* will be freed after init */
|
||||
. = ALIGN(8192); /* Init code and data */
|
||||
. = ALIGN(PAGE_SIZE); /* Init code and data */
|
||||
__init_begin = .;
|
||||
.init.text : {
|
||||
_sinittext = .;
|
||||
|
@ -61,12 +62,12 @@ __init_begin = .;
|
|||
}
|
||||
SECURITY_INIT
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
. = ALIGN(8192);
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__initramfs_start = .;
|
||||
.init.ramfs : { *(.init.ramfs) }
|
||||
__initramfs_end = .;
|
||||
#endif
|
||||
. = ALIGN(8192);
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__init_end = .;
|
||||
.data.init.task : { *(.data.init_task) }
|
||||
|
||||
|
|
|
@ -2,7 +2,5 @@
|
|||
# Makefile for m68k-specific library files..
|
||||
#
|
||||
|
||||
EXTRA_AFLAGS := -traditional
|
||||
|
||||
lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
|
||||
checksum.o string.o uaccess.o
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
# Makefile for Linux arch/m68k/mac source directory
|
||||
#
|
||||
|
||||
obj-y := config.o bootparse.o macints.o iop.o via.o oss.o psc.o \
|
||||
obj-y := config.o macints.o iop.o via.o oss.o psc.o \
|
||||
baboon.o macboing.o debug.o misc.o
|
||||
|
|
|
@ -23,9 +23,7 @@
|
|||
/* #define DEBUG_IRQS */
|
||||
|
||||
int baboon_present;
|
||||
volatile struct baboon *baboon;
|
||||
|
||||
irqreturn_t baboon_irq(int, void *);
|
||||
static volatile struct baboon *baboon;
|
||||
|
||||
#if 0
|
||||
extern int macide_ack_intr(struct ata_channel *);
|
||||
|
@ -49,21 +47,11 @@ void __init baboon_init(void)
|
|||
printk("Baboon detected at %p\n", baboon);
|
||||
}
|
||||
|
||||
/*
|
||||
* Register the Baboon interrupt dispatcher on nubus slot $C.
|
||||
*/
|
||||
|
||||
void __init baboon_register_interrupts(void)
|
||||
{
|
||||
request_irq(IRQ_NUBUS_C, baboon_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST,
|
||||
"baboon", (void *) baboon);
|
||||
}
|
||||
|
||||
/*
|
||||
* Baboon interrupt handler. This works a lot like a VIA.
|
||||
*/
|
||||
|
||||
irqreturn_t baboon_irq(int irq, void *dev_id)
|
||||
static irqreturn_t baboon_irq(int irq, void *dev_id)
|
||||
{
|
||||
int irq_bit, irq_num;
|
||||
unsigned char events;
|
||||
|
@ -95,6 +83,16 @@ irqreturn_t baboon_irq(int irq, void *dev_id)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register the Baboon interrupt dispatcher on nubus slot $C.
|
||||
*/
|
||||
|
||||
void __init baboon_register_interrupts(void)
|
||||
{
|
||||
request_irq(IRQ_NUBUS_C, baboon_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST,
|
||||
"baboon", (void *) baboon);
|
||||
}
|
||||
|
||||
void baboon_irq_enable(int irq) {
|
||||
#ifdef DEBUG_IRQUSE
|
||||
printk("baboon_irq_enable(%d)\n", irq);
|
||||
|
|
|
@ -1,122 +0,0 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/macintosh.h>
|
||||
|
||||
/*
|
||||
* Booter vars
|
||||
*/
|
||||
|
||||
int boothowto;
|
||||
int _boothowto;
|
||||
|
||||
/*
|
||||
* Called early to parse the environment (passed to us from the booter)
|
||||
* into a bootinfo struct. Will die as soon as we have our own booter
|
||||
*/
|
||||
|
||||
#define atol(x) simple_strtoul(x,NULL,0)
|
||||
|
||||
void parse_booter(char *env)
|
||||
{
|
||||
char *name;
|
||||
char *value;
|
||||
#if 0
|
||||
while(0 && *env)
|
||||
#else
|
||||
while(*env)
|
||||
#endif
|
||||
{
|
||||
name=env;
|
||||
value=name;
|
||||
while(*value!='='&&*value)
|
||||
value++;
|
||||
if(*value=='=')
|
||||
*value++=0;
|
||||
env=value;
|
||||
while(*env)
|
||||
env++;
|
||||
env++;
|
||||
#if 0
|
||||
if(strcmp(name,"VIDEO_ADDR")==0)
|
||||
mac_mch.videoaddr=atol(value);
|
||||
if(strcmp(name,"ROW_BYTES")==0)
|
||||
mac_mch.videorow=atol(value);
|
||||
if(strcmp(name,"SCREEN_DEPTH")==0)
|
||||
mac_mch.videodepth=atol(value);
|
||||
if(strcmp(name,"DIMENSIONS")==0)
|
||||
mac_mch.dimensions=atol(value);
|
||||
#endif
|
||||
if(strcmp(name,"BOOTTIME")==0)
|
||||
mac_bi_data.boottime=atol(value);
|
||||
if(strcmp(name,"GMTBIAS")==0)
|
||||
mac_bi_data.gmtbias=atol(value);
|
||||
if(strcmp(name,"BOOTERVER")==0)
|
||||
mac_bi_data.bootver=atol(value);
|
||||
if(strcmp(name,"MACOS_VIDEO")==0)
|
||||
mac_bi_data.videological=atol(value);
|
||||
if(strcmp(name,"MACOS_SCC")==0)
|
||||
mac_bi_data.sccbase=atol(value);
|
||||
if(strcmp(name,"MACHINEID")==0)
|
||||
mac_bi_data.id=atol(value);
|
||||
if(strcmp(name,"MEMSIZE")==0)
|
||||
mac_bi_data.memsize=atol(value);
|
||||
if(strcmp(name,"SERIAL_MODEM_FLAGS")==0)
|
||||
mac_bi_data.serialmf=atol(value);
|
||||
if(strcmp(name,"SERIAL_MODEM_HSKICLK")==0)
|
||||
mac_bi_data.serialhsk=atol(value);
|
||||
if(strcmp(name,"SERIAL_MODEM_GPICLK")==0)
|
||||
mac_bi_data.serialgpi=atol(value);
|
||||
if(strcmp(name,"SERIAL_PRINT_FLAGS")==0)
|
||||
mac_bi_data.printmf=atol(value);
|
||||
if(strcmp(name,"SERIAL_PRINT_HSKICLK")==0)
|
||||
mac_bi_data.printhsk=atol(value);
|
||||
if(strcmp(name,"SERIAL_PRINT_GPICLK")==0)
|
||||
mac_bi_data.printgpi=atol(value);
|
||||
if(strcmp(name,"PROCESSOR")==0)
|
||||
mac_bi_data.cpuid=atol(value);
|
||||
if(strcmp(name,"ROMBASE")==0)
|
||||
mac_bi_data.rombase=atol(value);
|
||||
if(strcmp(name,"TIMEDBRA")==0)
|
||||
mac_bi_data.timedbra=atol(value);
|
||||
if(strcmp(name,"ADBDELAY")==0)
|
||||
mac_bi_data.adbdelay=atol(value);
|
||||
}
|
||||
#if 0 /* XXX: TODO with m68k_mach_* */
|
||||
/* Fill in the base stuff */
|
||||
boot_info.machtype=MACH_MAC;
|
||||
/* Read this from the macinfo we got ! */
|
||||
/* boot_info.cputype=CPU_68020|FPUB_68881;*/
|
||||
/* boot_info.memory[0].addr=0;*/
|
||||
/* boot_info.memory[0].size=((mac_bi_data.id>>7)&31)<<20;*/
|
||||
boot_info.num_memory=1; /* On a MacII */
|
||||
boot_info.ramdisk_size=0; /* For now */
|
||||
*boot_info.command_line=0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void print_booter(char *env)
|
||||
{
|
||||
char *name;
|
||||
char *value;
|
||||
while(*env)
|
||||
{
|
||||
name=env;
|
||||
value=name;
|
||||
while(*value!='='&&*value)
|
||||
value++;
|
||||
if(*value=='=')
|
||||
*value++=0;
|
||||
env=value;
|
||||
while(*env)
|
||||
env++;
|
||||
env++;
|
||||
printk("%s=%s\n", name,value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +46,6 @@
|
|||
/* Mac bootinfo struct */
|
||||
|
||||
struct mac_booter_data mac_bi_data;
|
||||
int mac_bisize = sizeof mac_bi_data;
|
||||
|
||||
/* New m68k bootinfo stuff and videobase */
|
||||
|
||||
|
@ -55,10 +54,8 @@ extern struct mem_info m68k_memory[NUM_MEMINFO];
|
|||
|
||||
extern struct mem_info m68k_ramdisk;
|
||||
|
||||
void *mac_env; /* Loaded by the boot asm */
|
||||
|
||||
/* The phys. video addr. - might be bogus on some machines */
|
||||
unsigned long mac_orig_videoaddr;
|
||||
static unsigned long mac_orig_videoaddr;
|
||||
|
||||
/* Mac specific timer functions */
|
||||
extern unsigned long mac_gettimeoffset(void);
|
||||
|
@ -79,6 +76,8 @@ extern void mac_mksound(unsigned int, unsigned int);
|
|||
extern void nubus_sweep_video(void);
|
||||
|
||||
static void mac_get_model(char *str);
|
||||
static void mac_identify(void);
|
||||
static void mac_report_hardware(void);
|
||||
|
||||
static void __init mac_sched_init(irq_handler_t vector)
|
||||
{
|
||||
|
@ -765,7 +764,7 @@ static struct mac_model mac_data_table[] = {
|
|||
}
|
||||
};
|
||||
|
||||
void __init mac_identify(void)
|
||||
static void __init mac_identify(void)
|
||||
{
|
||||
struct mac_model *m;
|
||||
|
||||
|
@ -821,7 +820,7 @@ void __init mac_identify(void)
|
|||
baboon_init();
|
||||
}
|
||||
|
||||
void __init mac_report_hardware(void)
|
||||
static void __init mac_report_hardware(void)
|
||||
{
|
||||
printk(KERN_INFO "Apple Macintosh %s\n", macintosh_config->name);
|
||||
}
|
||||
|
|
|
@ -51,6 +51,8 @@ extern void mac_serial_print(const char *);
|
|||
static int peng, line;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
void mac_debugging_short(int pos, short num)
|
||||
{
|
||||
#ifdef DEBUG_SCREEN
|
||||
|
@ -125,6 +127,8 @@ void mac_debugging_long(int pos, long addr)
|
|||
#endif
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
#ifdef DEBUG_SERIAL
|
||||
/*
|
||||
* TODO: serial debug code
|
||||
|
@ -142,12 +146,6 @@ struct mac_SCC {
|
|||
|
||||
# define scc (*((volatile struct mac_SCC*)mac_bi_data.sccbase))
|
||||
|
||||
/* Flag that serial port is already initialized and used */
|
||||
int mac_SCC_init_done;
|
||||
/* Can be set somewhere, if a SCC master reset has already be done and should
|
||||
* not be repeated; used by kgdb */
|
||||
int mac_SCC_reset_done;
|
||||
|
||||
static int scc_port = -1;
|
||||
|
||||
static struct console mac_console_driver = {
|
||||
|
@ -171,8 +169,8 @@ static struct console mac_console_driver = {
|
|||
* this driver if Mac.
|
||||
*/
|
||||
|
||||
void mac_debug_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
static void mac_debug_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
{
|
||||
mac_serial_print(str);
|
||||
}
|
||||
|
@ -209,8 +207,8 @@ static inline void mac_scca_out(char c)
|
|||
scc.cha_a_data = c;
|
||||
}
|
||||
|
||||
void mac_sccb_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
static void mac_sccb_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
{
|
||||
while (count--) {
|
||||
if (*str == '\n')
|
||||
|
@ -219,8 +217,8 @@ void mac_sccb_console_write(struct console *co, const char *str,
|
|||
}
|
||||
}
|
||||
|
||||
void mac_scca_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
static void mac_scca_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
{
|
||||
while (count--) {
|
||||
if (*str == '\n')
|
||||
|
@ -265,14 +263,8 @@ void mac_scca_console_write(struct console *co, const char *str,
|
|||
barrier(); \
|
||||
} while(0)
|
||||
|
||||
#ifndef CONFIG_SERIAL_CONSOLE
|
||||
static void __init mac_init_scc_port(int cflag, int port)
|
||||
#else
|
||||
void mac_init_scc_port(int cflag, int port)
|
||||
#endif
|
||||
{
|
||||
extern int mac_SCC_reset_done;
|
||||
|
||||
/*
|
||||
* baud rates: 1200, 1800, 2400, 4800, 9600, 19.2k, 38.4k, 57.6k, 115.2k
|
||||
*/
|
||||
|
@ -340,22 +332,9 @@ void mac_init_scc_port(int cflag, int port)
|
|||
SCCA_WRITE(3, reg3 | 1);
|
||||
SCCA_WRITE(5, reg5 | 8);
|
||||
}
|
||||
|
||||
mac_SCC_reset_done = 1;
|
||||
mac_SCC_init_done = 1;
|
||||
}
|
||||
#endif /* DEBUG_SERIAL */
|
||||
|
||||
void mac_init_scca_port(int cflag)
|
||||
{
|
||||
mac_init_scc_port(cflag, 0);
|
||||
}
|
||||
|
||||
void mac_init_sccb_port(int cflag)
|
||||
{
|
||||
mac_init_scc_port(cflag, 1);
|
||||
}
|
||||
|
||||
static int __init mac_debug_setup(char *arg)
|
||||
{
|
||||
if (!MACH_IS_MAC)
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
int oss_present;
|
||||
volatile struct mac_oss *oss;
|
||||
|
||||
irqreturn_t oss_irq(int, void *);
|
||||
irqreturn_t oss_nubus_irq(int, void *);
|
||||
static irqreturn_t oss_irq(int, void *);
|
||||
static irqreturn_t oss_nubus_irq(int, void *);
|
||||
|
||||
extern irqreturn_t via1_irq(int, void *);
|
||||
extern irqreturn_t mac_scc_dispatch(int, void *);
|
||||
|
@ -92,7 +92,7 @@ void __init oss_nubus_init(void)
|
|||
* and SCSI; everything else is routed to its own autovector IRQ.
|
||||
*/
|
||||
|
||||
irqreturn_t oss_irq(int irq, void *dev_id)
|
||||
static irqreturn_t oss_irq(int irq, void *dev_id)
|
||||
{
|
||||
int events;
|
||||
|
||||
|
@ -126,7 +126,7 @@ irqreturn_t oss_irq(int irq, void *dev_id)
|
|||
* Unlike the VIA/RBV this is on its own autovector interrupt level.
|
||||
*/
|
||||
|
||||
irqreturn_t oss_nubus_irq(int irq, void *dev_id)
|
||||
static irqreturn_t oss_nubus_irq(int irq, void *dev_id)
|
||||
{
|
||||
int events, irq_bit, i;
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ irqreturn_t psc_irq(int, void *);
|
|||
* Debugging dump, used in various places to see what's going on.
|
||||
*/
|
||||
|
||||
void psc_debug_dump(void)
|
||||
static void psc_debug_dump(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -55,7 +55,7 @@ void psc_debug_dump(void)
|
|||
* expanded to cover what I think are the other 7 channels.
|
||||
*/
|
||||
|
||||
void psc_dma_die_die_die(void)
|
||||
static void psc_dma_die_die_die(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ volatile long *via_memory_bogon=(long *)&via_memory_bogon;
|
|||
int rbv_present;
|
||||
int via_alt_mapping;
|
||||
EXPORT_SYMBOL(via_alt_mapping);
|
||||
__u8 rbv_clear;
|
||||
static __u8 rbv_clear;
|
||||
|
||||
/*
|
||||
* Globals for accessing the VIA chip registers without having to
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
# Makefile for the linux kernel.
|
||||
#
|
||||
|
||||
EXTRA_AFLAGS := -traditional
|
||||
|
||||
#EXTRA_AFLAGS += -DFPU_EMU_DEBUG
|
||||
#EXTRA_CFLAGS += -DFPU_EMU_DEBUG
|
||||
|
||||
|
|
|
@ -285,7 +285,6 @@ void __init paging_init(void)
|
|||
* to a couple of allocated pages
|
||||
*/
|
||||
empty_zero_page = alloc_bootmem_pages(PAGE_SIZE);
|
||||
memset(empty_zero_page, 0, PAGE_SIZE);
|
||||
|
||||
/*
|
||||
* Set up SFC/DFC registers
|
||||
|
|
|
@ -53,7 +53,6 @@ void __init paging_init(void)
|
|||
wp_works_ok = 0;
|
||||
#endif
|
||||
empty_zero_page = alloc_bootmem_pages(PAGE_SIZE);
|
||||
memset(empty_zero_page, 0, PAGE_SIZE);
|
||||
|
||||
address = PAGE_OFFSET;
|
||||
pg_dir = swapper_pg_dir;
|
||||
|
|
|
@ -41,14 +41,12 @@ static void q40_get_model(char *model);
|
|||
static int q40_get_hardware_list(char *buffer);
|
||||
extern void q40_sched_init(irq_handler_t handler);
|
||||
|
||||
extern unsigned long q40_gettimeoffset(void);
|
||||
extern int q40_hwclk(int, struct rtc_time *);
|
||||
extern unsigned int q40_get_ss(void);
|
||||
extern int q40_set_clock_mmss(unsigned long);
|
||||
static unsigned long q40_gettimeoffset(void);
|
||||
static int q40_hwclk(int, struct rtc_time *);
|
||||
static unsigned int q40_get_ss(void);
|
||||
static int q40_set_clock_mmss(unsigned long);
|
||||
static int q40_get_rtc_pll(struct rtc_pll_info *pll);
|
||||
static int q40_set_rtc_pll(struct rtc_pll_info *pll);
|
||||
extern void q40_reset(void);
|
||||
void q40_halt(void);
|
||||
extern void q40_waitbut(void);
|
||||
void q40_set_vectors(void);
|
||||
|
||||
|
@ -127,7 +125,7 @@ static void q40_heartbeat(int on)
|
|||
}
|
||||
#endif
|
||||
|
||||
void q40_reset(void)
|
||||
static void q40_reset(void)
|
||||
{
|
||||
halted = 1;
|
||||
printk("\n\n*******************************************\n"
|
||||
|
@ -137,7 +135,8 @@ void q40_reset(void)
|
|||
while (1)
|
||||
;
|
||||
}
|
||||
void q40_halt(void)
|
||||
|
||||
static void q40_halt(void)
|
||||
{
|
||||
halted = 1;
|
||||
printk("\n\n*******************\n"
|
||||
|
@ -165,7 +164,8 @@ static unsigned int serports[] =
|
|||
{
|
||||
0x3f8,0x2f8,0x3e8,0x2e8,0
|
||||
};
|
||||
void q40_disable_irqs(void)
|
||||
|
||||
static void q40_disable_irqs(void)
|
||||
{
|
||||
unsigned i, j;
|
||||
|
||||
|
@ -227,7 +227,7 @@ static inline unsigned char bin2bcd(unsigned char b)
|
|||
}
|
||||
|
||||
|
||||
unsigned long q40_gettimeoffset(void)
|
||||
static unsigned long q40_gettimeoffset(void)
|
||||
{
|
||||
return 5000 * (ql_ticks != 0);
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ unsigned long q40_gettimeoffset(void)
|
|||
* };
|
||||
*/
|
||||
|
||||
int q40_hwclk(int op, struct rtc_time *t)
|
||||
static int q40_hwclk(int op, struct rtc_time *t)
|
||||
{
|
||||
if (op) {
|
||||
/* Write.... */
|
||||
|
@ -285,7 +285,7 @@ int q40_hwclk(int op, struct rtc_time *t)
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned int q40_get_ss(void)
|
||||
static unsigned int q40_get_ss(void)
|
||||
{
|
||||
return bcd2bin(Q40_RTC_SECS);
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ unsigned int q40_get_ss(void)
|
|||
* clock is out by > 30 minutes. Logic lifted from atari code.
|
||||
*/
|
||||
|
||||
int q40_set_clock_mmss(unsigned long nowtime)
|
||||
static int q40_set_clock_mmss(unsigned long nowtime)
|
||||
{
|
||||
int retval = 0;
|
||||
short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
# Makefile for Linux arch/m68k/sun3 source directory
|
||||
#
|
||||
|
||||
obj-y := sun3ints.o sun3dvma.o sbus.o idprom.o
|
||||
obj-y := sun3ints.o sun3dvma.o idprom.o
|
||||
|
||||
obj-$(CONFIG_SUN3) += config.o mmu_emu.o leds.o dvma.o intersil.o
|
||||
|
|
|
@ -36,7 +36,7 @@ extern char _text, _end;
|
|||
char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
|
||||
|
||||
extern unsigned long sun3_gettimeoffset(void);
|
||||
extern void sun3_sched_init(irq_handler_t handler);
|
||||
static void sun3_sched_init(irq_handler_t handler);
|
||||
extern void sun3_get_model (char* model);
|
||||
extern void idprom_init (void);
|
||||
extern int sun3_hwclk(int set, struct rtc_time *t);
|
||||
|
@ -114,7 +114,8 @@ static void sun3_halt (void)
|
|||
|
||||
/* sun3 bootmem allocation */
|
||||
|
||||
void __init sun3_bootmem_alloc(unsigned long memory_start, unsigned long memory_end)
|
||||
static void __init sun3_bootmem_alloc(unsigned long memory_start,
|
||||
unsigned long memory_end)
|
||||
{
|
||||
unsigned long start_page;
|
||||
|
||||
|
@ -164,7 +165,7 @@ void __init config_sun3(void)
|
|||
sun3_bootmem_alloc(memory_start, memory_end);
|
||||
}
|
||||
|
||||
void __init sun3_sched_init(irq_handler_t timer_routine)
|
||||
static void __init sun3_sched_init(irq_handler_t timer_routine)
|
||||
{
|
||||
sun3_disable_interrupts();
|
||||
intersil_clock->cmd_reg=(INTERSIL_RUN|INTERSIL_INT_DISABLE|INTERSIL_24H_MODE);
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче