Auto merge with /home/aegl/GIT/linus
This commit is contained in:
Коммит
88c3cdfdde
|
@ -13,14 +13,17 @@ different way: With the help of a dvb-usb-framework.
|
||||||
The framework provides generic functions (mostly kernel API calls), such as:
|
The framework provides generic functions (mostly kernel API calls), such as:
|
||||||
|
|
||||||
- Transport Stream URB handling in conjunction with dvb-demux-feed-control
|
- Transport Stream URB handling in conjunction with dvb-demux-feed-control
|
||||||
(bulk and isoc (TODO) are supported)
|
(bulk and isoc are supported)
|
||||||
- registering the device for the DVB-API
|
- registering the device for the DVB-API
|
||||||
- registering an I2C-adapter if applicable
|
- registering an I2C-adapter if applicable
|
||||||
- remote-control/input-device handling
|
- remote-control/input-device handling
|
||||||
- firmware requesting and loading (currently just for the Cypress USB
|
- firmware requesting and loading (currently just for the Cypress USB
|
||||||
controller)
|
controllers)
|
||||||
- other functions/methods which can be shared by several drivers (such as
|
- other functions/methods which can be shared by several drivers (such as
|
||||||
functions for bulk-control-commands)
|
functions for bulk-control-commands)
|
||||||
|
- TODO: a I2C-chunker. It creates device-specific chunks of register-accesses
|
||||||
|
depending on length of a register and the number of values that can be
|
||||||
|
multi-written and multi-read.
|
||||||
|
|
||||||
The source code of the particular DVB USB devices does just the communication
|
The source code of the particular DVB USB devices does just the communication
|
||||||
with the device via the bus. The connection between the DVB-API-functionality
|
with the device via the bus. The connection between the DVB-API-functionality
|
||||||
|
@ -36,93 +39,18 @@ the dvb-usb-lib.
|
||||||
TODO: dynamic enabling and disabling of the pid-filter in regard to number of
|
TODO: dynamic enabling and disabling of the pid-filter in regard to number of
|
||||||
feeds requested.
|
feeds requested.
|
||||||
|
|
||||||
Supported devices USB1.1
|
Supported devices
|
||||||
========================
|
========================
|
||||||
|
|
||||||
Produced and reselled by Twinhan:
|
See the LinuxTV DVB Wiki at www.linuxtv.org for a complete list of
|
||||||
---------------------------------
|
cards/drivers/firmwares:
|
||||||
- TwinhanDTV USB-Ter DVB-T Device (VP7041)
|
|
||||||
http://www.twinhan.com/product_terrestrial_3.asp
|
|
||||||
|
|
||||||
- TwinhanDTV Magic Box (VP7041e)
|
http://www.linuxtv.org/wiki/index.php/DVB_USB
|
||||||
http://www.twinhan.com/product_terrestrial_4.asp
|
|
||||||
|
|
||||||
- HAMA DVB-T USB device
|
|
||||||
http://www.hama.de/portal/articleId*110620/action*2598
|
|
||||||
|
|
||||||
- CTS Portable (Chinese Television System) (2)
|
|
||||||
http://www.2cts.tv/ctsportable/
|
|
||||||
|
|
||||||
- Unknown USB DVB-T device with vendor ID Hyper-Paltek
|
|
||||||
|
|
||||||
|
|
||||||
Produced and reselled by KWorld:
|
|
||||||
--------------------------------
|
|
||||||
- KWorld V-Stream XPERT DTV DVB-T USB
|
|
||||||
http://www.kworld.com.tw/en/product/DVBT-USB/DVBT-USB.html
|
|
||||||
|
|
||||||
- JetWay DTV DVB-T USB
|
|
||||||
http://www.jetway.com.tw/evisn/product/lcd-tv/DVT-USB/dtv-usb.htm
|
|
||||||
|
|
||||||
- ADSTech Instant TV DVB-T USB
|
|
||||||
http://www.adstech.com/products/PTV-333/intro/PTV-333_intro.asp?pid=PTV-333
|
|
||||||
|
|
||||||
|
|
||||||
Others:
|
|
||||||
-------
|
|
||||||
- Ultima Electronic/Artec T1 USB TVBOX (AN2135, AN2235, AN2235 with Panasonic Tuner)
|
|
||||||
http://82.161.246.249/products-tvbox.html
|
|
||||||
|
|
||||||
- Compro Videomate DVB-U2000 - DVB-T USB (2)
|
|
||||||
http://www.comprousa.com/products/vmu2000.htm
|
|
||||||
|
|
||||||
- Grandtec USB DVB-T
|
|
||||||
http://www.grand.com.tw/
|
|
||||||
|
|
||||||
- AVerMedia AverTV DVBT USB
|
|
||||||
http://www.avermedia.com/
|
|
||||||
|
|
||||||
- DiBcom USB DVB-T reference device (non-public)
|
|
||||||
|
|
||||||
|
|
||||||
Supported devices USB2.0-only
|
|
||||||
=============================
|
|
||||||
- Twinhan MagicBox II
|
|
||||||
http://www.twinhan.com/product_terrestrial_7.asp
|
|
||||||
|
|
||||||
- TwinhanDTV Alpha
|
|
||||||
http://www.twinhan.com/product_terrestrial_8.asp
|
|
||||||
|
|
||||||
- DigitalNow TinyUSB 2 DVB-t Receiver
|
|
||||||
http://www.digitalnow.com.au/DigitalNow%20tinyUSB2%20Specifications.html
|
|
||||||
|
|
||||||
- Hanftek UMT-010
|
|
||||||
http://www.globalsources.com/si/6008819757082/ProductDetail/Digital-TV/product_id-100046529
|
|
||||||
|
|
||||||
|
|
||||||
Supported devices USB2.0 and USB1.1
|
|
||||||
=============================
|
|
||||||
- Typhoon/Yakumo/HAMA/Yuan DVB-T mobile USB2.0
|
|
||||||
http://www.yakumo.de/produkte/index.php?pid=1&ag=DVB-T
|
|
||||||
http://www.yuan.com.tw/en/products/vdo_ub300.html
|
|
||||||
http://www.hama.de/portal/articleId*114663/action*2563
|
|
||||||
http://www.anubisline.com/english/articlec.asp?id=50502&catid=002
|
|
||||||
|
|
||||||
- Artec T1 USB TVBOX (FX2) (2)
|
|
||||||
|
|
||||||
- Hauppauge WinTV NOVA-T USB2
|
|
||||||
http://www.hauppauge.com/
|
|
||||||
|
|
||||||
- KWorld/ADSTech Instant DVB-T USB2.0 (DiB3000M-B)
|
|
||||||
|
|
||||||
- DiBcom USB2.0 DVB-T reference device (non-public)
|
|
||||||
|
|
||||||
- AVerMedia AverTV A800 DVB-T USB2.0
|
|
||||||
|
|
||||||
1) It is working almost - work-in-progress.
|
|
||||||
2) No test reports received yet.
|
|
||||||
|
|
||||||
0. History & News:
|
0. History & News:
|
||||||
|
2005-06-30 - added support for WideView WT-220U (Thanks to Steve Chang)
|
||||||
|
2005-05-30 - added basic isochronous support to the dvb-usb-framework
|
||||||
|
added support for Conexant Hybrid reference design and Nebula DigiTV USB
|
||||||
2005-04-17 - all dibusb devices ported to make use of the dvb-usb-framework
|
2005-04-17 - all dibusb devices ported to make use of the dvb-usb-framework
|
||||||
2005-04-02 - re-enabled and improved remote control code.
|
2005-04-02 - re-enabled and improved remote control code.
|
||||||
2005-03-31 - ported the Yakumo/Hama/Typhoon DVB-T USB2.0 device to dvb-usb.
|
2005-03-31 - ported the Yakumo/Hama/Typhoon DVB-T USB2.0 device to dvb-usb.
|
||||||
|
@ -137,7 +65,7 @@ Supported devices USB2.0 and USB1.1
|
||||||
2005-01-31 - distorted streaming is gone for USB1.1 devices
|
2005-01-31 - distorted streaming is gone for USB1.1 devices
|
||||||
2005-01-13 - moved the mirrored pid_filter_table back to dvb-dibusb
|
2005-01-13 - moved the mirrored pid_filter_table back to dvb-dibusb
|
||||||
- first almost working version for HanfTek UMT-010
|
- first almost working version for HanfTek UMT-010
|
||||||
- found out, that Yakumo/HAMA/Typhoon are predessors of the HanfTek UMT-010
|
- found out, that Yakumo/HAMA/Typhoon are predecessors of the HanfTek UMT-010
|
||||||
2005-01-10 - refactoring completed, now everything is very delightful
|
2005-01-10 - refactoring completed, now everything is very delightful
|
||||||
- tuner quirks for some weird devices (Artec T1 AN2235 device has sometimes a
|
- tuner quirks for some weird devices (Artec T1 AN2235 device has sometimes a
|
||||||
Panasonic Tuner assembled). Tunerprobing implemented. Thanks a lot to Gunnar Wittich.
|
Panasonic Tuner assembled). Tunerprobing implemented. Thanks a lot to Gunnar Wittich.
|
||||||
|
@ -187,25 +115,13 @@ Supported devices USB2.0 and USB1.1
|
||||||
1. How to use?
|
1. How to use?
|
||||||
1.1. Firmware
|
1.1. Firmware
|
||||||
|
|
||||||
Most of the USB drivers need to download a firmware to start working.
|
Most of the USB drivers need to download a firmware to the device before start
|
||||||
|
working.
|
||||||
|
|
||||||
for USB1.1 (AN2135) you need: dvb-usb-dibusb-5.0.0.11.fw
|
Have a look at the Wikipage for the DVB-USB-drivers to find out, which firmware
|
||||||
for USB2.0 HanfTek: dvb-usb-umt-010-02.fw
|
you need for your device:
|
||||||
for USB2.0 DiBcom: dvb-usb-dibusb-6.0.0.8.fw
|
|
||||||
for USB2.0 AVerMedia AverTV DVB-T USB2: dvb-usb-avertv-a800-01.fw
|
|
||||||
for USB2.0 TwinhanDTV Alpha/MagicBox II: dvb-usb-vp7045-01.fw
|
|
||||||
|
|
||||||
The files can be found on http://www.linuxtv.org/download/firmware/ .
|
http://www.linuxtv.org/wiki/index.php/DVB_USB
|
||||||
|
|
||||||
We do not have the permission (yet) to publish the following firmware-files.
|
|
||||||
You'll need to extract them from the windows drivers.
|
|
||||||
|
|
||||||
You should be able to use "get_dvb_firmware dvb-usb" to get the firmware:
|
|
||||||
|
|
||||||
for USB1.1 (AN2235) (a few Artec T1 devices): dvb-usb-dibusb-an2235-01.fw
|
|
||||||
for USB2.0 Hauppauge: dvb-usb-nova-t-usb2-01.fw
|
|
||||||
for USB2.0 ADSTech/Kworld USB2.0: dvb-usb-adstech-usb2-01.fw
|
|
||||||
for USB2.0 Yakumo/Typhoon/Hama: dvb-usb-dtt200u-01.fw
|
|
||||||
|
|
||||||
1.2. Compiling
|
1.2. Compiling
|
||||||
|
|
||||||
|
@ -289,6 +205,9 @@ Patches, comments and suggestions are very very welcome.
|
||||||
Gunnar Wittich and Joachim von Caron for their trust for providing
|
Gunnar Wittich and Joachim von Caron for their trust for providing
|
||||||
root-shells on their machines to implement support for new devices.
|
root-shells on their machines to implement support for new devices.
|
||||||
|
|
||||||
|
Allan Third and Michael Hutchinson for their help to write the Nebula
|
||||||
|
digitv-driver.
|
||||||
|
|
||||||
Glen Harris for bringing up, that there is a new dibusb-device and Jiun-Kuei
|
Glen Harris for bringing up, that there is a new dibusb-device and Jiun-Kuei
|
||||||
Jung from AVerMedia who kindly provided a special firmware to get the device
|
Jung from AVerMedia who kindly provided a special firmware to get the device
|
||||||
up and running in Linux.
|
up and running in Linux.
|
||||||
|
@ -296,7 +215,12 @@ Patches, comments and suggestions are very very welcome.
|
||||||
Jennifer Chen, Jeff and Jack from Twinhan for kindly supporting by
|
Jennifer Chen, Jeff and Jack from Twinhan for kindly supporting by
|
||||||
writing the vp7045-driver.
|
writing the vp7045-driver.
|
||||||
|
|
||||||
Some guys on the linux-dvb mailing list for encouraging me
|
Steve Chang from WideView for providing information for new devices and
|
||||||
|
firmware files.
|
||||||
|
|
||||||
|
Michael Paxton for submitting remote control keymaps.
|
||||||
|
|
||||||
|
Some guys on the linux-dvb mailing list for encouraging me.
|
||||||
|
|
||||||
Peter Schildmann >peter.schildmann-nospam-at-web.de< for his
|
Peter Schildmann >peter.schildmann-nospam-at-web.de< for his
|
||||||
user-level firmware loader, which saves a lot of time
|
user-level firmware loader, which saves a lot of time
|
||||||
|
@ -305,4 +229,4 @@ Patches, comments and suggestions are very very welcome.
|
||||||
Ulf Hermenau for helping me out with traditional chinese.
|
Ulf Hermenau for helping me out with traditional chinese.
|
||||||
|
|
||||||
André Smoktun and Christian Frömmel for supporting me with
|
André Smoktun and Christian Frömmel for supporting me with
|
||||||
hardware and listening to my problems very patient.
|
hardware and listening to my problems very patiently.
|
||||||
|
|
|
@ -1,66 +1,55 @@
|
||||||
How to get the Nebula, PCTV and Twinhan DST cards working
|
How to get the Nebula Electronics DigiTV, Pinnacle PCTV Sat, Twinhan DST + clones working
|
||||||
=========================================================
|
=========================================================================================
|
||||||
|
|
||||||
This class of cards has a bt878a as the PCI interface, and
|
1) General information
|
||||||
require the bttv driver.
|
======================
|
||||||
|
|
||||||
Please pay close attention to the warning about the bttv module
|
This class of cards has a bt878a chip as the PCI interface.
|
||||||
options below for the DST card.
|
The different card drivers require the bttv driver to provide the means
|
||||||
|
to access the i2c bus and the gpio pins of the bt8xx chipset.
|
||||||
|
|
||||||
1) General informations
|
2) Compilation rules for Kernel >= 2.6.12
|
||||||
=======================
|
=========================================
|
||||||
|
|
||||||
These drivers require the bttv driver to provide the means to access
|
Enable the following options:
|
||||||
the i2c bus and the gpio pins of the bt8xx chipset.
|
|
||||||
|
|
||||||
Because of this, you need to enable
|
|
||||||
"Device drivers" => "Multimedia devices"
|
"Device drivers" => "Multimedia devices"
|
||||||
=> "Video For Linux" => "BT848 Video For Linux"
|
=> "Video For Linux" => "BT848 Video For Linux"
|
||||||
|
|
||||||
Furthermore you need to enable
|
|
||||||
"Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices"
|
"Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices"
|
||||||
=> "DVB for Linux" "DVB Core Support" "Nebula/Pinnacle PCTV/TwinHan PCI Cards"
|
=> "DVB for Linux" "DVB Core Support" "Nebula/Pinnacle PCTV/TwinHan PCI Cards"
|
||||||
|
|
||||||
2) Loading Modules
|
3) Loading Modules, described by two approaches
|
||||||
==================
|
===============================================
|
||||||
|
|
||||||
In general you need to load the bttv driver, which will handle the gpio and
|
In general you need to load the bttv driver, which will handle the gpio and
|
||||||
i2c communication for us, plus the common dvb-bt8xx device driver.
|
i2c communication for us, plus the common dvb-bt8xx device driver,
|
||||||
The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110) and
|
which is called the backend.
|
||||||
TwinHan (dst) are loaded automatically by the dvb-bt8xx device driver.
|
The frontends for Nebula DigiTV (nxt6000), Pinnacle PCTV Sat (cx24110),
|
||||||
|
TwinHan DST + clones (dst and dst-ca) are loaded automatically by the backend.
|
||||||
|
For further details about TwinHan DST + clones see /Documentation/dvb/ci.txt.
|
||||||
|
|
||||||
3a) Nebula / Pinnacle PCTV
|
3a) The manual approach
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Loading modules:
|
||||||
|
modprobe bttv
|
||||||
|
modprobe dvb-bt8xx
|
||||||
|
|
||||||
|
Unloading modules:
|
||||||
|
modprobe -r dvb-bt8xx
|
||||||
|
modprobe -r bttv
|
||||||
|
|
||||||
|
3b) The automatic approach
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
$ modprobe bttv (normally bttv is being loaded automatically by kmod)
|
If not already done by installation, place a line either in
|
||||||
$ modprobe dvb-bt8xx (or just place dvb-bt8xx in /etc/modules for automatic loading)
|
/etc/modules.conf or in /etc/modprobe.conf containing this text:
|
||||||
|
alias char-major-81 bttv
|
||||||
|
|
||||||
|
Then place a line in /etc/modules containing this text:
|
||||||
|
dvb-bt8xx
|
||||||
|
|
||||||
3b) TwinHan and Clones
|
Reboot your system and have fun!
|
||||||
--------------------------
|
|
||||||
|
|
||||||
$ modprobe bttv i2c_hw=1 card=0x71
|
|
||||||
$ modprobe dvb-bt8xx
|
|
||||||
$ modprobe dst
|
|
||||||
|
|
||||||
The value 0x71 will override the PCI type detection for dvb-bt8xx,
|
|
||||||
which is necessary for TwinHan cards.
|
|
||||||
|
|
||||||
If you're having an older card (blue color circuit) and card=0x71 locks
|
|
||||||
your machine, try using 0x68, too. If that does not work, ask on the
|
|
||||||
mailing list.
|
|
||||||
|
|
||||||
The DST module takes a couple of useful parameters:
|
|
||||||
|
|
||||||
a. verbose takes values 0 to 5. These values control the verbosity level.
|
|
||||||
b. debug takes values 0 and 1. You can either disable or enable debugging.
|
|
||||||
c. dst_addons takes values 0 and 0x20:
|
|
||||||
- A value of 0 means it is a FTA card.
|
|
||||||
- A value of 0x20 means it has a Conditional Access slot.
|
|
||||||
|
|
||||||
The autodetected values are determined by the "response string"
|
|
||||||
of the card, which you can see in your logs:
|
|
||||||
e.g.: dst_get_device_id: Recognize [DSTMCI]
|
|
||||||
|
|
||||||
--
|
--
|
||||||
Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham, Uwe Bugla
|
Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham, Uwe Bugla
|
||||||
|
|
|
@ -119,3 +119,19 @@ Why: Match the other drivers' name for the same function, duplicate names
|
||||||
will be available until removal of old names.
|
will be available until removal of old names.
|
||||||
Who: Grant Coady <gcoady@gmail.com>
|
Who: Grant Coady <gcoady@gmail.com>
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl])
|
||||||
|
When: November 2005
|
||||||
|
Files: drivers/pcmcia/: pcmcia_ioctl.c
|
||||||
|
Why: With the 16-bit PCMCIA subsystem now behaving (almost) like a
|
||||||
|
normal hotpluggable bus, and with it using the default kernel
|
||||||
|
infrastructure (hotplug, driver core, sysfs) keeping the PCMCIA
|
||||||
|
control ioctl needed by cardmgr and cardctl from pcmcia-cs is
|
||||||
|
unnecessary, and makes further cleanups and integration of the
|
||||||
|
PCMCIA subsystem into the Linux kernel device driver model more
|
||||||
|
difficult. The features provided by cardmgr and cardctl are either
|
||||||
|
handled by the kernel itself now or are available in the new
|
||||||
|
pcmciautils package available at
|
||||||
|
http://kernel.org/pub/linux/utils/kernel/pcmcia/
|
||||||
|
Who: Dominik Brodowski <linux@brodo.de>
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
USERSPACE VERBS ACCESS
|
||||||
|
|
||||||
|
The ib_uverbs module, built by enabling CONFIG_INFINIBAND_USER_VERBS,
|
||||||
|
enables direct userspace access to IB hardware via "verbs," as
|
||||||
|
described in chapter 11 of the InfiniBand Architecture Specification.
|
||||||
|
|
||||||
|
To use the verbs, the libibverbs library, available from
|
||||||
|
<http://openib.org/>, is required. libibverbs contains a
|
||||||
|
device-independent API for using the ib_uverbs interface.
|
||||||
|
libibverbs also requires appropriate device-dependent kernel and
|
||||||
|
userspace driver for your InfiniBand hardware. For example, to use
|
||||||
|
a Mellanox HCA, you will need the ib_mthca kernel module and the
|
||||||
|
libmthca userspace driver be installed.
|
||||||
|
|
||||||
|
User-kernel communication
|
||||||
|
|
||||||
|
Userspace communicates with the kernel for slow path, resource
|
||||||
|
management operations via the /dev/infiniband/uverbsN character
|
||||||
|
devices. Fast path operations are typically performed by writing
|
||||||
|
directly to hardware registers mmap()ed into userspace, with no
|
||||||
|
system call or context switch into the kernel.
|
||||||
|
|
||||||
|
Commands are sent to the kernel via write()s on these device files.
|
||||||
|
The ABI is defined in drivers/infiniband/include/ib_user_verbs.h.
|
||||||
|
The structs for commands that require a response from the kernel
|
||||||
|
contain a 64-bit field used to pass a pointer to an output buffer.
|
||||||
|
Status is returned to userspace as the return value of the write()
|
||||||
|
system call.
|
||||||
|
|
||||||
|
Resource management
|
||||||
|
|
||||||
|
Since creation and destruction of all IB resources is done by
|
||||||
|
commands passed through a file descriptor, the kernel can keep track
|
||||||
|
of which resources are attached to a given userspace context. The
|
||||||
|
ib_uverbs module maintains idr tables that are used to translate
|
||||||
|
between kernel pointers and opaque userspace handles, so that kernel
|
||||||
|
pointers are never exposed to userspace and userspace cannot trick
|
||||||
|
the kernel into following a bogus pointer.
|
||||||
|
|
||||||
|
This also allows the kernel to clean up when a process exits and
|
||||||
|
prevent one process from touching another process's resources.
|
||||||
|
|
||||||
|
Memory pinning
|
||||||
|
|
||||||
|
Direct userspace I/O requires that memory regions that are potential
|
||||||
|
I/O targets be kept resident at the same physical address. The
|
||||||
|
ib_uverbs module manages pinning and unpinning memory regions via
|
||||||
|
get_user_pages() and put_page() calls. It also accounts for the
|
||||||
|
amount of memory pinned in the process's locked_vm, and checks that
|
||||||
|
unprivileged processes do not exceed their RLIMIT_MEMLOCK limit.
|
||||||
|
|
||||||
|
Pages that are pinned multiple times are counted each time they are
|
||||||
|
pinned, so the value of locked_vm may be an overestimate of the
|
||||||
|
number of pages pinned by a process.
|
||||||
|
|
||||||
|
/dev files
|
||||||
|
|
||||||
|
To create the appropriate character device files automatically with
|
||||||
|
udev, a rule like
|
||||||
|
|
||||||
|
KERNEL="uverbs*", NAME="infiniband/%k"
|
||||||
|
|
||||||
|
can be used. This will create device nodes named
|
||||||
|
|
||||||
|
/dev/infiniband/uverbs0
|
||||||
|
|
||||||
|
and so on. Since the InfiniBand userspace verbs should be safe for
|
||||||
|
use by non-privileged processes, it may be useful to add an
|
||||||
|
appropriate MODE or GROUP to the udev rule.
|
|
@ -117,6 +117,7 @@ IBM Thinkpad X40 Type 2371-7JG s3_bios,s3_mode (4)
|
||||||
Medion MD4220 ??? (*)
|
Medion MD4220 ??? (*)
|
||||||
Samsung P35 vbetool needed (6)
|
Samsung P35 vbetool needed (6)
|
||||||
Sharp PC-AR10 (ATI rage) none (1)
|
Sharp PC-AR10 (ATI rage) none (1)
|
||||||
|
Sony Vaio PCG-C1VRX/K s3_bios (2)
|
||||||
Sony Vaio PCG-F403 ??? (*)
|
Sony Vaio PCG-F403 ??? (*)
|
||||||
Sony Vaio PCG-N505SN ??? (*)
|
Sony Vaio PCG-N505SN ??? (*)
|
||||||
Sony Vaio vgn-s260 X or boot-radeon can init it (5)
|
Sony Vaio vgn-s260 X or boot-radeon can init it (5)
|
||||||
|
|
|
@ -370,6 +370,10 @@ W: http://www.thekelleys.org.uk/atmel
|
||||||
W: http://atmelwlandriver.sourceforge.net/
|
W: http://atmelwlandriver.sourceforge.net/
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
AUDIT SUBSYSTEM
|
||||||
|
L: linux-audit@redhat.com (subscribers-only)
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
AX.25 NETWORK LAYER
|
AX.25 NETWORK LAYER
|
||||||
P: Ralf Baechle
|
P: Ralf Baechle
|
||||||
M: ralf@linux-mips.org
|
M: ralf@linux-mips.org
|
||||||
|
@ -1803,8 +1807,9 @@ M: greg@kroah.com
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
PCMCIA SUBSYSTEM
|
PCMCIA SUBSYSTEM
|
||||||
|
P: Linux PCMCIA Team
|
||||||
L: http://lists.infradead.org/mailman/listinfo/linux-pcmcia
|
L: http://lists.infradead.org/mailman/listinfo/linux-pcmcia
|
||||||
S: Unmaintained
|
S: Maintained
|
||||||
|
|
||||||
PCNET32 NETWORK DRIVER
|
PCNET32 NETWORK DRIVER
|
||||||
P: Thomas Bogendörfer
|
P: Thomas Bogendörfer
|
||||||
|
|
6
Makefile
6
Makefile
|
@ -792,6 +792,9 @@ export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
|
||||||
$(Q)$(MAKE) $(build)=$(@D) $@
|
$(Q)$(MAKE) $(build)=$(@D) $@
|
||||||
%.o: %.c scripts FORCE
|
%.o: %.c scripts FORCE
|
||||||
$(Q)$(MAKE) $(build)=$(@D) $@
|
$(Q)$(MAKE) $(build)=$(@D) $@
|
||||||
|
%.ko: scripts FORCE
|
||||||
|
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) $(build)=$(@D) $(@:.ko=.o)
|
||||||
|
$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost
|
||||||
%/: scripts prepare FORCE
|
%/: scripts prepare FORCE
|
||||||
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) $(build)=$(@D)
|
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) $(build)=$(@D)
|
||||||
%.lst: %.c scripts FORCE
|
%.lst: %.c scripts FORCE
|
||||||
|
@ -1033,6 +1036,7 @@ help:
|
||||||
@echo ' modules_install - Install all modules'
|
@echo ' modules_install - Install all modules'
|
||||||
@echo ' dir/ - Build all files in dir and below'
|
@echo ' dir/ - Build all files in dir and below'
|
||||||
@echo ' dir/file.[ois] - Build specified target only'
|
@echo ' dir/file.[ois] - Build specified target only'
|
||||||
|
@echo ' dir/file.ko - Build module including final link'
|
||||||
@echo ' rpm - Build a kernel as an RPM package'
|
@echo ' rpm - Build a kernel as an RPM package'
|
||||||
@echo ' tags/TAGS - Generate tags file for editors'
|
@echo ' tags/TAGS - Generate tags file for editors'
|
||||||
@echo ' cscope - Generate cscope index'
|
@echo ' cscope - Generate cscope index'
|
||||||
|
@ -1149,7 +1153,7 @@ endif # KBUILD_EXTMOD
|
||||||
#(which is the most common case IMHO) to avoid unneeded clutter in the big tags file.
|
#(which is the most common case IMHO) to avoid unneeded clutter in the big tags file.
|
||||||
#Adding $(srctree) adds about 20M on i386 to the size of the output file!
|
#Adding $(srctree) adds about 20M on i386 to the size of the output file!
|
||||||
|
|
||||||
ifeq ($(KBUILD_OUTPUT),)
|
ifeq ($(src),$(obj))
|
||||||
__srctree =
|
__srctree =
|
||||||
else
|
else
|
||||||
__srctree = $(srctree)/
|
__srctree = $(srctree)/
|
||||||
|
|
|
@ -0,0 +1,627 @@
|
||||||
|
#
|
||||||
|
# Automatically generated make config: don't edit
|
||||||
|
# Linux kernel version: 2.6.11.8
|
||||||
|
# Fri May 13 17:16:03 2005
|
||||||
|
#
|
||||||
|
CONFIG_FRV=y
|
||||||
|
CONFIG_UID16=y
|
||||||
|
CONFIG_RWSEM_GENERIC_SPINLOCK=y
|
||||||
|
CONFIG_GENERIC_FIND_NEXT_BIT=y
|
||||||
|
# CONFIG_GENERIC_CALIBRATE_DELAY is not set
|
||||||
|
# CONFIG_GENERIC_HARDIRQS is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Code maturity level options
|
||||||
|
#
|
||||||
|
CONFIG_EXPERIMENTAL=y
|
||||||
|
CONFIG_CLEAN_COMPILE=y
|
||||||
|
CONFIG_BROKEN_ON_SMP=y
|
||||||
|
CONFIG_INIT_ENV_ARG_LIMIT=32
|
||||||
|
|
||||||
|
#
|
||||||
|
# General setup
|
||||||
|
#
|
||||||
|
CONFIG_LOCALVERSION=""
|
||||||
|
CONFIG_SWAP=y
|
||||||
|
CONFIG_SYSVIPC=y
|
||||||
|
CONFIG_POSIX_MQUEUE=y
|
||||||
|
# CONFIG_BSD_PROCESS_ACCT is not set
|
||||||
|
CONFIG_SYSCTL=y
|
||||||
|
# CONFIG_AUDIT is not set
|
||||||
|
# CONFIG_HOTPLUG is not set
|
||||||
|
# CONFIG_KOBJECT_UEVENT is not set
|
||||||
|
# CONFIG_IKCONFIG is not set
|
||||||
|
CONFIG_EMBEDDED=y
|
||||||
|
CONFIG_KALLSYMS=y
|
||||||
|
# CONFIG_KALLSYMS_ALL is not set
|
||||||
|
# CONFIG_KALLSYMS_EXTRA_PASS is not set
|
||||||
|
CONFIG_PRINTK=y
|
||||||
|
CONFIG_BUG=y
|
||||||
|
CONFIG_BASE_FULL=y
|
||||||
|
CONFIG_FUTEX=y
|
||||||
|
CONFIG_EPOLL=y
|
||||||
|
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
|
||||||
|
CONFIG_SHMEM=y
|
||||||
|
CONFIG_CC_ALIGN_FUNCTIONS=0
|
||||||
|
CONFIG_CC_ALIGN_LABELS=0
|
||||||
|
CONFIG_CC_ALIGN_LOOPS=0
|
||||||
|
CONFIG_CC_ALIGN_JUMPS=0
|
||||||
|
# CONFIG_TINY_SHMEM is not set
|
||||||
|
CONFIG_BASE_SMALL=0
|
||||||
|
|
||||||
|
#
|
||||||
|
# Loadable module support
|
||||||
|
#
|
||||||
|
# CONFIG_MODULES is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Fujitsu FR-V system setup
|
||||||
|
#
|
||||||
|
CONFIG_MMU=y
|
||||||
|
CONFIG_FRV_OUTOFLINE_ATOMIC_OPS=y
|
||||||
|
CONFIG_HIGHMEM=y
|
||||||
|
CONFIG_HIGHPTE=y
|
||||||
|
CONFIG_SELECT_MEMORY_MODEL=y
|
||||||
|
CONFIG_FLATMEM_MANUAL=y
|
||||||
|
# CONFIG_DISCONTIGMEM_MANUAL is not set
|
||||||
|
# CONFIG_SPARSEMEM_MANUAL is not set
|
||||||
|
CONFIG_FLATMEM=y
|
||||||
|
CONFIG_FLAT_NODE_MEM_MAP=y
|
||||||
|
# CONFIG_FRV_DEFL_CACHE_WBACK is not set
|
||||||
|
# CONFIG_FRV_DEFL_CACHE_WBEHIND is not set
|
||||||
|
CONFIG_FRV_DEFL_CACHE_WTHRU=y
|
||||||
|
# CONFIG_FRV_DEFL_CACHE_DISABLED is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# CPU core support
|
||||||
|
#
|
||||||
|
CONFIG_CPU_FR451=y
|
||||||
|
CONFIG_CPU_FR451_COMPILE=y
|
||||||
|
CONFIG_FRV_L1_CACHE_SHIFT=5
|
||||||
|
CONFIG_MB93091_VDK=y
|
||||||
|
# CONFIG_MB93093_PDK is not set
|
||||||
|
CONFIG_MB93090_MB00=y
|
||||||
|
# CONFIG_MB93091_NO_MB is not set
|
||||||
|
# CONFIG_GPREL_DATA_8 is not set
|
||||||
|
CONFIG_GPREL_DATA_4=y
|
||||||
|
# CONFIG_GPREL_DATA_NONE is not set
|
||||||
|
CONFIG_PCI=y
|
||||||
|
# CONFIG_PCI_LEGACY_PROC is not set
|
||||||
|
# CONFIG_PCI_NAMES is not set
|
||||||
|
# CONFIG_PCI_DEBUG is not set
|
||||||
|
# CONFIG_PCMCIA is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Power management options
|
||||||
|
#
|
||||||
|
# CONFIG_PM is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Executable formats
|
||||||
|
#
|
||||||
|
# CONFIG_BINFMT_ELF is not set
|
||||||
|
CONFIG_BINFMT_ELF_FDPIC=y
|
||||||
|
# CONFIG_BINFMT_MISC is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Device Drivers
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generic Driver Options
|
||||||
|
#
|
||||||
|
# CONFIG_STANDALONE is not set
|
||||||
|
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
|
||||||
|
# CONFIG_FW_LOADER is not set
|
||||||
|
# CONFIG_DEBUG_DRIVER is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Connector - unified userspace <-> kernelspace linker
|
||||||
|
#
|
||||||
|
# CONFIG_CONNECTOR is not set
|
||||||
|
# CONFIG_FORK_CONNECTOR is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Memory Technology Devices (MTD)
|
||||||
|
#
|
||||||
|
# CONFIG_MTD is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Parallel port support
|
||||||
|
#
|
||||||
|
# CONFIG_PARPORT is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Plug and Play support
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Block devices
|
||||||
|
#
|
||||||
|
# CONFIG_BLK_DEV_FD is not set
|
||||||
|
# CONFIG_BLK_CPQ_DA is not set
|
||||||
|
# CONFIG_BLK_CPQ_CISS_DA is not set
|
||||||
|
# CONFIG_BLK_DEV_DAC960 is not set
|
||||||
|
# CONFIG_BLK_DEV_UMEM is not set
|
||||||
|
# CONFIG_BLK_DEV_COW_COMMON is not set
|
||||||
|
# CONFIG_BLK_DEV_LOOP is not set
|
||||||
|
# CONFIG_BLK_DEV_NBD is not set
|
||||||
|
# CONFIG_BLK_DEV_SX8 is not set
|
||||||
|
# CONFIG_BLK_DEV_RAM is not set
|
||||||
|
CONFIG_BLK_DEV_RAM_COUNT=16
|
||||||
|
CONFIG_INITRAMFS_SOURCE=""
|
||||||
|
# CONFIG_CDROM_PKTCDVD is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# IO Schedulers
|
||||||
|
#
|
||||||
|
CONFIG_IOSCHED_NOOP=y
|
||||||
|
CONFIG_IOSCHED_AS=y
|
||||||
|
CONFIG_IOSCHED_DEADLINE=y
|
||||||
|
CONFIG_IOSCHED_CFQ=y
|
||||||
|
# CONFIG_ATA_OVER_ETH is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# ATA/ATAPI/MFM/RLL support
|
||||||
|
#
|
||||||
|
# CONFIG_IDE is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# SCSI device support
|
||||||
|
#
|
||||||
|
# CONFIG_SCSI is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Multi-device support (RAID and LVM)
|
||||||
|
#
|
||||||
|
# CONFIG_MD is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Fusion MPT device support
|
||||||
|
#
|
||||||
|
# CONFIG_FUSION is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# IEEE 1394 (FireWire) support
|
||||||
|
#
|
||||||
|
# CONFIG_IEEE1394 is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# I2O device support
|
||||||
|
#
|
||||||
|
# CONFIG_I2O is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Networking support
|
||||||
|
#
|
||||||
|
CONFIG_NET=y
|
||||||
|
|
||||||
|
#
|
||||||
|
# Networking options
|
||||||
|
#
|
||||||
|
CONFIG_PACKET=y
|
||||||
|
# CONFIG_PACKET_MMAP is not set
|
||||||
|
CONFIG_UNIX=y
|
||||||
|
# CONFIG_NET_KEY is not set
|
||||||
|
CONFIG_INET=y
|
||||||
|
# CONFIG_IP_MULTICAST is not set
|
||||||
|
# CONFIG_IP_ADVANCED_ROUTER is not set
|
||||||
|
CONFIG_IP_PNP=y
|
||||||
|
# CONFIG_IP_PNP_DHCP is not set
|
||||||
|
# CONFIG_IP_PNP_BOOTP is not set
|
||||||
|
# CONFIG_IP_PNP_RARP is not set
|
||||||
|
# CONFIG_NET_IPIP is not set
|
||||||
|
# CONFIG_NET_IPGRE is not set
|
||||||
|
# CONFIG_ARPD is not set
|
||||||
|
# CONFIG_SYN_COOKIES is not set
|
||||||
|
# CONFIG_INET_AH is not set
|
||||||
|
# CONFIG_INET_ESP is not set
|
||||||
|
# CONFIG_INET_IPCOMP is not set
|
||||||
|
# CONFIG_INET_TUNNEL is not set
|
||||||
|
# CONFIG_IP_TCPDIAG is not set
|
||||||
|
# CONFIG_IP_TCPDIAG_IPV6 is not set
|
||||||
|
# CONFIG_IPV6 is not set
|
||||||
|
# CONFIG_NETFILTER is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# SCTP Configuration (EXPERIMENTAL)
|
||||||
|
#
|
||||||
|
# CONFIG_IP_SCTP is not set
|
||||||
|
# CONFIG_ATM is not set
|
||||||
|
# CONFIG_BRIDGE is not set
|
||||||
|
# CONFIG_VLAN_8021Q is not set
|
||||||
|
# CONFIG_DECNET is not set
|
||||||
|
# CONFIG_LLC2 is not set
|
||||||
|
# CONFIG_IPX is not set
|
||||||
|
# CONFIG_ATALK is not set
|
||||||
|
# CONFIG_X25 is not set
|
||||||
|
# CONFIG_LAPB is not set
|
||||||
|
# CONFIG_NET_DIVERT is not set
|
||||||
|
# CONFIG_ECONET is not set
|
||||||
|
# CONFIG_WAN_ROUTER is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# QoS and/or fair queueing
|
||||||
|
#
|
||||||
|
# CONFIG_NET_SCHED is not set
|
||||||
|
# CONFIG_NET_CLS_ROUTE is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Network testing
|
||||||
|
#
|
||||||
|
# CONFIG_NET_PKTGEN is not set
|
||||||
|
# CONFIG_KGDBOE is not set
|
||||||
|
# CONFIG_NETPOLL is not set
|
||||||
|
# CONFIG_NETPOLL_RX is not set
|
||||||
|
# CONFIG_NETPOLL_TRAP is not set
|
||||||
|
# CONFIG_NET_POLL_CONTROLLER is not set
|
||||||
|
# CONFIG_HAMRADIO is not set
|
||||||
|
# CONFIG_IRDA is not set
|
||||||
|
# CONFIG_BT is not set
|
||||||
|
# CONFIG_IEEE80211 is not set
|
||||||
|
CONFIG_NETDEVICES=y
|
||||||
|
# CONFIG_DUMMY is not set
|
||||||
|
# CONFIG_BONDING is not set
|
||||||
|
# CONFIG_EQUALIZER is not set
|
||||||
|
# CONFIG_TUN is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# ARCnet devices
|
||||||
|
#
|
||||||
|
# CONFIG_ARCNET is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Ethernet (10 or 100Mbit)
|
||||||
|
#
|
||||||
|
CONFIG_NET_ETHERNET=y
|
||||||
|
CONFIG_MII=y
|
||||||
|
# CONFIG_HAPPYMEAL is not set
|
||||||
|
# CONFIG_SUNGEM is not set
|
||||||
|
# CONFIG_NET_VENDOR_3COM is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Tulip family network device support
|
||||||
|
#
|
||||||
|
# CONFIG_NET_TULIP is not set
|
||||||
|
# CONFIG_HP100 is not set
|
||||||
|
CONFIG_NET_PCI=y
|
||||||
|
# CONFIG_PCNET32 is not set
|
||||||
|
# CONFIG_AMD8111_ETH is not set
|
||||||
|
# CONFIG_ADAPTEC_STARFIRE is not set
|
||||||
|
# CONFIG_B44 is not set
|
||||||
|
# CONFIG_FORCEDETH is not set
|
||||||
|
# CONFIG_DGRS is not set
|
||||||
|
# CONFIG_EEPRO100 is not set
|
||||||
|
# CONFIG_E100 is not set
|
||||||
|
# CONFIG_FEALNX is not set
|
||||||
|
# CONFIG_NATSEMI is not set
|
||||||
|
CONFIG_NE2K_PCI=y
|
||||||
|
# CONFIG_8139CP is not set
|
||||||
|
# CONFIG_8139TOO is not set
|
||||||
|
# CONFIG_SIS900 is not set
|
||||||
|
# CONFIG_EPIC100 is not set
|
||||||
|
# CONFIG_SUNDANCE is not set
|
||||||
|
# CONFIG_TLAN is not set
|
||||||
|
# CONFIG_VIA_RHINE is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Ethernet (1000 Mbit)
|
||||||
|
#
|
||||||
|
# CONFIG_ACENIC is not set
|
||||||
|
# CONFIG_DL2K is not set
|
||||||
|
# CONFIG_E1000 is not set
|
||||||
|
# CONFIG_NS83820 is not set
|
||||||
|
# CONFIG_HAMACHI is not set
|
||||||
|
# CONFIG_YELLOWFIN is not set
|
||||||
|
# CONFIG_R8169 is not set
|
||||||
|
# CONFIG_SKGE is not set
|
||||||
|
# CONFIG_SK98LIN is not set
|
||||||
|
# CONFIG_VIA_VELOCITY is not set
|
||||||
|
# CONFIG_TIGON3 is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Ethernet (10000 Mbit)
|
||||||
|
#
|
||||||
|
# CONFIG_CHELSIO_T1 is not set
|
||||||
|
# CONFIG_IXGB is not set
|
||||||
|
# CONFIG_S2IO is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Token Ring devices
|
||||||
|
#
|
||||||
|
# CONFIG_TR is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Wireless LAN (non-hamradio)
|
||||||
|
#
|
||||||
|
# CONFIG_NET_RADIO is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Wan interfaces
|
||||||
|
#
|
||||||
|
# CONFIG_WAN is not set
|
||||||
|
# CONFIG_FDDI is not set
|
||||||
|
# CONFIG_HIPPI is not set
|
||||||
|
# CONFIG_PPP is not set
|
||||||
|
# CONFIG_SLIP is not set
|
||||||
|
# CONFIG_SHAPER is not set
|
||||||
|
# CONFIG_NETCONSOLE is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# ISDN subsystem
|
||||||
|
#
|
||||||
|
# CONFIG_ISDN is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Telephony Support
|
||||||
|
#
|
||||||
|
# CONFIG_PHONE is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Input device support
|
||||||
|
#
|
||||||
|
# CONFIG_INPUT is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Hardware I/O ports
|
||||||
|
#
|
||||||
|
# CONFIG_SERIO is not set
|
||||||
|
# CONFIG_GAMEPORT is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Character devices
|
||||||
|
#
|
||||||
|
# CONFIG_VT is not set
|
||||||
|
# CONFIG_SERIAL_NONSTANDARD is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Serial drivers
|
||||||
|
#
|
||||||
|
CONFIG_SERIAL_8250=y
|
||||||
|
CONFIG_SERIAL_8250_CONSOLE=y
|
||||||
|
CONFIG_SERIAL_8250_NR_UARTS=1
|
||||||
|
CONFIG_SERIAL_8250_EXTENDED=y
|
||||||
|
# CONFIG_SERIAL_8250_MANY_PORTS is not set
|
||||||
|
CONFIG_SERIAL_8250_SHARE_IRQ=y
|
||||||
|
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
|
||||||
|
# CONFIG_SERIAL_8250_MULTIPORT is not set
|
||||||
|
# CONFIG_SERIAL_8250_RSA is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Non-8250 serial port support
|
||||||
|
#
|
||||||
|
CONFIG_SERIAL_CORE=y
|
||||||
|
CONFIG_SERIAL_CORE_CONSOLE=y
|
||||||
|
# CONFIG_SERIAL_JSM is not set
|
||||||
|
CONFIG_UNIX98_PTYS=y
|
||||||
|
# CONFIG_LEGACY_PTYS is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# IPMI
|
||||||
|
#
|
||||||
|
# CONFIG_IPMI_HANDLER is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Watchdog Cards
|
||||||
|
#
|
||||||
|
# CONFIG_WATCHDOG is not set
|
||||||
|
# CONFIG_RTC is not set
|
||||||
|
# CONFIG_GEN_RTC is not set
|
||||||
|
# CONFIG_DTLK is not set
|
||||||
|
# CONFIG_R3964 is not set
|
||||||
|
# CONFIG_APPLICOM is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Ftape, the floppy tape device driver
|
||||||
|
#
|
||||||
|
# CONFIG_DRM is not set
|
||||||
|
# CONFIG_RAW_DRIVER is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# TPM devices
|
||||||
|
#
|
||||||
|
# CONFIG_TCG_TPM is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# I2C support
|
||||||
|
#
|
||||||
|
# CONFIG_I2C is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dallas's 1-wire bus
|
||||||
|
#
|
||||||
|
# CONFIG_W1 is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Misc devices
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Multimedia devices
|
||||||
|
#
|
||||||
|
# CONFIG_VIDEO_DEV is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Digital Video Broadcasting Devices
|
||||||
|
#
|
||||||
|
# CONFIG_DVB is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Graphics support
|
||||||
|
#
|
||||||
|
# CONFIG_FB is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Sound
|
||||||
|
#
|
||||||
|
# CONFIG_SOUND is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# USB support
|
||||||
|
#
|
||||||
|
CONFIG_USB_ARCH_HAS_HCD=y
|
||||||
|
CONFIG_USB_ARCH_HAS_OHCI=y
|
||||||
|
# CONFIG_USB is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# USB Gadget Support
|
||||||
|
#
|
||||||
|
# CONFIG_USB_GADGET is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# MMC/SD Card support
|
||||||
|
#
|
||||||
|
# CONFIG_MMC is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# InfiniBand support
|
||||||
|
#
|
||||||
|
# CONFIG_INFINIBAND is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# File systems
|
||||||
|
#
|
||||||
|
# CONFIG_EXT2_FS is not set
|
||||||
|
# CONFIG_EXT3_FS is not set
|
||||||
|
# CONFIG_JBD is not set
|
||||||
|
# CONFIG_REISER4_FS is not set
|
||||||
|
# CONFIG_REISERFS_FS is not set
|
||||||
|
# CONFIG_JFS_FS is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# XFS support
|
||||||
|
#
|
||||||
|
# CONFIG_XFS_FS is not set
|
||||||
|
# CONFIG_MINIX_FS is not set
|
||||||
|
# CONFIG_ROMFS_FS is not set
|
||||||
|
CONFIG_INOTIFY=y
|
||||||
|
# CONFIG_QUOTA is not set
|
||||||
|
CONFIG_DNOTIFY=y
|
||||||
|
# CONFIG_AUTOFS_FS is not set
|
||||||
|
# CONFIG_AUTOFS4_FS is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Caches
|
||||||
|
#
|
||||||
|
# CONFIG_FSCACHE is not set
|
||||||
|
# CONFIG_FUSE_FS is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# CD-ROM/DVD Filesystems
|
||||||
|
#
|
||||||
|
# CONFIG_ISO9660_FS is not set
|
||||||
|
# CONFIG_UDF_FS is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# DOS/FAT/NT Filesystems
|
||||||
|
#
|
||||||
|
# CONFIG_MSDOS_FS is not set
|
||||||
|
# CONFIG_VFAT_FS is not set
|
||||||
|
# CONFIG_NTFS_FS is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Pseudo filesystems
|
||||||
|
#
|
||||||
|
CONFIG_PROC_FS=y
|
||||||
|
# CONFIG_PROC_KCORE is not set
|
||||||
|
CONFIG_SYSFS=y
|
||||||
|
# CONFIG_DEVFS_FS is not set
|
||||||
|
# CONFIG_DEVPTS_FS_XATTR is not set
|
||||||
|
CONFIG_TMPFS=y
|
||||||
|
# CONFIG_TMPFS_XATTR is not set
|
||||||
|
# CONFIG_HUGETLB_PAGE is not set
|
||||||
|
CONFIG_RAMFS=y
|
||||||
|
# CONFIG_RELAYFS_FS is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Miscellaneous filesystems
|
||||||
|
#
|
||||||
|
# CONFIG_ADFS_FS is not set
|
||||||
|
# CONFIG_AFFS_FS is not set
|
||||||
|
# CONFIG_HFS_FS is not set
|
||||||
|
# CONFIG_HFSPLUS_FS is not set
|
||||||
|
# CONFIG_BEFS_FS is not set
|
||||||
|
# CONFIG_BFS_FS is not set
|
||||||
|
# CONFIG_EFS_FS is not set
|
||||||
|
# CONFIG_CRAMFS is not set
|
||||||
|
# CONFIG_VXFS_FS is not set
|
||||||
|
# CONFIG_HPFS_FS is not set
|
||||||
|
# CONFIG_QNX4FS_FS is not set
|
||||||
|
# CONFIG_SYSV_FS is not set
|
||||||
|
# CONFIG_UFS_FS is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Network File Systems
|
||||||
|
#
|
||||||
|
CONFIG_NFS_FS=y
|
||||||
|
# CONFIG_NFS_V3 is not set
|
||||||
|
# CONFIG_NFS_V4 is not set
|
||||||
|
# CONFIG_NFS_DIRECTIO is not set
|
||||||
|
# CONFIG_NFSD is not set
|
||||||
|
CONFIG_ROOT_NFS=y
|
||||||
|
CONFIG_LOCKD=y
|
||||||
|
CONFIG_NFS_COMMON=y
|
||||||
|
CONFIG_SUNRPC=y
|
||||||
|
# CONFIG_RPCSEC_GSS_KRB5 is not set
|
||||||
|
# CONFIG_RPCSEC_GSS_SPKM3 is not set
|
||||||
|
# CONFIG_SMB_FS is not set
|
||||||
|
# CONFIG_CIFS is not set
|
||||||
|
# CONFIG_NCP_FS is not set
|
||||||
|
# CONFIG_CODA_FS is not set
|
||||||
|
# CONFIG_AFS_FS is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Partition Types
|
||||||
|
#
|
||||||
|
# CONFIG_PARTITION_ADVANCED is not set
|
||||||
|
CONFIG_MSDOS_PARTITION=y
|
||||||
|
|
||||||
|
#
|
||||||
|
# Native Language Support
|
||||||
|
#
|
||||||
|
# CONFIG_NLS is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Kernel hacking
|
||||||
|
#
|
||||||
|
# CONFIG_PRINTK_TIME is not set
|
||||||
|
CONFIG_DEBUG_KERNEL=y
|
||||||
|
# CONFIG_MAGIC_SYSRQ is not set
|
||||||
|
CONFIG_LOG_BUF_SHIFT=14
|
||||||
|
CONFIG_DETECT_SOFTLOCKUP=y
|
||||||
|
# CONFIG_SCHEDSTATS is not set
|
||||||
|
# CONFIG_DEBUG_SLAB is not set
|
||||||
|
# CONFIG_DEBUG_SPINLOCK is not set
|
||||||
|
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
|
||||||
|
# CONFIG_DEBUG_KOBJECT is not set
|
||||||
|
# CONFIG_DEBUG_HIGHMEM is not set
|
||||||
|
# CONFIG_DEBUG_BUGVERBOSE is not set
|
||||||
|
# CONFIG_DEBUG_INFO is not set
|
||||||
|
# CONFIG_DEBUG_FS is not set
|
||||||
|
# CONFIG_FRAME_POINTER is not set
|
||||||
|
# CONFIG_EARLY_PRINTK is not set
|
||||||
|
CONFIG_DEBUG_STACKOVERFLOW=y
|
||||||
|
# CONFIG_DEBUG_PAGEALLOC is not set
|
||||||
|
# CONFIG_GDBSTUB is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Security options
|
||||||
|
#
|
||||||
|
# CONFIG_KEYS is not set
|
||||||
|
# CONFIG_SECURITY is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Cryptographic options
|
||||||
|
#
|
||||||
|
# CONFIG_CRYPTO is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# Hardware crypto devices
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Library routines
|
||||||
|
#
|
||||||
|
# CONFIG_CRC_CCITT is not set
|
||||||
|
CONFIG_CRC32=y
|
||||||
|
# CONFIG_LIBCRC32C is not set
|
|
@ -435,6 +435,11 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c)
|
||||||
if (c == &boot_cpu_data)
|
if (c == &boot_cpu_data)
|
||||||
sysenter_setup();
|
sysenter_setup();
|
||||||
enable_sep_cpu();
|
enable_sep_cpu();
|
||||||
|
|
||||||
|
if (c == &boot_cpu_data)
|
||||||
|
mtrr_bp_init();
|
||||||
|
else
|
||||||
|
mtrr_ap_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_X86_HT
|
#ifdef CONFIG_X86_HT
|
||||||
|
|
|
@ -25,7 +25,7 @@ extern int trap_init_f00f_bug(void);
|
||||||
/*
|
/*
|
||||||
* Alignment at which movsl is preferred for bulk memory copies.
|
* Alignment at which movsl is preferred for bulk memory copies.
|
||||||
*/
|
*/
|
||||||
struct movsl_mask movsl_mask;
|
struct movsl_mask movsl_mask __read_mostly;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void __devinit early_intel_workaround(struct cpuinfo_x86 *c)
|
void __devinit early_intel_workaround(struct cpuinfo_x86 *c)
|
||||||
|
|
|
@ -67,13 +67,6 @@ void __init get_mtrr_state(void)
|
||||||
mtrr_state.enabled = (lo & 0xc00) >> 10;
|
mtrr_state.enabled = (lo & 0xc00) >> 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free resources associated with a struct mtrr_state */
|
|
||||||
void __init finalize_mtrr_state(void)
|
|
||||||
{
|
|
||||||
kfree(mtrr_state.var_ranges);
|
|
||||||
mtrr_state.var_ranges = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Some BIOS's are fucked and don't set all MTRRs the same! */
|
/* Some BIOS's are fucked and don't set all MTRRs the same! */
|
||||||
void __init mtrr_state_warn(void)
|
void __init mtrr_state_warn(void)
|
||||||
{
|
{
|
||||||
|
@ -334,6 +327,9 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base,
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
struct mtrr_var_range *vr;
|
||||||
|
|
||||||
|
vr = &mtrr_state.var_ranges[reg];
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
prepare_set();
|
prepare_set();
|
||||||
|
@ -342,11 +338,15 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base,
|
||||||
/* The invalid bit is kept in the mask, so we simply clear the
|
/* The invalid bit is kept in the mask, so we simply clear the
|
||||||
relevant mask register to disable a range. */
|
relevant mask register to disable a range. */
|
||||||
mtrr_wrmsr(MTRRphysMask_MSR(reg), 0, 0);
|
mtrr_wrmsr(MTRRphysMask_MSR(reg), 0, 0);
|
||||||
|
memset(vr, 0, sizeof(struct mtrr_var_range));
|
||||||
} else {
|
} else {
|
||||||
mtrr_wrmsr(MTRRphysBase_MSR(reg), base << PAGE_SHIFT | type,
|
vr->base_lo = base << PAGE_SHIFT | type;
|
||||||
(base & size_and_mask) >> (32 - PAGE_SHIFT));
|
vr->base_hi = (base & size_and_mask) >> (32 - PAGE_SHIFT);
|
||||||
mtrr_wrmsr(MTRRphysMask_MSR(reg), -size << PAGE_SHIFT | 0x800,
|
vr->mask_lo = -size << PAGE_SHIFT | 0x800;
|
||||||
(-size & size_and_mask) >> (32 - PAGE_SHIFT));
|
vr->mask_hi = (-size & size_and_mask) >> (32 - PAGE_SHIFT);
|
||||||
|
|
||||||
|
mtrr_wrmsr(MTRRphysBase_MSR(reg), vr->base_lo, vr->base_hi);
|
||||||
|
mtrr_wrmsr(MTRRphysMask_MSR(reg), vr->mask_lo, vr->mask_hi);
|
||||||
}
|
}
|
||||||
|
|
||||||
post_set();
|
post_set();
|
||||||
|
|
|
@ -332,6 +332,8 @@ int mtrr_add_page(unsigned long base, unsigned long size,
|
||||||
|
|
||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
|
|
||||||
|
/* No CPU hotplug when we change MTRR entries */
|
||||||
|
lock_cpu_hotplug();
|
||||||
/* Search for existing MTRR */
|
/* Search for existing MTRR */
|
||||||
down(&main_lock);
|
down(&main_lock);
|
||||||
for (i = 0; i < num_var_ranges; ++i) {
|
for (i = 0; i < num_var_ranges; ++i) {
|
||||||
|
@ -372,6 +374,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
|
||||||
error = i;
|
error = i;
|
||||||
out:
|
out:
|
||||||
up(&main_lock);
|
up(&main_lock);
|
||||||
|
unlock_cpu_hotplug();
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,6 +464,8 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
max = num_var_ranges;
|
max = num_var_ranges;
|
||||||
|
/* No CPU hotplug when we change MTRR entries */
|
||||||
|
lock_cpu_hotplug();
|
||||||
down(&main_lock);
|
down(&main_lock);
|
||||||
if (reg < 0) {
|
if (reg < 0) {
|
||||||
/* Search for existing MTRR */
|
/* Search for existing MTRR */
|
||||||
|
@ -501,6 +506,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
|
||||||
error = reg;
|
error = reg;
|
||||||
out:
|
out:
|
||||||
up(&main_lock);
|
up(&main_lock);
|
||||||
|
unlock_cpu_hotplug();
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -544,21 +550,9 @@ static void __init init_ifs(void)
|
||||||
centaur_init_mtrr();
|
centaur_init_mtrr();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init init_other_cpus(void)
|
/* The suspend/resume methods are only for CPU without MTRR. CPU using generic
|
||||||
{
|
* MTRR driver doesn't require this
|
||||||
if (use_intel())
|
*/
|
||||||
get_mtrr_state();
|
|
||||||
|
|
||||||
/* bring up the other processors */
|
|
||||||
set_mtrr(~0U,0,0,0);
|
|
||||||
|
|
||||||
if (use_intel()) {
|
|
||||||
finalize_mtrr_state();
|
|
||||||
mtrr_state_warn();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct mtrr_value {
|
struct mtrr_value {
|
||||||
mtrr_type ltype;
|
mtrr_type ltype;
|
||||||
unsigned long lbase;
|
unsigned long lbase;
|
||||||
|
@ -611,13 +605,13 @@ static struct sysdev_driver mtrr_sysdev_driver = {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mtrr_init - initialize mtrrs on the boot CPU
|
* mtrr_bp_init - initialize mtrrs on the boot CPU
|
||||||
*
|
*
|
||||||
* This needs to be called early; before any of the other CPUs are
|
* This needs to be called early; before any of the other CPUs are
|
||||||
* initialized (i.e. before smp_init()).
|
* initialized (i.e. before smp_init()).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int __init mtrr_init(void)
|
void __init mtrr_bp_init(void)
|
||||||
{
|
{
|
||||||
init_ifs();
|
init_ifs();
|
||||||
|
|
||||||
|
@ -674,12 +668,48 @@ static int __init mtrr_init(void)
|
||||||
if (mtrr_if) {
|
if (mtrr_if) {
|
||||||
set_num_var_ranges();
|
set_num_var_ranges();
|
||||||
init_table();
|
init_table();
|
||||||
init_other_cpus();
|
if (use_intel())
|
||||||
|
get_mtrr_state();
|
||||||
return sysdev_driver_register(&cpu_sysdev_class,
|
|
||||||
&mtrr_sysdev_driver);
|
|
||||||
}
|
}
|
||||||
return -ENXIO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
subsys_initcall(mtrr_init);
|
void mtrr_ap_init(void)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (!mtrr_if || !use_intel())
|
||||||
|
return;
|
||||||
|
/*
|
||||||
|
* Ideally we should hold main_lock here to avoid mtrr entries changed,
|
||||||
|
* but this routine will be called in cpu boot time, holding the lock
|
||||||
|
* breaks it. This routine is called in two cases: 1.very earily time
|
||||||
|
* of software resume, when there absolutely isn't mtrr entry changes;
|
||||||
|
* 2.cpu hotadd time. We let mtrr_add/del_page hold cpuhotplug lock to
|
||||||
|
* prevent mtrr entry changes
|
||||||
|
*/
|
||||||
|
local_irq_save(flags);
|
||||||
|
|
||||||
|
mtrr_if->set_all();
|
||||||
|
|
||||||
|
local_irq_restore(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init mtrr_init_finialize(void)
|
||||||
|
{
|
||||||
|
if (!mtrr_if)
|
||||||
|
return 0;
|
||||||
|
if (use_intel())
|
||||||
|
mtrr_state_warn();
|
||||||
|
else {
|
||||||
|
/* The CPUs haven't MTRR and seemes not support SMP. They have
|
||||||
|
* specific drivers, we use a tricky method to support
|
||||||
|
* suspend/resume for them.
|
||||||
|
* TBD: is there any system with such CPU which supports
|
||||||
|
* suspend/resume? if no, we should remove the code.
|
||||||
|
*/
|
||||||
|
sysdev_driver_register(&cpu_sysdev_class,
|
||||||
|
&mtrr_sysdev_driver);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
subsys_initcall(mtrr_init_finialize);
|
||||||
|
|
|
@ -91,7 +91,6 @@ extern struct mtrr_ops * mtrr_if;
|
||||||
|
|
||||||
extern unsigned int num_var_ranges;
|
extern unsigned int num_var_ranges;
|
||||||
|
|
||||||
void finalize_mtrr_state(void);
|
|
||||||
void mtrr_state_warn(void);
|
void mtrr_state_warn(void);
|
||||||
char *mtrr_attrib_to_str(int x);
|
char *mtrr_attrib_to_str(int x);
|
||||||
void mtrr_wrmsr(unsigned, unsigned, unsigned);
|
void mtrr_wrmsr(unsigned, unsigned, unsigned);
|
||||||
|
|
|
@ -68,21 +68,21 @@ EXPORT_SYMBOL(smp_num_siblings);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Package ID of each logical CPU */
|
/* Package ID of each logical CPU */
|
||||||
int phys_proc_id[NR_CPUS] = {[0 ... NR_CPUS-1] = BAD_APICID};
|
int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
|
||||||
EXPORT_SYMBOL(phys_proc_id);
|
EXPORT_SYMBOL(phys_proc_id);
|
||||||
|
|
||||||
/* Core ID of each logical CPU */
|
/* Core ID of each logical CPU */
|
||||||
int cpu_core_id[NR_CPUS] = {[0 ... NR_CPUS-1] = BAD_APICID};
|
int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
|
||||||
EXPORT_SYMBOL(cpu_core_id);
|
EXPORT_SYMBOL(cpu_core_id);
|
||||||
|
|
||||||
cpumask_t cpu_sibling_map[NR_CPUS];
|
cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
|
||||||
EXPORT_SYMBOL(cpu_sibling_map);
|
EXPORT_SYMBOL(cpu_sibling_map);
|
||||||
|
|
||||||
cpumask_t cpu_core_map[NR_CPUS];
|
cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
|
||||||
EXPORT_SYMBOL(cpu_core_map);
|
EXPORT_SYMBOL(cpu_core_map);
|
||||||
|
|
||||||
/* bitmap of online cpus */
|
/* bitmap of online cpus */
|
||||||
cpumask_t cpu_online_map;
|
cpumask_t cpu_online_map __read_mostly;
|
||||||
EXPORT_SYMBOL(cpu_online_map);
|
EXPORT_SYMBOL(cpu_online_map);
|
||||||
|
|
||||||
cpumask_t cpu_callin_map;
|
cpumask_t cpu_callin_map;
|
||||||
|
@ -100,7 +100,7 @@ static int __devinitdata tsc_sync_disabled;
|
||||||
struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
|
struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
|
||||||
EXPORT_SYMBOL(cpu_data);
|
EXPORT_SYMBOL(cpu_data);
|
||||||
|
|
||||||
u8 x86_cpu_to_apicid[NR_CPUS] =
|
u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly =
|
||||||
{ [0 ... NR_CPUS-1] = 0xff };
|
{ [0 ... NR_CPUS-1] = 0xff };
|
||||||
EXPORT_SYMBOL(x86_cpu_to_apicid);
|
EXPORT_SYMBOL(x86_cpu_to_apicid);
|
||||||
|
|
||||||
|
@ -550,10 +550,10 @@ extern struct {
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
|
|
||||||
/* which logical CPUs are on which nodes */
|
/* which logical CPUs are on which nodes */
|
||||||
cpumask_t node_2_cpu_mask[MAX_NUMNODES] =
|
cpumask_t node_2_cpu_mask[MAX_NUMNODES] __read_mostly =
|
||||||
{ [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE };
|
{ [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE };
|
||||||
/* which node each logical CPU is on */
|
/* which node each logical CPU is on */
|
||||||
int cpu_2_node[NR_CPUS] = { [0 ... NR_CPUS-1] = 0 };
|
int cpu_2_node[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 };
|
||||||
EXPORT_SYMBOL(cpu_2_node);
|
EXPORT_SYMBOL(cpu_2_node);
|
||||||
|
|
||||||
/* set up a mapping between cpu and node. */
|
/* set up a mapping between cpu and node. */
|
||||||
|
@ -581,7 +581,7 @@ static inline void unmap_cpu_to_node(int cpu)
|
||||||
|
|
||||||
#endif /* CONFIG_NUMA */
|
#endif /* CONFIG_NUMA */
|
||||||
|
|
||||||
u8 cpu_2_logical_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
|
u8 cpu_2_logical_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
|
||||||
|
|
||||||
static void map_cpu_to_logical_apicid(void)
|
static void map_cpu_to_logical_apicid(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -91,7 +91,7 @@ EXPORT_SYMBOL(rtc_lock);
|
||||||
DEFINE_SPINLOCK(i8253_lock);
|
DEFINE_SPINLOCK(i8253_lock);
|
||||||
EXPORT_SYMBOL(i8253_lock);
|
EXPORT_SYMBOL(i8253_lock);
|
||||||
|
|
||||||
struct timer_opts *cur_timer = &timer_none;
|
struct timer_opts *cur_timer __read_mostly = &timer_none;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a special lock that is owned by the CPU and holds the index
|
* This is a special lock that is owned by the CPU and holds the index
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include "mach_timer.h"
|
#include "mach_timer.h"
|
||||||
#include <asm/hpet.h>
|
#include <asm/hpet.h>
|
||||||
|
|
||||||
static unsigned long hpet_usec_quotient; /* convert hpet clks to usec */
|
static unsigned long __read_mostly hpet_usec_quotient; /* convert hpet clks to usec */
|
||||||
static unsigned long tsc_hpet_quotient; /* convert tsc to hpet clks */
|
static unsigned long tsc_hpet_quotient; /* convert tsc to hpet clks */
|
||||||
static unsigned long hpet_last; /* hpet counter value at last tick*/
|
static unsigned long hpet_last; /* hpet counter value at last tick*/
|
||||||
static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */
|
static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */
|
||||||
|
@ -180,7 +180,7 @@ static int __init init_hpet(char* override)
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
|
|
||||||
/* tsc timer_opts struct */
|
/* tsc timer_opts struct */
|
||||||
static struct timer_opts timer_hpet = {
|
static struct timer_opts timer_hpet __read_mostly = {
|
||||||
.name = "hpet",
|
.name = "hpet",
|
||||||
.mark_offset = mark_offset_hpet,
|
.mark_offset = mark_offset_hpet,
|
||||||
.get_offset = get_offset_hpet,
|
.get_offset = get_offset_hpet,
|
||||||
|
|
|
@ -57,6 +57,9 @@ SECTIONS
|
||||||
*(.data.cacheline_aligned)
|
*(.data.cacheline_aligned)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* rarely changed data like cpu maps */
|
||||||
|
. = ALIGN(32);
|
||||||
|
.data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) }
|
||||||
_edata = .; /* End of data section */
|
_edata = .; /* End of data section */
|
||||||
|
|
||||||
. = ALIGN(THREAD_SIZE); /* init_task */
|
. = ALIGN(THREAD_SIZE); /* init_task */
|
||||||
|
|
|
@ -228,7 +228,8 @@ EXPORT_SYMBOL(ioremap_nocache);
|
||||||
void iounmap(volatile void __iomem *addr)
|
void iounmap(volatile void __iomem *addr)
|
||||||
{
|
{
|
||||||
struct vm_struct *p;
|
struct vm_struct *p;
|
||||||
if ((void __force *) addr <= high_memory)
|
|
||||||
|
if ((void __force *)addr <= high_memory)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -241,9 +242,10 @@ void iounmap(volatile void __iomem *addr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
write_lock(&vmlist_lock);
|
write_lock(&vmlist_lock);
|
||||||
p = __remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
|
p = __remove_vm_area((void *)(PAGE_MASK & (unsigned long __force)addr));
|
||||||
if (!p) {
|
if (!p) {
|
||||||
printk(KERN_WARNING "iounmap: bad address %p\n", addr);
|
printk(KERN_WARNING "iounmap: bad address %p\n", addr);
|
||||||
|
dump_stack();
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,7 @@ void __restore_processor_state(struct saved_context *ctxt)
|
||||||
|
|
||||||
fix_processor_context();
|
fix_processor_context();
|
||||||
do_fpu_end();
|
do_fpu_end();
|
||||||
|
mtrr_ap_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void restore_processor_state(void)
|
void restore_processor_state(void)
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
*
|
*
|
||||||
* Setup routines for Renesas M32700UT Board
|
* Setup routines for Renesas M32700UT Board
|
||||||
*
|
*
|
||||||
* Copyright (c) 2002 Hiroyuki Kondo, Hirokazu Takata,
|
* Copyright (c) 2002-2005 Hiroyuki Kondo, Hirokazu Takata,
|
||||||
* Hitoshi Yamamoto, Takeo Takahashi
|
* Hitoshi Yamamoto, Takeo Takahashi
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU General
|
* This file is subject to the terms and conditions of the GNU General
|
||||||
* Public License. See the file "COPYING" in the main directory of this
|
* Public License. See the file "COPYING" in the main directory of this
|
||||||
|
@ -435,7 +435,7 @@ void __init init_IRQ(void)
|
||||||
icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01;
|
icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01;
|
||||||
enable_m32700ut_irq(M32R_IRQ_INT2);
|
enable_m32700ut_irq(M32R_IRQ_INT2);
|
||||||
|
|
||||||
//#if defined(CONFIG_VIDEO_M32R_AR)
|
#if defined(CONFIG_VIDEO_M32R_AR)
|
||||||
/*
|
/*
|
||||||
* INT3# is used for AR
|
* INT3# is used for AR
|
||||||
*/
|
*/
|
||||||
|
@ -445,9 +445,11 @@ void __init init_IRQ(void)
|
||||||
irq_desc[M32R_IRQ_INT3].depth = 1;
|
irq_desc[M32R_IRQ_INT3].depth = 1;
|
||||||
icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
|
icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
|
||||||
disable_m32700ut_irq(M32R_IRQ_INT3);
|
disable_m32700ut_irq(M32R_IRQ_INT3);
|
||||||
//#endif /* CONFIG_VIDEO_M32R_AR */
|
#endif /* CONFIG_VIDEO_M32R_AR */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_SMC91X)
|
||||||
|
|
||||||
#define LAN_IOSTART 0x300
|
#define LAN_IOSTART 0x300
|
||||||
#define LAN_IOEND 0x320
|
#define LAN_IOEND 0x320
|
||||||
static struct resource smc91x_resources[] = {
|
static struct resource smc91x_resources[] = {
|
||||||
|
@ -469,10 +471,55 @@ static struct platform_device smc91x_device = {
|
||||||
.num_resources = ARRAY_SIZE(smc91x_resources),
|
.num_resources = ARRAY_SIZE(smc91x_resources),
|
||||||
.resource = smc91x_resources,
|
.resource = smc91x_resources,
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_FB_S1D13XXX)
|
||||||
|
|
||||||
|
#include <video/s1d13xxxfb.h>
|
||||||
|
#include <asm/s1d13806.h>
|
||||||
|
|
||||||
|
static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
|
||||||
|
.initregs = s1d13xxxfb_initregs,
|
||||||
|
.initregssize = ARRAY_SIZE(s1d13xxxfb_initregs),
|
||||||
|
.platform_init_video = NULL,
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
.platform_suspend_video = NULL,
|
||||||
|
.platform_resume_video = NULL,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource s1d13xxxfb_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = 0x10600000UL,
|
||||||
|
.end = 0x1073FFFFUL,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = 0x10400000UL,
|
||||||
|
.end = 0x104001FFUL,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device s1d13xxxfb_device = {
|
||||||
|
.name = S1D_DEVICENAME,
|
||||||
|
.id = 0,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &s1d13xxxfb_data,
|
||||||
|
},
|
||||||
|
.num_resources = ARRAY_SIZE(s1d13xxxfb_resources),
|
||||||
|
.resource = s1d13xxxfb_resources,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static int __init platform_init(void)
|
static int __init platform_init(void)
|
||||||
{
|
{
|
||||||
|
#if defined(CONFIG_SMC91X)
|
||||||
platform_device_register(&smc91x_device);
|
platform_device_register(&smc91x_device);
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_FB_S1D13XXX)
|
||||||
|
platform_device_register(&s1d13xxxfb_device);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
arch_initcall(platform_init);
|
arch_initcall(platform_init);
|
||||||
|
|
|
@ -3,14 +3,15 @@
|
||||||
*
|
*
|
||||||
* Setup routines for Renesas MAPPI Board
|
* Setup routines for Renesas MAPPI Board
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001, 2002 Hiroyuki Kondo, Hirokazu Takata,
|
* Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata,
|
||||||
* Hitoshi Yamamoto
|
* Hitoshi Yamamoto
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/device.h>
|
||||||
|
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/m32r.h>
|
#include <asm/m32r.h>
|
||||||
|
@ -158,3 +159,49 @@ void __init init_IRQ(void)
|
||||||
disable_mappi_irq(M32R_IRQ_INT2);
|
disable_mappi_irq(M32R_IRQ_INT2);
|
||||||
#endif /* CONFIG_M32RPCC */
|
#endif /* CONFIG_M32RPCC */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_FB_S1D13XXX)
|
||||||
|
|
||||||
|
#include <video/s1d13xxxfb.h>
|
||||||
|
#include <asm/s1d13806.h>
|
||||||
|
|
||||||
|
static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
|
||||||
|
.initregs = s1d13xxxfb_initregs,
|
||||||
|
.initregssize = ARRAY_SIZE(s1d13xxxfb_initregs),
|
||||||
|
.platform_init_video = NULL,
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
.platform_suspend_video = NULL,
|
||||||
|
.platform_resume_video = NULL,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource s1d13xxxfb_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = 0x10200000UL,
|
||||||
|
.end = 0x1033FFFFUL,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = 0x10000000UL,
|
||||||
|
.end = 0x100001FFUL,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device s1d13xxxfb_device = {
|
||||||
|
.name = S1D_DEVICENAME,
|
||||||
|
.id = 0,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &s1d13xxxfb_data,
|
||||||
|
},
|
||||||
|
.num_resources = ARRAY_SIZE(s1d13xxxfb_resources),
|
||||||
|
.resource = s1d13xxxfb_resources,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init platform_init(void)
|
||||||
|
{
|
||||||
|
platform_device_register(&s1d13xxxfb_device);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
arch_initcall(platform_init);
|
||||||
|
#endif
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
*
|
*
|
||||||
* Setup routines for Renesas MAPPI-II(M3A-ZA36) Board
|
* Setup routines for Renesas MAPPI-II(M3A-ZA36) Board
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001, 2002 Hiroyuki Kondo, Hirokazu Takata,
|
* Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata,
|
||||||
* Hitoshi Yamamoto, Mamoru Sakugawa
|
* Hitoshi Yamamoto, Mamoru Sakugawa
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
*
|
*
|
||||||
* Setup routines for Renesas MAPPI-III(M3A-2170) Board
|
* Setup routines for Renesas MAPPI-III(M3A-2170) Board
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata,
|
* Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata,
|
||||||
* Hitoshi Yamamoto, Mamoru Sakugawa
|
* Hitoshi Yamamoto, Mamoru Sakugawa
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
|
@ -178,6 +178,8 @@ void __init init_IRQ(void)
|
||||||
#endif /* CONFIG_M32R_CFC */
|
#endif /* CONFIG_M32R_CFC */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_SMC91X)
|
||||||
|
|
||||||
#define LAN_IOSTART 0x300
|
#define LAN_IOSTART 0x300
|
||||||
#define LAN_IOEND 0x320
|
#define LAN_IOEND 0x320
|
||||||
static struct resource smc91x_resources[] = {
|
static struct resource smc91x_resources[] = {
|
||||||
|
@ -200,9 +202,55 @@ static struct platform_device smc91x_device = {
|
||||||
.resource = smc91x_resources,
|
.resource = smc91x_resources,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_FB_S1D13XXX)
|
||||||
|
|
||||||
|
#include <video/s1d13xxxfb.h>
|
||||||
|
#include <asm/s1d13806.h>
|
||||||
|
|
||||||
|
static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
|
||||||
|
.initregs = s1d13xxxfb_initregs,
|
||||||
|
.initregssize = ARRAY_SIZE(s1d13xxxfb_initregs),
|
||||||
|
.platform_init_video = NULL,
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
.platform_suspend_video = NULL,
|
||||||
|
.platform_resume_video = NULL,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource s1d13xxxfb_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = 0x1d600000UL,
|
||||||
|
.end = 0x1d73FFFFUL,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = 0x1d400000UL,
|
||||||
|
.end = 0x1d4001FFUL,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device s1d13xxxfb_device = {
|
||||||
|
.name = S1D_DEVICENAME,
|
||||||
|
.id = 0,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &s1d13xxxfb_data,
|
||||||
|
},
|
||||||
|
.num_resources = ARRAY_SIZE(s1d13xxxfb_resources),
|
||||||
|
.resource = s1d13xxxfb_resources,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static int __init platform_init(void)
|
static int __init platform_init(void)
|
||||||
{
|
{
|
||||||
|
#if defined(CONFIG_SMC91X)
|
||||||
platform_device_register(&smc91x_device);
|
platform_device_register(&smc91x_device);
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_FB_S1D13XXX)
|
||||||
|
platform_device_register(&s1d13xxxfb_device);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
arch_initcall(platform_init);
|
arch_initcall(platform_init);
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
*
|
*
|
||||||
* Setup routines for OAKS32R Board
|
* Setup routines for OAKS32R Board
|
||||||
*
|
*
|
||||||
* Copyright (c) 2002-2004 Hiroyuki Kondo, Hirokazu Takata,
|
* Copyright (c) 2002-2005 Hiroyuki Kondo, Hirokazu Takata,
|
||||||
* Hitoshi Yamamoto, Mamoru Sakugawa
|
* Hitoshi Yamamoto, Mamoru Sakugawa
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
|
@ -139,5 +139,4 @@ void __init init_IRQ(void)
|
||||||
icu_data[M32R_IRQ_SIO1_S].icucr = 0;
|
icu_data[M32R_IRQ_SIO1_S].icucr = 0;
|
||||||
disable_oaks32r_irq(M32R_IRQ_SIO1_S);
|
disable_oaks32r_irq(M32R_IRQ_SIO1_S);
|
||||||
#endif /* CONFIG_SERIAL_M32R_SIO */
|
#endif /* CONFIG_SERIAL_M32R_SIO */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* Setup routines for Renesas OPSPUT Board
|
* Setup routines for Renesas OPSPUT Board
|
||||||
*
|
*
|
||||||
* Copyright (c) 2002-2004
|
* Copyright (c) 2002-2005
|
||||||
* Hiroyuki Kondo, Hirokazu Takata,
|
* Hiroyuki Kondo, Hirokazu Takata,
|
||||||
* Hitoshi Yamamoto, Takeo Takahashi, Mamoru Sakugawa
|
* Hitoshi Yamamoto, Takeo Takahashi, Mamoru Sakugawa
|
||||||
*
|
*
|
||||||
|
@ -439,7 +439,7 @@ void __init init_IRQ(void)
|
||||||
icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01;
|
icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01;
|
||||||
enable_opsput_irq(M32R_IRQ_INT2);
|
enable_opsput_irq(M32R_IRQ_INT2);
|
||||||
|
|
||||||
//#if defined(CONFIG_VIDEO_M32R_AR)
|
#if defined(CONFIG_VIDEO_M32R_AR)
|
||||||
/*
|
/*
|
||||||
* INT3# is used for AR
|
* INT3# is used for AR
|
||||||
*/
|
*/
|
||||||
|
@ -449,9 +449,11 @@ void __init init_IRQ(void)
|
||||||
irq_desc[M32R_IRQ_INT3].depth = 1;
|
irq_desc[M32R_IRQ_INT3].depth = 1;
|
||||||
icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
|
icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
|
||||||
disable_opsput_irq(M32R_IRQ_INT3);
|
disable_opsput_irq(M32R_IRQ_INT3);
|
||||||
//#endif /* CONFIG_VIDEO_M32R_AR */
|
#endif /* CONFIG_VIDEO_M32R_AR */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_SMC91X)
|
||||||
|
|
||||||
#define LAN_IOSTART 0x300
|
#define LAN_IOSTART 0x300
|
||||||
#define LAN_IOEND 0x320
|
#define LAN_IOEND 0x320
|
||||||
static struct resource smc91x_resources[] = {
|
static struct resource smc91x_resources[] = {
|
||||||
|
@ -473,10 +475,55 @@ static struct platform_device smc91x_device = {
|
||||||
.num_resources = ARRAY_SIZE(smc91x_resources),
|
.num_resources = ARRAY_SIZE(smc91x_resources),
|
||||||
.resource = smc91x_resources,
|
.resource = smc91x_resources,
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_FB_S1D13XXX)
|
||||||
|
|
||||||
|
#include <video/s1d13xxxfb.h>
|
||||||
|
#include <asm/s1d13806.h>
|
||||||
|
|
||||||
|
static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
|
||||||
|
.initregs = s1d13xxxfb_initregs,
|
||||||
|
.initregssize = ARRAY_SIZE(s1d13xxxfb_initregs),
|
||||||
|
.platform_init_video = NULL,
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
.platform_suspend_video = NULL,
|
||||||
|
.platform_resume_video = NULL,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource s1d13xxxfb_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = 0x10600000UL,
|
||||||
|
.end = 0x1073FFFFUL,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = 0x10400000UL,
|
||||||
|
.end = 0x104001FFUL,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device s1d13xxxfb_device = {
|
||||||
|
.name = S1D_DEVICENAME,
|
||||||
|
.id = 0,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &s1d13xxxfb_data,
|
||||||
|
},
|
||||||
|
.num_resources = ARRAY_SIZE(s1d13xxxfb_resources),
|
||||||
|
.resource = s1d13xxxfb_resources,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static int __init platform_init(void)
|
static int __init platform_init(void)
|
||||||
{
|
{
|
||||||
|
#if defined(CONFIG_SMC91X)
|
||||||
platform_device_register(&smc91x_device);
|
platform_device_register(&smc91x_device);
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_FB_S1D13XXX)
|
||||||
|
platform_device_register(&s1d13xxxfb_device);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
arch_initcall(platform_init);
|
arch_initcall(platform_init);
|
||||||
|
|
|
@ -452,7 +452,7 @@ static u32 __pmac read_gpio(struct device_node *np)
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, u32 state)
|
static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg)
|
||||||
{
|
{
|
||||||
/* Ok, this could be made a bit smarter, but let's be robust for now. We
|
/* Ok, this could be made a bit smarter, but let's be robust for now. We
|
||||||
* always force a speed change to high speed before sleep, to make sure
|
* always force a speed change to high speed before sleep, to make sure
|
||||||
|
|
|
@ -49,160 +49,219 @@ extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct cpu_spec cpu_specs[] = {
|
struct cpu_spec cpu_specs[] = {
|
||||||
{ /* Power3 */
|
{ /* Power3 */
|
||||||
0xffff0000, 0x00400000, "POWER3 (630)",
|
.pvr_mask = 0xffff0000,
|
||||||
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
.pvr_value = 0x00400000,
|
||||||
CPU_FTR_IABR | CPU_FTR_PMC8,
|
.cpu_name = "POWER3 (630)",
|
||||||
COMMON_USER_PPC64,
|
.cpu_features = CPU_FTR_SPLIT_ID_CACHE |
|
||||||
128, 128,
|
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
|
||||||
__setup_cpu_power3,
|
CPU_FTR_PMC8,
|
||||||
COMMON_PPC64_FW
|
.cpu_user_features = COMMON_USER_PPC64,
|
||||||
},
|
.icache_bsize = 128,
|
||||||
{ /* Power3+ */
|
.dcache_bsize = 128,
|
||||||
0xffff0000, 0x00410000, "POWER3 (630+)",
|
.cpu_setup = __setup_cpu_power3,
|
||||||
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
.firmware_features = COMMON_PPC64_FW,
|
||||||
CPU_FTR_IABR | CPU_FTR_PMC8,
|
},
|
||||||
COMMON_USER_PPC64,
|
{ /* Power3+ */
|
||||||
128, 128,
|
.pvr_mask = 0xffff0000,
|
||||||
__setup_cpu_power3,
|
.pvr_value = 0x00410000,
|
||||||
COMMON_PPC64_FW
|
.cpu_name = "POWER3 (630+)",
|
||||||
},
|
.cpu_features = CPU_FTR_SPLIT_ID_CACHE |
|
||||||
{ /* Northstar */
|
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
|
||||||
0xffff0000, 0x00330000, "RS64-II (northstar)",
|
CPU_FTR_PMC8,
|
||||||
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
.cpu_user_features = COMMON_USER_PPC64,
|
||||||
CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
|
.icache_bsize = 128,
|
||||||
COMMON_USER_PPC64,
|
.dcache_bsize = 128,
|
||||||
128, 128,
|
.cpu_setup = __setup_cpu_power3,
|
||||||
__setup_cpu_power3,
|
.firmware_features = COMMON_PPC64_FW,
|
||||||
COMMON_PPC64_FW
|
},
|
||||||
},
|
{ /* Northstar */
|
||||||
{ /* Pulsar */
|
.pvr_mask = 0xffff0000,
|
||||||
0xffff0000, 0x00340000, "RS64-III (pulsar)",
|
.pvr_value = 0x00330000,
|
||||||
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
.cpu_name = "RS64-II (northstar)",
|
||||||
CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
|
.cpu_features = CPU_FTR_SPLIT_ID_CACHE |
|
||||||
COMMON_USER_PPC64,
|
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
|
||||||
128, 128,
|
CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL,
|
||||||
__setup_cpu_power3,
|
.cpu_user_features = COMMON_USER_PPC64,
|
||||||
COMMON_PPC64_FW
|
.icache_bsize = 128,
|
||||||
},
|
.dcache_bsize = 128,
|
||||||
{ /* I-star */
|
.cpu_setup = __setup_cpu_power3,
|
||||||
0xffff0000, 0x00360000, "RS64-III (icestar)",
|
.firmware_features = COMMON_PPC64_FW,
|
||||||
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
},
|
||||||
CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
|
{ /* Pulsar */
|
||||||
COMMON_USER_PPC64,
|
.pvr_mask = 0xffff0000,
|
||||||
128, 128,
|
.pvr_value = 0x00340000,
|
||||||
__setup_cpu_power3,
|
.cpu_name = "RS64-III (pulsar)",
|
||||||
COMMON_PPC64_FW
|
.cpu_features = CPU_FTR_SPLIT_ID_CACHE |
|
||||||
},
|
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
|
||||||
{ /* S-star */
|
CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL,
|
||||||
0xffff0000, 0x00370000, "RS64-IV (sstar)",
|
.cpu_user_features = COMMON_USER_PPC64,
|
||||||
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
.icache_bsize = 128,
|
||||||
CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
|
.dcache_bsize = 128,
|
||||||
COMMON_USER_PPC64,
|
.cpu_setup = __setup_cpu_power3,
|
||||||
128, 128,
|
.firmware_features = COMMON_PPC64_FW,
|
||||||
__setup_cpu_power3,
|
},
|
||||||
COMMON_PPC64_FW
|
{ /* I-star */
|
||||||
},
|
.pvr_mask = 0xffff0000,
|
||||||
{ /* Power4 */
|
.pvr_value = 0x00360000,
|
||||||
0xffff0000, 0x00350000, "POWER4 (gp)",
|
.cpu_name = "RS64-III (icestar)",
|
||||||
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
.cpu_features = CPU_FTR_SPLIT_ID_CACHE |
|
||||||
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
|
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
|
||||||
COMMON_USER_PPC64,
|
CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL,
|
||||||
128, 128,
|
.cpu_user_features = COMMON_USER_PPC64,
|
||||||
__setup_cpu_power4,
|
.icache_bsize = 128,
|
||||||
COMMON_PPC64_FW
|
.dcache_bsize = 128,
|
||||||
},
|
.cpu_setup = __setup_cpu_power3,
|
||||||
{ /* Power4+ */
|
.firmware_features = COMMON_PPC64_FW,
|
||||||
0xffff0000, 0x00380000, "POWER4+ (gq)",
|
},
|
||||||
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
{ /* S-star */
|
||||||
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
|
.pvr_mask = 0xffff0000,
|
||||||
COMMON_USER_PPC64,
|
.pvr_value = 0x00370000,
|
||||||
128, 128,
|
.cpu_name = "RS64-IV (sstar)",
|
||||||
__setup_cpu_power4,
|
.cpu_features = CPU_FTR_SPLIT_ID_CACHE |
|
||||||
COMMON_PPC64_FW
|
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
|
||||||
},
|
CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL,
|
||||||
{ /* PPC970 */
|
.cpu_user_features = COMMON_USER_PPC64,
|
||||||
0xffff0000, 0x00390000, "PPC970",
|
.icache_bsize = 128,
|
||||||
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
.dcache_bsize = 128,
|
||||||
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
|
.cpu_setup = __setup_cpu_power3,
|
||||||
CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
|
.firmware_features = COMMON_PPC64_FW,
|
||||||
COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP,
|
},
|
||||||
128, 128,
|
{ /* Power4 */
|
||||||
__setup_cpu_ppc970,
|
.pvr_mask = 0xffff0000,
|
||||||
COMMON_PPC64_FW
|
.pvr_value = 0x00350000,
|
||||||
},
|
.cpu_name = "POWER4 (gp)",
|
||||||
{ /* PPC970FX */
|
.cpu_features = CPU_FTR_SPLIT_ID_CACHE |
|
||||||
0xffff0000, 0x003c0000, "PPC970FX",
|
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
||||||
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
|
||||||
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
|
.cpu_user_features = COMMON_USER_PPC64,
|
||||||
CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
|
.icache_bsize = 128,
|
||||||
COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP,
|
.dcache_bsize = 128,
|
||||||
128, 128,
|
.cpu_setup = __setup_cpu_power4,
|
||||||
__setup_cpu_ppc970,
|
.firmware_features = COMMON_PPC64_FW,
|
||||||
COMMON_PPC64_FW
|
},
|
||||||
},
|
{ /* Power4+ */
|
||||||
{ /* Power5 */
|
.pvr_mask = 0xffff0000,
|
||||||
0xffff0000, 0x003a0000, "POWER5 (gr)",
|
.pvr_value = 0x00380000,
|
||||||
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
.cpu_name = "POWER4+ (gq)",
|
||||||
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT |
|
.cpu_features = CPU_FTR_SPLIT_ID_CACHE |
|
||||||
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
|
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
||||||
CPU_FTR_MMCRA_SIHV,
|
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
|
||||||
COMMON_USER_PPC64,
|
.cpu_user_features = COMMON_USER_PPC64,
|
||||||
128, 128,
|
.icache_bsize = 128,
|
||||||
__setup_cpu_power4,
|
.dcache_bsize = 128,
|
||||||
COMMON_PPC64_FW
|
.cpu_setup = __setup_cpu_power4,
|
||||||
},
|
.firmware_features = COMMON_PPC64_FW,
|
||||||
{ /* Power5 */
|
},
|
||||||
0xffff0000, 0x003b0000, "POWER5 (gs)",
|
{ /* PPC970 */
|
||||||
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
.pvr_mask = 0xffff0000,
|
||||||
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT |
|
.pvr_value = 0x00390000,
|
||||||
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
|
.cpu_name = "PPC970",
|
||||||
CPU_FTR_MMCRA_SIHV,
|
.cpu_features = CPU_FTR_SPLIT_ID_CACHE |
|
||||||
COMMON_USER_PPC64,
|
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
||||||
128, 128,
|
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
|
||||||
__setup_cpu_power4,
|
CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
|
||||||
COMMON_PPC64_FW
|
.cpu_user_features = COMMON_USER_PPC64 |
|
||||||
},
|
PPC_FEATURE_HAS_ALTIVEC_COMP,
|
||||||
{ /* BE DD1.x */
|
.icache_bsize = 128,
|
||||||
0xffff0000, 0x00700000, "Broadband Engine",
|
.dcache_bsize = 128,
|
||||||
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
.cpu_setup = __setup_cpu_ppc970,
|
||||||
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
|
.firmware_features = COMMON_PPC64_FW,
|
||||||
CPU_FTR_SMT,
|
},
|
||||||
COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP,
|
{ /* PPC970FX */
|
||||||
128, 128,
|
.pvr_mask = 0xffff0000,
|
||||||
__setup_cpu_be,
|
.pvr_value = 0x003c0000,
|
||||||
COMMON_PPC64_FW
|
.cpu_name = "PPC970FX",
|
||||||
},
|
.cpu_features = CPU_FTR_SPLIT_ID_CACHE |
|
||||||
{ /* default match */
|
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
||||||
0x00000000, 0x00000000, "POWER4 (compatible)",
|
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
|
||||||
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
|
||||||
CPU_FTR_PPCAS_ARCH_V2,
|
.cpu_user_features = COMMON_USER_PPC64 |
|
||||||
COMMON_USER_PPC64,
|
PPC_FEATURE_HAS_ALTIVEC_COMP,
|
||||||
128, 128,
|
.icache_bsize = 128,
|
||||||
__setup_cpu_power4,
|
.dcache_bsize = 128,
|
||||||
COMMON_PPC64_FW
|
.cpu_setup = __setup_cpu_ppc970,
|
||||||
}
|
.firmware_features = COMMON_PPC64_FW,
|
||||||
|
},
|
||||||
|
{ /* Power5 */
|
||||||
|
.pvr_mask = 0xffff0000,
|
||||||
|
.pvr_value = 0x003a0000,
|
||||||
|
.cpu_name = "POWER5 (gr)",
|
||||||
|
.cpu_features = CPU_FTR_SPLIT_ID_CACHE |
|
||||||
|
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
||||||
|
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT |
|
||||||
|
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
|
||||||
|
CPU_FTR_MMCRA_SIHV,
|
||||||
|
.cpu_user_features = COMMON_USER_PPC64,
|
||||||
|
.icache_bsize = 128,
|
||||||
|
.dcache_bsize = 128,
|
||||||
|
.cpu_setup = __setup_cpu_power4,
|
||||||
|
.firmware_features = COMMON_PPC64_FW,
|
||||||
|
},
|
||||||
|
{ /* Power5 */
|
||||||
|
.pvr_mask = 0xffff0000,
|
||||||
|
.pvr_value = 0x003b0000,
|
||||||
|
.cpu_name = "POWER5 (gs)",
|
||||||
|
.cpu_features = CPU_FTR_SPLIT_ID_CACHE |
|
||||||
|
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
||||||
|
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT |
|
||||||
|
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
|
||||||
|
CPU_FTR_MMCRA_SIHV,
|
||||||
|
.cpu_user_features = COMMON_USER_PPC64,
|
||||||
|
.icache_bsize = 128,
|
||||||
|
.dcache_bsize = 128,
|
||||||
|
.cpu_setup = __setup_cpu_power4,
|
||||||
|
.firmware_features = COMMON_PPC64_FW,
|
||||||
|
},
|
||||||
|
{ /* BE DD1.x */
|
||||||
|
.pvr_mask = 0xffff0000,
|
||||||
|
.pvr_value = 0x00700000,
|
||||||
|
.cpu_name = "Broadband Engine",
|
||||||
|
.cpu_features = CPU_FTR_SPLIT_ID_CACHE |
|
||||||
|
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
||||||
|
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
|
||||||
|
CPU_FTR_SMT,
|
||||||
|
.cpu_user_features = COMMON_USER_PPC64 |
|
||||||
|
PPC_FEATURE_HAS_ALTIVEC_COMP,
|
||||||
|
.icache_bsize = 128,
|
||||||
|
.dcache_bsize = 128,
|
||||||
|
.cpu_setup = __setup_cpu_be,
|
||||||
|
.firmware_features = COMMON_PPC64_FW,
|
||||||
|
},
|
||||||
|
{ /* default match */
|
||||||
|
.pvr_mask = 0x00000000,
|
||||||
|
.pvr_value = 0x00000000,
|
||||||
|
.cpu_name = "POWER4 (compatible)",
|
||||||
|
.cpu_features = CPU_FTR_SPLIT_ID_CACHE |
|
||||||
|
CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
|
||||||
|
CPU_FTR_PPCAS_ARCH_V2,
|
||||||
|
.cpu_user_features = COMMON_USER_PPC64,
|
||||||
|
.icache_bsize = 128,
|
||||||
|
.dcache_bsize = 128,
|
||||||
|
.cpu_setup = __setup_cpu_power4,
|
||||||
|
.firmware_features = COMMON_PPC64_FW,
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = {
|
firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = {
|
||||||
{FW_FEATURE_PFT, "hcall-pft"},
|
{FW_FEATURE_PFT, "hcall-pft"},
|
||||||
{FW_FEATURE_TCE, "hcall-tce"},
|
{FW_FEATURE_TCE, "hcall-tce"},
|
||||||
{FW_FEATURE_SPRG0, "hcall-sprg0"},
|
{FW_FEATURE_SPRG0, "hcall-sprg0"},
|
||||||
{FW_FEATURE_DABR, "hcall-dabr"},
|
{FW_FEATURE_DABR, "hcall-dabr"},
|
||||||
{FW_FEATURE_COPY, "hcall-copy"},
|
{FW_FEATURE_COPY, "hcall-copy"},
|
||||||
{FW_FEATURE_ASR, "hcall-asr"},
|
{FW_FEATURE_ASR, "hcall-asr"},
|
||||||
{FW_FEATURE_DEBUG, "hcall-debug"},
|
{FW_FEATURE_DEBUG, "hcall-debug"},
|
||||||
{FW_FEATURE_PERF, "hcall-perf"},
|
{FW_FEATURE_PERF, "hcall-perf"},
|
||||||
{FW_FEATURE_DUMP, "hcall-dump"},
|
{FW_FEATURE_DUMP, "hcall-dump"},
|
||||||
{FW_FEATURE_INTERRUPT, "hcall-interrupt"},
|
{FW_FEATURE_INTERRUPT, "hcall-interrupt"},
|
||||||
{FW_FEATURE_MIGRATE, "hcall-migrate"},
|
{FW_FEATURE_MIGRATE, "hcall-migrate"},
|
||||||
{FW_FEATURE_PERFMON, "hcall-perfmon"},
|
{FW_FEATURE_PERFMON, "hcall-perfmon"},
|
||||||
{FW_FEATURE_CRQ, "hcall-crq"},
|
{FW_FEATURE_CRQ, "hcall-crq"},
|
||||||
{FW_FEATURE_VIO, "hcall-vio"},
|
{FW_FEATURE_VIO, "hcall-vio"},
|
||||||
{FW_FEATURE_RDMA, "hcall-rdma"},
|
{FW_FEATURE_RDMA, "hcall-rdma"},
|
||||||
{FW_FEATURE_LLAN, "hcall-lLAN"},
|
{FW_FEATURE_LLAN, "hcall-lLAN"},
|
||||||
{FW_FEATURE_BULK, "hcall-bulk"},
|
{FW_FEATURE_BULK, "hcall-bulk"},
|
||||||
{FW_FEATURE_XDABR, "hcall-xdabr"},
|
{FW_FEATURE_XDABR, "hcall-xdabr"},
|
||||||
{FW_FEATURE_MULTITCE, "hcall-multi-tce"},
|
{FW_FEATURE_MULTITCE, "hcall-multi-tce"},
|
||||||
{FW_FEATURE_SPLPAR, "hcall-splpar"},
|
{FW_FEATURE_SPLPAR, "hcall-splpar"},
|
||||||
};
|
};
|
||||||
|
|
|
@ -308,6 +308,7 @@ exception_marker:
|
||||||
label##_pSeries: \
|
label##_pSeries: \
|
||||||
HMT_MEDIUM; \
|
HMT_MEDIUM; \
|
||||||
mtspr SPRG1,r13; /* save r13 */ \
|
mtspr SPRG1,r13; /* save r13 */ \
|
||||||
|
RUNLATCH_ON(r13); \
|
||||||
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
|
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
|
||||||
|
|
||||||
#define STD_EXCEPTION_ISERIES(n, label, area) \
|
#define STD_EXCEPTION_ISERIES(n, label, area) \
|
||||||
|
@ -315,6 +316,7 @@ label##_pSeries: \
|
||||||
label##_iSeries: \
|
label##_iSeries: \
|
||||||
HMT_MEDIUM; \
|
HMT_MEDIUM; \
|
||||||
mtspr SPRG1,r13; /* save r13 */ \
|
mtspr SPRG1,r13; /* save r13 */ \
|
||||||
|
RUNLATCH_ON(r13); \
|
||||||
EXCEPTION_PROLOG_ISERIES_1(area); \
|
EXCEPTION_PROLOG_ISERIES_1(area); \
|
||||||
EXCEPTION_PROLOG_ISERIES_2; \
|
EXCEPTION_PROLOG_ISERIES_2; \
|
||||||
b label##_common
|
b label##_common
|
||||||
|
@ -324,6 +326,7 @@ label##_iSeries: \
|
||||||
label##_iSeries: \
|
label##_iSeries: \
|
||||||
HMT_MEDIUM; \
|
HMT_MEDIUM; \
|
||||||
mtspr SPRG1,r13; /* save r13 */ \
|
mtspr SPRG1,r13; /* save r13 */ \
|
||||||
|
RUNLATCH_ON(r13); \
|
||||||
EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \
|
EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \
|
||||||
lbz r10,PACAPROCENABLED(r13); \
|
lbz r10,PACAPROCENABLED(r13); \
|
||||||
cmpwi 0,r10,0; \
|
cmpwi 0,r10,0; \
|
||||||
|
@ -393,6 +396,7 @@ __start_interrupts:
|
||||||
_machine_check_pSeries:
|
_machine_check_pSeries:
|
||||||
HMT_MEDIUM
|
HMT_MEDIUM
|
||||||
mtspr SPRG1,r13 /* save r13 */
|
mtspr SPRG1,r13 /* save r13 */
|
||||||
|
RUNLATCH_ON(r13)
|
||||||
EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
|
EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
|
||||||
|
|
||||||
. = 0x300
|
. = 0x300
|
||||||
|
@ -419,6 +423,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
|
||||||
data_access_slb_pSeries:
|
data_access_slb_pSeries:
|
||||||
HMT_MEDIUM
|
HMT_MEDIUM
|
||||||
mtspr SPRG1,r13
|
mtspr SPRG1,r13
|
||||||
|
RUNLATCH_ON(r13)
|
||||||
mfspr r13,SPRG3 /* get paca address into r13 */
|
mfspr r13,SPRG3 /* get paca address into r13 */
|
||||||
std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
|
std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
|
||||||
std r10,PACA_EXSLB+EX_R10(r13)
|
std r10,PACA_EXSLB+EX_R10(r13)
|
||||||
|
@ -439,6 +444,7 @@ data_access_slb_pSeries:
|
||||||
instruction_access_slb_pSeries:
|
instruction_access_slb_pSeries:
|
||||||
HMT_MEDIUM
|
HMT_MEDIUM
|
||||||
mtspr SPRG1,r13
|
mtspr SPRG1,r13
|
||||||
|
RUNLATCH_ON(r13)
|
||||||
mfspr r13,SPRG3 /* get paca address into r13 */
|
mfspr r13,SPRG3 /* get paca address into r13 */
|
||||||
std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
|
std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
|
||||||
std r10,PACA_EXSLB+EX_R10(r13)
|
std r10,PACA_EXSLB+EX_R10(r13)
|
||||||
|
@ -464,6 +470,7 @@ instruction_access_slb_pSeries:
|
||||||
.globl system_call_pSeries
|
.globl system_call_pSeries
|
||||||
system_call_pSeries:
|
system_call_pSeries:
|
||||||
HMT_MEDIUM
|
HMT_MEDIUM
|
||||||
|
RUNLATCH_ON(r9)
|
||||||
mr r9,r13
|
mr r9,r13
|
||||||
mfmsr r10
|
mfmsr r10
|
||||||
mfspr r13,SPRG3
|
mfspr r13,SPRG3
|
||||||
|
@ -707,11 +714,13 @@ fwnmi_data_area:
|
||||||
system_reset_fwnmi:
|
system_reset_fwnmi:
|
||||||
HMT_MEDIUM
|
HMT_MEDIUM
|
||||||
mtspr SPRG1,r13 /* save r13 */
|
mtspr SPRG1,r13 /* save r13 */
|
||||||
|
RUNLATCH_ON(r13)
|
||||||
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
|
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
|
||||||
.globl machine_check_fwnmi
|
.globl machine_check_fwnmi
|
||||||
machine_check_fwnmi:
|
machine_check_fwnmi:
|
||||||
HMT_MEDIUM
|
HMT_MEDIUM
|
||||||
mtspr SPRG1,r13 /* save r13 */
|
mtspr SPRG1,r13 /* save r13 */
|
||||||
|
RUNLATCH_ON(r13)
|
||||||
EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
|
EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -848,6 +857,7 @@ unrecov_fer:
|
||||||
.align 7
|
.align 7
|
||||||
.globl data_access_common
|
.globl data_access_common
|
||||||
data_access_common:
|
data_access_common:
|
||||||
|
RUNLATCH_ON(r10) /* It wont fit in the 0x300 handler */
|
||||||
mfspr r10,DAR
|
mfspr r10,DAR
|
||||||
std r10,PACA_EXGEN+EX_DAR(r13)
|
std r10,PACA_EXGEN+EX_DAR(r13)
|
||||||
mfspr r10,DSISR
|
mfspr r10,DSISR
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <asm/hvcall.h>
|
#include <asm/hvcall.h>
|
||||||
#include <asm/hvconsole.h>
|
#include <asm/hvconsole.h>
|
||||||
#include <asm/prom.h>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hvc_get_chars - retrieve characters from firmware for denoted vterm adatper
|
* hvc_get_chars - retrieve characters from firmware for denoted vterm adatper
|
||||||
|
@ -42,29 +41,14 @@ int hvc_get_chars(uint32_t vtermno, char *buf, int count)
|
||||||
unsigned long got;
|
unsigned long got;
|
||||||
|
|
||||||
if (plpar_hcall(H_GET_TERM_CHAR, vtermno, 0, 0, 0, &got,
|
if (plpar_hcall(H_GET_TERM_CHAR, vtermno, 0, 0, 0, &got,
|
||||||
(unsigned long *)buf, (unsigned long *)buf+1) == H_Success) {
|
(unsigned long *)buf, (unsigned long *)buf+1) == H_Success)
|
||||||
/*
|
|
||||||
* Work around a HV bug where it gives us a null
|
|
||||||
* after every \r. -- paulus
|
|
||||||
*/
|
|
||||||
if (got > 0) {
|
|
||||||
int i;
|
|
||||||
for (i = 1; i < got; ++i) {
|
|
||||||
if (buf[i] == 0 && buf[i-1] == '\r') {
|
|
||||||
--got;
|
|
||||||
if (i < got)
|
|
||||||
memmove(&buf[i], &buf[i+1],
|
|
||||||
got - i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return got;
|
return got;
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(hvc_get_chars);
|
EXPORT_SYMBOL(hvc_get_chars);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hvc_put_chars: send characters to firmware for denoted vterm adapter
|
* hvc_put_chars: send characters to firmware for denoted vterm adapter
|
||||||
* @vtermno: The vtermno or unit_address of the adapter from which the data
|
* @vtermno: The vtermno or unit_address of the adapter from which the data
|
||||||
|
@ -88,34 +72,3 @@ int hvc_put_chars(uint32_t vtermno, const char *buf, int count)
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(hvc_put_chars);
|
EXPORT_SYMBOL(hvc_put_chars);
|
||||||
|
|
||||||
/*
|
|
||||||
* We hope/assume that the first vty found corresponds to the first console
|
|
||||||
* device.
|
|
||||||
*/
|
|
||||||
int hvc_find_vtys(void)
|
|
||||||
{
|
|
||||||
struct device_node *vty;
|
|
||||||
int num_found = 0;
|
|
||||||
|
|
||||||
for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL;
|
|
||||||
vty = of_find_node_by_name(vty, "vty")) {
|
|
||||||
uint32_t *vtermno;
|
|
||||||
|
|
||||||
/* We have statically defined space for only a certain number of
|
|
||||||
* console adapters. */
|
|
||||||
if (num_found >= MAX_NR_HVC_CONSOLES)
|
|
||||||
break;
|
|
||||||
|
|
||||||
vtermno = (uint32_t *)get_property(vty, "reg", NULL);
|
|
||||||
if (!vtermno)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (device_is_compatible(vty, "hvterm1")) {
|
|
||||||
hvc_instantiate(*vtermno, num_found);
|
|
||||||
++num_found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return num_found;
|
|
||||||
}
|
|
||||||
|
|
|
@ -834,6 +834,92 @@ static int __init iSeries_src_init(void)
|
||||||
|
|
||||||
late_initcall(iSeries_src_init);
|
late_initcall(iSeries_src_init);
|
||||||
|
|
||||||
|
static inline void process_iSeries_events(void)
|
||||||
|
{
|
||||||
|
asm volatile ("li 0,0x5555; sc" : : : "r0", "r3");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void yield_shared_processor(void)
|
||||||
|
{
|
||||||
|
unsigned long tb;
|
||||||
|
|
||||||
|
HvCall_setEnabledInterrupts(HvCall_MaskIPI |
|
||||||
|
HvCall_MaskLpEvent |
|
||||||
|
HvCall_MaskLpProd |
|
||||||
|
HvCall_MaskTimeout);
|
||||||
|
|
||||||
|
tb = get_tb();
|
||||||
|
/* Compute future tb value when yield should expire */
|
||||||
|
HvCall_yieldProcessor(HvCall_YieldTimed, tb+tb_ticks_per_jiffy);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The decrementer stops during the yield. Force a fake decrementer
|
||||||
|
* here and let the timer_interrupt code sort out the actual time.
|
||||||
|
*/
|
||||||
|
get_paca()->lppaca.int_dword.fields.decr_int = 1;
|
||||||
|
process_iSeries_events();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int iseries_shared_idle(void)
|
||||||
|
{
|
||||||
|
while (1) {
|
||||||
|
while (!need_resched() && !hvlpevent_is_pending()) {
|
||||||
|
local_irq_disable();
|
||||||
|
ppc64_runlatch_off();
|
||||||
|
|
||||||
|
/* Recheck with irqs off */
|
||||||
|
if (!need_resched() && !hvlpevent_is_pending())
|
||||||
|
yield_shared_processor();
|
||||||
|
|
||||||
|
HMT_medium();
|
||||||
|
local_irq_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
ppc64_runlatch_on();
|
||||||
|
|
||||||
|
if (hvlpevent_is_pending())
|
||||||
|
process_iSeries_events();
|
||||||
|
|
||||||
|
schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int iseries_dedicated_idle(void)
|
||||||
|
{
|
||||||
|
long oldval;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
|
||||||
|
|
||||||
|
if (!oldval) {
|
||||||
|
set_thread_flag(TIF_POLLING_NRFLAG);
|
||||||
|
|
||||||
|
while (!need_resched()) {
|
||||||
|
ppc64_runlatch_off();
|
||||||
|
HMT_low();
|
||||||
|
|
||||||
|
if (hvlpevent_is_pending()) {
|
||||||
|
HMT_medium();
|
||||||
|
ppc64_runlatch_on();
|
||||||
|
process_iSeries_events();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HMT_medium();
|
||||||
|
clear_thread_flag(TIF_POLLING_NRFLAG);
|
||||||
|
} else {
|
||||||
|
set_need_resched();
|
||||||
|
}
|
||||||
|
|
||||||
|
ppc64_runlatch_on();
|
||||||
|
schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_PCI
|
#ifndef CONFIG_PCI
|
||||||
void __init iSeries_init_IRQ(void) { }
|
void __init iSeries_init_IRQ(void) { }
|
||||||
#endif
|
#endif
|
||||||
|
@ -859,5 +945,13 @@ void __init iSeries_early_setup(void)
|
||||||
ppc_md.get_rtc_time = iSeries_get_rtc_time;
|
ppc_md.get_rtc_time = iSeries_get_rtc_time;
|
||||||
ppc_md.calibrate_decr = iSeries_calibrate_decr;
|
ppc_md.calibrate_decr = iSeries_calibrate_decr;
|
||||||
ppc_md.progress = iSeries_progress;
|
ppc_md.progress = iSeries_progress;
|
||||||
|
|
||||||
|
if (get_paca()->lppaca.shared_proc) {
|
||||||
|
ppc_md.idle_loop = iseries_shared_idle;
|
||||||
|
printk(KERN_INFO "Using shared processor idle loop\n");
|
||||||
|
} else {
|
||||||
|
ppc_md.idle_loop = iseries_dedicated_idle;
|
||||||
|
printk(KERN_INFO "Using dedicated idle loop\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,109 +20,18 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
#include <linux/cpu.h>
|
#include <linux/cpu.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/sysctl.h>
|
#include <linux/sysctl.h>
|
||||||
#include <linux/smp.h>
|
|
||||||
|
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/mmu.h>
|
|
||||||
#include <asm/cputable.h>
|
#include <asm/cputable.h>
|
||||||
#include <asm/time.h>
|
#include <asm/time.h>
|
||||||
#include <asm/iSeries/HvCall.h>
|
|
||||||
#include <asm/iSeries/ItLpQueue.h>
|
|
||||||
#include <asm/plpar_wrappers.h>
|
|
||||||
#include <asm/systemcfg.h>
|
#include <asm/systemcfg.h>
|
||||||
|
#include <asm/machdep.h>
|
||||||
|
|
||||||
extern void power4_idle(void);
|
extern void power4_idle(void);
|
||||||
|
|
||||||
static int (*idle_loop)(void);
|
int default_idle(void)
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_ISERIES
|
|
||||||
static unsigned long maxYieldTime = 0;
|
|
||||||
static unsigned long minYieldTime = 0xffffffffffffffffUL;
|
|
||||||
|
|
||||||
static inline void process_iSeries_events(void)
|
|
||||||
{
|
|
||||||
asm volatile ("li 0,0x5555; sc" : : : "r0", "r3");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void yield_shared_processor(void)
|
|
||||||
{
|
|
||||||
unsigned long tb;
|
|
||||||
unsigned long yieldTime;
|
|
||||||
|
|
||||||
HvCall_setEnabledInterrupts(HvCall_MaskIPI |
|
|
||||||
HvCall_MaskLpEvent |
|
|
||||||
HvCall_MaskLpProd |
|
|
||||||
HvCall_MaskTimeout);
|
|
||||||
|
|
||||||
tb = get_tb();
|
|
||||||
/* Compute future tb value when yield should expire */
|
|
||||||
HvCall_yieldProcessor(HvCall_YieldTimed, tb+tb_ticks_per_jiffy);
|
|
||||||
|
|
||||||
yieldTime = get_tb() - tb;
|
|
||||||
if (yieldTime > maxYieldTime)
|
|
||||||
maxYieldTime = yieldTime;
|
|
||||||
|
|
||||||
if (yieldTime < minYieldTime)
|
|
||||||
minYieldTime = yieldTime;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The decrementer stops during the yield. Force a fake decrementer
|
|
||||||
* here and let the timer_interrupt code sort out the actual time.
|
|
||||||
*/
|
|
||||||
get_paca()->lppaca.int_dword.fields.decr_int = 1;
|
|
||||||
process_iSeries_events();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int iSeries_idle(void)
|
|
||||||
{
|
|
||||||
struct paca_struct *lpaca;
|
|
||||||
long oldval;
|
|
||||||
|
|
||||||
/* ensure iSeries run light will be out when idle */
|
|
||||||
ppc64_runlatch_off();
|
|
||||||
|
|
||||||
lpaca = get_paca();
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
if (lpaca->lppaca.shared_proc) {
|
|
||||||
if (hvlpevent_is_pending())
|
|
||||||
process_iSeries_events();
|
|
||||||
if (!need_resched())
|
|
||||||
yield_shared_processor();
|
|
||||||
} else {
|
|
||||||
oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
|
|
||||||
|
|
||||||
if (!oldval) {
|
|
||||||
set_thread_flag(TIF_POLLING_NRFLAG);
|
|
||||||
|
|
||||||
while (!need_resched()) {
|
|
||||||
HMT_medium();
|
|
||||||
if (hvlpevent_is_pending())
|
|
||||||
process_iSeries_events();
|
|
||||||
HMT_low();
|
|
||||||
}
|
|
||||||
|
|
||||||
HMT_medium();
|
|
||||||
clear_thread_flag(TIF_POLLING_NRFLAG);
|
|
||||||
} else {
|
|
||||||
set_need_resched();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ppc64_runlatch_on();
|
|
||||||
schedule();
|
|
||||||
ppc64_runlatch_off();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static int default_idle(void)
|
|
||||||
{
|
{
|
||||||
long oldval;
|
long oldval;
|
||||||
unsigned int cpu = smp_processor_id();
|
unsigned int cpu = smp_processor_id();
|
||||||
|
@ -134,7 +43,8 @@ static int default_idle(void)
|
||||||
set_thread_flag(TIF_POLLING_NRFLAG);
|
set_thread_flag(TIF_POLLING_NRFLAG);
|
||||||
|
|
||||||
while (!need_resched() && !cpu_is_offline(cpu)) {
|
while (!need_resched() && !cpu_is_offline(cpu)) {
|
||||||
barrier();
|
ppc64_runlatch_off();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Go into low thread priority and possibly
|
* Go into low thread priority and possibly
|
||||||
* low power mode.
|
* low power mode.
|
||||||
|
@ -149,6 +59,7 @@ static int default_idle(void)
|
||||||
set_need_resched();
|
set_need_resched();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ppc64_runlatch_on();
|
||||||
schedule();
|
schedule();
|
||||||
if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
|
if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
|
||||||
cpu_die();
|
cpu_die();
|
||||||
|
@ -157,127 +68,19 @@ static int default_idle(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_PSERIES
|
int native_idle(void)
|
||||||
|
|
||||||
DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
|
|
||||||
|
|
||||||
int dedicated_idle(void)
|
|
||||||
{
|
{
|
||||||
long oldval;
|
|
||||||
struct paca_struct *lpaca = get_paca(), *ppaca;
|
|
||||||
unsigned long start_snooze;
|
|
||||||
unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
|
|
||||||
unsigned int cpu = smp_processor_id();
|
|
||||||
|
|
||||||
ppaca = &paca[cpu ^ 1];
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
/*
|
ppc64_runlatch_off();
|
||||||
* Indicate to the HV that we are idle. Now would be
|
|
||||||
* a good time to find other work to dispatch.
|
|
||||||
*/
|
|
||||||
lpaca->lppaca.idle = 1;
|
|
||||||
|
|
||||||
oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
|
if (!need_resched())
|
||||||
if (!oldval) {
|
power4_idle();
|
||||||
set_thread_flag(TIF_POLLING_NRFLAG);
|
|
||||||
start_snooze = __get_tb() +
|
|
||||||
*smt_snooze_delay * tb_ticks_per_usec;
|
|
||||||
while (!need_resched() && !cpu_is_offline(cpu)) {
|
|
||||||
/*
|
|
||||||
* Go into low thread priority and possibly
|
|
||||||
* low power mode.
|
|
||||||
*/
|
|
||||||
HMT_low();
|
|
||||||
HMT_very_low();
|
|
||||||
|
|
||||||
if (*smt_snooze_delay == 0 ||
|
if (need_resched()) {
|
||||||
__get_tb() < start_snooze)
|
ppc64_runlatch_on();
|
||||||
continue;
|
schedule();
|
||||||
|
|
||||||
HMT_medium();
|
|
||||||
|
|
||||||
if (!(ppaca->lppaca.idle)) {
|
|
||||||
local_irq_disable();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We are about to sleep the thread
|
|
||||||
* and so wont be polling any
|
|
||||||
* more.
|
|
||||||
*/
|
|
||||||
clear_thread_flag(TIF_POLLING_NRFLAG);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SMT dynamic mode. Cede will result
|
|
||||||
* in this thread going dormant, if the
|
|
||||||
* partner thread is still doing work.
|
|
||||||
* Thread wakes up if partner goes idle,
|
|
||||||
* an interrupt is presented, or a prod
|
|
||||||
* occurs. Returning from the cede
|
|
||||||
* enables external interrupts.
|
|
||||||
*/
|
|
||||||
if (!need_resched())
|
|
||||||
cede_processor();
|
|
||||||
else
|
|
||||||
local_irq_enable();
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* Give the HV an opportunity at the
|
|
||||||
* processor, since we are not doing
|
|
||||||
* any work.
|
|
||||||
*/
|
|
||||||
poll_pending();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clear_thread_flag(TIF_POLLING_NRFLAG);
|
|
||||||
} else {
|
|
||||||
set_need_resched();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HMT_medium();
|
|
||||||
lpaca->lppaca.idle = 0;
|
|
||||||
schedule();
|
|
||||||
if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
|
|
||||||
cpu_die();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int shared_idle(void)
|
|
||||||
{
|
|
||||||
struct paca_struct *lpaca = get_paca();
|
|
||||||
unsigned int cpu = smp_processor_id();
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
/*
|
|
||||||
* Indicate to the HV that we are idle. Now would be
|
|
||||||
* a good time to find other work to dispatch.
|
|
||||||
*/
|
|
||||||
lpaca->lppaca.idle = 1;
|
|
||||||
|
|
||||||
while (!need_resched() && !cpu_is_offline(cpu)) {
|
|
||||||
local_irq_disable();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Yield the processor to the hypervisor. We return if
|
|
||||||
* an external interrupt occurs (which are driven prior
|
|
||||||
* to returning here) or if a prod occurs from another
|
|
||||||
* processor. When returning here, external interrupts
|
|
||||||
* are enabled.
|
|
||||||
*
|
|
||||||
* Check need_resched() again with interrupts disabled
|
|
||||||
* to avoid a race.
|
|
||||||
*/
|
|
||||||
if (!need_resched())
|
|
||||||
cede_processor();
|
|
||||||
else
|
|
||||||
local_irq_enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
HMT_medium();
|
|
||||||
lpaca->lppaca.idle = 0;
|
|
||||||
schedule();
|
|
||||||
if (cpu_is_offline(smp_processor_id()) &&
|
if (cpu_is_offline(smp_processor_id()) &&
|
||||||
system_state == SYSTEM_RUNNING)
|
system_state == SYSTEM_RUNNING)
|
||||||
cpu_die();
|
cpu_die();
|
||||||
|
@ -286,29 +89,10 @@ static int shared_idle(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_PPC_PSERIES */
|
|
||||||
|
|
||||||
static int native_idle(void)
|
|
||||||
{
|
|
||||||
while(1) {
|
|
||||||
/* check CPU type here */
|
|
||||||
if (!need_resched())
|
|
||||||
power4_idle();
|
|
||||||
if (need_resched())
|
|
||||||
schedule();
|
|
||||||
|
|
||||||
if (cpu_is_offline(raw_smp_processor_id()) &&
|
|
||||||
system_state == SYSTEM_RUNNING)
|
|
||||||
cpu_die();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CONFIG_PPC_ISERIES */
|
|
||||||
|
|
||||||
void cpu_idle(void)
|
void cpu_idle(void)
|
||||||
{
|
{
|
||||||
idle_loop();
|
BUG_ON(NULL == ppc_md.idle_loop);
|
||||||
|
ppc_md.idle_loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
int powersave_nap;
|
int powersave_nap;
|
||||||
|
@ -342,42 +126,3 @@ register_powersave_nap_sysctl(void)
|
||||||
}
|
}
|
||||||
__initcall(register_powersave_nap_sysctl);
|
__initcall(register_powersave_nap_sysctl);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int idle_setup(void)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Move that junk to each platform specific file, eventually define
|
|
||||||
* a pSeries_idle for shared processor stuff
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_PPC_ISERIES
|
|
||||||
idle_loop = iSeries_idle;
|
|
||||||
return 1;
|
|
||||||
#else
|
|
||||||
idle_loop = default_idle;
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_PPC_PSERIES
|
|
||||||
if (systemcfg->platform & PLATFORM_PSERIES) {
|
|
||||||
if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
|
|
||||||
if (get_paca()->lppaca.shared_proc) {
|
|
||||||
printk(KERN_INFO "Using shared processor idle loop\n");
|
|
||||||
idle_loop = shared_idle;
|
|
||||||
} else {
|
|
||||||
printk(KERN_INFO "Using dedicated idle loop\n");
|
|
||||||
idle_loop = dedicated_idle;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printk(KERN_INFO "Using default idle loop\n");
|
|
||||||
idle_loop = default_idle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_PPC_PSERIES */
|
|
||||||
#ifndef CONFIG_PPC_ISERIES
|
|
||||||
if (systemcfg->platform == PLATFORM_POWERMAC ||
|
|
||||||
systemcfg->platform == PLATFORM_MAPLE) {
|
|
||||||
printk(KERN_INFO "Using native/NAP idle loop\n");
|
|
||||||
idle_loop = native_idle;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_PPC_ISERIES */
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
|
@ -177,6 +177,8 @@ void __init maple_setup_arch(void)
|
||||||
#ifdef CONFIG_DUMMY_CONSOLE
|
#ifdef CONFIG_DUMMY_CONSOLE
|
||||||
conswitchp = &dummy_con;
|
conswitchp = &dummy_con;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
printk(KERN_INFO "Using native/NAP idle loop\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -297,4 +299,5 @@ struct machdep_calls __initdata maple_md = {
|
||||||
.get_rtc_time = maple_get_rtc_time,
|
.get_rtc_time = maple_get_rtc_time,
|
||||||
.calibrate_decr = generic_calibrate_decr,
|
.calibrate_decr = generic_calibrate_decr,
|
||||||
.progress = maple_progress,
|
.progress = maple_progress,
|
||||||
|
.idle_loop = native_idle,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1124,9 +1124,11 @@ _GLOBAL(sys_call_table32)
|
||||||
.llong .compat_sys_mq_getsetattr
|
.llong .compat_sys_mq_getsetattr
|
||||||
.llong .compat_sys_kexec_load
|
.llong .compat_sys_kexec_load
|
||||||
.llong .sys32_add_key
|
.llong .sys32_add_key
|
||||||
.llong .sys32_request_key
|
.llong .sys32_request_key /* 270 */
|
||||||
.llong .compat_sys_keyctl
|
.llong .compat_sys_keyctl
|
||||||
.llong .compat_sys_waitid
|
.llong .compat_sys_waitid
|
||||||
|
.llong .sys32_ioprio_set
|
||||||
|
.llong .sys32_ioprio_get
|
||||||
|
|
||||||
.balign 8
|
.balign 8
|
||||||
_GLOBAL(sys_call_table)
|
_GLOBAL(sys_call_table)
|
||||||
|
@ -1403,3 +1405,5 @@ _GLOBAL(sys_call_table)
|
||||||
.llong .sys_request_key /* 270 */
|
.llong .sys_request_key /* 270 */
|
||||||
.llong .sys_keyctl
|
.llong .sys_keyctl
|
||||||
.llong .sys_waitid
|
.llong .sys_waitid
|
||||||
|
.llong .sys_ioprio_set
|
||||||
|
.llong .sys_ioprio_get
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
|
|
||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
|
#include <linux/cpu.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
@ -82,6 +83,9 @@ int fwnmi_active; /* TRUE if an FWNMI handler is present */
|
||||||
extern void pSeries_system_reset_exception(struct pt_regs *regs);
|
extern void pSeries_system_reset_exception(struct pt_regs *regs);
|
||||||
extern int pSeries_machine_check_exception(struct pt_regs *regs);
|
extern int pSeries_machine_check_exception(struct pt_regs *regs);
|
||||||
|
|
||||||
|
static int pseries_shared_idle(void);
|
||||||
|
static int pseries_dedicated_idle(void);
|
||||||
|
|
||||||
static volatile void __iomem * chrp_int_ack_special;
|
static volatile void __iomem * chrp_int_ack_special;
|
||||||
struct mpic *pSeries_mpic;
|
struct mpic *pSeries_mpic;
|
||||||
|
|
||||||
|
@ -229,6 +233,20 @@ static void __init pSeries_setup_arch(void)
|
||||||
|
|
||||||
if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
|
if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
|
||||||
vpa_init(boot_cpuid);
|
vpa_init(boot_cpuid);
|
||||||
|
|
||||||
|
/* Choose an idle loop */
|
||||||
|
if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
|
||||||
|
if (get_paca()->lppaca.shared_proc) {
|
||||||
|
printk(KERN_INFO "Using shared processor idle loop\n");
|
||||||
|
ppc_md.idle_loop = pseries_shared_idle;
|
||||||
|
} else {
|
||||||
|
printk(KERN_INFO "Using dedicated idle loop\n");
|
||||||
|
ppc_md.idle_loop = pseries_dedicated_idle;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printk(KERN_INFO "Using default idle loop\n");
|
||||||
|
ppc_md.idle_loop = default_idle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init pSeries_init_panel(void)
|
static int __init pSeries_init_panel(void)
|
||||||
|
@ -418,6 +436,144 @@ static int __init pSeries_probe(int platform)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
|
||||||
|
|
||||||
|
static inline void dedicated_idle_sleep(unsigned int cpu)
|
||||||
|
{
|
||||||
|
struct paca_struct *ppaca = &paca[cpu ^ 1];
|
||||||
|
|
||||||
|
/* Only sleep if the other thread is not idle */
|
||||||
|
if (!(ppaca->lppaca.idle)) {
|
||||||
|
local_irq_disable();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are about to sleep the thread and so wont be polling any
|
||||||
|
* more.
|
||||||
|
*/
|
||||||
|
clear_thread_flag(TIF_POLLING_NRFLAG);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SMT dynamic mode. Cede will result in this thread going
|
||||||
|
* dormant, if the partner thread is still doing work. Thread
|
||||||
|
* wakes up if partner goes idle, an interrupt is presented, or
|
||||||
|
* a prod occurs. Returning from the cede enables external
|
||||||
|
* interrupts.
|
||||||
|
*/
|
||||||
|
if (!need_resched())
|
||||||
|
cede_processor();
|
||||||
|
else
|
||||||
|
local_irq_enable();
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Give the HV an opportunity at the processor, since we are
|
||||||
|
* not doing any work.
|
||||||
|
*/
|
||||||
|
poll_pending();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pseries_dedicated_idle(void)
|
||||||
|
{
|
||||||
|
long oldval;
|
||||||
|
struct paca_struct *lpaca = get_paca();
|
||||||
|
unsigned int cpu = smp_processor_id();
|
||||||
|
unsigned long start_snooze;
|
||||||
|
unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
/*
|
||||||
|
* Indicate to the HV that we are idle. Now would be
|
||||||
|
* a good time to find other work to dispatch.
|
||||||
|
*/
|
||||||
|
lpaca->lppaca.idle = 1;
|
||||||
|
|
||||||
|
oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
|
||||||
|
if (!oldval) {
|
||||||
|
set_thread_flag(TIF_POLLING_NRFLAG);
|
||||||
|
|
||||||
|
start_snooze = __get_tb() +
|
||||||
|
*smt_snooze_delay * tb_ticks_per_usec;
|
||||||
|
|
||||||
|
while (!need_resched() && !cpu_is_offline(cpu)) {
|
||||||
|
ppc64_runlatch_off();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Go into low thread priority and possibly
|
||||||
|
* low power mode.
|
||||||
|
*/
|
||||||
|
HMT_low();
|
||||||
|
HMT_very_low();
|
||||||
|
|
||||||
|
if (*smt_snooze_delay != 0 &&
|
||||||
|
__get_tb() > start_snooze) {
|
||||||
|
HMT_medium();
|
||||||
|
dedicated_idle_sleep(cpu);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
HMT_medium();
|
||||||
|
clear_thread_flag(TIF_POLLING_NRFLAG);
|
||||||
|
} else {
|
||||||
|
set_need_resched();
|
||||||
|
}
|
||||||
|
|
||||||
|
lpaca->lppaca.idle = 0;
|
||||||
|
ppc64_runlatch_on();
|
||||||
|
|
||||||
|
schedule();
|
||||||
|
|
||||||
|
if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
|
||||||
|
cpu_die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pseries_shared_idle(void)
|
||||||
|
{
|
||||||
|
struct paca_struct *lpaca = get_paca();
|
||||||
|
unsigned int cpu = smp_processor_id();
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
/*
|
||||||
|
* Indicate to the HV that we are idle. Now would be
|
||||||
|
* a good time to find other work to dispatch.
|
||||||
|
*/
|
||||||
|
lpaca->lppaca.idle = 1;
|
||||||
|
|
||||||
|
while (!need_resched() && !cpu_is_offline(cpu)) {
|
||||||
|
local_irq_disable();
|
||||||
|
ppc64_runlatch_off();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Yield the processor to the hypervisor. We return if
|
||||||
|
* an external interrupt occurs (which are driven prior
|
||||||
|
* to returning here) or if a prod occurs from another
|
||||||
|
* processor. When returning here, external interrupts
|
||||||
|
* are enabled.
|
||||||
|
*
|
||||||
|
* Check need_resched() again with interrupts disabled
|
||||||
|
* to avoid a race.
|
||||||
|
*/
|
||||||
|
if (!need_resched())
|
||||||
|
cede_processor();
|
||||||
|
else
|
||||||
|
local_irq_enable();
|
||||||
|
|
||||||
|
HMT_medium();
|
||||||
|
}
|
||||||
|
|
||||||
|
lpaca->lppaca.idle = 0;
|
||||||
|
ppc64_runlatch_on();
|
||||||
|
|
||||||
|
schedule();
|
||||||
|
|
||||||
|
if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
|
||||||
|
cpu_die();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct machdep_calls __initdata pSeries_md = {
|
struct machdep_calls __initdata pSeries_md = {
|
||||||
.probe = pSeries_probe,
|
.probe = pSeries_probe,
|
||||||
.setup_arch = pSeries_setup_arch,
|
.setup_arch = pSeries_setup_arch,
|
||||||
|
|
|
@ -186,6 +186,8 @@ void __init pmac_setup_arch(void)
|
||||||
#ifdef CONFIG_DUMMY_CONSOLE
|
#ifdef CONFIG_DUMMY_CONSOLE
|
||||||
conswitchp = &dummy_con;
|
conswitchp = &dummy_con;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
printk(KERN_INFO "Using native/NAP idle loop\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SCSI
|
#ifdef CONFIG_SCSI
|
||||||
|
@ -507,5 +509,6 @@ struct machdep_calls __initdata pmac_md = {
|
||||||
.calibrate_decr = pmac_calibrate_decr,
|
.calibrate_decr = pmac_calibrate_decr,
|
||||||
.feature_call = pmac_do_feature_call,
|
.feature_call = pmac_do_feature_call,
|
||||||
.progress = pmac_progress,
|
.progress = pmac_progress,
|
||||||
.check_legacy_ioport = pmac_check_legacy_ioport
|
.check_legacy_ioport = pmac_check_legacy_ioport,
|
||||||
|
.idle_loop = native_idle,
|
||||||
};
|
};
|
||||||
|
|
|
@ -96,7 +96,6 @@ extern void udbg_init_maple_realmode(void);
|
||||||
extern unsigned long klimit;
|
extern unsigned long klimit;
|
||||||
|
|
||||||
extern void mm_init_ppc64(void);
|
extern void mm_init_ppc64(void);
|
||||||
extern int idle_setup(void);
|
|
||||||
extern void stab_initialize(unsigned long stab);
|
extern void stab_initialize(unsigned long stab);
|
||||||
extern void htab_initialize(void);
|
extern void htab_initialize(void);
|
||||||
extern void early_init_devtree(void *flat_dt);
|
extern void early_init_devtree(void *flat_dt);
|
||||||
|
@ -1081,8 +1080,11 @@ void __init setup_arch(char **cmdline_p)
|
||||||
|
|
||||||
ppc_md.setup_arch();
|
ppc_md.setup_arch();
|
||||||
|
|
||||||
/* Select the correct idle loop for the platform. */
|
/* Use the default idle loop if the platform hasn't provided one. */
|
||||||
idle_setup();
|
if (NULL == ppc_md.idle_loop) {
|
||||||
|
ppc_md.idle_loop = default_idle;
|
||||||
|
printk(KERN_INFO "Using default idle loop\n");
|
||||||
|
}
|
||||||
|
|
||||||
paging_init();
|
paging_init();
|
||||||
ppc64_boot_msg(0x15, "Setup Done");
|
ppc64_boot_msg(0x15, "Setup Done");
|
||||||
|
|
|
@ -30,47 +30,26 @@
|
||||||
#include <linux/sem.h>
|
#include <linux/sem.h>
|
||||||
#include <linux/msg.h>
|
#include <linux/msg.h>
|
||||||
#include <linux/shm.h>
|
#include <linux/shm.h>
|
||||||
#include <linux/slab.h>
|
|
||||||
#include <linux/uio.h>
|
|
||||||
#include <linux/aio.h>
|
|
||||||
#include <linux/nfs_fs.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/sunrpc/svc.h>
|
|
||||||
#include <linux/nfsd/nfsd.h>
|
|
||||||
#include <linux/nfsd/cache.h>
|
|
||||||
#include <linux/nfsd/xdr.h>
|
|
||||||
#include <linux/nfsd/syscall.h>
|
|
||||||
#include <linux/poll.h>
|
#include <linux/poll.h>
|
||||||
#include <linux/personality.h>
|
#include <linux/personality.h>
|
||||||
#include <linux/stat.h>
|
#include <linux/stat.h>
|
||||||
#include <linux/filter.h>
|
|
||||||
#include <linux/highmem.h>
|
|
||||||
#include <linux/highuid.h>
|
|
||||||
#include <linux/mman.h>
|
#include <linux/mman.h>
|
||||||
#include <linux/ipv6.h>
|
|
||||||
#include <linux/in.h>
|
#include <linux/in.h>
|
||||||
#include <linux/icmpv6.h>
|
|
||||||
#include <linux/syscalls.h>
|
#include <linux/syscalls.h>
|
||||||
#include <linux/unistd.h>
|
#include <linux/unistd.h>
|
||||||
#include <linux/sysctl.h>
|
#include <linux/sysctl.h>
|
||||||
#include <linux/binfmts.h>
|
#include <linux/binfmts.h>
|
||||||
#include <linux/dnotify.h>
|
|
||||||
#include <linux/security.h>
|
#include <linux/security.h>
|
||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
#include <linux/ptrace.h>
|
#include <linux/ptrace.h>
|
||||||
#include <linux/aio_abi.h>
|
|
||||||
#include <linux/elf.h>
|
#include <linux/elf.h>
|
||||||
|
|
||||||
#include <net/scm.h>
|
|
||||||
#include <net/sock.h>
|
|
||||||
|
|
||||||
#include <asm/ptrace.h>
|
#include <asm/ptrace.h>
|
||||||
#include <asm/types.h>
|
#include <asm/types.h>
|
||||||
#include <asm/ipc.h>
|
#include <asm/ipc.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/unistd.h>
|
#include <asm/unistd.h>
|
||||||
#include <asm/semaphore.h>
|
#include <asm/semaphore.h>
|
||||||
#include <asm/ppcdebug.h>
|
|
||||||
#include <asm/time.h>
|
#include <asm/time.h>
|
||||||
#include <asm/mmu_context.h>
|
#include <asm/mmu_context.h>
|
||||||
#include <asm/systemcfg.h>
|
#include <asm/systemcfg.h>
|
||||||
|
@ -350,8 +329,6 @@ asmlinkage long sys32_adjtimex(struct timex32 __user *utp)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* These are here just in case some old sparc32 binary calls it. */
|
|
||||||
asmlinkage long sys32_pause(void)
|
asmlinkage long sys32_pause(void)
|
||||||
{
|
{
|
||||||
current->state = TASK_INTERRUPTIBLE;
|
current->state = TASK_INTERRUPTIBLE;
|
||||||
|
@ -360,8 +337,6 @@ asmlinkage long sys32_pause(void)
|
||||||
return -ERESTARTNOHAND;
|
return -ERESTARTNOHAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
|
static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
|
||||||
{
|
{
|
||||||
long usec;
|
long usec;
|
||||||
|
@ -847,16 +822,6 @@ asmlinkage long sys32_getpgid(u32 pid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Note: it is necessary to treat which and who as unsigned ints,
|
|
||||||
* with the corresponding cast to a signed int to insure that the
|
|
||||||
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
|
|
||||||
* and the register representation of a signed int (msr in 64-bit mode) is performed.
|
|
||||||
*/
|
|
||||||
asmlinkage long sys32_getpriority(u32 which, u32 who)
|
|
||||||
{
|
|
||||||
return sys_getpriority((int)which, (int)who);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Note: it is necessary to treat pid as an unsigned int,
|
/* Note: it is necessary to treat pid as an unsigned int,
|
||||||
* with the corresponding cast to a signed int to insure that the
|
* with the corresponding cast to a signed int to insure that the
|
||||||
|
@ -1048,6 +1013,11 @@ asmlinkage long sys32_setpgid(u32 pid, u32 pgid)
|
||||||
return sys_setpgid((int)pid, (int)pgid);
|
return sys_setpgid((int)pid, (int)pgid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long sys32_getpriority(u32 which, u32 who)
|
||||||
|
{
|
||||||
|
/* sign extend which and who */
|
||||||
|
return sys_getpriority((int)which, (int)who);
|
||||||
|
}
|
||||||
|
|
||||||
long sys32_setpriority(u32 which, u32 who, u32 niceval)
|
long sys32_setpriority(u32 which, u32 who, u32 niceval)
|
||||||
{
|
{
|
||||||
|
@ -1055,6 +1025,18 @@ long sys32_setpriority(u32 which, u32 who, u32 niceval)
|
||||||
return sys_setpriority((int)which, (int)who, (int)niceval);
|
return sys_setpriority((int)which, (int)who, (int)niceval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long sys32_ioprio_get(u32 which, u32 who)
|
||||||
|
{
|
||||||
|
/* sign extend which and who */
|
||||||
|
return sys_ioprio_get((int)which, (int)who);
|
||||||
|
}
|
||||||
|
|
||||||
|
long sys32_ioprio_set(u32 which, u32 who, u32 ioprio)
|
||||||
|
{
|
||||||
|
/* sign extend which, who and ioprio */
|
||||||
|
return sys_ioprio_set((int)which, (int)who, (int)ioprio);
|
||||||
|
}
|
||||||
|
|
||||||
/* Note: it is necessary to treat newmask as an unsigned int,
|
/* Note: it is necessary to treat newmask as an unsigned int,
|
||||||
* with the corresponding cast to a signed int to insure that the
|
* with the corresponding cast to a signed int to insure that the
|
||||||
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
|
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
|
||||||
|
@ -1273,8 +1255,6 @@ long ppc32_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low,
|
||||||
(u64)len_high << 32 | len_low, advice);
|
(u64)len_high << 32 | len_low, advice);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern asmlinkage long sys_timer_create(clockid_t, sigevent_t __user *, timer_t __user *);
|
|
||||||
|
|
||||||
long ppc32_timer_create(clockid_t clock,
|
long ppc32_timer_create(clockid_t clock,
|
||||||
struct compat_sigevent __user *ev32,
|
struct compat_sigevent __user *ev32,
|
||||||
timer_t __user *timer_id)
|
timer_t __user *timer_id)
|
||||||
|
|
|
@ -112,7 +112,6 @@ void ppc64_enable_pmcs(void)
|
||||||
unsigned long hid0;
|
unsigned long hid0;
|
||||||
#ifdef CONFIG_PPC_PSERIES
|
#ifdef CONFIG_PPC_PSERIES
|
||||||
unsigned long set, reset;
|
unsigned long set, reset;
|
||||||
int ret;
|
|
||||||
#endif /* CONFIG_PPC_PSERIES */
|
#endif /* CONFIG_PPC_PSERIES */
|
||||||
|
|
||||||
/* Only need to enable them once */
|
/* Only need to enable them once */
|
||||||
|
@ -145,11 +144,7 @@ void ppc64_enable_pmcs(void)
|
||||||
case PLATFORM_PSERIES_LPAR:
|
case PLATFORM_PSERIES_LPAR:
|
||||||
set = 1UL << 63;
|
set = 1UL << 63;
|
||||||
reset = 0;
|
reset = 0;
|
||||||
ret = plpar_hcall_norets(H_PERFMON, set, reset);
|
plpar_hcall_norets(H_PERFMON, set, reset);
|
||||||
if (ret)
|
|
||||||
printk(KERN_ERR "H_PERFMON call on cpu %u "
|
|
||||||
"returned %d\n",
|
|
||||||
smp_processor_id(), ret);
|
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_PPC_PSERIES */
|
#endif /* CONFIG_PPC_PSERIES */
|
||||||
|
|
||||||
|
@ -161,13 +156,6 @@ void ppc64_enable_pmcs(void)
|
||||||
/* instruct hypervisor to maintain PMCs */
|
/* instruct hypervisor to maintain PMCs */
|
||||||
if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
|
if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
|
||||||
get_paca()->lppaca.pmcregs_in_use = 1;
|
get_paca()->lppaca.pmcregs_in_use = 1;
|
||||||
|
|
||||||
/*
|
|
||||||
* On SMT machines we have to set the run latch in the ctrl register
|
|
||||||
* in order to make PMC6 spin.
|
|
||||||
*/
|
|
||||||
if (cpu_has_feature(CPU_FTR_SMT))
|
|
||||||
ppc64_runlatch_on();
|
|
||||||
#endif /* CONFIG_PPC_PSERIES */
|
#endif /* CONFIG_PPC_PSERIES */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,9 +40,9 @@ SECTIONS
|
||||||
.gcc_except_table : { *(.gcc_except_table) }
|
.gcc_except_table : { *(.gcc_except_table) }
|
||||||
.fixup : { *(.fixup) }
|
.fixup : { *(.fixup) }
|
||||||
|
|
||||||
.got ALIGN(4) : { *(.got.plt) *(.got) }
|
|
||||||
|
|
||||||
.dynamic : { *(.dynamic) } :text :dynamic
|
.dynamic : { *(.dynamic) } :text :dynamic
|
||||||
|
.got : { *(.got) }
|
||||||
|
.plt : { *(.plt) }
|
||||||
|
|
||||||
_end = .;
|
_end = .;
|
||||||
__end = .;
|
__end = .;
|
||||||
|
|
|
@ -128,7 +128,6 @@ config HOSTFS
|
||||||
|
|
||||||
config HPPFS
|
config HPPFS
|
||||||
tristate "HoneyPot ProcFS (EXPERIMENTAL)"
|
tristate "HoneyPot ProcFS (EXPERIMENTAL)"
|
||||||
depends on BROKEN
|
|
||||||
help
|
help
|
||||||
hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
|
hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
|
||||||
entries to be overridden, removed, or fabricated from the host.
|
entries to be overridden, removed, or fabricated from the host.
|
||||||
|
@ -141,8 +140,9 @@ config HPPFS
|
||||||
You only need this if you are setting up a UML honeypot. Otherwise,
|
You only need this if you are setting up a UML honeypot. Otherwise,
|
||||||
it is safe to say 'N' here.
|
it is safe to say 'N' here.
|
||||||
|
|
||||||
If you are actively using it, please ask for it to be fixed. In this
|
If you are actively using it, please report any problems, since it's
|
||||||
moment, it does not work on 2.6 (it works somehow on 2.4).
|
getting fixed. In this moment, it is experimental on 2.6 (it works on
|
||||||
|
2.4).
|
||||||
|
|
||||||
config MCONSOLE
|
config MCONSOLE
|
||||||
bool "Management console"
|
bool "Management console"
|
||||||
|
|
|
@ -19,6 +19,18 @@ config 3_LEVEL_PGTABLES
|
||||||
memory. All the memory that can't be mapped directly will be treated
|
memory. All the memory that can't be mapped directly will be treated
|
||||||
as high memory.
|
as high memory.
|
||||||
|
|
||||||
|
config STUB_CODE
|
||||||
|
hex
|
||||||
|
default 0xbfffe000
|
||||||
|
|
||||||
|
config STUB_DATA
|
||||||
|
hex
|
||||||
|
default 0xbffff000
|
||||||
|
|
||||||
|
config STUB_START
|
||||||
|
hex
|
||||||
|
default STUB_CODE
|
||||||
|
|
||||||
config ARCH_HAS_SC_SIGNALS
|
config ARCH_HAS_SC_SIGNALS
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
|
@ -14,6 +14,18 @@ config 3_LEVEL_PGTABLES
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config STUB_CODE
|
||||||
|
hex
|
||||||
|
default 0x7fbfffe000
|
||||||
|
|
||||||
|
config STUB_DATA
|
||||||
|
hex
|
||||||
|
default 0x7fbffff000
|
||||||
|
|
||||||
|
config STUB_START
|
||||||
|
hex
|
||||||
|
default STUB_CODE
|
||||||
|
|
||||||
config ARCH_HAS_SC_SIGNALS
|
config ARCH_HAS_SC_SIGNALS
|
||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
|
|
@ -8,7 +8,7 @@ ifeq ($(CONFIG_MODE_SKAS),y)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH)
|
CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH) $(STUB_CFLAGS)
|
||||||
ARCH_USER_CFLAGS :=
|
ARCH_USER_CFLAGS :=
|
||||||
|
|
||||||
ifneq ($(CONFIG_GPROF),y)
|
ifneq ($(CONFIG_GPROF),y)
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
SUBARCH_LIBS := arch/um/sys-x86_64/
|
SUBARCH_LIBS := arch/um/sys-x86_64/
|
||||||
START := 0x60000000
|
START := 0x60000000
|
||||||
|
|
||||||
CFLAGS += -U__$(SUBARCH)__ -fno-builtin
|
CFLAGS += -U__$(SUBARCH)__ -fno-builtin $(STUB_CFLAGS)
|
||||||
ARCH_USER_CFLAGS := -D__x86_64__
|
ARCH_USER_CFLAGS := -D__x86_64__
|
||||||
|
|
||||||
ELF_ARCH := i386:x86-64
|
ELF_ARCH := i386:x86-64
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
# Automatically generated make config: don't edit
|
# Automatically generated make config: don't edit
|
||||||
# Linux kernel version: 2.6.12-rc3-skas3-v9-pre2
|
# Linux kernel version: 2.6.12-rc6-mm1
|
||||||
# Sun Apr 24 19:46:10 2005
|
# Tue Jun 14 18:22:21 2005
|
||||||
#
|
#
|
||||||
CONFIG_GENERIC_HARDIRQS=y
|
CONFIG_GENERIC_HARDIRQS=y
|
||||||
CONFIG_UML=y
|
CONFIG_UML=y
|
||||||
|
@ -13,23 +13,32 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
|
||||||
#
|
#
|
||||||
# UML-specific options
|
# UML-specific options
|
||||||
#
|
#
|
||||||
CONFIG_MODE_TT=y
|
# CONFIG_MODE_TT is not set
|
||||||
|
# CONFIG_STATIC_LINK is not set
|
||||||
CONFIG_MODE_SKAS=y
|
CONFIG_MODE_SKAS=y
|
||||||
CONFIG_UML_X86=y
|
CONFIG_UML_X86=y
|
||||||
# CONFIG_64BIT is not set
|
# CONFIG_64BIT is not set
|
||||||
CONFIG_TOP_ADDR=0xc0000000
|
CONFIG_TOP_ADDR=0xc0000000
|
||||||
# CONFIG_3_LEVEL_PGTABLES is not set
|
# CONFIG_3_LEVEL_PGTABLES is not set
|
||||||
|
CONFIG_STUB_CODE=0xbfffe000
|
||||||
|
CONFIG_STUB_DATA=0xbffff000
|
||||||
|
CONFIG_STUB_START=0xbfffe000
|
||||||
CONFIG_ARCH_HAS_SC_SIGNALS=y
|
CONFIG_ARCH_HAS_SC_SIGNALS=y
|
||||||
CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA=y
|
CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA=y
|
||||||
CONFIG_LD_SCRIPT_STATIC=y
|
CONFIG_SELECT_MEMORY_MODEL=y
|
||||||
|
CONFIG_FLATMEM_MANUAL=y
|
||||||
|
# CONFIG_DISCONTIGMEM_MANUAL is not set
|
||||||
|
# CONFIG_SPARSEMEM_MANUAL is not set
|
||||||
|
CONFIG_FLATMEM=y
|
||||||
|
CONFIG_FLAT_NODE_MEM_MAP=y
|
||||||
|
CONFIG_LD_SCRIPT_DYN=y
|
||||||
CONFIG_NET=y
|
CONFIG_NET=y
|
||||||
CONFIG_BINFMT_ELF=y
|
CONFIG_BINFMT_ELF=y
|
||||||
CONFIG_BINFMT_MISC=m
|
CONFIG_BINFMT_MISC=m
|
||||||
CONFIG_HOSTFS=y
|
# CONFIG_HOSTFS is not set
|
||||||
CONFIG_MCONSOLE=y
|
CONFIG_MCONSOLE=y
|
||||||
# CONFIG_MAGIC_SYSRQ is not set
|
# CONFIG_MAGIC_SYSRQ is not set
|
||||||
# CONFIG_HOST_2G_2G is not set
|
# CONFIG_HOST_2G_2G is not set
|
||||||
# CONFIG_SMP is not set
|
|
||||||
CONFIG_NEST_LEVEL=0
|
CONFIG_NEST_LEVEL=0
|
||||||
CONFIG_KERNEL_HALF_GIGS=1
|
CONFIG_KERNEL_HALF_GIGS=1
|
||||||
# CONFIG_HIGHMEM is not set
|
# CONFIG_HIGHMEM is not set
|
||||||
|
@ -63,6 +72,8 @@ CONFIG_IKCONFIG_PROC=y
|
||||||
CONFIG_KALLSYMS=y
|
CONFIG_KALLSYMS=y
|
||||||
# CONFIG_KALLSYMS_ALL is not set
|
# CONFIG_KALLSYMS_ALL is not set
|
||||||
CONFIG_KALLSYMS_EXTRA_PASS=y
|
CONFIG_KALLSYMS_EXTRA_PASS=y
|
||||||
|
CONFIG_PRINTK=y
|
||||||
|
CONFIG_BUG=y
|
||||||
CONFIG_BASE_FULL=y
|
CONFIG_BASE_FULL=y
|
||||||
CONFIG_FUTEX=y
|
CONFIG_FUTEX=y
|
||||||
CONFIG_EPOLL=y
|
CONFIG_EPOLL=y
|
||||||
|
@ -81,6 +92,7 @@ CONFIG_MODULES=y
|
||||||
CONFIG_MODULE_UNLOAD=y
|
CONFIG_MODULE_UNLOAD=y
|
||||||
# CONFIG_MODULE_FORCE_UNLOAD is not set
|
# CONFIG_MODULE_FORCE_UNLOAD is not set
|
||||||
CONFIG_OBSOLETE_MODPARM=y
|
CONFIG_OBSOLETE_MODPARM=y
|
||||||
|
# CONFIG_MODVERSIONS is not set
|
||||||
# CONFIG_MODULE_SRCVERSION_ALL is not set
|
# CONFIG_MODULE_SRCVERSION_ALL is not set
|
||||||
CONFIG_KMOD=y
|
CONFIG_KMOD=y
|
||||||
|
|
||||||
|
@ -115,6 +127,7 @@ CONFIG_UML_SOUND=m
|
||||||
CONFIG_SOUND=m
|
CONFIG_SOUND=m
|
||||||
CONFIG_HOSTAUDIO=m
|
CONFIG_HOSTAUDIO=m
|
||||||
CONFIG_UML_RANDOM=y
|
CONFIG_UML_RANDOM=y
|
||||||
|
# CONFIG_MMAPPER is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# Block devices
|
# Block devices
|
||||||
|
@ -176,6 +189,17 @@ CONFIG_INET=y
|
||||||
# CONFIG_INET_TUNNEL is not set
|
# CONFIG_INET_TUNNEL is not set
|
||||||
CONFIG_IP_TCPDIAG=y
|
CONFIG_IP_TCPDIAG=y
|
||||||
# CONFIG_IP_TCPDIAG_IPV6 is not set
|
# CONFIG_IP_TCPDIAG_IPV6 is not set
|
||||||
|
|
||||||
|
#
|
||||||
|
# TCP congestion control
|
||||||
|
#
|
||||||
|
CONFIG_TCP_CONG_BIC=y
|
||||||
|
CONFIG_TCP_CONG_WESTWOOD=y
|
||||||
|
CONFIG_TCP_CONG_HTCP=y
|
||||||
|
# CONFIG_TCP_CONG_HSTCP is not set
|
||||||
|
# CONFIG_TCP_CONG_HYBLA is not set
|
||||||
|
# CONFIG_TCP_CONG_VEGAS is not set
|
||||||
|
# CONFIG_TCP_CONG_SCALABLE is not set
|
||||||
# CONFIG_IPV6 is not set
|
# CONFIG_IPV6 is not set
|
||||||
# CONFIG_NETFILTER is not set
|
# CONFIG_NETFILTER is not set
|
||||||
|
|
||||||
|
@ -206,11 +230,15 @@ CONFIG_IP_TCPDIAG=y
|
||||||
# Network testing
|
# Network testing
|
||||||
#
|
#
|
||||||
# CONFIG_NET_PKTGEN is not set
|
# CONFIG_NET_PKTGEN is not set
|
||||||
|
# CONFIG_KGDBOE is not set
|
||||||
# CONFIG_NETPOLL is not set
|
# CONFIG_NETPOLL is not set
|
||||||
|
# CONFIG_NETPOLL_RX is not set
|
||||||
|
# CONFIG_NETPOLL_TRAP is not set
|
||||||
# CONFIG_NET_POLL_CONTROLLER is not set
|
# CONFIG_NET_POLL_CONTROLLER is not set
|
||||||
# CONFIG_HAMRADIO is not set
|
# CONFIG_HAMRADIO is not set
|
||||||
# CONFIG_IRDA is not set
|
# CONFIG_IRDA is not set
|
||||||
# CONFIG_BT is not set
|
# CONFIG_BT is not set
|
||||||
|
# CONFIG_IEEE80211 is not set
|
||||||
CONFIG_DUMMY=m
|
CONFIG_DUMMY=m
|
||||||
# CONFIG_BONDING is not set
|
# CONFIG_BONDING is not set
|
||||||
# CONFIG_EQUALIZER is not set
|
# CONFIG_EQUALIZER is not set
|
||||||
|
@ -227,6 +255,7 @@ CONFIG_PPP=m
|
||||||
# CONFIG_PPP_SYNC_TTY is not set
|
# CONFIG_PPP_SYNC_TTY is not set
|
||||||
# CONFIG_PPP_DEFLATE is not set
|
# CONFIG_PPP_DEFLATE is not set
|
||||||
# CONFIG_PPP_BSDCOMP is not set
|
# CONFIG_PPP_BSDCOMP is not set
|
||||||
|
# CONFIG_PPP_MPPE is not set
|
||||||
# CONFIG_PPPOE is not set
|
# CONFIG_PPPOE is not set
|
||||||
CONFIG_SLIP=m
|
CONFIG_SLIP=m
|
||||||
# CONFIG_SLIP_COMPRESSED is not set
|
# CONFIG_SLIP_COMPRESSED is not set
|
||||||
|
@ -240,10 +269,12 @@ CONFIG_SLIP=m
|
||||||
#
|
#
|
||||||
CONFIG_EXT2_FS=y
|
CONFIG_EXT2_FS=y
|
||||||
# CONFIG_EXT2_FS_XATTR is not set
|
# CONFIG_EXT2_FS_XATTR is not set
|
||||||
|
# CONFIG_EXT2_FS_XIP is not set
|
||||||
CONFIG_EXT3_FS=y
|
CONFIG_EXT3_FS=y
|
||||||
# CONFIG_EXT3_FS_XATTR is not set
|
# CONFIG_EXT3_FS_XATTR is not set
|
||||||
CONFIG_JBD=y
|
CONFIG_JBD=y
|
||||||
# CONFIG_JBD_DEBUG is not set
|
# CONFIG_JBD_DEBUG is not set
|
||||||
|
# CONFIG_REISER4_FS is not set
|
||||||
CONFIG_REISERFS_FS=y
|
CONFIG_REISERFS_FS=y
|
||||||
# CONFIG_REISERFS_CHECK is not set
|
# CONFIG_REISERFS_CHECK is not set
|
||||||
# CONFIG_REISERFS_PROC_INFO is not set
|
# CONFIG_REISERFS_PROC_INFO is not set
|
||||||
|
@ -256,6 +287,7 @@ CONFIG_REISERFS_FS=y
|
||||||
# CONFIG_XFS_FS is not set
|
# CONFIG_XFS_FS is not set
|
||||||
# CONFIG_MINIX_FS is not set
|
# CONFIG_MINIX_FS is not set
|
||||||
# CONFIG_ROMFS_FS is not set
|
# CONFIG_ROMFS_FS is not set
|
||||||
|
CONFIG_INOTIFY=y
|
||||||
CONFIG_QUOTA=y
|
CONFIG_QUOTA=y
|
||||||
# CONFIG_QFMT_V1 is not set
|
# CONFIG_QFMT_V1 is not set
|
||||||
# CONFIG_QFMT_V2 is not set
|
# CONFIG_QFMT_V2 is not set
|
||||||
|
@ -264,6 +296,12 @@ CONFIG_DNOTIFY=y
|
||||||
CONFIG_AUTOFS_FS=m
|
CONFIG_AUTOFS_FS=m
|
||||||
CONFIG_AUTOFS4_FS=m
|
CONFIG_AUTOFS4_FS=m
|
||||||
|
|
||||||
|
#
|
||||||
|
# Caches
|
||||||
|
#
|
||||||
|
# CONFIG_FSCACHE is not set
|
||||||
|
# CONFIG_FUSE_FS is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# CD-ROM/DVD Filesystems
|
# CD-ROM/DVD Filesystems
|
||||||
#
|
#
|
||||||
|
@ -291,6 +329,8 @@ CONFIG_TMPFS=y
|
||||||
# CONFIG_TMPFS_XATTR is not set
|
# CONFIG_TMPFS_XATTR is not set
|
||||||
# CONFIG_HUGETLB_PAGE is not set
|
# CONFIG_HUGETLB_PAGE is not set
|
||||||
CONFIG_RAMFS=y
|
CONFIG_RAMFS=y
|
||||||
|
# CONFIG_CONFIGFS_FS is not set
|
||||||
|
# CONFIG_RELAYFS_FS is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# Miscellaneous filesystems
|
# Miscellaneous filesystems
|
||||||
|
@ -319,6 +359,7 @@ CONFIG_RAMFS=y
|
||||||
# CONFIG_NCP_FS is not set
|
# CONFIG_NCP_FS is not set
|
||||||
# CONFIG_CODA_FS is not set
|
# CONFIG_CODA_FS is not set
|
||||||
# CONFIG_AFS_FS is not set
|
# CONFIG_AFS_FS is not set
|
||||||
|
# CONFIG_9P_FS is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# Partition Types
|
# Partition Types
|
||||||
|
@ -404,14 +445,15 @@ CONFIG_CRC32=m
|
||||||
# CONFIG_PRINTK_TIME is not set
|
# CONFIG_PRINTK_TIME is not set
|
||||||
CONFIG_DEBUG_KERNEL=y
|
CONFIG_DEBUG_KERNEL=y
|
||||||
CONFIG_LOG_BUF_SHIFT=14
|
CONFIG_LOG_BUF_SHIFT=14
|
||||||
|
CONFIG_DETECT_SOFTLOCKUP=y
|
||||||
# CONFIG_SCHEDSTATS is not set
|
# CONFIG_SCHEDSTATS is not set
|
||||||
# CONFIG_DEBUG_SLAB is not set
|
CONFIG_DEBUG_SLAB=y
|
||||||
# CONFIG_DEBUG_SPINLOCK is not set
|
# CONFIG_DEBUG_SPINLOCK is not set
|
||||||
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
|
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
|
||||||
# CONFIG_DEBUG_KOBJECT is not set
|
# CONFIG_DEBUG_KOBJECT is not set
|
||||||
CONFIG_DEBUG_INFO=y
|
CONFIG_DEBUG_INFO=y
|
||||||
# CONFIG_DEBUG_FS is not set
|
# CONFIG_DEBUG_FS is not set
|
||||||
CONFIG_FRAME_POINTER=y
|
CONFIG_FRAME_POINTER=y
|
||||||
CONFIG_PT_PROXY=y
|
# CONFIG_GPROF is not set
|
||||||
# CONFIG_GCOV is not set
|
# CONFIG_GCOV is not set
|
||||||
# CONFIG_SYSCALL_DEBUG is not set
|
# CONFIG_SYSCALL_DEBUG is not set
|
||||||
|
|
|
@ -663,11 +663,15 @@ struct tty_driver *line_register_devfs(struct lines *set,
|
||||||
return driver;
|
return driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static spinlock_t winch_handler_lock;
|
||||||
|
LIST_HEAD(winch_handlers);
|
||||||
|
|
||||||
void lines_init(struct line *lines, int nlines)
|
void lines_init(struct line *lines, int nlines)
|
||||||
{
|
{
|
||||||
struct line *line;
|
struct line *line;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
spin_lock_init(&winch_handler_lock);
|
||||||
for(i = 0; i < nlines; i++){
|
for(i = 0; i < nlines; i++){
|
||||||
line = &lines[i];
|
line = &lines[i];
|
||||||
INIT_LIST_HEAD(&line->chan_list);
|
INIT_LIST_HEAD(&line->chan_list);
|
||||||
|
@ -724,31 +728,30 @@ irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
DECLARE_MUTEX(winch_handler_sem);
|
|
||||||
LIST_HEAD(winch_handlers);
|
|
||||||
|
|
||||||
void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty)
|
void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty)
|
||||||
{
|
{
|
||||||
struct winch *winch;
|
struct winch *winch;
|
||||||
|
|
||||||
down(&winch_handler_sem);
|
|
||||||
winch = kmalloc(sizeof(*winch), GFP_KERNEL);
|
winch = kmalloc(sizeof(*winch), GFP_KERNEL);
|
||||||
if (winch == NULL) {
|
if (winch == NULL) {
|
||||||
printk("register_winch_irq - kmalloc failed\n");
|
printk("register_winch_irq - kmalloc failed\n");
|
||||||
goto out;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*winch = ((struct winch) { .list = LIST_HEAD_INIT(winch->list),
|
*winch = ((struct winch) { .list = LIST_HEAD_INIT(winch->list),
|
||||||
.fd = fd,
|
.fd = fd,
|
||||||
.tty_fd = tty_fd,
|
.tty_fd = tty_fd,
|
||||||
.pid = pid,
|
.pid = pid,
|
||||||
.tty = tty });
|
.tty = tty });
|
||||||
|
|
||||||
|
spin_lock(&winch_handler_lock);
|
||||||
list_add(&winch->list, &winch_handlers);
|
list_add(&winch->list, &winch_handlers);
|
||||||
|
spin_unlock(&winch_handler_lock);
|
||||||
|
|
||||||
if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
|
if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
|
||||||
SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
|
SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
|
||||||
"winch", winch) < 0)
|
"winch", winch) < 0)
|
||||||
printk("register_winch_irq - failed to register IRQ\n");
|
printk("register_winch_irq - failed to register IRQ\n");
|
||||||
out:
|
|
||||||
up(&winch_handler_sem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unregister_winch(struct tty_struct *tty)
|
static void unregister_winch(struct tty_struct *tty)
|
||||||
|
@ -756,7 +759,7 @@ static void unregister_winch(struct tty_struct *tty)
|
||||||
struct list_head *ele;
|
struct list_head *ele;
|
||||||
struct winch *winch, *found = NULL;
|
struct winch *winch, *found = NULL;
|
||||||
|
|
||||||
down(&winch_handler_sem);
|
spin_lock(&winch_handler_lock);
|
||||||
list_for_each(ele, &winch_handlers){
|
list_for_each(ele, &winch_handlers){
|
||||||
winch = list_entry(ele, struct winch, list);
|
winch = list_entry(ele, struct winch, list);
|
||||||
if(winch->tty == tty){
|
if(winch->tty == tty){
|
||||||
|
@ -764,20 +767,25 @@ static void unregister_winch(struct tty_struct *tty)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(found == NULL)
|
if(found == NULL)
|
||||||
goto out;
|
goto err;
|
||||||
|
|
||||||
|
list_del(&winch->list);
|
||||||
|
spin_unlock(&winch_handler_lock);
|
||||||
|
|
||||||
if(winch->pid != -1)
|
if(winch->pid != -1)
|
||||||
os_kill_process(winch->pid, 1);
|
os_kill_process(winch->pid, 1);
|
||||||
|
|
||||||
free_irq(WINCH_IRQ, winch);
|
free_irq(WINCH_IRQ, winch);
|
||||||
list_del(&winch->list);
|
|
||||||
kfree(winch);
|
kfree(winch);
|
||||||
out:
|
|
||||||
up(&winch_handler_sem);
|
return;
|
||||||
|
err:
|
||||||
|
spin_unlock(&winch_handler_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX: No lock as it's an exitcall... is this valid? Depending on cleanup
|
||||||
|
* order... are we sure that nothing else is done on the list? */
|
||||||
static void winch_cleanup(void)
|
static void winch_cleanup(void)
|
||||||
{
|
{
|
||||||
struct list_head *ele;
|
struct list_head *ele;
|
||||||
|
@ -786,6 +794,9 @@ static void winch_cleanup(void)
|
||||||
list_for_each(ele, &winch_handlers){
|
list_for_each(ele, &winch_handlers){
|
||||||
winch = list_entry(ele, struct winch, list);
|
winch = list_entry(ele, struct winch, list);
|
||||||
if(winch->fd != -1){
|
if(winch->fd != -1){
|
||||||
|
/* Why is this different from the above free_irq(),
|
||||||
|
* which deactivates SIGIO? This searches the FD
|
||||||
|
* somewhere else and removes it from the list... */
|
||||||
deactivate_fd(winch->fd, WINCH_IRQ);
|
deactivate_fd(winch->fd, WINCH_IRQ);
|
||||||
os_close_file(winch->fd);
|
os_close_file(winch->fd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w);
|
||||||
extern int is_remapped(void *virt);
|
extern int is_remapped(void *virt);
|
||||||
extern int physmem_remove_mapping(void *virt);
|
extern int physmem_remove_mapping(void *virt);
|
||||||
extern void physmem_forget_descriptor(int fd);
|
extern void physmem_forget_descriptor(int fd);
|
||||||
|
extern unsigned long to_phys(void *virt);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ extern int restore_fp_registers(int pid, unsigned long *fp_regs);
|
||||||
extern void save_registers(int pid, union uml_pt_regs *regs);
|
extern void save_registers(int pid, union uml_pt_regs *regs);
|
||||||
extern void restore_registers(int pid, union uml_pt_regs *regs);
|
extern void restore_registers(int pid, union uml_pt_regs *regs);
|
||||||
extern void init_registers(int pid);
|
extern void init_registers(int pid);
|
||||||
|
extern void get_safe_registers(unsigned long * regs);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -20,11 +20,24 @@
|
||||||
#define PT_SYSCALL_ARG3_OFFSET PT_OFFSET(EDX)
|
#define PT_SYSCALL_ARG3_OFFSET PT_OFFSET(EDX)
|
||||||
#define PT_SYSCALL_ARG4_OFFSET PT_OFFSET(ESI)
|
#define PT_SYSCALL_ARG4_OFFSET PT_OFFSET(ESI)
|
||||||
#define PT_SYSCALL_ARG5_OFFSET PT_OFFSET(EDI)
|
#define PT_SYSCALL_ARG5_OFFSET PT_OFFSET(EDI)
|
||||||
|
#define PT_SYSCALL_ARG6_OFFSET PT_OFFSET(EBP)
|
||||||
|
|
||||||
#define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX)
|
#define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX)
|
||||||
|
|
||||||
|
#define REGS_SYSCALL_NR EAX /* This is used before a system call */
|
||||||
|
#define REGS_SYSCALL_ARG1 EBX
|
||||||
|
#define REGS_SYSCALL_ARG2 ECX
|
||||||
|
#define REGS_SYSCALL_ARG3 EDX
|
||||||
|
#define REGS_SYSCALL_ARG4 ESI
|
||||||
|
#define REGS_SYSCALL_ARG5 EDI
|
||||||
|
#define REGS_SYSCALL_ARG6 EBP
|
||||||
|
|
||||||
|
#define REGS_IP_INDEX EIP
|
||||||
|
#define REGS_SP_INDEX UESP
|
||||||
|
|
||||||
#define PT_IP_OFFSET PT_OFFSET(EIP)
|
#define PT_IP_OFFSET PT_OFFSET(EIP)
|
||||||
#define PT_IP(regs) ((regs)[EIP])
|
#define PT_IP(regs) ((regs)[EIP])
|
||||||
|
#define PT_SP_OFFSET PT_OFFSET(UESP)
|
||||||
#define PT_SP(regs) ((regs)[UESP])
|
#define PT_SP(regs) ((regs)[UESP])
|
||||||
|
|
||||||
#ifndef FRAME_SIZE
|
#ifndef FRAME_SIZE
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
|
||||||
|
* Licensed under the GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SYSDEP_STUB_H
|
||||||
|
#define __SYSDEP_STUB_H
|
||||||
|
|
||||||
|
#include <asm/ptrace.h>
|
||||||
|
#include <asm/unistd.h>
|
||||||
|
|
||||||
|
extern void stub_segv_handler(int sig);
|
||||||
|
extern void stub_clone_handler(void);
|
||||||
|
|
||||||
|
#define STUB_SYSCALL_RET EAX
|
||||||
|
#define STUB_MMAP_NR __NR_mmap2
|
||||||
|
#define MMAP_OFFSET(o) ((o) >> PAGE_SHIFT)
|
||||||
|
|
||||||
|
static inline long stub_syscall2(long syscall, long arg1, long arg2)
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
|
||||||
|
__asm__("movl %0, %%ecx; " : : "g" (arg2) : "%ecx");
|
||||||
|
__asm__("movl %0, %%ebx; " : : "g" (arg1) : "%ebx");
|
||||||
|
__asm__("movl %0, %%eax; " : : "g" (syscall) : "%eax");
|
||||||
|
__asm__("int $0x80;" : : : "%eax");
|
||||||
|
__asm__ __volatile__("movl %%eax, %0; " : "=g" (ret) :);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3)
|
||||||
|
{
|
||||||
|
__asm__("movl %0, %%edx; " : : "g" (arg3) : "%edx");
|
||||||
|
return(stub_syscall2(syscall, arg1, arg2));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3,
|
||||||
|
long arg4)
|
||||||
|
{
|
||||||
|
__asm__("movl %0, %%esi; " : : "g" (arg4) : "%esi");
|
||||||
|
return(stub_syscall3(syscall, arg1, arg2, arg3));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3,
|
||||||
|
long arg4, long arg5, long arg6)
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
__asm__("movl %0, %%eax; " : : "g" (syscall) : "%eax");
|
||||||
|
__asm__("movl %0, %%ebx; " : : "g" (arg1) : "%ebx");
|
||||||
|
__asm__("movl %0, %%ecx; " : : "g" (arg2) : "%ecx");
|
||||||
|
__asm__("movl %0, %%edx; " : : "g" (arg3) : "%edx");
|
||||||
|
__asm__("movl %0, %%esi; " : : "g" (arg4) : "%esi");
|
||||||
|
__asm__("movl %0, %%edi; " : : "g" (arg5) : "%edi");
|
||||||
|
__asm__ __volatile__("pushl %%ebp ; movl %1, %%ebp; "
|
||||||
|
"int $0x80; popl %%ebp ; "
|
||||||
|
"movl %%eax, %0; " : "=g" (ret) : "g" (arg6) : "%eax");
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void trap_myself(void)
|
||||||
|
{
|
||||||
|
__asm("int3");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -55,6 +55,20 @@
|
||||||
#define PTRACE_OLDSETOPTIONS 21
|
#define PTRACE_OLDSETOPTIONS 21
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* These are before the system call, so the the system call number is RAX
|
||||||
|
* rather than ORIG_RAX, and arg4 is R10 rather than RCX
|
||||||
|
*/
|
||||||
|
#define REGS_SYSCALL_NR PT_INDEX(RAX)
|
||||||
|
#define REGS_SYSCALL_ARG1 PT_INDEX(RDI)
|
||||||
|
#define REGS_SYSCALL_ARG2 PT_INDEX(RSI)
|
||||||
|
#define REGS_SYSCALL_ARG3 PT_INDEX(RDX)
|
||||||
|
#define REGS_SYSCALL_ARG4 PT_INDEX(R10)
|
||||||
|
#define REGS_SYSCALL_ARG5 PT_INDEX(R8)
|
||||||
|
#define REGS_SYSCALL_ARG6 PT_INDEX(R9)
|
||||||
|
|
||||||
|
#define REGS_IP_INDEX PT_INDEX(RIP)
|
||||||
|
#define REGS_SP_INDEX PT_INDEX(RSP)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
|
||||||
|
* Licensed under the GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SYSDEP_STUB_H
|
||||||
|
#define __SYSDEP_STUB_H
|
||||||
|
|
||||||
|
#include <asm/ptrace.h>
|
||||||
|
#include <asm/unistd.h>
|
||||||
|
#include <sysdep/ptrace_user.h>
|
||||||
|
|
||||||
|
extern void stub_segv_handler(int sig);
|
||||||
|
extern void stub_clone_handler(void);
|
||||||
|
|
||||||
|
#define STUB_SYSCALL_RET PT_INDEX(RAX)
|
||||||
|
#define STUB_MMAP_NR __NR_mmap
|
||||||
|
#define MMAP_OFFSET(o) (o)
|
||||||
|
|
||||||
|
static inline long stub_syscall2(long syscall, long arg1, long arg2)
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
|
||||||
|
__asm__("movq %0, %%rsi; " : : "g" (arg2) : "%rsi");
|
||||||
|
__asm__("movq %0, %%rdi; " : : "g" (arg1) : "%rdi");
|
||||||
|
__asm__("movq %0, %%rax; " : : "g" (syscall) : "%rax");
|
||||||
|
__asm__("syscall;" : : : "%rax", "%r11", "%rcx");
|
||||||
|
__asm__ __volatile__("movq %%rax, %0; " : "=g" (ret) :);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3)
|
||||||
|
{
|
||||||
|
__asm__("movq %0, %%rdx; " : : "g" (arg3) : "%rdx");
|
||||||
|
return(stub_syscall2(syscall, arg1, arg2));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3,
|
||||||
|
long arg4)
|
||||||
|
{
|
||||||
|
__asm__("movq %0, %%r10; " : : "g" (arg4) : "%r10");
|
||||||
|
return(stub_syscall3(syscall, arg1, arg2, arg3));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3,
|
||||||
|
long arg4, long arg5, long arg6)
|
||||||
|
{
|
||||||
|
__asm__("movq %0, %%r9; " : : "g" (arg6) : "%r9");
|
||||||
|
__asm__("movq %0, %%r8; " : : "g" (arg5) : "%r8");
|
||||||
|
return(stub_syscall4(syscall, arg1, arg2, arg3, arg4));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void trap_myself(void)
|
||||||
|
{
|
||||||
|
__asm("int3");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -10,6 +10,7 @@ extern void timer(void);
|
||||||
extern void switch_timers(int to_real);
|
extern void switch_timers(int to_real);
|
||||||
extern void idle_sleep(int secs);
|
extern void idle_sleep(int secs);
|
||||||
extern void enable_timer(void);
|
extern void enable_timer(void);
|
||||||
|
extern void prepare_timer(void * ptr);
|
||||||
extern void disable_timer(void);
|
extern void disable_timer(void);
|
||||||
extern unsigned long time_lock(void);
|
extern unsigned long time_lock(void);
|
||||||
extern void time_unlock(unsigned long);
|
extern void time_unlock(unsigned long);
|
||||||
|
|
|
@ -37,31 +37,25 @@ struct host_vm_op {
|
||||||
extern void mprotect_kernel_vm(int w);
|
extern void mprotect_kernel_vm(int w);
|
||||||
extern void force_flush_all(void);
|
extern void force_flush_all(void);
|
||||||
extern void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
|
extern void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
|
||||||
unsigned long end_addr, int force, int data,
|
unsigned long end_addr, int force,
|
||||||
void (*do_ops)(int, struct host_vm_op *, int));
|
void (*do_ops)(union mm_context *,
|
||||||
|
struct host_vm_op *, int));
|
||||||
extern int flush_tlb_kernel_range_common(unsigned long start,
|
extern int flush_tlb_kernel_range_common(unsigned long start,
|
||||||
unsigned long end);
|
unsigned long end);
|
||||||
|
|
||||||
extern int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
|
extern int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
|
||||||
int r, int w, int x, struct host_vm_op *ops, int index,
|
int r, int w, int x, struct host_vm_op *ops, int index,
|
||||||
int last_filled, int data,
|
int last_filled, union mm_context *mmu,
|
||||||
void (*do_ops)(int, struct host_vm_op *, int));
|
void (*do_ops)(union mm_context *, struct host_vm_op *,
|
||||||
|
int));
|
||||||
extern int add_munmap(unsigned long addr, unsigned long len,
|
extern int add_munmap(unsigned long addr, unsigned long len,
|
||||||
struct host_vm_op *ops, int index, int last_filled,
|
struct host_vm_op *ops, int index, int last_filled,
|
||||||
int data, void (*do_ops)(int, struct host_vm_op *, int));
|
union mm_context *mmu,
|
||||||
|
void (*do_ops)(union mm_context *, struct host_vm_op *,
|
||||||
|
int));
|
||||||
extern int add_mprotect(unsigned long addr, unsigned long len, int r, int w,
|
extern int add_mprotect(unsigned long addr, unsigned long len, int r, int w,
|
||||||
int x, struct host_vm_op *ops, int index,
|
int x, struct host_vm_op *ops, int index,
|
||||||
int last_filled, int data,
|
int last_filled, union mm_context *mmu,
|
||||||
void (*do_ops)(int, struct host_vm_op *, int));
|
void (*do_ops)(union mm_context *, struct host_vm_op *,
|
||||||
|
int));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
|
||||||
* Emacs will notice this stuff at the end of the file and automatically
|
|
||||||
* adjust the settings for this buffer only. This must remain at the end
|
|
||||||
* of the file.
|
|
||||||
* ---------------------------------------------------------------------------
|
|
||||||
* Local variables:
|
|
||||||
* c-file-style: "linux"
|
|
||||||
* End:
|
|
||||||
*/
|
|
||||||
|
|
|
@ -67,6 +67,12 @@ SECTIONS
|
||||||
*(.stub .text.* .gnu.linkonce.t.*)
|
*(.stub .text.* .gnu.linkonce.t.*)
|
||||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||||
*(.gnu.warning)
|
*(.gnu.warning)
|
||||||
|
|
||||||
|
. = ALIGN(4096);
|
||||||
|
__syscall_stub_start = .;
|
||||||
|
*(.__syscall_stub*)
|
||||||
|
__syscall_stub_end = .;
|
||||||
|
. = ALIGN(4096);
|
||||||
} =0x90909090
|
} =0x90909090
|
||||||
.fini : {
|
.fini : {
|
||||||
KEEP (*(.fini))
|
KEEP (*(.fini))
|
||||||
|
|
|
@ -353,6 +353,8 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
|
||||||
|
|
||||||
#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
|
#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
|
||||||
|
|
||||||
|
extern int __syscall_stub_start, __binary_start;
|
||||||
|
|
||||||
void setup_physmem(unsigned long start, unsigned long reserve_end,
|
void setup_physmem(unsigned long start, unsigned long reserve_end,
|
||||||
unsigned long len, unsigned long highmem)
|
unsigned long len, unsigned long highmem)
|
||||||
{
|
{
|
||||||
|
@ -371,6 +373,12 @@ void setup_physmem(unsigned long start, unsigned long reserve_end,
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Special kludge - This page will be mapped in to userspace processes
|
||||||
|
* from physmem_fd, so it needs to be written out there.
|
||||||
|
*/
|
||||||
|
os_seek_file(physmem_fd, __pa(&__syscall_stub_start));
|
||||||
|
os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE);
|
||||||
|
|
||||||
bootmap_size = init_bootmem(pfn, pfn + delta);
|
bootmap_size = init_bootmem(pfn, pfn + delta);
|
||||||
free_bootmem(__pa(reserve_end) + bootmap_size,
|
free_bootmem(__pa(reserve_end) + bootmap_size,
|
||||||
len - bootmap_size - reserve);
|
len - bootmap_size - reserve);
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "uml-config.h"
|
#include "uml-config.h"
|
||||||
#include "choose-mode.h"
|
#include "choose-mode.h"
|
||||||
#include "mode.h"
|
#include "mode.h"
|
||||||
|
#include "tempfile.h"
|
||||||
#ifdef UML_CONFIG_MODE_SKAS
|
#ifdef UML_CONFIG_MODE_SKAS
|
||||||
#include "skas.h"
|
#include "skas.h"
|
||||||
#include "skas_ptrace.h"
|
#include "skas_ptrace.h"
|
||||||
|
@ -358,11 +359,16 @@ void forward_pending_sigio(int target)
|
||||||
kill(target, SIGIO);
|
kill(target, SIGIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ptrace_faultinfo = 0;
|
||||||
|
int proc_mm = 1;
|
||||||
|
|
||||||
|
extern void *__syscall_stub_start, __syscall_stub_end;
|
||||||
|
|
||||||
#ifdef UML_CONFIG_MODE_SKAS
|
#ifdef UML_CONFIG_MODE_SKAS
|
||||||
static inline int check_skas3_ptrace_support(void)
|
static inline void check_skas3_ptrace_support(void)
|
||||||
{
|
{
|
||||||
struct ptrace_faultinfo fi;
|
struct ptrace_faultinfo fi;
|
||||||
int pid, n, ret = 1;
|
int pid, n;
|
||||||
|
|
||||||
printf("Checking for the skas3 patch in the host...");
|
printf("Checking for the skas3 patch in the host...");
|
||||||
pid = start_ptraced_child();
|
pid = start_ptraced_child();
|
||||||
|
@ -374,33 +380,31 @@ static inline int check_skas3_ptrace_support(void)
|
||||||
else {
|
else {
|
||||||
perror("not found");
|
perror("not found");
|
||||||
}
|
}
|
||||||
ret = 0;
|
}
|
||||||
} else {
|
else {
|
||||||
|
ptrace_faultinfo = 1;
|
||||||
printf("found\n");
|
printf("found\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
init_registers(pid);
|
init_registers(pid);
|
||||||
stop_ptraced_child(pid, 1, 1);
|
stop_ptraced_child(pid, 1, 1);
|
||||||
|
|
||||||
return(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int can_do_skas(void)
|
int can_do_skas(void)
|
||||||
{
|
{
|
||||||
int ret = 1;
|
|
||||||
|
|
||||||
printf("Checking for /proc/mm...");
|
printf("Checking for /proc/mm...");
|
||||||
if (os_access("/proc/mm", OS_ACC_W_OK) < 0) {
|
if (os_access("/proc/mm", OS_ACC_W_OK) < 0) {
|
||||||
|
proc_mm = 0;
|
||||||
printf("not found\n");
|
printf("not found\n");
|
||||||
ret = 0;
|
|
||||||
goto out;
|
goto out;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
printf("found\n");
|
printf("found\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = check_skas3_ptrace_support();
|
|
||||||
out:
|
out:
|
||||||
return ret;
|
check_skas3_ptrace_support();
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int can_do_skas(void)
|
int can_do_skas(void)
|
||||||
|
|
|
@ -3,11 +3,14 @@
|
||||||
# Licensed under the GPL
|
# Licensed under the GPL
|
||||||
#
|
#
|
||||||
|
|
||||||
obj-y := exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \
|
obj-y := clone.o exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \
|
||||||
syscall_kern.o syscall_user.o tlb.o trap_user.o uaccess.o \
|
syscall_kern.o syscall_user.o tlb.o trap_user.o uaccess.o \
|
||||||
|
|
||||||
subdir- := util
|
subdir- := util
|
||||||
|
|
||||||
USER_OBJS := process.o
|
USER_OBJS := process.o clone.o
|
||||||
|
|
||||||
include arch/um/scripts/Makefile.rules
|
include arch/um/scripts/Makefile.rules
|
||||||
|
|
||||||
|
# clone.o is in the stub, so it can't be built with profiling
|
||||||
|
$(obj)/clone.o : c_flags = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS))
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
#include <sched.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <asm/unistd.h>
|
||||||
|
#include <asm/page.h>
|
||||||
|
#include "ptrace_user.h"
|
||||||
|
#include "skas.h"
|
||||||
|
#include "stub-data.h"
|
||||||
|
#include "uml-config.h"
|
||||||
|
#include "sysdep/stub.h"
|
||||||
|
|
||||||
|
/* This is in a separate file because it needs to be compiled with any
|
||||||
|
* extraneous gcc flags (-pg, -fprofile-arcs, -ftest-coverage) disabled
|
||||||
|
*/
|
||||||
|
void __attribute__ ((__section__ (".__syscall_stub")))
|
||||||
|
stub_clone_handler(void)
|
||||||
|
{
|
||||||
|
long err;
|
||||||
|
struct stub_data *from = (struct stub_data *) UML_CONFIG_STUB_DATA;
|
||||||
|
|
||||||
|
err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
|
||||||
|
UML_CONFIG_STUB_DATA + PAGE_SIZE / 2 -
|
||||||
|
sizeof(void *));
|
||||||
|
if(err != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
err = stub_syscall4(__NR_ptrace, PTRACE_TRACEME, 0, 0, 0);
|
||||||
|
if(err)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL,
|
||||||
|
(long) &from->timer, 0);
|
||||||
|
if(err)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
err = stub_syscall6(STUB_MMAP_NR, UML_CONFIG_STUB_DATA, PAGE_SIZE,
|
||||||
|
PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED,
|
||||||
|
from->fd, from->offset);
|
||||||
|
out:
|
||||||
|
/* save current result. Parent: pid; child: retcode of mmap */
|
||||||
|
from->err = err;
|
||||||
|
trap_myself();
|
||||||
|
}
|
|
@ -18,7 +18,7 @@
|
||||||
void flush_thread_skas(void)
|
void flush_thread_skas(void)
|
||||||
{
|
{
|
||||||
force_flush_all();
|
force_flush_all();
|
||||||
switch_mm_skas(current->mm->context.skas.mm_fd);
|
switch_mm_skas(¤t->mm->context.skas.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_thread_skas(struct pt_regs *regs, unsigned long eip,
|
void start_thread_skas(struct pt_regs *regs, unsigned long eip,
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2005 Jeff Dike (jdike@karaya.com)
|
||||||
|
* Licensed under the GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MM_ID_H
|
||||||
|
#define __MM_ID_H
|
||||||
|
|
||||||
|
struct mm_id {
|
||||||
|
union {
|
||||||
|
int mm_fd;
|
||||||
|
int pid;
|
||||||
|
} u;
|
||||||
|
unsigned long stack;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -6,10 +6,15 @@
|
||||||
#ifndef __SKAS_MMU_H
|
#ifndef __SKAS_MMU_H
|
||||||
#define __SKAS_MMU_H
|
#define __SKAS_MMU_H
|
||||||
|
|
||||||
|
#include "mm_id.h"
|
||||||
|
|
||||||
struct mmu_context_skas {
|
struct mmu_context_skas {
|
||||||
int mm_fd;
|
struct mm_id id;
|
||||||
|
unsigned long last_page_table;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern void switch_mm_skas(struct mm_id * mm_idp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -6,9 +6,11 @@
|
||||||
#ifndef __SKAS_H
|
#ifndef __SKAS_H
|
||||||
#define __SKAS_H
|
#define __SKAS_H
|
||||||
|
|
||||||
|
#include "mm_id.h"
|
||||||
#include "sysdep/ptrace.h"
|
#include "sysdep/ptrace.h"
|
||||||
|
|
||||||
extern int userspace_pid[];
|
extern int userspace_pid[];
|
||||||
|
extern int proc_mm, ptrace_faultinfo;
|
||||||
|
|
||||||
extern void switch_threads(void *me, void *next);
|
extern void switch_threads(void *me, void *next);
|
||||||
extern void thread_wait(void *sw, void *fb);
|
extern void thread_wait(void *sw, void *fb);
|
||||||
|
@ -22,16 +24,18 @@ extern void new_thread_proc(void *stack, void (*handler)(int sig));
|
||||||
extern void remove_sigstack(void);
|
extern void remove_sigstack(void);
|
||||||
extern void new_thread_handler(int sig);
|
extern void new_thread_handler(int sig);
|
||||||
extern void handle_syscall(union uml_pt_regs *regs);
|
extern void handle_syscall(union uml_pt_regs *regs);
|
||||||
extern void map(int fd, unsigned long virt, unsigned long len, int r, int w,
|
extern int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
|
||||||
int x, int phys_fd, unsigned long long offset);
|
int r, int w, int x, int phys_fd, unsigned long long offset);
|
||||||
extern int unmap(int fd, void *addr, unsigned long len);
|
extern int unmap(struct mm_id * mm_idp, void *addr, unsigned long len);
|
||||||
extern int protect(int fd, unsigned long addr, unsigned long len,
|
extern int protect(struct mm_id * mm_idp, unsigned long addr,
|
||||||
int r, int w, int x);
|
unsigned long len, int r, int w, int x);
|
||||||
extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
|
extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
|
||||||
extern int new_mm(int from);
|
extern int new_mm(int from);
|
||||||
extern void start_userspace(int cpu);
|
extern int start_userspace(unsigned long stub_stack);
|
||||||
|
extern int copy_context_skas0(unsigned long stack, int pid);
|
||||||
extern void get_skas_faultinfo(int pid, struct faultinfo * fi);
|
extern void get_skas_faultinfo(int pid, struct faultinfo * fi);
|
||||||
extern long execute_syscall_skas(void *r);
|
extern long execute_syscall_skas(void *r);
|
||||||
|
extern unsigned long current_stub_stack(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2005 Jeff Dike (jdike@karaya.com)
|
||||||
|
* Licensed under the GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __STUB_DATA_H
|
||||||
|
#define __STUB_DATA_H
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
struct stub_data {
|
||||||
|
long offset;
|
||||||
|
int fd;
|
||||||
|
struct itimerval timer;
|
||||||
|
long err;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -5,7 +5,9 @@
|
||||||
|
|
||||||
#include "linux/config.h"
|
#include "linux/config.h"
|
||||||
#include "linux/mm.h"
|
#include "linux/mm.h"
|
||||||
|
#include "asm/pgtable.h"
|
||||||
#include "mem_user.h"
|
#include "mem_user.h"
|
||||||
|
#include "skas.h"
|
||||||
|
|
||||||
unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
|
unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
|
||||||
unsigned long *task_size_out)
|
unsigned long *task_size_out)
|
||||||
|
@ -18,7 +20,9 @@ unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
|
||||||
*task_size_out = CONFIG_HOST_TASK_SIZE;
|
*task_size_out = CONFIG_HOST_TASK_SIZE;
|
||||||
#else
|
#else
|
||||||
*host_size_out = top;
|
*host_size_out = top;
|
||||||
*task_size_out = top;
|
if (proc_mm && ptrace_faultinfo)
|
||||||
|
*task_size_out = top;
|
||||||
|
else *task_size_out = CONFIG_STUB_START & PGDIR_MASK;
|
||||||
#endif
|
#endif
|
||||||
return(((unsigned long) set_task_sizes_skas) & ~0xffffff);
|
return(((unsigned long) set_task_sizes_skas) & ~0xffffff);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,100 +3,171 @@
|
||||||
* Licensed under the GPL
|
* Licensed under the GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <asm/page.h>
|
||||||
|
#include <asm/unistd.h>
|
||||||
#include "mem_user.h"
|
#include "mem_user.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
#include "mm_id.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "proc_mm.h"
|
#include "proc_mm.h"
|
||||||
|
#include "ptrace_user.h"
|
||||||
|
#include "user_util.h"
|
||||||
|
#include "kern_util.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "registers.h"
|
||||||
|
#include "uml-config.h"
|
||||||
|
#include "sysdep/ptrace.h"
|
||||||
|
#include "sysdep/stub.h"
|
||||||
|
#include "skas.h"
|
||||||
|
|
||||||
void map(int fd, unsigned long virt, unsigned long len, int r, int w,
|
extern unsigned long syscall_stub, __syscall_stub_start;
|
||||||
int x, int phys_fd, unsigned long long offset)
|
|
||||||
|
extern void wait_stub_done(int pid, int sig, char * fname);
|
||||||
|
|
||||||
|
static long run_syscall_stub(struct mm_id * mm_idp, int syscall,
|
||||||
|
unsigned long *args)
|
||||||
{
|
{
|
||||||
struct proc_mm_op map;
|
int n, pid = mm_idp->u.pid;
|
||||||
int prot, n;
|
unsigned long regs[MAX_REG_NR];
|
||||||
|
|
||||||
prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
|
get_safe_registers(regs);
|
||||||
(x ? PROT_EXEC : 0);
|
regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
|
||||||
|
((unsigned long) &syscall_stub -
|
||||||
|
(unsigned long) &__syscall_stub_start);
|
||||||
|
/* XXX Don't have a define for starting a syscall */
|
||||||
|
regs[REGS_SYSCALL_NR] = syscall;
|
||||||
|
regs[REGS_SYSCALL_ARG1] = args[0];
|
||||||
|
regs[REGS_SYSCALL_ARG2] = args[1];
|
||||||
|
regs[REGS_SYSCALL_ARG3] = args[2];
|
||||||
|
regs[REGS_SYSCALL_ARG4] = args[3];
|
||||||
|
regs[REGS_SYSCALL_ARG5] = args[4];
|
||||||
|
regs[REGS_SYSCALL_ARG6] = args[5];
|
||||||
|
n = ptrace_setregs(pid, regs);
|
||||||
|
if(n < 0){
|
||||||
|
printk("run_syscall_stub : PTRACE_SETREGS failed, "
|
||||||
|
"errno = %d\n", n);
|
||||||
|
return(n);
|
||||||
|
}
|
||||||
|
|
||||||
map = ((struct proc_mm_op) { .op = MM_MMAP,
|
wait_stub_done(pid, 0, "run_syscall_stub");
|
||||||
.u =
|
|
||||||
{ .mmap =
|
return(*((unsigned long *) mm_idp->stack));
|
||||||
{ .addr = virt,
|
|
||||||
.len = len,
|
|
||||||
.prot = prot,
|
|
||||||
.flags = MAP_SHARED |
|
|
||||||
MAP_FIXED,
|
|
||||||
.fd = phys_fd,
|
|
||||||
.offset = offset
|
|
||||||
} } } );
|
|
||||||
n = os_write_file(fd, &map, sizeof(map));
|
|
||||||
if(n != sizeof(map))
|
|
||||||
printk("map : /proc/mm map failed, err = %d\n", -n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int unmap(int fd, void *addr, unsigned long len)
|
int map(struct mm_id *mm_idp, unsigned long virt, unsigned long len,
|
||||||
|
int r, int w, int x, int phys_fd, unsigned long long offset)
|
||||||
{
|
{
|
||||||
struct proc_mm_op unmap;
|
int prot, n;
|
||||||
int n;
|
|
||||||
|
|
||||||
unmap = ((struct proc_mm_op) { .op = MM_MUNMAP,
|
prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
|
||||||
.u =
|
(x ? PROT_EXEC : 0);
|
||||||
{ .munmap =
|
|
||||||
{ .addr = (unsigned long) addr,
|
|
||||||
.len = len } } } );
|
|
||||||
n = os_write_file(fd, &unmap, sizeof(unmap));
|
|
||||||
if(n != sizeof(unmap)) {
|
|
||||||
if(n < 0)
|
|
||||||
return(n);
|
|
||||||
else if(n > 0)
|
|
||||||
return(-EIO);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(0);
|
if(proc_mm){
|
||||||
|
struct proc_mm_op map;
|
||||||
|
int fd = mm_idp->u.mm_fd;
|
||||||
|
map = ((struct proc_mm_op) { .op = MM_MMAP,
|
||||||
|
.u =
|
||||||
|
{ .mmap =
|
||||||
|
{ .addr = virt,
|
||||||
|
.len = len,
|
||||||
|
.prot = prot,
|
||||||
|
.flags = MAP_SHARED |
|
||||||
|
MAP_FIXED,
|
||||||
|
.fd = phys_fd,
|
||||||
|
.offset= offset
|
||||||
|
} } } );
|
||||||
|
n = os_write_file(fd, &map, sizeof(map));
|
||||||
|
if(n != sizeof(map))
|
||||||
|
printk("map : /proc/mm map failed, err = %d\n", -n);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
long res;
|
||||||
|
unsigned long args[] = { virt, len, prot,
|
||||||
|
MAP_SHARED | MAP_FIXED, phys_fd,
|
||||||
|
MMAP_OFFSET(offset) };
|
||||||
|
|
||||||
|
res = run_syscall_stub(mm_idp, STUB_MMAP_NR, args);
|
||||||
|
if((void *) res == MAP_FAILED)
|
||||||
|
printk("mmap stub failed, errno = %d\n", res);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int protect(int fd, unsigned long addr, unsigned long len, int r, int w,
|
int unmap(struct mm_id *mm_idp, void *addr, unsigned long len)
|
||||||
int x, int must_succeed)
|
|
||||||
{
|
{
|
||||||
struct proc_mm_op protect;
|
int n;
|
||||||
int prot, n;
|
|
||||||
|
|
||||||
prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
|
if(proc_mm){
|
||||||
(x ? PROT_EXEC : 0);
|
struct proc_mm_op unmap;
|
||||||
|
int fd = mm_idp->u.mm_fd;
|
||||||
|
unmap = ((struct proc_mm_op) { .op = MM_MUNMAP,
|
||||||
|
.u =
|
||||||
|
{ .munmap =
|
||||||
|
{ .addr =
|
||||||
|
(unsigned long) addr,
|
||||||
|
.len = len } } } );
|
||||||
|
n = os_write_file(fd, &unmap, sizeof(unmap));
|
||||||
|
if(n != sizeof(unmap)) {
|
||||||
|
if(n < 0)
|
||||||
|
return(n);
|
||||||
|
else if(n > 0)
|
||||||
|
return(-EIO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int res;
|
||||||
|
unsigned long args[] = { (unsigned long) addr, len, 0, 0, 0,
|
||||||
|
0 };
|
||||||
|
|
||||||
protect = ((struct proc_mm_op) { .op = MM_MPROTECT,
|
res = run_syscall_stub(mm_idp, __NR_munmap, args);
|
||||||
.u =
|
if(res < 0)
|
||||||
{ .mprotect =
|
printk("munmap stub failed, errno = %d\n", res);
|
||||||
{ .addr = (unsigned long) addr,
|
}
|
||||||
.len = len,
|
|
||||||
.prot = prot } } } );
|
|
||||||
|
|
||||||
n = os_write_file(fd, &protect, sizeof(protect));
|
return(0);
|
||||||
if(n != sizeof(protect)) {
|
}
|
||||||
if(n == 0) return(0);
|
|
||||||
|
|
||||||
if(must_succeed)
|
int protect(struct mm_id *mm_idp, unsigned long addr, unsigned long len,
|
||||||
panic("protect failed, err = %d", -n);
|
int r, int w, int x)
|
||||||
|
{
|
||||||
|
struct proc_mm_op protect;
|
||||||
|
int prot, n;
|
||||||
|
|
||||||
return(-EIO);
|
prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
|
||||||
}
|
(x ? PROT_EXEC : 0);
|
||||||
|
|
||||||
return(0);
|
if(proc_mm){
|
||||||
|
int fd = mm_idp->u.mm_fd;
|
||||||
|
protect = ((struct proc_mm_op) { .op = MM_MPROTECT,
|
||||||
|
.u =
|
||||||
|
{ .mprotect =
|
||||||
|
{ .addr =
|
||||||
|
(unsigned long) addr,
|
||||||
|
.len = len,
|
||||||
|
.prot = prot } } } );
|
||||||
|
|
||||||
|
n = os_write_file(fd, &protect, sizeof(protect));
|
||||||
|
if(n != sizeof(protect))
|
||||||
|
panic("protect failed, err = %d", -n);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int res;
|
||||||
|
unsigned long args[] = { addr, len, prot, 0, 0, 0 };
|
||||||
|
|
||||||
|
res = run_syscall_stub(mm_idp, __NR_mprotect, args);
|
||||||
|
if(res < 0)
|
||||||
|
panic("mprotect stub failed, errno = %d\n", res);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void before_mem_skas(unsigned long unused)
|
void before_mem_skas(unsigned long unused)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
|
||||||
* Emacs will notice this stuff at the end of the file and automatically
|
|
||||||
* adjust the settings for this buffer only. This must remain at the end
|
|
||||||
* of the file.
|
|
||||||
* ---------------------------------------------------------------------------
|
|
||||||
* Local variables:
|
|
||||||
* c-file-style: "linux"
|
|
||||||
* End:
|
|
||||||
*/
|
|
||||||
|
|
|
@ -3,46 +3,143 @@
|
||||||
* Licensed under the GPL
|
* Licensed under the GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "linux/config.h"
|
||||||
#include "linux/sched.h"
|
#include "linux/sched.h"
|
||||||
#include "linux/list.h"
|
#include "linux/list.h"
|
||||||
#include "linux/spinlock.h"
|
#include "linux/spinlock.h"
|
||||||
#include "linux/slab.h"
|
#include "linux/slab.h"
|
||||||
|
#include "linux/errno.h"
|
||||||
|
#include "linux/mm.h"
|
||||||
#include "asm/current.h"
|
#include "asm/current.h"
|
||||||
#include "asm/segment.h"
|
#include "asm/segment.h"
|
||||||
#include "asm/mmu.h"
|
#include "asm/mmu.h"
|
||||||
|
#include "asm/pgalloc.h"
|
||||||
|
#include "asm/pgtable.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "skas.h"
|
#include "skas.h"
|
||||||
|
|
||||||
|
extern int __syscall_stub_start;
|
||||||
|
|
||||||
|
static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
|
||||||
|
unsigned long kernel)
|
||||||
|
{
|
||||||
|
pgd_t *pgd;
|
||||||
|
pud_t *pud;
|
||||||
|
pmd_t *pmd;
|
||||||
|
pte_t *pte;
|
||||||
|
|
||||||
|
spin_lock(&mm->page_table_lock);
|
||||||
|
pgd = pgd_offset(mm, proc);
|
||||||
|
pud = pud_alloc(mm, pgd, proc);
|
||||||
|
if (!pud)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
pmd = pmd_alloc(mm, pud, proc);
|
||||||
|
if (!pmd)
|
||||||
|
goto out_pmd;
|
||||||
|
|
||||||
|
pte = pte_alloc_map(mm, pmd, proc);
|
||||||
|
if (!pte)
|
||||||
|
goto out_pte;
|
||||||
|
|
||||||
|
/* There's an interaction between the skas0 stub pages, stack
|
||||||
|
* randomization, and the BUG at the end of exit_mmap. exit_mmap
|
||||||
|
* checks that the number of page tables freed is the same as had
|
||||||
|
* been allocated. If the stack is on the last page table page,
|
||||||
|
* then the stack pte page will be freed, and if not, it won't. To
|
||||||
|
* avoid having to know where the stack is, or if the process mapped
|
||||||
|
* something at the top of its address space for some other reason,
|
||||||
|
* we set TASK_SIZE to end at the start of the last page table.
|
||||||
|
* This keeps exit_mmap off the last page, but introduces a leak
|
||||||
|
* of that page. So, we hang onto it here and free it in
|
||||||
|
* destroy_context_skas.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mm->context.skas.last_page_table = pmd_page_kernel(*pmd);
|
||||||
|
|
||||||
|
*pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT));
|
||||||
|
*pte = pte_mkexec(*pte);
|
||||||
|
*pte = pte_wrprotect(*pte);
|
||||||
|
spin_unlock(&mm->page_table_lock);
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
out_pmd:
|
||||||
|
pud_free(pud);
|
||||||
|
out_pte:
|
||||||
|
pmd_free(pmd);
|
||||||
|
out:
|
||||||
|
spin_unlock(&mm->page_table_lock);
|
||||||
|
return(-ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
|
int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
|
||||||
{
|
{
|
||||||
int from;
|
struct mm_struct *cur_mm = current->mm;
|
||||||
|
struct mm_id *cur_mm_id = &cur_mm->context.skas.id;
|
||||||
|
struct mm_id *mm_id = &mm->context.skas.id;
|
||||||
|
unsigned long stack;
|
||||||
|
int from, ret;
|
||||||
|
|
||||||
if((current->mm != NULL) && (current->mm != &init_mm))
|
if(proc_mm){
|
||||||
from = current->mm->context.skas.mm_fd;
|
if((cur_mm != NULL) && (cur_mm != &init_mm))
|
||||||
else from = -1;
|
from = cur_mm->context.skas.id.u.mm_fd;
|
||||||
|
else from = -1;
|
||||||
|
|
||||||
mm->context.skas.mm_fd = new_mm(from);
|
ret = new_mm(from);
|
||||||
if(mm->context.skas.mm_fd < 0){
|
if(ret < 0){
|
||||||
printk("init_new_context_skas - new_mm failed, errno = %d\n",
|
printk("init_new_context_skas - new_mm failed, "
|
||||||
mm->context.skas.mm_fd);
|
"errno = %d\n", ret);
|
||||||
return(mm->context.skas.mm_fd);
|
return ret;
|
||||||
|
}
|
||||||
|
mm_id->u.mm_fd = ret;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* This zeros the entry that pgd_alloc didn't, needed since
|
||||||
|
* we are about to reinitialize it, and want mm.nr_ptes to
|
||||||
|
* be accurate.
|
||||||
|
*/
|
||||||
|
mm->pgd[USER_PTRS_PER_PGD] = __pgd(0);
|
||||||
|
|
||||||
|
ret = init_stub_pte(mm, CONFIG_STUB_CODE,
|
||||||
|
(unsigned long) &__syscall_stub_start);
|
||||||
|
if(ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = -ENOMEM;
|
||||||
|
stack = get_zeroed_page(GFP_KERNEL);
|
||||||
|
if(stack == 0)
|
||||||
|
goto out;
|
||||||
|
mm_id->stack = stack;
|
||||||
|
|
||||||
|
ret = init_stub_pte(mm, CONFIG_STUB_DATA, stack);
|
||||||
|
if(ret)
|
||||||
|
goto out_free;
|
||||||
|
|
||||||
|
mm->nr_ptes--;
|
||||||
|
|
||||||
|
if((cur_mm != NULL) && (cur_mm != &init_mm))
|
||||||
|
mm_id->u.pid = copy_context_skas0(stack,
|
||||||
|
cur_mm_id->u.pid);
|
||||||
|
else mm_id->u.pid = start_userspace(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return 0;
|
||||||
|
|
||||||
|
out_free:
|
||||||
|
free_page(mm_id->stack);
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_context_skas(struct mm_struct *mm)
|
void destroy_context_skas(struct mm_struct *mm)
|
||||||
{
|
{
|
||||||
os_close_file(mm->context.skas.mm_fd);
|
struct mmu_context_skas *mmu = &mm->context.skas;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
if(proc_mm)
|
||||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
os_close_file(mmu->id.u.mm_fd);
|
||||||
* Emacs will notice this stuff at the end of the file and automatically
|
else {
|
||||||
* adjust the settings for this buffer only. This must remain at the end
|
os_kill_ptraced_process(mmu->id.u.pid, 1);
|
||||||
* of the file.
|
free_page(mmu->id.stack);
|
||||||
* ---------------------------------------------------------------------------
|
free_page(mmu->last_page_table);
|
||||||
* Local variables:
|
}
|
||||||
* c-file-style: "linux"
|
}
|
||||||
* End:
|
|
||||||
*/
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
|
* Copyright (C) 2002- 2004 Jeff Dike (jdike@addtoit.com)
|
||||||
* Licensed under the GPL
|
* Licensed under the GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -13,7 +13,9 @@
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/user.h>
|
#include <sys/user.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include <asm/unistd.h>
|
#include <asm/unistd.h>
|
||||||
|
#include <asm/types.h>
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
#include "ptrace_user.h"
|
#include "ptrace_user.h"
|
||||||
#include "time_user.h"
|
#include "time_user.h"
|
||||||
|
@ -21,13 +23,18 @@
|
||||||
#include "user_util.h"
|
#include "user_util.h"
|
||||||
#include "kern_util.h"
|
#include "kern_util.h"
|
||||||
#include "skas.h"
|
#include "skas.h"
|
||||||
|
#include "stub-data.h"
|
||||||
|
#include "mm_id.h"
|
||||||
#include "sysdep/sigcontext.h"
|
#include "sysdep/sigcontext.h"
|
||||||
|
#include "sysdep/stub.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "proc_mm.h"
|
#include "proc_mm.h"
|
||||||
#include "skas_ptrace.h"
|
#include "skas_ptrace.h"
|
||||||
#include "chan_user.h"
|
#include "chan_user.h"
|
||||||
#include "signal_user.h"
|
#include "signal_user.h"
|
||||||
#include "registers.h"
|
#include "registers.h"
|
||||||
|
#include "mem.h"
|
||||||
|
#include "uml-config.h"
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
|
|
||||||
int is_skas_winch(int pid, int fd, void *data)
|
int is_skas_winch(int pid, int fd, void *data)
|
||||||
|
@ -39,20 +46,55 @@ int is_skas_winch(int pid, int fd, void *data)
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wait_stub_done(int pid, int sig, char * fname)
|
||||||
|
{
|
||||||
|
int n, status, err;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if ( sig != -1 ) {
|
||||||
|
err = ptrace(PTRACE_CONT, pid, 0, sig);
|
||||||
|
if(err)
|
||||||
|
panic("%s : continue failed, errno = %d\n",
|
||||||
|
fname, errno);
|
||||||
|
}
|
||||||
|
sig = 0;
|
||||||
|
|
||||||
|
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
|
||||||
|
} while((n >= 0) && WIFSTOPPED(status) &&
|
||||||
|
(WSTOPSIG(status) == SIGVTALRM));
|
||||||
|
|
||||||
|
if((n < 0) || !WIFSTOPPED(status) ||
|
||||||
|
(WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status != SIGTRAP))){
|
||||||
|
panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
|
||||||
|
"pid = %d, n = %d, errno = %d, status = 0x%x\n",
|
||||||
|
fname, pid, n, errno, status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void get_skas_faultinfo(int pid, struct faultinfo * fi)
|
void get_skas_faultinfo(int pid, struct faultinfo * fi)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
|
if(ptrace_faultinfo){
|
||||||
if(err)
|
err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
|
||||||
panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
|
if(err)
|
||||||
"errno = %d\n", errno);
|
panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
|
||||||
|
"errno = %d\n", errno);
|
||||||
|
|
||||||
/* Special handling for i386, which has different structs */
|
/* Special handling for i386, which has different structs */
|
||||||
if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo))
|
if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo))
|
||||||
memset((char *)fi + sizeof(struct ptrace_faultinfo), 0,
|
memset((char *)fi + sizeof(struct ptrace_faultinfo), 0,
|
||||||
sizeof(struct faultinfo) -
|
sizeof(struct faultinfo) -
|
||||||
sizeof(struct ptrace_faultinfo));
|
sizeof(struct ptrace_faultinfo));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wait_stub_done(pid, SIGSEGV, "get_skas_faultinfo");
|
||||||
|
|
||||||
|
/* faultinfo is prepared by the stub-segv-handler at start of
|
||||||
|
* the stub stack page. We just have to copy it.
|
||||||
|
*/
|
||||||
|
memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_segv(int pid, union uml_pt_regs * regs)
|
static void handle_segv(int pid, union uml_pt_regs * regs)
|
||||||
|
@ -91,11 +133,56 @@ static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu
|
||||||
handle_syscall(regs);
|
handle_syscall(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int userspace_tramp(void *arg)
|
extern int __syscall_stub_start;
|
||||||
|
|
||||||
|
static int userspace_tramp(void *stack)
|
||||||
{
|
{
|
||||||
init_new_thread_signals(0);
|
void *addr;
|
||||||
enable_timer();
|
|
||||||
ptrace(PTRACE_TRACEME, 0, 0, 0);
|
ptrace(PTRACE_TRACEME, 0, 0, 0);
|
||||||
|
|
||||||
|
init_new_thread_signals(1);
|
||||||
|
enable_timer();
|
||||||
|
|
||||||
|
if(!proc_mm){
|
||||||
|
/* This has a pte, but it can't be mapped in with the usual
|
||||||
|
* tlb_flush mechanism because this is part of that mechanism
|
||||||
|
*/
|
||||||
|
int fd;
|
||||||
|
__u64 offset;
|
||||||
|
|
||||||
|
fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
|
||||||
|
addr = mmap64((void *) UML_CONFIG_STUB_CODE, page_size(),
|
||||||
|
PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
|
||||||
|
if(addr == MAP_FAILED){
|
||||||
|
printk("mapping mmap stub failed, errno = %d\n",
|
||||||
|
errno);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(stack != NULL){
|
||||||
|
fd = phys_mapping(to_phys(stack), &offset);
|
||||||
|
addr = mmap((void *) UML_CONFIG_STUB_DATA, page_size(),
|
||||||
|
PROT_READ | PROT_WRITE,
|
||||||
|
MAP_FIXED | MAP_SHARED, fd, offset);
|
||||||
|
if(addr == MAP_FAILED){
|
||||||
|
printk("mapping segfault stack failed, "
|
||||||
|
"errno = %d\n", errno);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!ptrace_faultinfo && (stack != NULL)){
|
||||||
|
unsigned long v = UML_CONFIG_STUB_CODE +
|
||||||
|
(unsigned long) stub_segv_handler -
|
||||||
|
(unsigned long) &__syscall_stub_start;
|
||||||
|
|
||||||
|
set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size());
|
||||||
|
set_handler(SIGSEGV, (void *) v, SA_ONSTACK,
|
||||||
|
SIGIO, SIGWINCH, SIGALRM, SIGVTALRM,
|
||||||
|
SIGUSR1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
os_stop_process(os_getpid());
|
os_stop_process(os_getpid());
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
@ -105,11 +192,11 @@ static int userspace_tramp(void *arg)
|
||||||
#define NR_CPUS 1
|
#define NR_CPUS 1
|
||||||
int userspace_pid[NR_CPUS];
|
int userspace_pid[NR_CPUS];
|
||||||
|
|
||||||
void start_userspace(int cpu)
|
int start_userspace(unsigned long stub_stack)
|
||||||
{
|
{
|
||||||
void *stack;
|
void *stack;
|
||||||
unsigned long sp;
|
unsigned long sp;
|
||||||
int pid, status, n;
|
int pid, status, n, flags;
|
||||||
|
|
||||||
stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
|
stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
|
@ -117,8 +204,9 @@ void start_userspace(int cpu)
|
||||||
panic("start_userspace : mmap failed, errno = %d", errno);
|
panic("start_userspace : mmap failed, errno = %d", errno);
|
||||||
sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
|
sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
|
||||||
|
|
||||||
pid = clone(userspace_tramp, (void *) sp,
|
flags = CLONE_FILES | SIGCHLD;
|
||||||
CLONE_FILES | CLONE_VM | SIGCHLD, NULL);
|
if(proc_mm) flags |= CLONE_VM;
|
||||||
|
pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack);
|
||||||
if(pid < 0)
|
if(pid < 0)
|
||||||
panic("start_userspace : clone failed, errno = %d", errno);
|
panic("start_userspace : clone failed, errno = %d", errno);
|
||||||
|
|
||||||
|
@ -140,7 +228,7 @@ void start_userspace(int cpu)
|
||||||
if(munmap(stack, PAGE_SIZE) < 0)
|
if(munmap(stack, PAGE_SIZE) < 0)
|
||||||
panic("start_userspace : munmap failed, errno = %d\n", errno);
|
panic("start_userspace : munmap failed, errno = %d\n", errno);
|
||||||
|
|
||||||
userspace_pid[cpu] = pid;
|
return(pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void userspace(union uml_pt_regs *regs)
|
void userspace(union uml_pt_regs *regs)
|
||||||
|
@ -174,7 +262,9 @@ void userspace(union uml_pt_regs *regs)
|
||||||
if(WIFSTOPPED(status)){
|
if(WIFSTOPPED(status)){
|
||||||
switch(WSTOPSIG(status)){
|
switch(WSTOPSIG(status)){
|
||||||
case SIGSEGV:
|
case SIGSEGV:
|
||||||
handle_segv(pid, regs);
|
if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo)
|
||||||
|
user_signal(SIGSEGV, regs, pid);
|
||||||
|
else handle_segv(pid, regs);
|
||||||
break;
|
break;
|
||||||
case SIGTRAP + 0x80:
|
case SIGTRAP + 0x80:
|
||||||
handle_trap(pid, regs, local_using_sysemu);
|
handle_trap(pid, regs, local_using_sysemu);
|
||||||
|
@ -194,6 +284,7 @@ void userspace(union uml_pt_regs *regs)
|
||||||
printk("userspace - child stopped with signal "
|
printk("userspace - child stopped with signal "
|
||||||
"%d\n", WSTOPSIG(status));
|
"%d\n", WSTOPSIG(status));
|
||||||
}
|
}
|
||||||
|
pid = userspace_pid[0];
|
||||||
interrupt_end();
|
interrupt_end();
|
||||||
|
|
||||||
/* Avoid -ERESTARTSYS handling in host */
|
/* Avoid -ERESTARTSYS handling in host */
|
||||||
|
@ -207,6 +298,67 @@ void userspace(union uml_pt_regs *regs)
|
||||||
#define INIT_JMP_HALT 3
|
#define INIT_JMP_HALT 3
|
||||||
#define INIT_JMP_REBOOT 4
|
#define INIT_JMP_REBOOT 4
|
||||||
|
|
||||||
|
|
||||||
|
int copy_context_skas0(unsigned long new_stack, int pid)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
unsigned long regs[MAX_REG_NR];
|
||||||
|
unsigned long current_stack = current_stub_stack();
|
||||||
|
struct stub_data *data = (struct stub_data *) current_stack;
|
||||||
|
struct stub_data *child_data = (struct stub_data *) new_stack;
|
||||||
|
__u64 new_offset;
|
||||||
|
int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset);
|
||||||
|
|
||||||
|
/* prepare offset and fd of child's stack as argument for parent's
|
||||||
|
* and child's mmap2 calls
|
||||||
|
*/
|
||||||
|
*data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset),
|
||||||
|
.fd = new_fd,
|
||||||
|
.timer = ((struct itimerval)
|
||||||
|
{ { 0, 1000000 / hz() },
|
||||||
|
{ 0, 1000000 / hz() }})});
|
||||||
|
get_safe_registers(regs);
|
||||||
|
|
||||||
|
/* Set parent's instruction pointer to start of clone-stub */
|
||||||
|
regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
|
||||||
|
(unsigned long) stub_clone_handler -
|
||||||
|
(unsigned long) &__syscall_stub_start;
|
||||||
|
regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE -
|
||||||
|
sizeof(void *);
|
||||||
|
err = ptrace_setregs(pid, regs);
|
||||||
|
if(err < 0)
|
||||||
|
panic("copy_context_skas0 : PTRACE_SETREGS failed, "
|
||||||
|
"pid = %d, errno = %d\n", pid, errno);
|
||||||
|
|
||||||
|
/* set a well known return code for detection of child write failure */
|
||||||
|
child_data->err = 12345678;
|
||||||
|
|
||||||
|
/* Wait, until parent has finished its work: read child's pid from
|
||||||
|
* parent's stack, and check, if bad result.
|
||||||
|
*/
|
||||||
|
wait_stub_done(pid, 0, "copy_context_skas0");
|
||||||
|
|
||||||
|
pid = data->err;
|
||||||
|
if(pid < 0)
|
||||||
|
panic("copy_context_skas0 - stub-parent reports error %d\n",
|
||||||
|
pid);
|
||||||
|
|
||||||
|
/* Wait, until child has finished too: read child's result from
|
||||||
|
* child's stack and check it.
|
||||||
|
*/
|
||||||
|
wait_stub_done(pid, -1, "copy_context_skas0");
|
||||||
|
if (child_data->err != UML_CONFIG_STUB_DATA)
|
||||||
|
panic("copy_context_skas0 - stub-child reports error %d\n",
|
||||||
|
child_data->err);
|
||||||
|
|
||||||
|
if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
|
||||||
|
(void *)PTRACE_O_TRACESYSGOOD) < 0)
|
||||||
|
panic("copy_context_skas0 : PTRACE_SETOPTIONS failed, "
|
||||||
|
"errno = %d\n", errno);
|
||||||
|
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
|
void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
|
||||||
void (*handler)(int))
|
void (*handler)(int))
|
||||||
{
|
{
|
||||||
|
@ -334,21 +486,19 @@ void reboot_skas(void)
|
||||||
siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT);
|
siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void switch_mm_skas(int mm_fd)
|
void switch_mm_skas(struct mm_id *mm_idp)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
#warning need cpu pid in switch_mm_skas
|
#warning need cpu pid in switch_mm_skas
|
||||||
err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, mm_fd);
|
if(proc_mm){
|
||||||
if(err)
|
err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0,
|
||||||
panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n",
|
mm_idp->u.mm_fd);
|
||||||
errno);
|
if(err)
|
||||||
}
|
panic("switch_mm_skas - PTRACE_SWITCH_MM failed, "
|
||||||
|
"errno = %d\n", errno);
|
||||||
void kill_off_processes_skas(void)
|
}
|
||||||
{
|
else userspace_pid[0] = mm_idp->u.pid;
|
||||||
#warning need to loop over userspace_pids in kill_off_processes_skas
|
|
||||||
os_kill_ptraced_process(userspace_pid[0], 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -175,9 +175,12 @@ static int start_kernel_proc(void *unused)
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern int userspace_pid[];
|
||||||
|
|
||||||
int start_uml_skas(void)
|
int start_uml_skas(void)
|
||||||
{
|
{
|
||||||
start_userspace(0);
|
if(proc_mm)
|
||||||
|
userspace_pid[0] = start_userspace(0);
|
||||||
|
|
||||||
init_new_thread_signals(1);
|
init_new_thread_signals(1);
|
||||||
|
|
||||||
|
@ -199,3 +202,31 @@ int thread_pid_skas(struct task_struct *task)
|
||||||
#warning Need to look up userspace_pid by cpu
|
#warning Need to look up userspace_pid by cpu
|
||||||
return(userspace_pid[0]);
|
return(userspace_pid[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kill_off_processes_skas(void)
|
||||||
|
{
|
||||||
|
if(proc_mm)
|
||||||
|
#warning need to loop over userspace_pids in kill_off_processes_skas
|
||||||
|
os_kill_ptraced_process(userspace_pid[0], 1);
|
||||||
|
else {
|
||||||
|
struct task_struct *p;
|
||||||
|
int pid, me;
|
||||||
|
|
||||||
|
me = os_getpid();
|
||||||
|
for_each_process(p){
|
||||||
|
if(p->mm == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pid = p->mm->context.skas.id.u.pid;
|
||||||
|
os_kill_ptraced_process(pid, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long current_stub_stack(void)
|
||||||
|
{
|
||||||
|
if(current->mm == NULL)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
return(current->mm->context.skas.id.stack);
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "linux/stddef.h"
|
#include "linux/stddef.h"
|
||||||
#include "linux/sched.h"
|
#include "linux/sched.h"
|
||||||
|
#include "linux/config.h"
|
||||||
#include "linux/mm.h"
|
#include "linux/mm.h"
|
||||||
#include "asm/page.h"
|
#include "asm/page.h"
|
||||||
#include "asm/pgtable.h"
|
#include "asm/pgtable.h"
|
||||||
|
@ -17,7 +18,7 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "tlb.h"
|
#include "tlb.h"
|
||||||
|
|
||||||
static void do_ops(int fd, struct host_vm_op *ops, int last)
|
static void do_ops(union mm_context *mmu, struct host_vm_op *ops, int last)
|
||||||
{
|
{
|
||||||
struct host_vm_op *op;
|
struct host_vm_op *op;
|
||||||
int i;
|
int i;
|
||||||
|
@ -26,18 +27,18 @@ static void do_ops(int fd, struct host_vm_op *ops, int last)
|
||||||
op = &ops[i];
|
op = &ops[i];
|
||||||
switch(op->type){
|
switch(op->type){
|
||||||
case MMAP:
|
case MMAP:
|
||||||
map(fd, op->u.mmap.addr, op->u.mmap.len,
|
map(&mmu->skas.id, op->u.mmap.addr, op->u.mmap.len,
|
||||||
op->u.mmap.r, op->u.mmap.w, op->u.mmap.x,
|
op->u.mmap.r, op->u.mmap.w, op->u.mmap.x,
|
||||||
op->u.mmap.fd, op->u.mmap.offset);
|
op->u.mmap.fd, op->u.mmap.offset);
|
||||||
break;
|
break;
|
||||||
case MUNMAP:
|
case MUNMAP:
|
||||||
unmap(fd, (void *) op->u.munmap.addr,
|
unmap(&mmu->skas.id, (void *) op->u.munmap.addr,
|
||||||
op->u.munmap.len);
|
op->u.munmap.len);
|
||||||
break;
|
break;
|
||||||
case MPROTECT:
|
case MPROTECT:
|
||||||
protect(fd, op->u.mprotect.addr, op->u.mprotect.len,
|
protect(&mmu->skas.id, op->u.mprotect.addr,
|
||||||
op->u.mprotect.r, op->u.mprotect.w,
|
op->u.mprotect.len, op->u.mprotect.r,
|
||||||
op->u.mprotect.x);
|
op->u.mprotect.w, op->u.mprotect.x);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printk("Unknown op type %d in do_ops\n", op->type);
|
printk("Unknown op type %d in do_ops\n", op->type);
|
||||||
|
@ -46,12 +47,15 @@ static void do_ops(int fd, struct host_vm_op *ops, int last)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern int proc_mm;
|
||||||
|
|
||||||
static void fix_range(struct mm_struct *mm, unsigned long start_addr,
|
static void fix_range(struct mm_struct *mm, unsigned long start_addr,
|
||||||
unsigned long end_addr, int force)
|
unsigned long end_addr, int force)
|
||||||
{
|
{
|
||||||
int fd = mm->context.skas.mm_fd;
|
if(!proc_mm && (end_addr > CONFIG_STUB_START))
|
||||||
|
end_addr = CONFIG_STUB_START;
|
||||||
|
|
||||||
fix_range_common(mm, start_addr, end_addr, force, fd, do_ops);
|
fix_range_common(mm, start_addr, end_addr, force, do_ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __flush_tlb_one_skas(unsigned long addr)
|
void __flush_tlb_one_skas(unsigned long addr)
|
||||||
|
@ -69,17 +73,20 @@ void flush_tlb_range_skas(struct vm_area_struct *vma, unsigned long start,
|
||||||
|
|
||||||
void flush_tlb_mm_skas(struct mm_struct *mm)
|
void flush_tlb_mm_skas(struct mm_struct *mm)
|
||||||
{
|
{
|
||||||
|
unsigned long end;
|
||||||
|
|
||||||
/* Don't bother flushing if this address space is about to be
|
/* Don't bother flushing if this address space is about to be
|
||||||
* destroyed.
|
* destroyed.
|
||||||
*/
|
*/
|
||||||
if(atomic_read(&mm->mm_users) == 0)
|
if(atomic_read(&mm->mm_users) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fix_range(mm, 0, host_task_size, 0);
|
end = proc_mm ? task_size : CONFIG_STUB_START;
|
||||||
flush_tlb_kernel_range_common(start_vm, end_vm);
|
fix_range(mm, 0, end, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void force_flush_all_skas(void)
|
void force_flush_all_skas(void)
|
||||||
{
|
{
|
||||||
fix_range(current->mm, 0, host_task_size, 1);
|
unsigned long end = proc_mm ? task_size : CONFIG_STUB_START;
|
||||||
|
fix_range(current->mm, 0, end, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,13 @@ void enable_timer(void)
|
||||||
set_interval(ITIMER_VIRTUAL);
|
set_interval(ITIMER_VIRTUAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void prepare_timer(void * ptr)
|
||||||
|
{
|
||||||
|
int usec = 1000000/hz();
|
||||||
|
*(struct itimerval *)ptr = ((struct itimerval) { { 0, usec },
|
||||||
|
{ 0, usec }});
|
||||||
|
}
|
||||||
|
|
||||||
void disable_timer(void)
|
void disable_timer(void)
|
||||||
{
|
{
|
||||||
struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
|
struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
|
||||||
|
|
|
@ -18,13 +18,15 @@
|
||||||
#define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1))
|
#define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1))
|
||||||
|
|
||||||
void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
|
void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
|
||||||
unsigned long end_addr, int force, int data,
|
unsigned long end_addr, int force,
|
||||||
void (*do_ops)(int, struct host_vm_op *, int))
|
void (*do_ops)(union mm_context *, struct host_vm_op *,
|
||||||
|
int))
|
||||||
{
|
{
|
||||||
pgd_t *npgd;
|
pgd_t *npgd;
|
||||||
pud_t *npud;
|
pud_t *npud;
|
||||||
pmd_t *npmd;
|
pmd_t *npmd;
|
||||||
pte_t *npte;
|
pte_t *npte;
|
||||||
|
union mm_context *mmu = &mm->context;
|
||||||
unsigned long addr, end;
|
unsigned long addr, end;
|
||||||
int r, w, x;
|
int r, w, x;
|
||||||
struct host_vm_op ops[16];
|
struct host_vm_op ops[16];
|
||||||
|
@ -40,7 +42,7 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
|
||||||
end = end_addr;
|
end = end_addr;
|
||||||
if(force || pgd_newpage(*npgd)){
|
if(force || pgd_newpage(*npgd)){
|
||||||
op_index = add_munmap(addr, end - addr, ops,
|
op_index = add_munmap(addr, end - addr, ops,
|
||||||
op_index, last_op, data,
|
op_index, last_op, mmu,
|
||||||
do_ops);
|
do_ops);
|
||||||
pgd_mkuptodate(*npgd);
|
pgd_mkuptodate(*npgd);
|
||||||
}
|
}
|
||||||
|
@ -55,7 +57,7 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
|
||||||
end = end_addr;
|
end = end_addr;
|
||||||
if(force || pud_newpage(*npud)){
|
if(force || pud_newpage(*npud)){
|
||||||
op_index = add_munmap(addr, end - addr, ops,
|
op_index = add_munmap(addr, end - addr, ops,
|
||||||
op_index, last_op, data,
|
op_index, last_op, mmu,
|
||||||
do_ops);
|
do_ops);
|
||||||
pud_mkuptodate(*npud);
|
pud_mkuptodate(*npud);
|
||||||
}
|
}
|
||||||
|
@ -70,7 +72,7 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
|
||||||
end = end_addr;
|
end = end_addr;
|
||||||
if(force || pmd_newpage(*npmd)){
|
if(force || pmd_newpage(*npmd)){
|
||||||
op_index = add_munmap(addr, end - addr, ops,
|
op_index = add_munmap(addr, end - addr, ops,
|
||||||
op_index, last_op, data,
|
op_index, last_op, mmu,
|
||||||
do_ops);
|
do_ops);
|
||||||
pmd_mkuptodate(*npmd);
|
pmd_mkuptodate(*npmd);
|
||||||
}
|
}
|
||||||
|
@ -93,21 +95,21 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
|
||||||
op_index = add_mmap(addr,
|
op_index = add_mmap(addr,
|
||||||
pte_val(*npte) & PAGE_MASK,
|
pte_val(*npte) & PAGE_MASK,
|
||||||
PAGE_SIZE, r, w, x, ops,
|
PAGE_SIZE, r, w, x, ops,
|
||||||
op_index, last_op, data,
|
op_index, last_op, mmu,
|
||||||
do_ops);
|
do_ops);
|
||||||
else op_index = add_munmap(addr, PAGE_SIZE, ops,
|
else op_index = add_munmap(addr, PAGE_SIZE, ops,
|
||||||
op_index, last_op, data,
|
op_index, last_op, mmu,
|
||||||
do_ops);
|
do_ops);
|
||||||
}
|
}
|
||||||
else if(pte_newprot(*npte))
|
else if(pte_newprot(*npte))
|
||||||
op_index = add_mprotect(addr, PAGE_SIZE, r, w, x, ops,
|
op_index = add_mprotect(addr, PAGE_SIZE, r, w, x, ops,
|
||||||
op_index, last_op, data,
|
op_index, last_op, mmu,
|
||||||
do_ops);
|
do_ops);
|
||||||
|
|
||||||
*npte = pte_mkuptodate(*npte);
|
*npte = pte_mkuptodate(*npte);
|
||||||
addr += PAGE_SIZE;
|
addr += PAGE_SIZE;
|
||||||
}
|
}
|
||||||
(*do_ops)(data, ops, op_index);
|
(*do_ops)(mmu, ops, op_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
|
int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
|
||||||
|
@ -195,51 +197,6 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
|
||||||
return(updated);
|
return(updated);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
|
|
||||||
{
|
|
||||||
address &= PAGE_MASK;
|
|
||||||
flush_tlb_range(vma, address, address + PAGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush_tlb_all(void)
|
|
||||||
{
|
|
||||||
flush_tlb_mm(current->mm);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
|
|
||||||
{
|
|
||||||
CHOOSE_MODE_PROC(flush_tlb_kernel_range_tt,
|
|
||||||
flush_tlb_kernel_range_common, start, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush_tlb_kernel_vm(void)
|
|
||||||
{
|
|
||||||
CHOOSE_MODE(flush_tlb_kernel_vm_tt(),
|
|
||||||
flush_tlb_kernel_range_common(start_vm, end_vm));
|
|
||||||
}
|
|
||||||
|
|
||||||
void __flush_tlb_one(unsigned long addr)
|
|
||||||
{
|
|
||||||
CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
|
|
||||||
unsigned long end)
|
|
||||||
{
|
|
||||||
CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, vma, start,
|
|
||||||
end);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush_tlb_mm(struct mm_struct *mm)
|
|
||||||
{
|
|
||||||
CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
|
|
||||||
}
|
|
||||||
|
|
||||||
void force_flush_all(void)
|
|
||||||
{
|
|
||||||
CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
|
|
||||||
}
|
|
||||||
|
|
||||||
pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
|
pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
|
||||||
{
|
{
|
||||||
return(pgd_offset(mm, address));
|
return(pgd_offset(mm, address));
|
||||||
|
@ -270,9 +227,9 @@ pte_t *addr_pte(struct task_struct *task, unsigned long addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
|
int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
|
||||||
int r, int w, int x, struct host_vm_op *ops, int index,
|
int r, int w, int x, struct host_vm_op *ops, int index,
|
||||||
int last_filled, int data,
|
int last_filled, union mm_context *mmu,
|
||||||
void (*do_ops)(int, struct host_vm_op *, int))
|
void (*do_ops)(union mm_context *, struct host_vm_op *, int))
|
||||||
{
|
{
|
||||||
__u64 offset;
|
__u64 offset;
|
||||||
struct host_vm_op *last;
|
struct host_vm_op *last;
|
||||||
|
@ -292,7 +249,7 @@ int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
|
||||||
}
|
}
|
||||||
|
|
||||||
if(index == last_filled){
|
if(index == last_filled){
|
||||||
(*do_ops)(data, ops, last_filled);
|
(*do_ops)(mmu, ops, last_filled);
|
||||||
index = -1;
|
index = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,8 +267,8 @@ int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
|
||||||
}
|
}
|
||||||
|
|
||||||
int add_munmap(unsigned long addr, unsigned long len, struct host_vm_op *ops,
|
int add_munmap(unsigned long addr, unsigned long len, struct host_vm_op *ops,
|
||||||
int index, int last_filled, int data,
|
int index, int last_filled, union mm_context *mmu,
|
||||||
void (*do_ops)(int, struct host_vm_op *, int))
|
void (*do_ops)(union mm_context *, struct host_vm_op *, int))
|
||||||
{
|
{
|
||||||
struct host_vm_op *last;
|
struct host_vm_op *last;
|
||||||
|
|
||||||
|
@ -325,7 +282,7 @@ int add_munmap(unsigned long addr, unsigned long len, struct host_vm_op *ops,
|
||||||
}
|
}
|
||||||
|
|
||||||
if(index == last_filled){
|
if(index == last_filled){
|
||||||
(*do_ops)(data, ops, last_filled);
|
(*do_ops)(mmu, ops, last_filled);
|
||||||
index = -1;
|
index = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,8 +294,9 @@ int add_munmap(unsigned long addr, unsigned long len, struct host_vm_op *ops,
|
||||||
}
|
}
|
||||||
|
|
||||||
int add_mprotect(unsigned long addr, unsigned long len, int r, int w, int x,
|
int add_mprotect(unsigned long addr, unsigned long len, int r, int w, int x,
|
||||||
struct host_vm_op *ops, int index, int last_filled, int data,
|
struct host_vm_op *ops, int index, int last_filled,
|
||||||
void (*do_ops)(int, struct host_vm_op *, int))
|
union mm_context *mmu,
|
||||||
|
void (*do_ops)(union mm_context *, struct host_vm_op *, int))
|
||||||
{
|
{
|
||||||
struct host_vm_op *last;
|
struct host_vm_op *last;
|
||||||
|
|
||||||
|
@ -354,7 +312,7 @@ int add_mprotect(unsigned long addr, unsigned long len, int r, int w, int x,
|
||||||
}
|
}
|
||||||
|
|
||||||
if(index == last_filled){
|
if(index == last_filled){
|
||||||
(*do_ops)(data, ops, last_filled);
|
(*do_ops)(mmu, ops, last_filled);
|
||||||
index = -1;
|
index = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,3 +325,49 @@ int add_mprotect(unsigned long addr, unsigned long len, int r, int w, int x,
|
||||||
.x = x } } });
|
.x = x } } });
|
||||||
return(index);
|
return(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
|
||||||
|
{
|
||||||
|
address &= PAGE_MASK;
|
||||||
|
flush_tlb_range(vma, address, address + PAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush_tlb_all(void)
|
||||||
|
{
|
||||||
|
flush_tlb_mm(current->mm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
|
||||||
|
{
|
||||||
|
CHOOSE_MODE_PROC(flush_tlb_kernel_range_tt,
|
||||||
|
flush_tlb_kernel_range_common, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush_tlb_kernel_vm(void)
|
||||||
|
{
|
||||||
|
CHOOSE_MODE(flush_tlb_kernel_vm_tt(),
|
||||||
|
flush_tlb_kernel_range_common(start_vm, end_vm));
|
||||||
|
}
|
||||||
|
|
||||||
|
void __flush_tlb_one(unsigned long addr)
|
||||||
|
{
|
||||||
|
CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
|
||||||
|
unsigned long end)
|
||||||
|
{
|
||||||
|
CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, vma, start,
|
||||||
|
end);
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush_tlb_mm(struct mm_struct *mm)
|
||||||
|
{
|
||||||
|
CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void force_flush_all(void)
|
||||||
|
{
|
||||||
|
CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "tlb.h"
|
#include "tlb.h"
|
||||||
|
|
||||||
static void do_ops(int unused, struct host_vm_op *ops, int last)
|
static void do_ops(union mm_context *mmu, struct host_vm_op *ops, int last)
|
||||||
{
|
{
|
||||||
struct host_vm_op *op;
|
struct host_vm_op *op;
|
||||||
int i;
|
int i;
|
||||||
|
@ -55,7 +55,7 @@ static void fix_range(struct mm_struct *mm, unsigned long start_addr,
|
||||||
panic("fix_range fixing wrong address space, current = 0x%p",
|
panic("fix_range fixing wrong address space, current = 0x%p",
|
||||||
current);
|
current);
|
||||||
|
|
||||||
fix_range_common(mm, start_addr, end_addr, force, 0, do_ops);
|
fix_range_common(mm, start_addr, end_addr, force, do_ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic_t vmchange_seq = ATOMIC_INIT(1);
|
atomic_t vmchange_seq = ATOMIC_INIT(1);
|
||||||
|
|
|
@ -30,6 +30,7 @@ SECTIONS
|
||||||
_einittext = .;
|
_einittext = .;
|
||||||
}
|
}
|
||||||
. = ALIGN(4096);
|
. = ALIGN(4096);
|
||||||
|
|
||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
*(.text)
|
*(.text)
|
||||||
|
@ -39,6 +40,12 @@ SECTIONS
|
||||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||||
*(.gnu.warning)
|
*(.gnu.warning)
|
||||||
*(.gnu.linkonce.t*)
|
*(.gnu.linkonce.t*)
|
||||||
|
|
||||||
|
. = ALIGN(4096);
|
||||||
|
__syscall_stub_start = .;
|
||||||
|
*(.__syscall_stub*)
|
||||||
|
__syscall_stub_end = .;
|
||||||
|
. = ALIGN(4096);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "asm/common.lds.S"
|
#include "asm/common.lds.S"
|
||||||
|
|
|
@ -121,6 +121,11 @@ void init_registers(int pid)
|
||||||
err);
|
err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void get_safe_registers(unsigned long *regs)
|
||||||
|
{
|
||||||
|
memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
* Overrides for Emacs so that we follow Linus's tabbing style.
|
||||||
* Emacs will notice this stuff at the end of the file and automatically
|
* Emacs will notice this stuff at the end of the file and automatically
|
||||||
|
|
|
@ -69,6 +69,11 @@ void init_registers(int pid)
|
||||||
err);
|
err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void get_safe_registers(unsigned long *regs)
|
||||||
|
{
|
||||||
|
memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
* Overrides for Emacs so that we follow Linus's tabbing style.
|
||||||
* Emacs will notice this stuff at the end of the file and automatically
|
* Emacs will notice this stuff at the end of the file and automatically
|
||||||
|
|
|
@ -16,6 +16,11 @@ define unprofile
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
|
||||||
|
# The stubs and unmap.o can't try to call mcount or update basic block data
|
||||||
|
define unprofile
|
||||||
|
$(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1)))
|
||||||
|
endef
|
||||||
|
|
||||||
quiet_cmd_make_link = SYMLINK $@
|
quiet_cmd_make_link = SYMLINK $@
|
||||||
cmd_make_link = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@
|
cmd_make_link = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
|
obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
|
||||||
ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o \
|
ptrace_user.o semaphore.o signal.o sigcontext.o stub.o stub_segv.o \
|
||||||
sys_call_table.o
|
syscalls.o sysrq.o sys_call_table.o
|
||||||
|
|
||||||
obj-$(CONFIG_HIGHMEM) += highmem.o
|
obj-$(CONFIG_HIGHMEM) += highmem.o
|
||||||
obj-$(CONFIG_MODULES) += module.o
|
obj-$(CONFIG_MODULES) += module.o
|
||||||
|
@ -16,6 +16,14 @@ semaphore.c-dir = kernel
|
||||||
highmem.c-dir = mm
|
highmem.c-dir = mm
|
||||||
module.c-dir = kernel
|
module.c-dir = kernel
|
||||||
|
|
||||||
|
STUB_CFLAGS = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS))
|
||||||
|
|
||||||
|
# _cflags works with kernel files, not with userspace ones, but c_flags does,
|
||||||
|
# why ask why?
|
||||||
|
$(obj)/stub_segv.o : c_flags = $(STUB_CFLAGS)
|
||||||
|
|
||||||
|
$(obj)/stub.o : a_flags = $(STUB_CFLAGS)
|
||||||
|
|
||||||
subdir- := util
|
subdir- := util
|
||||||
|
|
||||||
include arch/um/scripts/Makefile.unmap
|
include arch/um/scripts/Makefile.unmap
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include "uml-config.h"
|
||||||
|
|
||||||
|
.globl syscall_stub
|
||||||
|
.section .__syscall_stub, "x"
|
||||||
|
syscall_stub:
|
||||||
|
int $0x80
|
||||||
|
mov %eax, UML_CONFIG_STUB_DATA
|
||||||
|
int3
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
|
||||||
|
* Licensed under the GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <asm/sigcontext.h>
|
||||||
|
#include <asm/unistd.h>
|
||||||
|
#include "uml-config.h"
|
||||||
|
#include "sysdep/sigcontext.h"
|
||||||
|
#include "sysdep/faultinfo.h"
|
||||||
|
|
||||||
|
void __attribute__ ((__section__ (".__syscall_stub")))
|
||||||
|
stub_segv_handler(int sig)
|
||||||
|
{
|
||||||
|
struct sigcontext *sc = (struct sigcontext *) (&sig + 1);
|
||||||
|
|
||||||
|
GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA),
|
||||||
|
sc);
|
||||||
|
|
||||||
|
__asm__("movl %0, %%eax ; int $0x80": : "g" (__NR_getpid));
|
||||||
|
__asm__("movl %%eax, %%ebx ; movl %0, %%eax ; movl %1, %%ecx ;"
|
||||||
|
"int $0x80": : "g" (__NR_kill), "g" (SIGUSR1));
|
||||||
|
/* Pop the frame pointer and return address since we need to leave
|
||||||
|
* the stack in its original form when we do the sigreturn here, by
|
||||||
|
* hand.
|
||||||
|
*/
|
||||||
|
__asm__("popl %%eax ; popl %%eax ; popl %%eax ; movl %0, %%eax ; "
|
||||||
|
"int $0x80" : : "g" (__NR_sigreturn));
|
||||||
|
}
|
|
@ -6,8 +6,8 @@
|
||||||
|
|
||||||
#XXX: why into lib-y?
|
#XXX: why into lib-y?
|
||||||
lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \
|
lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \
|
||||||
ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \
|
ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o stub.o \
|
||||||
syscalls.o sysrq.o thunk.o syscall_table.o
|
stub_segv.o syscalls.o syscall_table.o sysrq.o thunk.o
|
||||||
|
|
||||||
obj-y := ksyms.o
|
obj-y := ksyms.o
|
||||||
obj-$(CONFIG_MODULES) += module.o um_module.o
|
obj-$(CONFIG_MODULES) += module.o um_module.o
|
||||||
|
@ -28,6 +28,14 @@ semaphore.c-dir = kernel
|
||||||
thunk.S-dir = lib
|
thunk.S-dir = lib
|
||||||
module.c-dir = kernel
|
module.c-dir = kernel
|
||||||
|
|
||||||
|
STUB_CFLAGS = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS))
|
||||||
|
|
||||||
|
# _cflags works with kernel files, not with userspace ones, but c_flags does,
|
||||||
|
# why ask why?
|
||||||
|
$(obj)/stub_segv.o : c_flags = $(STUB_CFLAGS)
|
||||||
|
|
||||||
|
$(obj)/stub.o : a_flags = $(STUB_CFLAGS)
|
||||||
|
|
||||||
subdir- := util
|
subdir- := util
|
||||||
|
|
||||||
include arch/um/scripts/Makefile.unmap
|
include arch/um/scripts/Makefile.unmap
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#include "uml-config.h"
|
||||||
|
|
||||||
|
.globl syscall_stub
|
||||||
|
.section .__syscall_stub, "x"
|
||||||
|
syscall_stub:
|
||||||
|
syscall
|
||||||
|
/* We don't have 64-bit constants, so this constructs the address
|
||||||
|
* we need.
|
||||||
|
*/
|
||||||
|
movq $(UML_CONFIG_STUB_DATA >> 32), %rbx
|
||||||
|
salq $32, %rbx
|
||||||
|
movq $(UML_CONFIG_STUB_DATA & 0xffffffff), %rcx
|
||||||
|
or %rcx, %rbx
|
||||||
|
movq %rax, (%rbx)
|
||||||
|
int3
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
|
||||||
|
* Licensed under the GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
#include <asm/unistd.h>
|
||||||
|
#include "uml-config.h"
|
||||||
|
#include "sysdep/sigcontext.h"
|
||||||
|
#include "sysdep/faultinfo.h"
|
||||||
|
|
||||||
|
void __attribute__ ((__section__ (".__syscall_stub")))
|
||||||
|
stub_segv_handler(int sig)
|
||||||
|
{
|
||||||
|
struct ucontext *uc;
|
||||||
|
|
||||||
|
__asm__("movq %%rdx, %0" : "=g" (uc) :);
|
||||||
|
GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA),
|
||||||
|
&uc->uc_mcontext);
|
||||||
|
|
||||||
|
__asm__("movq %0, %%rax ; syscall": : "g" (__NR_getpid));
|
||||||
|
__asm__("movq %%rax, %%rdi ; movq %0, %%rax ; movq %1, %%rsi ;"
|
||||||
|
"syscall": : "g" (__NR_kill), "g" (SIGUSR1));
|
||||||
|
/* Two popqs to restore the stack to the state just before entering
|
||||||
|
* the handler, one pops the return address, the other pops the frame
|
||||||
|
* pointer.
|
||||||
|
*/
|
||||||
|
__asm__("popq %%rax ; popq %%rax ; movq %0, %%rax ; syscall" : : "g"
|
||||||
|
(__NR_rt_sigreturn));
|
||||||
|
}
|
|
@ -1076,6 +1076,10 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
|
||||||
#ifdef CONFIG_X86_MCE
|
#ifdef CONFIG_X86_MCE
|
||||||
mcheck_init(c);
|
mcheck_init(c);
|
||||||
#endif
|
#endif
|
||||||
|
if (c == &boot_cpu_data)
|
||||||
|
mtrr_bp_init();
|
||||||
|
else
|
||||||
|
mtrr_ap_init();
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
if (c != &boot_cpu_data)
|
if (c != &boot_cpu_data)
|
||||||
numa_add_cpu(c - cpu_data);
|
numa_add_cpu(c - cpu_data);
|
||||||
|
|
|
@ -119,6 +119,7 @@ void __restore_processor_state(struct saved_context *ctxt)
|
||||||
fix_processor_context();
|
fix_processor_context();
|
||||||
|
|
||||||
do_fpu_end();
|
do_fpu_end();
|
||||||
|
mtrr_ap_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void restore_processor_state(void)
|
void restore_processor_state(void)
|
||||||
|
|
|
@ -56,6 +56,10 @@ SECTIONS
|
||||||
.data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
|
.data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
|
||||||
*(.data.cacheline_aligned)
|
*(.data.cacheline_aligned)
|
||||||
}
|
}
|
||||||
|
. = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
|
||||||
|
.data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
|
||||||
|
*(.data.read_mostly)
|
||||||
|
}
|
||||||
|
|
||||||
#define VSYSCALL_ADDR (-10*1024*1024)
|
#define VSYSCALL_ADDR (-10*1024*1024)
|
||||||
#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095))
|
#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095))
|
||||||
|
|
|
@ -46,8 +46,6 @@
|
||||||
|
|
||||||
extern void do_syscall_trace(void);
|
extern void do_syscall_trace(void);
|
||||||
typedef int (*syscall_t)(void *a0,...);
|
typedef int (*syscall_t)(void *a0,...);
|
||||||
extern int (*do_syscalls)(struct pt_regs *regs, syscall_t fun,
|
|
||||||
int narg);
|
|
||||||
extern syscall_t sys_call_table[];
|
extern syscall_t sys_call_table[];
|
||||||
extern unsigned char sys_narg_table[];
|
extern unsigned char sys_narg_table[];
|
||||||
|
|
||||||
|
@ -72,10 +70,8 @@ int sys_pipe(int __user *userfds)
|
||||||
/*
|
/*
|
||||||
* Common code for old and new mmaps.
|
* Common code for old and new mmaps.
|
||||||
*/
|
*/
|
||||||
|
long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
|
||||||
static inline long do_mmap2(unsigned long addr, unsigned long len,
|
unsigned long flags, unsigned long fd, unsigned long pgoff)
|
||||||
unsigned long prot, unsigned long flags,
|
|
||||||
unsigned long fd, unsigned long pgoff)
|
|
||||||
{
|
{
|
||||||
int error = -EBADF;
|
int error = -EBADF;
|
||||||
struct file * file = NULL;
|
struct file * file = NULL;
|
||||||
|
@ -97,29 +93,6 @@ out:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long old_mmap(unsigned long addr, size_t len, int prot,
|
|
||||||
int flags, int fd, off_t offset)
|
|
||||||
{
|
|
||||||
return do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
|
|
||||||
}
|
|
||||||
|
|
||||||
long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
|
|
||||||
unsigned long flags, unsigned long fd, unsigned long pgoff)
|
|
||||||
{
|
|
||||||
return do_mmap2(addr, len, prot, flags, fd, pgoff);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sys_fork(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
return do_fork(SIGCHLD, regs->areg[1], regs, 0, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sys_vfork(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
return do_fork(CLONE_VFORK|CLONE_VM|SIGCHLD, regs->areg[1],
|
|
||||||
regs, 0, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sys_clone(struct pt_regs *regs)
|
int sys_clone(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
unsigned long clone_flags;
|
unsigned long clone_flags;
|
||||||
|
@ -162,30 +135,6 @@ int sys_uname(struct old_utsname * name)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_olduname(struct oldold_utsname * name)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
|
|
||||||
if (!name)
|
|
||||||
return -EFAULT;
|
|
||||||
if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
|
|
||||||
error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
|
|
||||||
error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
|
|
||||||
error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
|
|
||||||
error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
|
|
||||||
error -= __put_user(0,name->release+__OLD_UTS_LEN);
|
|
||||||
error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
|
|
||||||
error -= __put_user(0,name->version+__OLD_UTS_LEN);
|
|
||||||
error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
|
|
||||||
error -= __put_user(0,name->machine+__OLD_UTS_LEN);
|
|
||||||
|
|
||||||
return error ? -EFAULT : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build the string table for the builtin "poor man's strace".
|
* Build the string table for the builtin "poor man's strace".
|
||||||
*/
|
*/
|
||||||
|
@ -319,100 +268,3 @@ void system_call (struct pt_regs *regs)
|
||||||
regs->areg[2] = res;
|
regs->areg[2] = res;
|
||||||
do_syscall_trace();
|
do_syscall_trace();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* sys_ipc() is the de-multiplexer for the SysV IPC calls..
|
|
||||||
*
|
|
||||||
* This is really horribly ugly.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int sys_ipc (uint call, int first, int second,
|
|
||||||
int third, void __user *ptr, long fifth)
|
|
||||||
{
|
|
||||||
int version, ret;
|
|
||||||
|
|
||||||
version = call >> 16; /* hack for backward compatibility */
|
|
||||||
call &= 0xffff;
|
|
||||||
ret = -ENOSYS;
|
|
||||||
|
|
||||||
switch (call) {
|
|
||||||
case SEMOP:
|
|
||||||
ret = sys_semtimedop (first, (struct sembuf __user *)ptr,
|
|
||||||
second, NULL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SEMTIMEDOP:
|
|
||||||
ret = sys_semtimedop (first, (struct sembuf __user *)ptr,
|
|
||||||
second, (const struct timespec *) fifth);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SEMGET:
|
|
||||||
ret = sys_semget (first, second, third);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SEMCTL: {
|
|
||||||
union semun fourth;
|
|
||||||
|
|
||||||
if (ptr && !get_user(fourth.__pad, (void *__user *) ptr))
|
|
||||||
ret = sys_semctl (first, second, third, fourth);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MSGSND:
|
|
||||||
ret = sys_msgsnd (first, (struct msgbuf __user*) ptr,
|
|
||||||
second, third);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MSGRCV:
|
|
||||||
switch (version) {
|
|
||||||
case 0: {
|
|
||||||
struct ipc_kludge tmp;
|
|
||||||
|
|
||||||
if (ptr && !copy_from_user(&tmp,
|
|
||||||
(struct ipc_kludge *) ptr,
|
|
||||||
sizeof (tmp)))
|
|
||||||
ret = sys_msgrcv (first, tmp.msgp, second,
|
|
||||||
tmp.msgtyp, third);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
ret = sys_msgrcv (first, (struct msgbuf __user *) ptr,
|
|
||||||
second, 0, third);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MSGGET:
|
|
||||||
ret = sys_msgget ((key_t) first, second);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MSGCTL:
|
|
||||||
ret = sys_msgctl (first, second, (struct msqid_ds __user*) ptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SHMAT: {
|
|
||||||
ulong raddr;
|
|
||||||
ret = do_shmat (first, (char __user *) ptr, second, &raddr);
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
ret = put_user (raddr, (ulong __user *) third);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SHMDT:
|
|
||||||
ret = sys_shmdt ((char __user *)ptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SHMGET:
|
|
||||||
ret = sys_shmget (first, second, third);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SHMCTL:
|
|
||||||
ret = sys_shmctl (first, second, (struct shmid_ds __user*) ptr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -25,20 +25,19 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SYSCALL(0, 0) /* 00 */
|
SYSCALL(0, 0) /* 00 */
|
||||||
|
|
||||||
SYSCALL(sys_exit, 1)
|
SYSCALL(sys_exit, 1)
|
||||||
SYSCALL(sys_fork, 0)
|
SYSCALL(sys_ni_syscall, 0)
|
||||||
SYSCALL(sys_read, 3)
|
SYSCALL(sys_read, 3)
|
||||||
SYSCALL(sys_write, 3)
|
SYSCALL(sys_write, 3)
|
||||||
SYSCALL(sys_open, 3) /* 05 */
|
SYSCALL(sys_open, 3) /* 05 */
|
||||||
SYSCALL(sys_close, 1)
|
SYSCALL(sys_close, 1)
|
||||||
SYSCALL(sys_waitpid, 3)
|
SYSCALL(sys_ni_syscall, 3)
|
||||||
SYSCALL(sys_creat, 2)
|
SYSCALL(sys_creat, 2)
|
||||||
SYSCALL(sys_link, 2)
|
SYSCALL(sys_link, 2)
|
||||||
SYSCALL(sys_unlink, 1) /* 10 */
|
SYSCALL(sys_unlink, 1) /* 10 */
|
||||||
SYSCALL(sys_execve, 0)
|
SYSCALL(sys_execve, 0)
|
||||||
SYSCALL(sys_chdir, 1)
|
SYSCALL(sys_chdir, 1)
|
||||||
SYSCALL(sys_time, 1)
|
SYSCALL(sys_ni_syscall, 1)
|
||||||
SYSCALL(sys_mknod, 3)
|
SYSCALL(sys_mknod, 3)
|
||||||
SYSCALL(sys_chmod, 2) /* 15 */
|
SYSCALL(sys_chmod, 2) /* 15 */
|
||||||
SYSCALL(sys_lchown, 3)
|
SYSCALL(sys_lchown, 3)
|
||||||
|
@ -47,19 +46,19 @@ SYSCALL(sys_stat, 2)
|
||||||
SYSCALL(sys_lseek, 3)
|
SYSCALL(sys_lseek, 3)
|
||||||
SYSCALL(sys_getpid, 0) /* 20 */
|
SYSCALL(sys_getpid, 0) /* 20 */
|
||||||
SYSCALL(sys_mount, 5)
|
SYSCALL(sys_mount, 5)
|
||||||
SYSCALL(sys_oldumount, 1)
|
SYSCALL(sys_ni_syscall, 1)
|
||||||
SYSCALL(sys_setuid, 1)
|
SYSCALL(sys_setuid, 1)
|
||||||
SYSCALL(sys_getuid, 0)
|
SYSCALL(sys_getuid, 0)
|
||||||
SYSCALL(sys_stime, 1) /* 25 */
|
SYSCALL(sys_ni_syscall, 1) /* 25 */
|
||||||
SYSCALL(sys_ptrace, 4)
|
SYSCALL(sys_ptrace, 4)
|
||||||
SYSCALL(sys_alarm, 1)
|
SYSCALL(sys_ni_syscall, 1)
|
||||||
SYSCALL(sys_fstat, 2)
|
SYSCALL(sys_fstat, 2)
|
||||||
SYSCALL(sys_pause, 0)
|
SYSCALL(sys_ni_syscall, 0)
|
||||||
SYSCALL(sys_utime, 2) /* 30 */
|
SYSCALL(sys_utime, 2) /* 30 */
|
||||||
SYSCALL(sys_ni_syscall, 0)
|
SYSCALL(sys_ni_syscall, 0)
|
||||||
SYSCALL(sys_ni_syscall, 0)
|
SYSCALL(sys_ni_syscall, 0)
|
||||||
SYSCALL(sys_access, 2)
|
SYSCALL(sys_access, 2)
|
||||||
SYSCALL(sys_nice, 1)
|
SYSCALL(sys_ni_syscall, 1)
|
||||||
SYSCALL(sys_ni_syscall, 0) /* 35 */
|
SYSCALL(sys_ni_syscall, 0) /* 35 */
|
||||||
SYSCALL(sys_sync, 0)
|
SYSCALL(sys_sync, 0)
|
||||||
SYSCALL(sys_kill, 2)
|
SYSCALL(sys_kill, 2)
|
||||||
|
@ -73,7 +72,7 @@ SYSCALL(sys_ni_syscall, 0)
|
||||||
SYSCALL(sys_brk, 1) /* 45 */
|
SYSCALL(sys_brk, 1) /* 45 */
|
||||||
SYSCALL(sys_setgid, 1)
|
SYSCALL(sys_setgid, 1)
|
||||||
SYSCALL(sys_getgid, 0)
|
SYSCALL(sys_getgid, 0)
|
||||||
SYSCALL(sys_ni_syscall, 0) /* was signal(2) */
|
SYSCALL(sys_ni_syscall, 0)
|
||||||
SYSCALL(sys_geteuid, 0)
|
SYSCALL(sys_geteuid, 0)
|
||||||
SYSCALL(sys_getegid, 0) /* 50 */
|
SYSCALL(sys_getegid, 0) /* 50 */
|
||||||
SYSCALL(sys_acct, 1)
|
SYSCALL(sys_acct, 1)
|
||||||
|
@ -84,21 +83,21 @@ SYSCALL(sys_fcntl, 3) /* 55 */
|
||||||
SYSCALL(sys_ni_syscall, 2)
|
SYSCALL(sys_ni_syscall, 2)
|
||||||
SYSCALL(sys_setpgid, 2)
|
SYSCALL(sys_setpgid, 2)
|
||||||
SYSCALL(sys_ni_syscall, 0)
|
SYSCALL(sys_ni_syscall, 0)
|
||||||
SYSCALL(sys_olduname, 1)
|
SYSCALL(sys_ni_syscall, 0)
|
||||||
SYSCALL(sys_umask, 1) /* 60 */
|
SYSCALL(sys_umask, 1) /* 60 */
|
||||||
SYSCALL(sys_chroot, 1)
|
SYSCALL(sys_chroot, 1)
|
||||||
SYSCALL(sys_ustat, 2)
|
SYSCALL(sys_ustat, 2)
|
||||||
SYSCALL(sys_dup2, 2)
|
SYSCALL(sys_dup2, 2)
|
||||||
SYSCALL(sys_getppid, 0)
|
SYSCALL(sys_getppid, 0)
|
||||||
SYSCALL(sys_getpgrp, 0) /* 65 */
|
SYSCALL(sys_ni_syscall, 0) /* 65 */
|
||||||
SYSCALL(sys_setsid, 0)
|
SYSCALL(sys_setsid, 0)
|
||||||
SYSCALL(sys_sigaction, 3)
|
SYSCALL(sys_sigaction, 3)
|
||||||
SYSCALL(sys_sgetmask, 0)
|
SYSCALL(sys_ni_syscall, 0)
|
||||||
SYSCALL(sys_ssetmask, 1)
|
SYSCALL(sys_ni_syscall, 1)
|
||||||
SYSCALL(sys_setreuid, 2) /* 70 */
|
SYSCALL(sys_setreuid, 2) /* 70 */
|
||||||
SYSCALL(sys_setregid, 2)
|
SYSCALL(sys_setregid, 2)
|
||||||
SYSCALL(sys_sigsuspend, 0)
|
SYSCALL(sys_sigsuspend, 0)
|
||||||
SYSCALL(sys_sigpending, 1)
|
SYSCALL(sys_ni_syscall, 1)
|
||||||
SYSCALL(sys_sethostname, 2)
|
SYSCALL(sys_sethostname, 2)
|
||||||
SYSCALL(sys_setrlimit, 2) /* 75 */
|
SYSCALL(sys_setrlimit, 2) /* 75 */
|
||||||
SYSCALL(sys_getrlimit, 2)
|
SYSCALL(sys_getrlimit, 2)
|
||||||
|
@ -107,15 +106,15 @@ SYSCALL(sys_gettimeofday, 2)
|
||||||
SYSCALL(sys_settimeofday, 2)
|
SYSCALL(sys_settimeofday, 2)
|
||||||
SYSCALL(sys_getgroups, 2) /* 80 */
|
SYSCALL(sys_getgroups, 2) /* 80 */
|
||||||
SYSCALL(sys_setgroups, 2)
|
SYSCALL(sys_setgroups, 2)
|
||||||
SYSCALL(sys_ni_syscall, 0) /* old_select */
|
SYSCALL(sys_ni_syscall, 0)
|
||||||
SYSCALL(sys_symlink, 2)
|
SYSCALL(sys_symlink, 2)
|
||||||
SYSCALL(sys_lstat, 2)
|
SYSCALL(sys_lstat, 2)
|
||||||
SYSCALL(sys_readlink, 3) /* 85 */
|
SYSCALL(sys_readlink, 3) /* 85 */
|
||||||
SYSCALL(sys_uselib, 1)
|
SYSCALL(sys_uselib, 1)
|
||||||
SYSCALL(sys_swapon, 2)
|
SYSCALL(sys_swapon, 2)
|
||||||
SYSCALL(sys_reboot, 3)
|
SYSCALL(sys_reboot, 3)
|
||||||
SYSCALL(old_readdir, 3)
|
SYSCALL(sys_ni_syscall, 3)
|
||||||
SYSCALL(old_mmap, 6) /* 90 */
|
SYSCALL(sys_ni_syscall, 6) /* 90 */
|
||||||
SYSCALL(sys_munmap, 2)
|
SYSCALL(sys_munmap, 2)
|
||||||
SYSCALL(sys_truncate, 2)
|
SYSCALL(sys_truncate, 2)
|
||||||
SYSCALL(sys_ftruncate, 2)
|
SYSCALL(sys_ftruncate, 2)
|
||||||
|
@ -127,7 +126,7 @@ SYSCALL(sys_ni_syscall, 0)
|
||||||
SYSCALL(sys_statfs, 2)
|
SYSCALL(sys_statfs, 2)
|
||||||
SYSCALL(sys_fstatfs, 2) /* 100 */
|
SYSCALL(sys_fstatfs, 2) /* 100 */
|
||||||
SYSCALL(sys_ni_syscall, 3)
|
SYSCALL(sys_ni_syscall, 3)
|
||||||
SYSCALL(sys_socketcall, 2)
|
SYSCALL(sys_ni_syscall, 2)
|
||||||
SYSCALL(sys_syslog, 3)
|
SYSCALL(sys_syslog, 3)
|
||||||
SYSCALL(sys_setitimer, 3)
|
SYSCALL(sys_setitimer, 3)
|
||||||
SYSCALL(sys_getitimer, 2) /* 105 */
|
SYSCALL(sys_getitimer, 2) /* 105 */
|
||||||
|
@ -137,32 +136,32 @@ SYSCALL(sys_newfstat, 2)
|
||||||
SYSCALL(sys_uname, 1)
|
SYSCALL(sys_uname, 1)
|
||||||
SYSCALL(sys_ni_syscall, 0) /* 110 */
|
SYSCALL(sys_ni_syscall, 0) /* 110 */
|
||||||
SYSCALL(sys_vhangup, 0)
|
SYSCALL(sys_vhangup, 0)
|
||||||
SYSCALL(sys_ni_syscall, 0) /* was sys_idle() */
|
SYSCALL(sys_ni_syscall, 0)
|
||||||
SYSCALL(sys_ni_syscall, 0)
|
SYSCALL(sys_ni_syscall, 0)
|
||||||
SYSCALL(sys_wait4, 4)
|
SYSCALL(sys_wait4, 4)
|
||||||
SYSCALL(sys_swapoff, 1) /* 115 */
|
SYSCALL(sys_swapoff, 1) /* 115 */
|
||||||
SYSCALL(sys_sysinfo, 1)
|
SYSCALL(sys_sysinfo, 1)
|
||||||
SYSCALL(sys_ipc, 5) /* 6 really, but glibc uses only 5) */
|
SYSCALL(sys_ni_syscall, 0)
|
||||||
SYSCALL(sys_fsync, 1)
|
SYSCALL(sys_fsync, 1)
|
||||||
SYSCALL(sys_sigreturn, 0)
|
SYSCALL(sys_sigreturn, 0)
|
||||||
SYSCALL(sys_clone, 0) /* 120 */
|
SYSCALL(sys_clone, 0) /* 120 */
|
||||||
SYSCALL(sys_setdomainname, 2)
|
SYSCALL(sys_setdomainname, 2)
|
||||||
SYSCALL(sys_newuname, 1)
|
SYSCALL(sys_newuname, 1)
|
||||||
SYSCALL(sys_ni_syscall, 0) /* sys_modify_ldt */
|
SYSCALL(sys_ni_syscall, 0)
|
||||||
SYSCALL(sys_adjtimex, 1)
|
SYSCALL(sys_adjtimex, 1)
|
||||||
SYSCALL(sys_mprotect, 3) /* 125 */
|
SYSCALL(sys_mprotect, 3) /* 125 */
|
||||||
SYSCALL(sys_sigprocmask, 3)
|
SYSCALL(sys_ni_syscall, 3)
|
||||||
SYSCALL(sys_ni_syscall, 2) /* old sys_create_module */
|
SYSCALL(sys_ni_syscall, 2)
|
||||||
SYSCALL(sys_init_module, 2)
|
SYSCALL(sys_init_module, 2)
|
||||||
SYSCALL(sys_delete_module, 1)
|
SYSCALL(sys_delete_module, 1)
|
||||||
SYSCALL(sys_ni_syscall, 1) /* old sys_get_kernel_sysm */ /* 130 */
|
SYSCALL(sys_ni_syscall, 1) /* 130 */
|
||||||
SYSCALL(sys_quotactl, 0)
|
SYSCALL(sys_quotactl, 0)
|
||||||
SYSCALL(sys_getpgid, 1)
|
SYSCALL(sys_getpgid, 1)
|
||||||
SYSCALL(sys_fchdir, 1)
|
SYSCALL(sys_fchdir, 1)
|
||||||
SYSCALL(sys_bdflush, 2)
|
SYSCALL(sys_bdflush, 2)
|
||||||
SYSCALL(sys_sysfs, 3) /* 135 */
|
SYSCALL(sys_sysfs, 3) /* 135 */
|
||||||
SYSCALL(sys_personality, 1)
|
SYSCALL(sys_personality, 1)
|
||||||
SYSCALL(sys_ni_syscall, 0) /* for afs_syscall */
|
SYSCALL(sys_ni_syscall, 0)
|
||||||
SYSCALL(sys_setfsuid, 1)
|
SYSCALL(sys_setfsuid, 1)
|
||||||
SYSCALL(sys_setfsgid, 1)
|
SYSCALL(sys_setfsgid, 1)
|
||||||
SYSCALL(sys_llseek, 5) /* 140 */
|
SYSCALL(sys_llseek, 5) /* 140 */
|
||||||
|
@ -212,7 +211,7 @@ SYSCALL(sys_socket, 3)
|
||||||
SYSCALL(sys_socketpair, 4)
|
SYSCALL(sys_socketpair, 4)
|
||||||
SYSCALL(sys_setresuid, 3) /* 185 */
|
SYSCALL(sys_setresuid, 3) /* 185 */
|
||||||
SYSCALL(sys_getresuid, 3)
|
SYSCALL(sys_getresuid, 3)
|
||||||
SYSCALL(sys_ni_syscall, 5) /* old sys_query_module */
|
SYSCALL(sys_ni_syscall, 5)
|
||||||
SYSCALL(sys_poll, 3)
|
SYSCALL(sys_poll, 3)
|
||||||
SYSCALL(sys_nfsservctl, 3)
|
SYSCALL(sys_nfsservctl, 3)
|
||||||
SYSCALL(sys_setresgid, 3) /* 190 */
|
SYSCALL(sys_setresgid, 3) /* 190 */
|
||||||
|
@ -235,7 +234,7 @@ SYSCALL(sys_sigaltstack, 0)
|
||||||
SYSCALL(sys_sendfile, 4)
|
SYSCALL(sys_sendfile, 4)
|
||||||
SYSCALL(sys_ni_syscall, 0)
|
SYSCALL(sys_ni_syscall, 0)
|
||||||
SYSCALL(sys_ni_syscall, 0)
|
SYSCALL(sys_ni_syscall, 0)
|
||||||
SYSCALL(sys_mmap2, 6) /* 210 */
|
SYSCALL(sys_mmap, 6) /* 210 */
|
||||||
SYSCALL(sys_truncate64, 2)
|
SYSCALL(sys_truncate64, 2)
|
||||||
SYSCALL(sys_ftruncate64, 2)
|
SYSCALL(sys_ftruncate64, 2)
|
||||||
SYSCALL(sys_stat64, 2)
|
SYSCALL(sys_stat64, 2)
|
||||||
|
@ -245,4 +244,4 @@ SYSCALL(sys_pivot_root, 2)
|
||||||
SYSCALL(sys_mincore, 3)
|
SYSCALL(sys_mincore, 3)
|
||||||
SYSCALL(sys_madvise, 3)
|
SYSCALL(sys_madvise, 3)
|
||||||
SYSCALL(sys_getdents64, 3)
|
SYSCALL(sys_getdents64, 3)
|
||||||
SYSCALL(sys_vfork, 0) /* 220 */
|
SYSCALL(sys_ni_syscall, 0) /* 220 */
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
#include <pcmcia/version.h>
|
|
||||||
#include <pcmcia/cs_types.h>
|
#include <pcmcia/cs_types.h>
|
||||||
#include <pcmcia/cs.h>
|
#include <pcmcia/cs.h>
|
||||||
#include <pcmcia/cistpl.h>
|
#include <pcmcia/cistpl.h>
|
||||||
|
@ -895,11 +894,6 @@ static dev_link_t *bluecard_attach(void)
|
||||||
link->next = dev_list;
|
link->next = dev_list;
|
||||||
dev_list = link;
|
dev_list = link;
|
||||||
client_reg.dev_info = &dev_info;
|
client_reg.dev_info = &dev_info;
|
||||||
client_reg.EventMask =
|
|
||||||
CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
|
|
||||||
CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
|
|
||||||
CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
|
|
||||||
client_reg.event_handler = &bluecard_event;
|
|
||||||
client_reg.Version = 0x0210;
|
client_reg.Version = 0x0210;
|
||||||
client_reg.event_callback_args.client_data = link;
|
client_reg.event_callback_args.client_data = link;
|
||||||
|
|
||||||
|
@ -1103,6 +1097,7 @@ static struct pcmcia_driver bluecard_driver = {
|
||||||
.name = "bluecard_cs",
|
.name = "bluecard_cs",
|
||||||
},
|
},
|
||||||
.attach = bluecard_attach,
|
.attach = bluecard_attach,
|
||||||
|
.event = bluecard_event,
|
||||||
.detach = bluecard_detach,
|
.detach = bluecard_detach,
|
||||||
.id_table = bluecard_ids,
|
.id_table = bluecard_ids,
|
||||||
};
|
};
|
||||||
|
|
|
@ -47,7 +47,6 @@
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
|
|
||||||
#include <pcmcia/version.h>
|
|
||||||
#include <pcmcia/cs_types.h>
|
#include <pcmcia/cs_types.h>
|
||||||
#include <pcmcia/cs.h>
|
#include <pcmcia/cs.h>
|
||||||
#include <pcmcia/cistpl.h>
|
#include <pcmcia/cistpl.h>
|
||||||
|
@ -696,11 +695,6 @@ static dev_link_t *bt3c_attach(void)
|
||||||
link->next = dev_list;
|
link->next = dev_list;
|
||||||
dev_list = link;
|
dev_list = link;
|
||||||
client_reg.dev_info = &dev_info;
|
client_reg.dev_info = &dev_info;
|
||||||
client_reg.EventMask =
|
|
||||||
CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
|
|
||||||
CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
|
|
||||||
CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
|
|
||||||
client_reg.event_handler = &bt3c_event;
|
|
||||||
client_reg.Version = 0x0210;
|
client_reg.Version = 0x0210;
|
||||||
client_reg.event_callback_args.client_data = link;
|
client_reg.event_callback_args.client_data = link;
|
||||||
|
|
||||||
|
@ -947,6 +941,7 @@ static struct pcmcia_driver bt3c_driver = {
|
||||||
.name = "bt3c_cs",
|
.name = "bt3c_cs",
|
||||||
},
|
},
|
||||||
.attach = bt3c_attach,
|
.attach = bt3c_attach,
|
||||||
|
.event = bt3c_event,
|
||||||
.detach = bt3c_detach,
|
.detach = bt3c_detach,
|
||||||
.id_table = bt3c_ids,
|
.id_table = bt3c_ids,
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
#include <pcmcia/version.h>
|
|
||||||
#include <pcmcia/cs_types.h>
|
#include <pcmcia/cs_types.h>
|
||||||
#include <pcmcia/cs.h>
|
#include <pcmcia/cs.h>
|
||||||
#include <pcmcia/cistpl.h>
|
#include <pcmcia/cistpl.h>
|
||||||
|
@ -615,11 +614,6 @@ static dev_link_t *btuart_attach(void)
|
||||||
link->next = dev_list;
|
link->next = dev_list;
|
||||||
dev_list = link;
|
dev_list = link;
|
||||||
client_reg.dev_info = &dev_info;
|
client_reg.dev_info = &dev_info;
|
||||||
client_reg.EventMask =
|
|
||||||
CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
|
|
||||||
CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
|
|
||||||
CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
|
|
||||||
client_reg.event_handler = &btuart_event;
|
|
||||||
client_reg.Version = 0x0210;
|
client_reg.Version = 0x0210;
|
||||||
client_reg.event_callback_args.client_data = link;
|
client_reg.event_callback_args.client_data = link;
|
||||||
|
|
||||||
|
@ -867,6 +861,7 @@ static struct pcmcia_driver btuart_driver = {
|
||||||
.name = "btuart_cs",
|
.name = "btuart_cs",
|
||||||
},
|
},
|
||||||
.attach = btuart_attach,
|
.attach = btuart_attach,
|
||||||
|
.event = btuart_event,
|
||||||
.detach = btuart_detach,
|
.detach = btuart_detach,
|
||||||
.id_table = btuart_ids,
|
.id_table = btuart_ids,
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
#include <pcmcia/version.h>
|
|
||||||
#include <pcmcia/cs_types.h>
|
#include <pcmcia/cs_types.h>
|
||||||
#include <pcmcia/cs.h>
|
#include <pcmcia/cs.h>
|
||||||
#include <pcmcia/cistpl.h>
|
#include <pcmcia/cistpl.h>
|
||||||
|
@ -594,11 +593,6 @@ static dev_link_t *dtl1_attach(void)
|
||||||
link->next = dev_list;
|
link->next = dev_list;
|
||||||
dev_list = link;
|
dev_list = link;
|
||||||
client_reg.dev_info = &dev_info;
|
client_reg.dev_info = &dev_info;
|
||||||
client_reg.EventMask =
|
|
||||||
CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
|
|
||||||
CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
|
|
||||||
CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
|
|
||||||
client_reg.event_handler = &dtl1_event;
|
|
||||||
client_reg.Version = 0x0210;
|
client_reg.Version = 0x0210;
|
||||||
client_reg.event_callback_args.client_data = link;
|
client_reg.event_callback_args.client_data = link;
|
||||||
|
|
||||||
|
@ -820,6 +814,7 @@ static struct pcmcia_driver dtl1_driver = {
|
||||||
.name = "dtl1_cs",
|
.name = "dtl1_cs",
|
||||||
},
|
},
|
||||||
.attach = dtl1_attach,
|
.attach = dtl1_attach,
|
||||||
|
.event = dtl1_event,
|
||||||
.detach = dtl1_detach,
|
.detach = dtl1_detach,
|
||||||
.id_table = dtl1_ids,
|
.id_table = dtl1_ids,
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,7 +40,7 @@ obj-$(CONFIG_N_HDLC) += n_hdlc.o
|
||||||
obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
|
obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
|
||||||
obj-$(CONFIG_SX) += sx.o generic_serial.o
|
obj-$(CONFIG_SX) += sx.o generic_serial.o
|
||||||
obj-$(CONFIG_RIO) += rio/ generic_serial.o
|
obj-$(CONFIG_RIO) += rio/ generic_serial.o
|
||||||
obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvsi.o
|
obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvc_vio.o hvsi.o
|
||||||
obj-$(CONFIG_RAW_DRIVER) += raw.o
|
obj-$(CONFIG_RAW_DRIVER) += raw.o
|
||||||
obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o
|
obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o
|
||||||
obj-$(CONFIG_MMTIMER) += mmtimer.o
|
obj-$(CONFIG_MMTIMER) += mmtimer.o
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/config.h>
|
||||||
#include <linux/console.h>
|
#include <linux/console.h>
|
||||||
#include <linux/cpumask.h>
|
#include <linux/cpumask.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
@ -40,7 +41,6 @@
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/hvconsole.h>
|
#include <asm/hvconsole.h>
|
||||||
#include <asm/vio.h>
|
|
||||||
|
|
||||||
#define HVC_MAJOR 229
|
#define HVC_MAJOR 229
|
||||||
#define HVC_MINOR 0
|
#define HVC_MINOR 0
|
||||||
|
@ -61,16 +61,21 @@
|
||||||
*/
|
*/
|
||||||
#define HVC_ALLOC_TTY_ADAPTERS 8
|
#define HVC_ALLOC_TTY_ADAPTERS 8
|
||||||
|
|
||||||
static struct tty_driver *hvc_driver;
|
|
||||||
#ifdef CONFIG_MAGIC_SYSRQ
|
|
||||||
static int sysrq_pressed;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define N_OUTBUF 16
|
#define N_OUTBUF 16
|
||||||
#define N_INBUF 16
|
#define N_INBUF 16
|
||||||
|
|
||||||
#define __ALIGNED__ __attribute__((__aligned__(8)))
|
#define __ALIGNED__ __attribute__((__aligned__(8)))
|
||||||
|
|
||||||
|
static struct tty_driver *hvc_driver;
|
||||||
|
static struct task_struct *hvc_task;
|
||||||
|
|
||||||
|
/* Picks up late kicks after list walk but before schedule() */
|
||||||
|
static int hvc_kicked;
|
||||||
|
|
||||||
|
#ifdef CONFIG_MAGIC_SYSRQ
|
||||||
|
static int sysrq_pressed;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct hvc_struct {
|
struct hvc_struct {
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
int index;
|
int index;
|
||||||
|
@ -80,11 +85,11 @@ struct hvc_struct {
|
||||||
char outbuf[N_OUTBUF] __ALIGNED__;
|
char outbuf[N_OUTBUF] __ALIGNED__;
|
||||||
int n_outbuf;
|
int n_outbuf;
|
||||||
uint32_t vtermno;
|
uint32_t vtermno;
|
||||||
|
struct hv_ops *ops;
|
||||||
int irq_requested;
|
int irq_requested;
|
||||||
int irq;
|
int irq;
|
||||||
struct list_head next;
|
struct list_head next;
|
||||||
struct kobject kobj; /* ref count & hvc_struct lifetime */
|
struct kobject kobj; /* ref count & hvc_struct lifetime */
|
||||||
struct vio_dev *vdev;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* dynamic list of hvc_struct instances */
|
/* dynamic list of hvc_struct instances */
|
||||||
|
@ -97,48 +102,11 @@ static struct list_head hvc_structs = LIST_HEAD_INIT(hvc_structs);
|
||||||
static DEFINE_SPINLOCK(hvc_structs_lock);
|
static DEFINE_SPINLOCK(hvc_structs_lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initial console vtermnos for console API usage prior to full console
|
* This value is used to assign a tty->index value to a hvc_struct based
|
||||||
* initialization. Any vty adapter outside this range will not have usable
|
* upon order of exposure via hvc_probe(), when we can not match it to
|
||||||
* console interfaces but can still be used as a tty device. This has to be
|
* a console canidate registered with hvc_instantiate().
|
||||||
* static because kmalloc will not work during early console init.
|
|
||||||
*/
|
*/
|
||||||
static uint32_t vtermnos[MAX_NR_HVC_CONSOLES];
|
static int last_hvc = -1;
|
||||||
|
|
||||||
/* Used for accounting purposes */
|
|
||||||
static int num_vterms = 0;
|
|
||||||
|
|
||||||
static struct task_struct *hvc_task;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This value is used to associate a tty->index value to a hvc_struct based
|
|
||||||
* upon order of exposure via hvc_probe().
|
|
||||||
*/
|
|
||||||
static int hvc_count = -1;
|
|
||||||
|
|
||||||
/* Picks up late kicks after list walk but before schedule() */
|
|
||||||
static int hvc_kicked;
|
|
||||||
|
|
||||||
/* Wake the sleeping khvcd */
|
|
||||||
static void hvc_kick(void)
|
|
||||||
{
|
|
||||||
hvc_kicked = 1;
|
|
||||||
wake_up_process(hvc_task);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NOTE: This API isn't used if the console adapter doesn't support interrupts.
|
|
||||||
* In this case the console is poll driven.
|
|
||||||
*/
|
|
||||||
static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
hvc_kick();
|
|
||||||
return IRQ_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hvc_unthrottle(struct tty_struct *tty)
|
|
||||||
{
|
|
||||||
hvc_kick();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do not call this function with either the hvc_strucst_lock or the hvc_struct
|
* Do not call this function with either the hvc_strucst_lock or the hvc_struct
|
||||||
|
@ -168,6 +136,178 @@ struct hvc_struct *hvc_get_by_index(int index)
|
||||||
return hp;
|
return hp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initial console vtermnos for console API usage prior to full console
|
||||||
|
* initialization. Any vty adapter outside this range will not have usable
|
||||||
|
* console interfaces but can still be used as a tty device. This has to be
|
||||||
|
* static because kmalloc will not work during early console init.
|
||||||
|
*/
|
||||||
|
static struct hv_ops *cons_ops[MAX_NR_HVC_CONSOLES];
|
||||||
|
static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
|
||||||
|
{[0 ... MAX_NR_HVC_CONSOLES - 1] = -1};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Console APIs, NOT TTY. These APIs are available immediately when
|
||||||
|
* hvc_console_setup() finds adapters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void hvc_console_print(struct console *co, const char *b, unsigned count)
|
||||||
|
{
|
||||||
|
char c[16] __ALIGNED__;
|
||||||
|
unsigned i = 0, n = 0;
|
||||||
|
int r, donecr = 0, index = co->index;
|
||||||
|
|
||||||
|
/* Console access attempt outside of acceptable console range. */
|
||||||
|
if (index >= MAX_NR_HVC_CONSOLES)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* This console adapter was removed so it is not useable. */
|
||||||
|
if (vtermnos[index] < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (count > 0 || i > 0) {
|
||||||
|
if (count > 0 && i < sizeof(c)) {
|
||||||
|
if (b[n] == '\n' && !donecr) {
|
||||||
|
c[i++] = '\r';
|
||||||
|
donecr = 1;
|
||||||
|
} else {
|
||||||
|
c[i++] = b[n++];
|
||||||
|
donecr = 0;
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
r = cons_ops[index]->put_chars(vtermnos[index], c, i);
|
||||||
|
if (r < 0) {
|
||||||
|
/* throw away chars on error */
|
||||||
|
i = 0;
|
||||||
|
} else if (r > 0) {
|
||||||
|
i -= r;
|
||||||
|
if (i > 0)
|
||||||
|
memmove(c, c+r, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct tty_driver *hvc_console_device(struct console *c, int *index)
|
||||||
|
{
|
||||||
|
if (vtermnos[c->index] == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*index = c->index;
|
||||||
|
return hvc_driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init hvc_console_setup(struct console *co, char *options)
|
||||||
|
{
|
||||||
|
if (co->index < 0 || co->index >= MAX_NR_HVC_CONSOLES)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
if (vtermnos[co->index] == -1)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct console hvc_con_driver = {
|
||||||
|
.name = "hvc",
|
||||||
|
.write = hvc_console_print,
|
||||||
|
.device = hvc_console_device,
|
||||||
|
.setup = hvc_console_setup,
|
||||||
|
.flags = CON_PRINTBUFFER,
|
||||||
|
.index = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Early console initialization. Preceeds driver initialization.
|
||||||
|
*
|
||||||
|
* (1) we are first, and the user specified another driver
|
||||||
|
* -- index will remain -1
|
||||||
|
* (2) we are first and the user specified no driver
|
||||||
|
* -- index will be set to 0, then we will fail setup.
|
||||||
|
* (3) we are first and the user specified our driver
|
||||||
|
* -- index will be set to user specified driver, and we will fail
|
||||||
|
* (4) we are after driver, and this initcall will register us
|
||||||
|
* -- if the user didn't specify a driver then the console will match
|
||||||
|
*
|
||||||
|
* Note that for cases 2 and 3, we will match later when the io driver
|
||||||
|
* calls hvc_instantiate() and call register again.
|
||||||
|
*/
|
||||||
|
static int __init hvc_console_init(void)
|
||||||
|
{
|
||||||
|
register_console(&hvc_con_driver);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
console_initcall(hvc_console_init);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hvc_instantiate() is an early console discovery method which locates
|
||||||
|
* consoles * prior to the vio subsystem discovering them. Hotplugged
|
||||||
|
* vty adapters do NOT get an hvc_instantiate() callback since they
|
||||||
|
* appear after early console init.
|
||||||
|
*/
|
||||||
|
int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops)
|
||||||
|
{
|
||||||
|
struct hvc_struct *hp;
|
||||||
|
|
||||||
|
if (index < 0 || index >= MAX_NR_HVC_CONSOLES)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (vtermnos[index] != -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* make sure no no tty has been registerd in this index */
|
||||||
|
hp = hvc_get_by_index(index);
|
||||||
|
if (hp) {
|
||||||
|
kobject_put(&hp->kobj);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
vtermnos[index] = vtermno;
|
||||||
|
cons_ops[index] = ops;
|
||||||
|
|
||||||
|
/* reserve all indices upto and including this index */
|
||||||
|
if (last_hvc < index)
|
||||||
|
last_hvc = index;
|
||||||
|
|
||||||
|
/* if this index is what the user requested, then register
|
||||||
|
* now (setup won't fail at this point). It's ok to just
|
||||||
|
* call register again if previously .setup failed.
|
||||||
|
*/
|
||||||
|
if (index == hvc_con_driver.index)
|
||||||
|
register_console(&hvc_con_driver);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(hvc_instantiate);
|
||||||
|
|
||||||
|
/* Wake the sleeping khvcd */
|
||||||
|
static void hvc_kick(void)
|
||||||
|
{
|
||||||
|
hvc_kicked = 1;
|
||||||
|
wake_up_process(hvc_task);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hvc_poll(struct hvc_struct *hp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: This API isn't used if the console adapter doesn't support interrupts.
|
||||||
|
* In this case the console is poll driven.
|
||||||
|
*/
|
||||||
|
static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
/* if hvc_poll request a repoll, then kick the hvcd thread */
|
||||||
|
if (hvc_poll(dev_instance))
|
||||||
|
hvc_kick();
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hvc_unthrottle(struct tty_struct *tty)
|
||||||
|
{
|
||||||
|
hvc_kick();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The TTY interface won't be used until after the vio layer has exposed the vty
|
* The TTY interface won't be used until after the vio layer has exposed the vty
|
||||||
* adapter to the kernel.
|
* adapter to the kernel.
|
||||||
|
@ -329,7 +469,7 @@ static void hvc_push(struct hvc_struct *hp)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
n = hvc_put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf);
|
n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf);
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -467,7 +607,7 @@ static int hvc_poll(struct hvc_struct *hp)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = hvc_get_chars(hp->vtermno, buf, count);
|
n = hp->ops->get_chars(hp->vtermno, buf, count);
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
/* Hangup the tty when disconnected from host */
|
/* Hangup the tty when disconnected from host */
|
||||||
if (n == -EPIPE) {
|
if (n == -EPIPE) {
|
||||||
|
@ -479,14 +619,17 @@ static int hvc_poll(struct hvc_struct *hp)
|
||||||
}
|
}
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
#ifdef CONFIG_MAGIC_SYSRQ
|
#ifdef CONFIG_MAGIC_SYSRQ
|
||||||
/* Handle the SysRq Hack */
|
if (hp->index == hvc_con_driver.index) {
|
||||||
if (buf[i] == '\x0f') { /* ^O -- should support a sequence */
|
/* Handle the SysRq Hack */
|
||||||
sysrq_pressed = 1;
|
/* XXX should support a sequence */
|
||||||
continue;
|
if (buf[i] == '\x0f') { /* ^O */
|
||||||
} else if (sysrq_pressed) {
|
sysrq_pressed = 1;
|
||||||
handle_sysrq(buf[i], NULL, tty);
|
continue;
|
||||||
sysrq_pressed = 0;
|
} else if (sysrq_pressed) {
|
||||||
continue;
|
handle_sysrq(buf[i], NULL, tty);
|
||||||
|
sysrq_pressed = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_MAGIC_SYSRQ */
|
#endif /* CONFIG_MAGIC_SYSRQ */
|
||||||
tty_insert_flip_char(tty, buf[i], 0);
|
tty_insert_flip_char(tty, buf[i], 0);
|
||||||
|
@ -497,8 +640,8 @@ static int hvc_poll(struct hvc_struct *hp)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Account for the total amount read in one loop, and if above
|
* Account for the total amount read in one loop, and if above
|
||||||
* 64 bytes, we do a quick schedule loop to let the tty grok the
|
* 64 bytes, we do a quick schedule loop to let the tty grok
|
||||||
* data and eventually throttle us.
|
* the data and eventually throttle us.
|
||||||
*/
|
*/
|
||||||
read_total += n;
|
read_total += n;
|
||||||
if (read_total >= 64) {
|
if (read_total >= 64) {
|
||||||
|
@ -542,7 +685,6 @@ int khvcd(void *unused)
|
||||||
if (cpus_empty(cpus_in_xmon)) {
|
if (cpus_empty(cpus_in_xmon)) {
|
||||||
spin_lock(&hvc_structs_lock);
|
spin_lock(&hvc_structs_lock);
|
||||||
list_for_each_entry(hp, &hvc_structs, next) {
|
list_for_each_entry(hp, &hvc_structs, next) {
|
||||||
/*hp = list_entry(node, struct hvc_struct, * next); */
|
|
||||||
poll_mask |= hvc_poll(hp);
|
poll_mask |= hvc_poll(hp);
|
||||||
}
|
}
|
||||||
spin_unlock(&hvc_structs_lock);
|
spin_unlock(&hvc_structs_lock);
|
||||||
|
@ -577,14 +719,6 @@ static struct tty_operations hvc_ops = {
|
||||||
.chars_in_buffer = hvc_chars_in_buffer,
|
.chars_in_buffer = hvc_chars_in_buffer,
|
||||||
};
|
};
|
||||||
|
|
||||||
char hvc_driver_name[] = "hvc_console";
|
|
||||||
|
|
||||||
static struct vio_device_id hvc_driver_table[] __devinitdata= {
|
|
||||||
{"serial", "hvterm1"},
|
|
||||||
{ NULL, }
|
|
||||||
};
|
|
||||||
MODULE_DEVICE_TABLE(vio, hvc_driver_table);
|
|
||||||
|
|
||||||
/* callback when the kboject ref count reaches zero. */
|
/* callback when the kboject ref count reaches zero. */
|
||||||
static void destroy_hvc_struct(struct kobject *kobj)
|
static void destroy_hvc_struct(struct kobject *kobj)
|
||||||
{
|
{
|
||||||
|
@ -606,41 +740,51 @@ static struct kobj_type hvc_kobj_type = {
|
||||||
.release = destroy_hvc_struct,
|
.release = destroy_hvc_struct,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit hvc_probe(
|
struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
|
||||||
struct vio_dev *dev,
|
struct hv_ops *ops)
|
||||||
const struct vio_device_id *id)
|
|
||||||
{
|
{
|
||||||
struct hvc_struct *hp;
|
struct hvc_struct *hp;
|
||||||
|
int i;
|
||||||
/* probed with invalid parameters. */
|
|
||||||
if (!dev || !id)
|
|
||||||
return -EPERM;
|
|
||||||
|
|
||||||
hp = kmalloc(sizeof(*hp), GFP_KERNEL);
|
hp = kmalloc(sizeof(*hp), GFP_KERNEL);
|
||||||
if (!hp)
|
if (!hp)
|
||||||
return -ENOMEM;
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
memset(hp, 0x00, sizeof(*hp));
|
memset(hp, 0x00, sizeof(*hp));
|
||||||
hp->vtermno = dev->unit_address;
|
|
||||||
hp->vdev = dev;
|
hp->vtermno = vtermno;
|
||||||
hp->vdev->dev.driver_data = hp;
|
hp->irq = irq;
|
||||||
hp->irq = dev->irq;
|
hp->ops = ops;
|
||||||
|
|
||||||
kobject_init(&hp->kobj);
|
kobject_init(&hp->kobj);
|
||||||
hp->kobj.ktype = &hvc_kobj_type;
|
hp->kobj.ktype = &hvc_kobj_type;
|
||||||
|
|
||||||
spin_lock_init(&hp->lock);
|
spin_lock_init(&hp->lock);
|
||||||
spin_lock(&hvc_structs_lock);
|
spin_lock(&hvc_structs_lock);
|
||||||
hp->index = ++hvc_count;
|
|
||||||
|
/*
|
||||||
|
* find index to use:
|
||||||
|
* see if this vterm id matches one registered for console.
|
||||||
|
*/
|
||||||
|
for (i=0; i < MAX_NR_HVC_CONSOLES; i++)
|
||||||
|
if (vtermnos[i] == hp->vtermno)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* no matching slot, just use a counter */
|
||||||
|
if (i >= MAX_NR_HVC_CONSOLES)
|
||||||
|
i = ++last_hvc;
|
||||||
|
|
||||||
|
hp->index = i;
|
||||||
|
|
||||||
list_add_tail(&(hp->next), &hvc_structs);
|
list_add_tail(&(hp->next), &hvc_structs);
|
||||||
spin_unlock(&hvc_structs_lock);
|
spin_unlock(&hvc_structs_lock);
|
||||||
|
|
||||||
return 0;
|
return hp;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(hvc_alloc);
|
||||||
|
|
||||||
static int __devexit hvc_remove(struct vio_dev *dev)
|
int __devexit hvc_remove(struct hvc_struct *hp)
|
||||||
{
|
{
|
||||||
struct hvc_struct *hp = dev->dev.driver_data;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct kobject *kobjp;
|
struct kobject *kobjp;
|
||||||
struct tty_struct *tty;
|
struct tty_struct *tty;
|
||||||
|
@ -673,23 +817,14 @@ static int __devexit hvc_remove(struct vio_dev *dev)
|
||||||
tty_hangup(tty);
|
tty_hangup(tty);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(hvc_remove);
|
||||||
static struct vio_driver hvc_vio_driver = {
|
|
||||||
.name = hvc_driver_name,
|
|
||||||
.id_table = hvc_driver_table,
|
|
||||||
.probe = hvc_probe,
|
|
||||||
.remove = hvc_remove,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Driver initialization. Follow console initialization. This is where the TTY
|
/* Driver initialization. Follow console initialization. This is where the TTY
|
||||||
* interfaces start to become available. */
|
* interfaces start to become available. */
|
||||||
int __init hvc_init(void)
|
int __init hvc_init(void)
|
||||||
{
|
{
|
||||||
int rc;
|
/* We need more than hvc_count adapters due to hotplug additions. */
|
||||||
|
|
||||||
/* We need more than num_vterms adapters due to hotplug additions. */
|
|
||||||
hvc_driver = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
|
hvc_driver = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
|
||||||
/* hvc_driver = alloc_tty_driver(num_vterms); */
|
|
||||||
if (!hvc_driver)
|
if (!hvc_driver)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -716,116 +851,20 @@ int __init hvc_init(void)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register as a vio device to receive callbacks */
|
return 0;
|
||||||
rc = vio_register_driver(&hvc_vio_driver);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
module_init(hvc_init);
|
||||||
|
|
||||||
/* This isn't particularily necessary due to this being a console driver but it
|
/* This isn't particularily necessary due to this being a console driver
|
||||||
* is nice to be thorough */
|
* but it is nice to be thorough.
|
||||||
|
*/
|
||||||
static void __exit hvc_exit(void)
|
static void __exit hvc_exit(void)
|
||||||
{
|
{
|
||||||
kthread_stop(hvc_task);
|
kthread_stop(hvc_task);
|
||||||
|
|
||||||
vio_unregister_driver(&hvc_vio_driver);
|
|
||||||
tty_unregister_driver(hvc_driver);
|
tty_unregister_driver(hvc_driver);
|
||||||
/* return tty_struct instances allocated in hvc_init(). */
|
/* return tty_struct instances allocated in hvc_init(). */
|
||||||
put_tty_driver(hvc_driver);
|
put_tty_driver(hvc_driver);
|
||||||
|
unregister_console(&hvc_con_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Console APIs, NOT TTY. These APIs are available immediately when
|
|
||||||
* hvc_console_setup() finds adapters.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* hvc_instantiate() is an early console discovery method which locates consoles
|
|
||||||
* prior to the vio subsystem discovering them. Hotplugged vty adapters do NOT
|
|
||||||
* get an hvc_instantiate() callback since the appear after early console init.
|
|
||||||
*/
|
|
||||||
int hvc_instantiate(uint32_t vtermno, int index)
|
|
||||||
{
|
|
||||||
if (index < 0 || index >= MAX_NR_HVC_CONSOLES)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (vtermnos[index] != -1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
vtermnos[index] = vtermno;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hvc_console_print(struct console *co, const char *b, unsigned count)
|
|
||||||
{
|
|
||||||
char c[16] __ALIGNED__;
|
|
||||||
unsigned i = 0, n = 0;
|
|
||||||
int r, donecr = 0;
|
|
||||||
|
|
||||||
/* Console access attempt outside of acceptable console range. */
|
|
||||||
if (co->index >= MAX_NR_HVC_CONSOLES)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* This console adapter was removed so it is not useable. */
|
|
||||||
if (vtermnos[co->index] < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
while (count > 0 || i > 0) {
|
|
||||||
if (count > 0 && i < sizeof(c)) {
|
|
||||||
if (b[n] == '\n' && !donecr) {
|
|
||||||
c[i++] = '\r';
|
|
||||||
donecr = 1;
|
|
||||||
} else {
|
|
||||||
c[i++] = b[n++];
|
|
||||||
donecr = 0;
|
|
||||||
--count;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
r = hvc_put_chars(vtermnos[co->index], c, i);
|
|
||||||
if (r < 0) {
|
|
||||||
/* throw away chars on error */
|
|
||||||
i = 0;
|
|
||||||
} else if (r > 0) {
|
|
||||||
i -= r;
|
|
||||||
if (i > 0)
|
|
||||||
memmove(c, c+r, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct tty_driver *hvc_console_device(struct console *c, int *index)
|
|
||||||
{
|
|
||||||
*index = c->index;
|
|
||||||
return hvc_driver;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init hvc_console_setup(struct console *co, char *options)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct console hvc_con_driver = {
|
|
||||||
.name = "hvc",
|
|
||||||
.write = hvc_console_print,
|
|
||||||
.device = hvc_console_device,
|
|
||||||
.setup = hvc_console_setup,
|
|
||||||
.flags = CON_PRINTBUFFER,
|
|
||||||
.index = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Early console initialization. Preceeds driver initialization. */
|
|
||||||
static int __init hvc_console_init(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0; i<MAX_NR_HVC_CONSOLES; i++)
|
|
||||||
vtermnos[i] = -1;
|
|
||||||
num_vterms = hvc_find_vtys();
|
|
||||||
register_console(&hvc_con_driver);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
console_initcall(hvc_console_init);
|
|
||||||
|
|
||||||
module_init(hvc_init);
|
|
||||||
module_exit(hvc_exit);
|
module_exit(hvc_exit);
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
/*
|
||||||
|
* vio driver interface to hvc_console.c
|
||||||
|
*
|
||||||
|
* This code was moved here to allow the remaing code to be reused as a
|
||||||
|
* generic polling mode with semi-reliable transport driver core to the
|
||||||
|
* console and tty subsystems.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
|
||||||
|
* Copyright (C) 2001 Paul Mackerras <paulus@au.ibm.com>, IBM
|
||||||
|
* Copyright (C) 2004 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
|
||||||
|
* Copyright (C) 2004 IBM Corporation
|
||||||
|
*
|
||||||
|
* Additional Author(s):
|
||||||
|
* Ryan S. Arnold <rsa@us.ibm.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/types.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <asm/hvconsole.h>
|
||||||
|
#include <asm/vio.h>
|
||||||
|
#include <asm/prom.h>
|
||||||
|
|
||||||
|
char hvc_driver_name[] = "hvc_console";
|
||||||
|
|
||||||
|
static struct vio_device_id hvc_driver_table[] __devinitdata = {
|
||||||
|
{"serial", "hvterm1"},
|
||||||
|
{ NULL, }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(vio, hvc_driver_table);
|
||||||
|
|
||||||
|
static int filtered_get_chars(uint32_t vtermno, char *buf, int count)
|
||||||
|
{
|
||||||
|
unsigned long got;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
got = hvc_get_chars(vtermno, buf, count);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Work around a HV bug where it gives us a null
|
||||||
|
* after every \r. -- paulus
|
||||||
|
*/
|
||||||
|
for (i = 1; i < got; ++i) {
|
||||||
|
if (buf[i] == 0 && buf[i-1] == '\r') {
|
||||||
|
--got;
|
||||||
|
if (i < got)
|
||||||
|
memmove(&buf[i], &buf[i+1],
|
||||||
|
got - i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return got;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct hv_ops hvc_get_put_ops = {
|
||||||
|
.get_chars = filtered_get_chars,
|
||||||
|
.put_chars = hvc_put_chars,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __devinit hvc_vio_probe(struct vio_dev *vdev,
|
||||||
|
const struct vio_device_id *id)
|
||||||
|
{
|
||||||
|
struct hvc_struct *hp;
|
||||||
|
|
||||||
|
/* probed with invalid parameters. */
|
||||||
|
if (!vdev || !id)
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
hp = hvc_alloc(vdev->unit_address, vdev->irq, &hvc_get_put_ops);
|
||||||
|
if (IS_ERR(hp))
|
||||||
|
return PTR_ERR(hp);
|
||||||
|
dev_set_drvdata(&vdev->dev, hp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __devexit hvc_vio_remove(struct vio_dev *vdev)
|
||||||
|
{
|
||||||
|
struct hvc_struct *hp = dev_get_drvdata(&vdev->dev);
|
||||||
|
|
||||||
|
return hvc_remove(hp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct vio_driver hvc_vio_driver = {
|
||||||
|
.name = hvc_driver_name,
|
||||||
|
.id_table = hvc_driver_table,
|
||||||
|
.probe = hvc_vio_probe,
|
||||||
|
.remove = hvc_vio_remove,
|
||||||
|
.driver = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int hvc_vio_init(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* Register as a vio device to receive callbacks */
|
||||||
|
rc = vio_register_driver(&hvc_vio_driver);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */
|
||||||
|
|
||||||
|
static void hvc_vio_exit(void)
|
||||||
|
{
|
||||||
|
vio_unregister_driver(&hvc_vio_driver);
|
||||||
|
}
|
||||||
|
module_exit(hvc_vio_exit);
|
||||||
|
|
||||||
|
/* the device tree order defines our numbering */
|
||||||
|
static int hvc_find_vtys(void)
|
||||||
|
{
|
||||||
|
struct device_node *vty;
|
||||||
|
int num_found = 0;
|
||||||
|
|
||||||
|
for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL;
|
||||||
|
vty = of_find_node_by_name(vty, "vty")) {
|
||||||
|
uint32_t *vtermno;
|
||||||
|
|
||||||
|
/* We have statically defined space for only a certain number
|
||||||
|
* of console adapters.
|
||||||
|
*/
|
||||||
|
if (num_found >= MAX_NR_HVC_CONSOLES)
|
||||||
|
break;
|
||||||
|
|
||||||
|
vtermno = (uint32_t *)get_property(vty, "reg", NULL);
|
||||||
|
if (!vtermno)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (device_is_compatible(vty, "hvterm1")) {
|
||||||
|
hvc_instantiate(*vtermno, num_found, &hvc_get_put_ops);
|
||||||
|
++num_found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_found;
|
||||||
|
}
|
||||||
|
console_initcall(hvc_find_vtys);
|
|
@ -291,15 +291,13 @@ static void dump_packet(uint8_t *packet)
|
||||||
dump_hex(packet, header->len);
|
dump_hex(packet, header->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* can't use hvc_get_chars because that strips CRs */
|
|
||||||
static int hvsi_read(struct hvsi_struct *hp, char *buf, int count)
|
static int hvsi_read(struct hvsi_struct *hp, char *buf, int count)
|
||||||
{
|
{
|
||||||
unsigned long got;
|
unsigned long got;
|
||||||
|
|
||||||
if (plpar_hcall(H_GET_TERM_CHAR, hp->vtermno, 0, 0, 0, &got,
|
got = hvc_get_chars(hp->vtermno, buf, count);
|
||||||
(unsigned long *)buf, (unsigned long *)buf+1) == H_Success)
|
|
||||||
return got;
|
return got;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet,
|
static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet,
|
||||||
|
|
|
@ -770,10 +770,8 @@ send_signal:
|
||||||
}
|
}
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
if (L_ECHO(tty) || L_ECHONL(tty)) {
|
if (L_ECHO(tty) || L_ECHONL(tty)) {
|
||||||
if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
|
if (tty->read_cnt >= N_TTY_BUF_SIZE-1)
|
||||||
put_char('\a', tty);
|
put_char('\a', tty);
|
||||||
return;
|
|
||||||
}
|
|
||||||
opost('\n', tty);
|
opost('\n', tty);
|
||||||
}
|
}
|
||||||
goto handle_newline;
|
goto handle_newline;
|
||||||
|
@ -790,10 +788,8 @@ send_signal:
|
||||||
* XXX are EOL_CHAR and EOL2_CHAR echoed?!?
|
* XXX are EOL_CHAR and EOL2_CHAR echoed?!?
|
||||||
*/
|
*/
|
||||||
if (L_ECHO(tty)) {
|
if (L_ECHO(tty)) {
|
||||||
if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
|
if (tty->read_cnt >= N_TTY_BUF_SIZE-1)
|
||||||
put_char('\a', tty);
|
put_char('\a', tty);
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* Record the column of first canon char. */
|
/* Record the column of first canon char. */
|
||||||
if (tty->canon_head == tty->read_head)
|
if (tty->canon_head == tty->read_head)
|
||||||
tty->canon_column = tty->column;
|
tty->canon_column = tty->column;
|
||||||
|
@ -862,12 +858,9 @@ static int n_tty_receive_room(struct tty_struct *tty)
|
||||||
* that erase characters will be handled. Other excess
|
* that erase characters will be handled. Other excess
|
||||||
* characters will be beeped.
|
* characters will be beeped.
|
||||||
*/
|
*/
|
||||||
if (tty->icanon && !tty->canon_data)
|
if (left <= 0)
|
||||||
return N_TTY_BUF_SIZE;
|
left = tty->icanon && !tty->canon_data;
|
||||||
|
return left;
|
||||||
if (left > 0)
|
|
||||||
return left;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1473,13 +1466,17 @@ static ssize_t write_chan(struct tty_struct * tty, struct file * file,
|
||||||
if (tty->driver->flush_chars)
|
if (tty->driver->flush_chars)
|
||||||
tty->driver->flush_chars(tty);
|
tty->driver->flush_chars(tty);
|
||||||
} else {
|
} else {
|
||||||
c = tty->driver->write(tty, b, nr);
|
while (nr > 0) {
|
||||||
if (c < 0) {
|
c = tty->driver->write(tty, b, nr);
|
||||||
retval = c;
|
if (c < 0) {
|
||||||
goto break_out;
|
retval = c;
|
||||||
|
goto break_out;
|
||||||
|
}
|
||||||
|
if (!c)
|
||||||
|
break;
|
||||||
|
b += c;
|
||||||
|
nr -= c;
|
||||||
}
|
}
|
||||||
b += c;
|
|
||||||
nr -= c;
|
|
||||||
}
|
}
|
||||||
if (!nr)
|
if (!nr)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -71,7 +71,6 @@
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/hdlc.h>
|
#include <linux/hdlc.h>
|
||||||
|
|
||||||
#include <pcmcia/version.h>
|
|
||||||
#include <pcmcia/cs_types.h>
|
#include <pcmcia/cs_types.h>
|
||||||
#include <pcmcia/cs.h>
|
#include <pcmcia/cs.h>
|
||||||
#include <pcmcia/cistpl.h>
|
#include <pcmcia/cistpl.h>
|
||||||
|
@ -593,11 +592,6 @@ static dev_link_t *mgslpc_attach(void)
|
||||||
dev_list = link;
|
dev_list = link;
|
||||||
|
|
||||||
client_reg.dev_info = &dev_info;
|
client_reg.dev_info = &dev_info;
|
||||||
client_reg.EventMask =
|
|
||||||
CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
|
|
||||||
CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
|
|
||||||
CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
|
|
||||||
client_reg.event_handler = &mgslpc_event;
|
|
||||||
client_reg.Version = 0x0210;
|
client_reg.Version = 0x0210;
|
||||||
client_reg.event_callback_args.client_data = link;
|
client_reg.event_callback_args.client_data = link;
|
||||||
|
|
||||||
|
@ -3093,6 +3087,7 @@ static struct pcmcia_driver mgslpc_driver = {
|
||||||
.name = "synclink_cs",
|
.name = "synclink_cs",
|
||||||
},
|
},
|
||||||
.attach = mgslpc_attach,
|
.attach = mgslpc_attach,
|
||||||
|
.event = mgslpc_event,
|
||||||
.detach = mgslpc_detach,
|
.detach = mgslpc_detach,
|
||||||
.id_table = mgslpc_ids,
|
.id_table = mgslpc_ids,
|
||||||
};
|
};
|
||||||
|
|
|
@ -271,7 +271,7 @@ static int random_write_wakeup_thresh = 128;
|
||||||
* samples to avoid wasting CPU time and reduce lock contention.
|
* samples to avoid wasting CPU time and reduce lock contention.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int trickle_thresh = INPUT_POOL_WORDS * 28;
|
static int trickle_thresh __read_mostly = INPUT_POOL_WORDS * 28;
|
||||||
|
|
||||||
static DEFINE_PER_CPU(int, trickle_count) = 0;
|
static DEFINE_PER_CPU(int, trickle_count) = 0;
|
||||||
|
|
||||||
|
|
|
@ -228,7 +228,7 @@ static struct sysrq_key_op sysrq_term_op = {
|
||||||
|
|
||||||
static void moom_callback(void *ignored)
|
static void moom_callback(void *ignored)
|
||||||
{
|
{
|
||||||
out_of_memory(GFP_KERNEL);
|
out_of_memory(GFP_KERNEL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DECLARE_WORK(moom_work, moom_callback, NULL);
|
static DECLARE_WORK(moom_work, moom_callback, NULL);
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче