forked from Minki/linux
Automerge with /usr/src/ntfs-2.6.git.
This commit is contained in:
commit
38b22b6e9f
@ -63,7 +63,7 @@ o PPP 2.4.0 # pppd --version
|
||||
o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version
|
||||
o nfs-utils 1.0.5 # showmount --version
|
||||
o procps 3.2.0 # ps --version
|
||||
o oprofile 0.5.3 # oprofiled --version
|
||||
o oprofile 0.9 # oprofiled --version
|
||||
|
||||
Kernel compilation
|
||||
==================
|
||||
|
@ -49,7 +49,7 @@ installmandocs: mandocs
|
||||
KERNELDOC = scripts/kernel-doc
|
||||
DOCPROC = scripts/basic/docproc
|
||||
|
||||
XMLTOFLAGS = -m Documentation/DocBook/stylesheet.xsl
|
||||
XMLTOFLAGS = -m $(srctree)/Documentation/DocBook/stylesheet.xsl
|
||||
#XMLTOFLAGS += --skip-validation
|
||||
|
||||
###
|
||||
|
@ -266,7 +266,7 @@ X!Ekernel/module.c
|
||||
<chapter id="hardware">
|
||||
<title>Hardware Interfaces</title>
|
||||
<sect1><title>Interrupt Handling</title>
|
||||
!Iarch/i386/kernel/irq.c
|
||||
!Ikernel/irq/manage.c
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Resources Management</title>
|
||||
|
@ -2,4 +2,5 @@
|
||||
<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||
<param name="chunk.quietly">1</param>
|
||||
<param name="funcsynopsis.style">ansi</param>
|
||||
<param name="funcsynopsis.tabular.threshold">80</param>
|
||||
</stylesheet>
|
||||
|
@ -25,9 +25,10 @@ subject and I can't cover it all here!
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
The LinuxIPMI driver is modular, which means you have to pick several
|
||||
The Linux IPMI driver is modular, which means you have to pick several
|
||||
things to have it work right depending on your hardware. Most of
|
||||
these are available in the 'Character Devices' menu.
|
||||
these are available in the 'Character Devices' menu then the IPMI
|
||||
menu.
|
||||
|
||||
No matter what, you must pick 'IPMI top-level message handler' to use
|
||||
IPMI. What you do beyond that depends on your needs and hardware.
|
||||
@ -35,33 +36,30 @@ IPMI. What you do beyond that depends on your needs and hardware.
|
||||
The message handler does not provide any user-level interfaces.
|
||||
Kernel code (like the watchdog) can still use it. If you need access
|
||||
from userland, you need to select 'Device interface for IPMI' if you
|
||||
want access through a device driver. Another interface is also
|
||||
available, you may select 'IPMI sockets' in the 'Networking Support'
|
||||
main menu. This provides a socket interface to IPMI. You may select
|
||||
both of these at the same time, they will both work together.
|
||||
want access through a device driver.
|
||||
|
||||
The driver interface depends on your hardware. If you have a board
|
||||
with a standard interface (These will generally be either "KCS",
|
||||
"SMIC", or "BT", consult your hardware manual), choose the 'IPMI SI
|
||||
handler' option. A driver also exists for direct I2C access to the
|
||||
IPMI management controller. Some boards support this, but it is
|
||||
unknown if it will work on every board. For this, choose 'IPMI SMBus
|
||||
handler', but be ready to try to do some figuring to see if it will
|
||||
work.
|
||||
|
||||
There is also a KCS-only driver interface supplied, but it is
|
||||
depracated in favor of the SI interface.
|
||||
The driver interface depends on your hardware. If your system
|
||||
properly provides the SMBIOS info for IPMI, the driver will detect it
|
||||
and just work. If you have a board with a standard interface (These
|
||||
will generally be either "KCS", "SMIC", or "BT", consult your hardware
|
||||
manual), choose the 'IPMI SI handler' option. A driver also exists
|
||||
for direct I2C access to the IPMI management controller. Some boards
|
||||
support this, but it is unknown if it will work on every board. For
|
||||
this, choose 'IPMI SMBus handler', but be ready to try to do some
|
||||
figuring to see if it will work on your system if the SMBIOS/APCI
|
||||
information is wrong or not present. It is fairly safe to have both
|
||||
these enabled and let the drivers auto-detect what is present.
|
||||
|
||||
You should generally enable ACPI on your system, as systems with IPMI
|
||||
should have ACPI tables describing them.
|
||||
can have ACPI tables describing them.
|
||||
|
||||
If you have a standard interface and the board manufacturer has done
|
||||
their job correctly, the IPMI controller should be automatically
|
||||
detect (via ACPI or SMBIOS tables) and should just work. Sadly, many
|
||||
boards do not have this information. The driver attempts standard
|
||||
defaults, but they may not work. If you fall into this situation, you
|
||||
need to read the section below named 'The SI Driver' on how to
|
||||
hand-configure your system.
|
||||
detected (via ACPI or SMBIOS tables) and should just work. Sadly,
|
||||
many boards do not have this information. The driver attempts
|
||||
standard defaults, but they may not work. If you fall into this
|
||||
situation, you need to read the section below named 'The SI Driver' or
|
||||
"The SMBus Driver" on how to hand-configure your system.
|
||||
|
||||
IPMI defines a standard watchdog timer. You can enable this with the
|
||||
'IPMI Watchdog Timer' config option. If you compile the driver into
|
||||
@ -73,6 +71,18 @@ closed (by default it is disabled on close). Go into the 'Watchdog
|
||||
Cards' menu, enable 'Watchdog Timer Support', and enable the option
|
||||
'Disable watchdog shutdown on close'.
|
||||
|
||||
IPMI systems can often be powered off using IPMI commands. Select
|
||||
'IPMI Poweroff' to do this. The driver will auto-detect if the system
|
||||
can be powered off by IPMI. It is safe to enable this even if your
|
||||
system doesn't support this option. This works on ATCA systems, the
|
||||
Radisys CPI1 card, and any IPMI system that supports standard chassis
|
||||
management commands.
|
||||
|
||||
If you want the driver to put an event into the event log on a panic,
|
||||
enable the 'Generate a panic event to all BMCs on a panic' option. If
|
||||
you want the whole panic string put into the event log using OEM
|
||||
events, enable the 'Generate OEM events containing the panic string'
|
||||
option.
|
||||
|
||||
Basic Design
|
||||
------------
|
||||
@ -80,7 +90,7 @@ Basic Design
|
||||
The Linux IPMI driver is designed to be very modular and flexible, you
|
||||
only need to take the pieces you need and you can use it in many
|
||||
different ways. Because of that, it's broken into many chunks of
|
||||
code. These chunks are:
|
||||
code. These chunks (by module name) are:
|
||||
|
||||
ipmi_msghandler - This is the central piece of software for the IPMI
|
||||
system. It handles all messages, message timing, and responses. The
|
||||
@ -93,18 +103,26 @@ ipmi_devintf - This provides a userland IOCTL interface for the IPMI
|
||||
driver, each open file for this device ties in to the message handler
|
||||
as an IPMI user.
|
||||
|
||||
ipmi_si - A driver for various system interfaces. This supports
|
||||
KCS, SMIC, and may support BT in the future. Unless you have your own
|
||||
custom interface, you probably need to use this.
|
||||
ipmi_si - A driver for various system interfaces. This supports KCS,
|
||||
SMIC, and BT interfaces. Unless you have an SMBus interface or your
|
||||
own custom interface, you probably need to use this.
|
||||
|
||||
ipmi_smb - A driver for accessing BMCs on the SMBus. It uses the
|
||||
I2C kernel driver's SMBus interfaces to send and receive IPMI messages
|
||||
over the SMBus.
|
||||
|
||||
af_ipmi - A network socket interface to IPMI. This doesn't take up
|
||||
a character device in your system.
|
||||
ipmi_watchdog - IPMI requires systems to have a very capable watchdog
|
||||
timer. This driver implements the standard Linux watchdog timer
|
||||
interface on top of the IPMI message handler.
|
||||
|
||||
Note that the KCS-only interface ahs been removed.
|
||||
ipmi_poweroff - Some systems support the ability to be turned off via
|
||||
IPMI commands.
|
||||
|
||||
These are all individually selectable via configuration options.
|
||||
|
||||
Note that the KCS-only interface has been removed. The af_ipmi driver
|
||||
is no longer supported and has been removed because it was impossible
|
||||
to do 32 bit emulation on 64-bit kernels with it.
|
||||
|
||||
Much documentation for the interface is in the include files. The
|
||||
IPMI include files are:
|
||||
@ -424,7 +442,7 @@ at module load time (for a module) with:
|
||||
modprobe ipmi_smb.o
|
||||
addr=<adapter1>,<i2caddr1>[,<adapter2>,<i2caddr2>[,...]]
|
||||
dbg=<flags1>,<flags2>...
|
||||
[defaultprobe=0] [dbg_probe=1]
|
||||
[defaultprobe=1] [dbg_probe=1]
|
||||
|
||||
The addresses are specified in pairs, the first is the adapter ID and the
|
||||
second is the I2C address on that adapter.
|
||||
@ -532,3 +550,67 @@ Once you open the watchdog timer, you must write a 'V' character to the
|
||||
device to close it, or the timer will not stop. This is a new semantic
|
||||
for the driver, but makes it consistent with the rest of the watchdog
|
||||
drivers in Linux.
|
||||
|
||||
|
||||
Panic Timeouts
|
||||
--------------
|
||||
|
||||
The OpenIPMI driver supports the ability to put semi-custom and custom
|
||||
events in the system event log if a panic occurs. if you enable the
|
||||
'Generate a panic event to all BMCs on a panic' option, you will get
|
||||
one event on a panic in a standard IPMI event format. If you enable
|
||||
the 'Generate OEM events containing the panic string' option, you will
|
||||
also get a bunch of OEM events holding the panic string.
|
||||
|
||||
|
||||
The field settings of the events are:
|
||||
* Generator ID: 0x21 (kernel)
|
||||
* EvM Rev: 0x03 (this event is formatting in IPMI 1.0 format)
|
||||
* Sensor Type: 0x20 (OS critical stop sensor)
|
||||
* Sensor #: The first byte of the panic string (0 if no panic string)
|
||||
* Event Dir | Event Type: 0x6f (Assertion, sensor-specific event info)
|
||||
* Event Data 1: 0xa1 (Runtime stop in OEM bytes 2 and 3)
|
||||
* Event data 2: second byte of panic string
|
||||
* Event data 3: third byte of panic string
|
||||
See the IPMI spec for the details of the event layout. This event is
|
||||
always sent to the local management controller. It will handle routing
|
||||
the message to the right place
|
||||
|
||||
Other OEM events have the following format:
|
||||
Record ID (bytes 0-1): Set by the SEL.
|
||||
Record type (byte 2): 0xf0 (OEM non-timestamped)
|
||||
byte 3: The slave address of the card saving the panic
|
||||
byte 4: A sequence number (starting at zero)
|
||||
The rest of the bytes (11 bytes) are the panic string. If the panic string
|
||||
is longer than 11 bytes, multiple messages will be sent with increasing
|
||||
sequence numbers.
|
||||
|
||||
Because you cannot send OEM events using the standard interface, this
|
||||
function will attempt to find an SEL and add the events there. It
|
||||
will first query the capabilities of the local management controller.
|
||||
If it has an SEL, then they will be stored in the SEL of the local
|
||||
management controller. If not, and the local management controller is
|
||||
an event generator, the event receiver from the local management
|
||||
controller will be queried and the events sent to the SEL on that
|
||||
device. Otherwise, the events go nowhere since there is nowhere to
|
||||
send them.
|
||||
|
||||
|
||||
Poweroff
|
||||
--------
|
||||
|
||||
If the poweroff capability is selected, the IPMI driver will install
|
||||
a shutdown function into the standard poweroff function pointer. This
|
||||
is in the ipmi_poweroff module. When the system requests a powerdown,
|
||||
it will send the proper IPMI commands to do this. This is supported on
|
||||
several platforms.
|
||||
|
||||
There is a module parameter named "poweroff_control" that may either be zero
|
||||
(do a power down) or 2 (do a power cycle, power the system off, then power
|
||||
it on in a few seconds). Setting ipmi_poweroff.poweroff_control=x will do
|
||||
the same thing on the kernel command line. The parameter is also available
|
||||
via the proc filesystem in /proc/ipmi/poweroff_control. Note that if the
|
||||
system does not support power cycling, it will always to the power off.
|
||||
|
||||
Note that if you have ACPI enabled, the system will prefer using ACPI to
|
||||
power off.
|
||||
|
@ -27,9 +27,13 @@ dump output readprofile -m /boot/System.map > captured_profile
|
||||
|
||||
Oprofile
|
||||
--------
|
||||
Get the source (I use 0.8) from http://oprofile.sourceforge.net/
|
||||
and add "idle=poll" to the kernel command line
|
||||
|
||||
Get the source (see Changes for required version) from
|
||||
http://oprofile.sourceforge.net/ and add "idle=poll" to the kernel command
|
||||
line.
|
||||
|
||||
Configure with CONFIG_PROFILING=y and CONFIG_OPROFILE=y & reboot on new kernel
|
||||
|
||||
./configure --with-kernel-support
|
||||
make install
|
||||
|
||||
@ -46,7 +50,7 @@ start opcontrol --start
|
||||
stop opcontrol --stop
|
||||
dump output opreport > output_file
|
||||
|
||||
To only report on the kernel, run opreport /boot/vmlinux > output_file
|
||||
To only report on the kernel, run opreport -l /boot/vmlinux > output_file
|
||||
|
||||
A reset is needed to clear old statistics, which survive a reboot.
|
||||
|
||||
|
@ -111,6 +111,7 @@ mkdep
|
||||
mktables
|
||||
modpost
|
||||
modversions.h*
|
||||
offset.h
|
||||
offsets.h
|
||||
oui.c*
|
||||
parse.c*
|
||||
|
@ -1,16 +1,40 @@
|
||||
Documentation for dib3000* frontend drivers and dibusb device driver
|
||||
====================================================================
|
||||
Documentation for dvb-usb-framework module and its devices
|
||||
|
||||
Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de),
|
||||
Idea behind the dvb-usb-framework
|
||||
=================================
|
||||
|
||||
dibusb and dib3000mb/mc drivers based on GPL code, which has
|
||||
In March 2005 I got the new Twinhan USB2.0 DVB-T device. They provided specs and a firmware.
|
||||
|
||||
Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
|
||||
Quite keen I wanted to put the driver (with some quirks of course) into dibusb.
|
||||
After reading some specs and doing some USB snooping, it realized, that the
|
||||
dibusb-driver would be a complete mess afterwards. So I decided to do it in a
|
||||
different way: With the help of a dvb-usb-framework.
|
||||
|
||||
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, version 2.
|
||||
The framework provides generic functions (mostly kernel API calls), such as:
|
||||
|
||||
- Transport Stream URB handling in conjunction with dvb-demux-feed-control
|
||||
(bulk and isoc (TODO) are supported)
|
||||
- registering the device for the DVB-API
|
||||
- registering an I2C-adapter if applicable
|
||||
- remote-control/input-device handling
|
||||
- firmware requesting and loading (currently just for the Cypress USB
|
||||
controller)
|
||||
- other functions/methods which can be shared by several drivers (such as
|
||||
functions for bulk-control-commands)
|
||||
|
||||
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
|
||||
is done via callbacks, assigned in a static device-description (struct
|
||||
dvb_usb_device) each device-driver has to have.
|
||||
|
||||
For an example have a look in drivers/media/dvb/dvb-usb/vp7045*.
|
||||
|
||||
Objective is to migrate all the usb-devices (dibusb, cinergyT2, maybe the
|
||||
ttusb; flexcop-usb already benefits from the generic flexcop-device) to use
|
||||
the dvb-usb-lib.
|
||||
|
||||
TODO: dynamic enabling and disabling of the pid-filter in regard to number of
|
||||
feeds requested.
|
||||
|
||||
Supported devices USB1.1
|
||||
========================
|
||||
@ -55,22 +79,34 @@ Others:
|
||||
- Grandtec USB DVB-T
|
||||
http://www.grand.com.tw/
|
||||
|
||||
- Avermedia AverTV DVBT USB (2)
|
||||
- AVerMedia AverTV DVBT USB
|
||||
http://www.avermedia.com/
|
||||
|
||||
- DiBcom USB DVB-T reference device (non-public)
|
||||
|
||||
|
||||
Supported devices USB2.0
|
||||
========================
|
||||
- Twinhan MagicBox II (2)
|
||||
Supported devices USB2.0-only
|
||||
=============================
|
||||
- Twinhan MagicBox II
|
||||
http://www.twinhan.com/product_terrestrial_7.asp
|
||||
|
||||
- Hanftek UMT-010 (1)
|
||||
- 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
|
||||
|
||||
- Typhoon/Yakumo/HAMA DVB-T mobile USB2.0 (1)
|
||||
|
||||
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)
|
||||
|
||||
@ -81,14 +117,24 @@ Supported devices USB2.0
|
||||
|
||||
- DiBcom USB2.0 DVB-T reference device (non-public)
|
||||
|
||||
1) It is working almost.
|
||||
- AVerMedia AverTV A800 DVB-T USB2.0
|
||||
|
||||
1) It is working almost - work-in-progress.
|
||||
2) No test reports received yet.
|
||||
|
||||
0. History & News:
|
||||
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-03-31 - ported the Yakumo/Hama/Typhoon DVB-T USB2.0 device to dvb-usb.
|
||||
2005-03-30 - first commit of the dvb-usb-module based on the dibusb-source. First device is a new driver for the
|
||||
TwinhanDTV Alpha / MagicBox II USB2.0-only DVB-T device.
|
||||
|
||||
0. NEWS:
|
||||
(change from dvb-dibusb to dvb-usb)
|
||||
2005-03-28 - added support for the AVerMedia AverTV DVB-T USB2.0 device (Thanks to Glen Harris and Jiun-Kuei Jung, AVerMedia)
|
||||
2005-03-14 - added support for the Typhoon/Yakumo/HAMA DVB-T mobile USB2.0
|
||||
2005-02-11 - added support for the KWorld/ADSTech Instant DVB-T USB2.0. Thanks a lot to Joachim von Caron
|
||||
2005-02-02 - added support for the Hauppauge Win-TV Nova-T USB2
|
||||
2005-01-31 - distorted streaming is finally 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
|
||||
- first almost working version for HanfTek UMT-010
|
||||
- found out, that Yakumo/HAMA/Typhoon are predessors of the HanfTek UMT-010
|
||||
@ -99,7 +145,7 @@ Supported devices USB2.0
|
||||
2004-12-26 - refactored the dibusb-driver, splitted into separate files
|
||||
- i2c-probing enabled
|
||||
2004-12-06 - possibility for demod i2c-address probing
|
||||
- new usb IDs (Compro,Artec)
|
||||
- new usb IDs (Compro, Artec)
|
||||
2004-11-23 - merged changes from DiB3000MC_ver2.1
|
||||
- revised the debugging
|
||||
- possibility to deliver the complete TS for USB2.0
|
||||
@ -127,8 +173,8 @@ Supported devices USB2.0
|
||||
CTS Portable (Chinese Television System)
|
||||
2004-07-08 - firmware-extraction-2.422-problem solved, driver is now working
|
||||
properly with firmware extracted from 2.422
|
||||
- #if for 2.6.4 (dvb), compile issue
|
||||
- changed firmware handling, see vp7041.txt sec 1.1
|
||||
- #if for 2.6.4 (dvb), compile issue
|
||||
- changed firmware handling, see vp7041.txt sec 1.1
|
||||
2004-07-02 - some tuner modifications, v0.1, cleanups, first public
|
||||
2004-06-28 - now using the dvb_dmx_swfilter_packets, everything
|
||||
runs fine now
|
||||
@ -139,38 +185,27 @@ Supported devices USB2.0
|
||||
2004-05-11 - start writing the driver
|
||||
|
||||
1. How to use?
|
||||
NOTE: This driver was developed using Linux 2.6.6.,
|
||||
it is working with 2.6.7 and above.
|
||||
|
||||
Linux 2.4.x support is not planned, but patches are very welcome.
|
||||
|
||||
NOTE: I'm using Debian testing, so the following explaination (especially
|
||||
the hotplug-path) needn't match your system, but probably it will :).
|
||||
|
||||
The driver is included in the kernel since Linux 2.6.10.
|
||||
|
||||
1.1. Firmware
|
||||
|
||||
The USB driver needs to download a firmware to start working.
|
||||
Most of the USB drivers need to download a firmware to start working.
|
||||
|
||||
You can either use "get_dvb_firmware dibusb" to download the firmware or you
|
||||
can get it directly via
|
||||
for USB1.1 (AN2135) you need: dvb-usb-dibusb-5.0.0.11.fw
|
||||
for USB2.0 HanfTek: dvb-usb-umt-010-02.fw
|
||||
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
|
||||
|
||||
for USB1.1 (AN2135)
|
||||
http://www.linuxtv.org/downloads/firmware/dvb-dibusb-5.0.0.11.fw
|
||||
The files can be found on http://www.linuxtv.org/download/firmware/ .
|
||||
|
||||
for USB1.1 (AN2235) (a few Artec T1 devices)
|
||||
http://www.linuxtv.org/downloads/firmware/dvb-dibusb-an2235-1.fw
|
||||
We do not have the permission (yet) to publish the following firmware-files.
|
||||
You'll need to extract them from the windows drivers.
|
||||
|
||||
for USB2.0 (FX2) Hauppauge, DiBcom
|
||||
http://www.linuxtv.org/downloads/firmware/dvb-dibusb-6.0.0.5.fw
|
||||
|
||||
for USB2.0 ADSTech/Kworld USB2.0
|
||||
http://www.linuxtv.org/downloads/firmware/dvb-dibusb-adstech-usb2-1.fw
|
||||
|
||||
for USB2.0 HanfTek
|
||||
http://www.linuxtv.org/downloads/firmware/dvb-dibusb-an2235-1.fw
|
||||
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
|
||||
|
||||
@ -178,6 +213,9 @@ Since the driver is in the linux kernel, activating the driver in
|
||||
your favorite config-environment should sufficient. I recommend
|
||||
to compile the driver as module. Hotplug does the rest.
|
||||
|
||||
If you use dvb-kernel enter the build-2.6 directory run 'make' and 'insmod.sh
|
||||
load' afterwards.
|
||||
|
||||
1.3. Loading the drivers
|
||||
|
||||
Hotplug is able to load the driver, when it is needed (because you plugged
|
||||
@ -188,15 +226,13 @@ from withing the dvb-kernel cvs repository.
|
||||
|
||||
first have a look, which debug level are available:
|
||||
|
||||
modinfo dib3000mb
|
||||
modinfo dib3000-common
|
||||
modinfo dib3000mc
|
||||
modinfo dvb-dibusb
|
||||
modinfo dvb-usb
|
||||
modinfo dvb-usb-vp7045
|
||||
etc.
|
||||
|
||||
modprobe dib3000-common debug=<level>
|
||||
modprobe dib3000mb debug=<level>
|
||||
modprobe dib3000mc debug=<level>
|
||||
modprobe dvb-dibusb debug=<level>
|
||||
modprobe dvb-usb debug=<level>
|
||||
modprobe dvb-usb-vp7045 debug=<level>
|
||||
etc.
|
||||
|
||||
should do the trick.
|
||||
|
||||
@ -204,52 +240,32 @@ When the driver is loaded successfully, the firmware file was in
|
||||
the right place and the device is connected, the "Power"-LED should be
|
||||
turned on.
|
||||
|
||||
At this point you should be able to start a dvb-capable application. For myself
|
||||
I used mplayer, dvbscan, tzap and kaxtv, they are working. Using the device
|
||||
in vdr is working now also.
|
||||
At this point you should be able to start a dvb-capable application. I'm use
|
||||
(t|s)zap, mplayer and dvbscan to test the basics. VDR-xine provides the
|
||||
long-term test scenario.
|
||||
|
||||
2. Known problems and bugs
|
||||
|
||||
- Don't remove the USB device while running an DVB application, your system will die.
|
||||
- Don't remove the USB device while running an DVB application, your system
|
||||
will go crazy or die most likely.
|
||||
|
||||
2.1. Adding support for devices
|
||||
|
||||
It is not possible to determine the range of devices based on the DiBcom
|
||||
reference designs. This is because the reference design of DiBcom can be sold
|
||||
to thirds, without telling DiBcom (so done with the Twinhan VP7041 and
|
||||
the HAMA device).
|
||||
|
||||
When you think you have a device like this and the driver does not recognizes it,
|
||||
please send the ****load*.inf and the ****cap*.inf of the Windows driver to me.
|
||||
|
||||
Sometimes the Vendor or Product ID is identical to the ones of Twinhan, even
|
||||
though it is not a Twinhan device (e.g. HAMA), then please send me the name
|
||||
of the device. I will add it to this list in order to make this clear to
|
||||
others.
|
||||
|
||||
If you are familar with C you can also add the VID and PID of the device to
|
||||
the dvb-dibusb-core.c-file and create a patch and send it over to me or to
|
||||
the linux-dvb mailing list, _after_ you have tried compiling and modprobing
|
||||
it.
|
||||
TODO
|
||||
|
||||
2.2. USB1.1 Bandwidth limitation
|
||||
|
||||
Most of the currently supported devices are USB1.1 and thus they have a
|
||||
A lot of the currently supported devices are USB1.1 and thus they have a
|
||||
maximum bandwidth of about 5-6 MBit/s when connected to a USB2.0 hub.
|
||||
This is not enough for receiving the complete transport stream of a
|
||||
DVB-T channel (which can be about 16 MBit/s). Normally this is not a
|
||||
DVB-T channel (which is about 16 MBit/s). Normally this is not a
|
||||
problem, if you only want to watch TV (this does not apply for HDTV),
|
||||
but watching a channel while recording another channel on the same
|
||||
frequency simply does not work very well. This applies to all USB1.1
|
||||
DVB-T devices, not just dibusb)
|
||||
|
||||
Update: For the USB1.1 and VDR some work has been done (patches and comments
|
||||
are still very welcome). Maybe the problem is solved in the meantime because I
|
||||
now use the dmx_sw_filter function instead of dmx_sw_filter_packet. I hope the
|
||||
linux-dvb software filter is able to get the best of the garbled TS.
|
||||
DVB-T devices, not just the dvb-usb-devices)
|
||||
|
||||
The bug, where the TS is distorted by a heavy usage of the device is gone
|
||||
definitely. All dibusb-devices I was using (Twinhan, Kworld, DiBcom) are
|
||||
definitely. All dvb-usb-devices I was using (Twinhan, Kworld, DiBcom) are
|
||||
working like charm now with VDR. Sometimes I even was able to record a channel
|
||||
and watch another one.
|
||||
|
||||
@ -258,7 +274,7 @@ and watch another one.
|
||||
Patches, comments and suggestions are very very welcome.
|
||||
|
||||
3. Acknowledgements
|
||||
Amaury Demol (ademol@dibcom.fr) and Francois Kanounnikoff from DiBcom for
|
||||
Amaury Demol (ademol@dibcom.fr) and Francois Kanounnikoff from DiBcom for
|
||||
providing specs, code and help, on which the dvb-dibusb, dib3000mb and
|
||||
dib3000mc are based.
|
||||
|
||||
@ -270,9 +286,16 @@ Patches, comments and suggestions are very very welcome.
|
||||
|
||||
Bernd Wagner for helping with huge bug reports and discussions.
|
||||
|
||||
Gunnar Wittich and Joachim von Caron for their trust for giving me
|
||||
Gunnar Wittich and Joachim von Caron for their trust for providing
|
||||
root-shells on their machines to implement support for new devices.
|
||||
|
||||
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
|
||||
up and running in Linux.
|
||||
|
||||
Jennifer Chen, Jeff and Jack from Twinhan for kindly supporting by
|
||||
writing the vp7045-driver.
|
||||
|
||||
Some guys on the linux-dvb mailing list for encouraging me
|
||||
|
||||
Peter Schildmann >peter.schildmann-nospam-at-web.de< for his
|
||||
@ -282,4 +305,4 @@ Patches, comments and suggestions are very very welcome.
|
||||
Ulf Hermenau for helping me out with traditional chinese.
|
||||
|
||||
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 patient.
|
@ -66,6 +66,14 @@ Who: Paul E. McKenney <paulmck@us.ibm.com>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: remove verify_area()
|
||||
When: July 2006
|
||||
Files: Various uaccess.h headers.
|
||||
Why: Deprecated and redundant. access_ok() should be used instead.
|
||||
Who: Jesper Juhl <juhl-lkml@dif.dk>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: IEEE1394 Audio and Music Data Transmission Protocol driver,
|
||||
Connection Management Procedures driver
|
||||
When: November 2005
|
||||
@ -86,6 +94,16 @@ Who: Jody McIntyre <scjody@steamballoon.com>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: register_serial/unregister_serial
|
||||
When: December 2005
|
||||
Why: This interface does not allow serial ports to be registered against
|
||||
a struct device, and as such does not allow correct power management
|
||||
of such ports. 8250-based ports should use serial8250_register_port
|
||||
and serial8250_unregister_port instead.
|
||||
Who: Russell King <rmk@arm.linux.org.uk>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: i2c sysfs name change: in1_ref, vid deprecated in favour of cpu0_vid
|
||||
When: November 2005
|
||||
Files: drivers/i2c/chips/adm1025.c, drivers/i2c/chips/adm1026.c
|
||||
|
@ -58,6 +58,8 @@ noacl Don't support POSIX ACLs.
|
||||
|
||||
nobh Do not attach buffer_heads to file pagecache.
|
||||
|
||||
xip Use execute in place (no caching) if possible
|
||||
|
||||
grpquota,noquota,quota,usrquota Quota options are silently ignored by ext2.
|
||||
|
||||
|
||||
|
67
Documentation/filesystems/xip.txt
Normal file
67
Documentation/filesystems/xip.txt
Normal file
@ -0,0 +1,67 @@
|
||||
Execute-in-place for file mappings
|
||||
----------------------------------
|
||||
|
||||
Motivation
|
||||
----------
|
||||
File mappings are performed by mapping page cache pages to userspace. In
|
||||
addition, read&write type file operations also transfer data from/to the page
|
||||
cache.
|
||||
|
||||
For memory backed storage devices that use the block device interface, the page
|
||||
cache pages are in fact copies of the original storage. Various approaches
|
||||
exist to work around the need for an extra copy. The ramdisk driver for example
|
||||
does read the data into the page cache, keeps a reference, and discards the
|
||||
original data behind later on.
|
||||
|
||||
Execute-in-place solves this issue the other way around: instead of keeping
|
||||
data in the page cache, the need to have a page cache copy is eliminated
|
||||
completely. With execute-in-place, read&write type operations are performed
|
||||
directly from/to the memory backed storage device. For file mappings, the
|
||||
storage device itself is mapped directly into userspace.
|
||||
|
||||
This implementation was initialy written for shared memory segments between
|
||||
different virtual machines on s390 hardware to allow multiple machines to
|
||||
share the same binaries and libraries.
|
||||
|
||||
Implementation
|
||||
--------------
|
||||
Execute-in-place is implemented in three steps: block device operation,
|
||||
address space operation, and file operations.
|
||||
|
||||
A block device operation named direct_access is used to retrieve a
|
||||
reference (pointer) to a block on-disk. The reference is supposed to be
|
||||
cpu-addressable, physical address and remain valid until the release operation
|
||||
is performed. A struct block_device reference is used to address the device,
|
||||
and a sector_t argument is used to identify the individual block. As an
|
||||
alternative, memory technology devices can be used for this.
|
||||
|
||||
The block device operation is optional, these block devices support it as of
|
||||
today:
|
||||
- dcssblk: s390 dcss block device driver
|
||||
|
||||
An address space operation named get_xip_page is used to retrieve reference
|
||||
to a struct page. To address the target page, a reference to an address_space,
|
||||
and a sector number is provided. A 3rd argument indicates whether the
|
||||
function should allocate blocks if needed.
|
||||
|
||||
This address space operation is mutually exclusive with readpage&writepage that
|
||||
do page cache read/write operations.
|
||||
The following filesystems support it as of today:
|
||||
- ext2: the second extended filesystem, see Documentation/filesystems/ext2.txt
|
||||
|
||||
A set of file operations that do utilize get_xip_page can be found in
|
||||
mm/filemap_xip.c . The following file operation implementations are provided:
|
||||
- aio_read/aio_write
|
||||
- readv/writev
|
||||
- sendfile
|
||||
|
||||
The generic file operations do_sync_read/do_sync_write can be used to implement
|
||||
classic synchronous IO calls.
|
||||
|
||||
Shortcomings
|
||||
------------
|
||||
This implementation is limited to storage devices that are cpu addressable at
|
||||
all times (no highmem or such). It works well on rom/ram, but enhancements are
|
||||
needed to make it work with flash in read+write mode.
|
||||
Putting the Linux kernel and/or its modules on a xip filesystem does not mean
|
||||
they are not copied.
|
@ -22,6 +22,7 @@ This document has the following sections:
|
||||
- New procfs files
|
||||
- Userspace system call interface
|
||||
- Kernel services
|
||||
- Notes on accessing payload contents
|
||||
- Defining a key type
|
||||
- Request-key callback service
|
||||
- Key access filesystem
|
||||
@ -45,27 +46,26 @@ Each key has a number of attributes:
|
||||
- State.
|
||||
|
||||
|
||||
(*) Each key is issued a serial number of type key_serial_t that is unique
|
||||
for the lifetime of that key. All serial numbers are positive non-zero
|
||||
32-bit integers.
|
||||
(*) Each key is issued a serial number of type key_serial_t that is unique for
|
||||
the lifetime of that key. All serial numbers are positive non-zero 32-bit
|
||||
integers.
|
||||
|
||||
Userspace programs can use a key's serial numbers as a way to gain access
|
||||
to it, subject to permission checking.
|
||||
|
||||
(*) Each key is of a defined "type". Types must be registered inside the
|
||||
kernel by a kernel service (such as a filesystem) before keys of that
|
||||
type can be added or used. Userspace programs cannot define new types
|
||||
directly.
|
||||
kernel by a kernel service (such as a filesystem) before keys of that type
|
||||
can be added or used. Userspace programs cannot define new types directly.
|
||||
|
||||
Key types are represented in the kernel by struct key_type. This defines
|
||||
a number of operations that can be performed on a key of that type.
|
||||
Key types are represented in the kernel by struct key_type. This defines a
|
||||
number of operations that can be performed on a key of that type.
|
||||
|
||||
Should a type be removed from the system, all the keys of that type will
|
||||
be invalidated.
|
||||
|
||||
(*) Each key has a description. This should be a printable string. The key
|
||||
type provides an operation to perform a match between the description on
|
||||
a key and a criterion string.
|
||||
type provides an operation to perform a match between the description on a
|
||||
key and a criterion string.
|
||||
|
||||
(*) Each key has an owner user ID, a group ID and a permissions mask. These
|
||||
are used to control what a process may do to a key from userspace, and
|
||||
@ -74,10 +74,10 @@ Each key has a number of attributes:
|
||||
(*) Each key can be set to expire at a specific time by the key type's
|
||||
instantiation function. Keys can also be immortal.
|
||||
|
||||
(*) Each key can have a payload. This is a quantity of data that represent
|
||||
the actual "key". In the case of a keyring, this is a list of keys to
|
||||
which the keyring links; in the case of a user-defined key, it's an
|
||||
arbitrary blob of data.
|
||||
(*) Each key can have a payload. This is a quantity of data that represent the
|
||||
actual "key". In the case of a keyring, this is a list of keys to which
|
||||
the keyring links; in the case of a user-defined key, it's an arbitrary
|
||||
blob of data.
|
||||
|
||||
Having a payload is not required; and the payload can, in fact, just be a
|
||||
value stored in the struct key itself.
|
||||
@ -92,8 +92,8 @@ Each key has a number of attributes:
|
||||
|
||||
(*) Each key can be in one of a number of basic states:
|
||||
|
||||
(*) Uninstantiated. The key exists, but does not have any data
|
||||
attached. Keys being requested from userspace will be in this state.
|
||||
(*) Uninstantiated. The key exists, but does not have any data attached.
|
||||
Keys being requested from userspace will be in this state.
|
||||
|
||||
(*) Instantiated. This is the normal state. The key is fully formed, and
|
||||
has data attached.
|
||||
@ -140,10 +140,10 @@ The key service provides a number of features besides keys:
|
||||
clone, fork, vfork or execve occurs. A new keyring is created only when
|
||||
required.
|
||||
|
||||
The process-specific keyring is replaced with an empty one in the child
|
||||
on clone, fork, vfork unless CLONE_THREAD is supplied, in which case it
|
||||
is shared. execve also discards the process's process keyring and creates
|
||||
a new one.
|
||||
The process-specific keyring is replaced with an empty one in the child on
|
||||
clone, fork, vfork unless CLONE_THREAD is supplied, in which case it is
|
||||
shared. execve also discards the process's process keyring and creates a
|
||||
new one.
|
||||
|
||||
The session-specific keyring is persistent across clone, fork, vfork and
|
||||
execve, even when the latter executes a set-UID or set-GID binary. A
|
||||
@ -177,11 +177,11 @@ The key service provides a number of features besides keys:
|
||||
If a system call that modifies a key or keyring in some way would put the
|
||||
user over quota, the operation is refused and error EDQUOT is returned.
|
||||
|
||||
(*) There's a system call interface by which userspace programs can create
|
||||
and manipulate keys and keyrings.
|
||||
(*) There's a system call interface by which userspace programs can create and
|
||||
manipulate keys and keyrings.
|
||||
|
||||
(*) There's a kernel interface by which services can register types and
|
||||
search for keys.
|
||||
(*) There's a kernel interface by which services can register types and search
|
||||
for keys.
|
||||
|
||||
(*) There's a way for the a search done from the kernel to call back to
|
||||
userspace to request a key that can't be found in a process's keyrings.
|
||||
@ -194,9 +194,9 @@ The key service provides a number of features besides keys:
|
||||
KEY ACCESS PERMISSIONS
|
||||
======================
|
||||
|
||||
Keys have an owner user ID, a group access ID, and a permissions mask. The
|
||||
mask has up to eight bits each for user, group and other access. Only five of
|
||||
each set of eight bits are defined. These permissions granted are:
|
||||
Keys have an owner user ID, a group access ID, and a permissions mask. The mask
|
||||
has up to eight bits each for user, group and other access. Only five of each
|
||||
set of eight bits are defined. These permissions granted are:
|
||||
|
||||
(*) View
|
||||
|
||||
@ -210,8 +210,8 @@ each set of eight bits are defined. These permissions granted are:
|
||||
|
||||
(*) Write
|
||||
|
||||
This permits a key's payload to be instantiated or updated, or it allows
|
||||
a link to be added to or removed from a keyring.
|
||||
This permits a key's payload to be instantiated or updated, or it allows a
|
||||
link to be added to or removed from a keyring.
|
||||
|
||||
(*) Search
|
||||
|
||||
@ -238,8 +238,8 @@ about the status of the key service:
|
||||
(*) /proc/keys
|
||||
|
||||
This lists all the keys on the system, giving information about their
|
||||
type, description and permissions. The payload of the key is not
|
||||
available this way:
|
||||
type, description and permissions. The payload of the key is not available
|
||||
this way:
|
||||
|
||||
SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY
|
||||
00000001 I----- 39 perm 1f0000 0 0 keyring _uid_ses.0: 1/4
|
||||
@ -318,21 +318,21 @@ The main syscalls are:
|
||||
If a key of the same type and description as that proposed already exists
|
||||
in the keyring, this will try to update it with the given payload, or it
|
||||
will return error EEXIST if that function is not supported by the key
|
||||
type. The process must also have permission to write to the key to be
|
||||
able to update it. The new key will have all user permissions granted and
|
||||
no group or third party permissions.
|
||||
type. The process must also have permission to write to the key to be able
|
||||
to update it. The new key will have all user permissions granted and no
|
||||
group or third party permissions.
|
||||
|
||||
Otherwise, this will attempt to create a new key of the specified type
|
||||
and description, and to instantiate it with the supplied payload and
|
||||
attach it to the keyring. In this case, an error will be generated if the
|
||||
process does not have permission to write to the keyring.
|
||||
Otherwise, this will attempt to create a new key of the specified type and
|
||||
description, and to instantiate it with the supplied payload and attach it
|
||||
to the keyring. In this case, an error will be generated if the process
|
||||
does not have permission to write to the keyring.
|
||||
|
||||
The payload is optional, and the pointer can be NULL if not required by
|
||||
the type. The payload is plen in size, and plen can be zero for an empty
|
||||
payload.
|
||||
|
||||
A new keyring can be generated by setting type "keyring", the keyring
|
||||
name as the description (or NULL) and setting the payload to NULL.
|
||||
A new keyring can be generated by setting type "keyring", the keyring name
|
||||
as the description (or NULL) and setting the payload to NULL.
|
||||
|
||||
User defined keys can be created by specifying type "user". It is
|
||||
recommended that a user defined key's description by prefixed with a type
|
||||
@ -369,9 +369,9 @@ The keyctl syscall functions are:
|
||||
key_serial_t keyctl(KEYCTL_GET_KEYRING_ID, key_serial_t id,
|
||||
int create);
|
||||
|
||||
The special key specified by "id" is looked up (with the key being
|
||||
created if necessary) and the ID of the key or keyring thus found is
|
||||
returned if it exists.
|
||||
The special key specified by "id" is looked up (with the key being created
|
||||
if necessary) and the ID of the key or keyring thus found is returned if
|
||||
it exists.
|
||||
|
||||
If the key does not yet exist, the key will be created if "create" is
|
||||
non-zero; and the error ENOKEY will be returned if "create" is zero.
|
||||
@ -402,8 +402,8 @@ The keyctl syscall functions are:
|
||||
|
||||
This will try to update the specified key with the given payload, or it
|
||||
will return error EOPNOTSUPP if that function is not supported by the key
|
||||
type. The process must also have permission to write to the key to be
|
||||
able to update it.
|
||||
type. The process must also have permission to write to the key to be able
|
||||
to update it.
|
||||
|
||||
The payload is of length plen, and may be absent or empty as for
|
||||
add_key().
|
||||
@ -422,8 +422,8 @@ The keyctl syscall functions are:
|
||||
|
||||
long keyctl(KEYCTL_CHOWN, key_serial_t key, uid_t uid, gid_t gid);
|
||||
|
||||
This function permits a key's owner and group ID to be changed. Either
|
||||
one of uid or gid can be set to -1 to suppress that change.
|
||||
This function permits a key's owner and group ID to be changed. Either one
|
||||
of uid or gid can be set to -1 to suppress that change.
|
||||
|
||||
Only the superuser can change a key's owner to something other than the
|
||||
key's current owner. Similarly, only the superuser can change a key's
|
||||
@ -484,12 +484,12 @@ The keyctl syscall functions are:
|
||||
|
||||
long keyctl(KEYCTL_LINK, key_serial_t keyring, key_serial_t key);
|
||||
|
||||
This function creates a link from the keyring to the key. The process
|
||||
must have write permission on the keyring and must have link permission
|
||||
on the key.
|
||||
This function creates a link from the keyring to the key. The process must
|
||||
have write permission on the keyring and must have link permission on the
|
||||
key.
|
||||
|
||||
Should the keyring not be a keyring, error ENOTDIR will result; and if
|
||||
the keyring is full, error ENFILE will result.
|
||||
Should the keyring not be a keyring, error ENOTDIR will result; and if the
|
||||
keyring is full, error ENFILE will result.
|
||||
|
||||
The link procedure checks the nesting of the keyrings, returning ELOOP if
|
||||
it appears to deep or EDEADLK if the link would introduce a cycle.
|
||||
@ -503,8 +503,8 @@ The keyctl syscall functions are:
|
||||
specified key, and removes it if found. Subsequent links to that key are
|
||||
ignored. The process must have write permission on the keyring.
|
||||
|
||||
If the keyring is not a keyring, error ENOTDIR will result; and if the
|
||||
key is not present, error ENOENT will be the result.
|
||||
If the keyring is not a keyring, error ENOTDIR will result; and if the key
|
||||
is not present, error ENOENT will be the result.
|
||||
|
||||
|
||||
(*) Search a keyring tree for a key:
|
||||
@ -513,9 +513,9 @@ The keyctl syscall functions are:
|
||||
const char *type, const char *description,
|
||||
key_serial_t dest_keyring);
|
||||
|
||||
This searches the keyring tree headed by the specified keyring until a
|
||||
key is found that matches the type and description criteria. Each keyring
|
||||
is checked for keys before recursion into its children occurs.
|
||||
This searches the keyring tree headed by the specified keyring until a key
|
||||
is found that matches the type and description criteria. Each keyring is
|
||||
checked for keys before recursion into its children occurs.
|
||||
|
||||
The process must have search permission on the top level keyring, or else
|
||||
error EACCES will result. Only keyrings that the process has search
|
||||
@ -549,8 +549,8 @@ The keyctl syscall functions are:
|
||||
As much of the data as can be fitted into the buffer will be copied to
|
||||
userspace if the buffer pointer is not NULL.
|
||||
|
||||
On a successful return, the function will always return the amount of
|
||||
data available rather than the amount copied.
|
||||
On a successful return, the function will always return the amount of data
|
||||
available rather than the amount copied.
|
||||
|
||||
|
||||
(*) Instantiate a partially constructed key.
|
||||
@ -568,8 +568,8 @@ The keyctl syscall functions are:
|
||||
it, and the key must be uninstantiated.
|
||||
|
||||
If a keyring is specified (non-zero), the key will also be linked into
|
||||
that keyring, however all the constraints applying in KEYCTL_LINK apply
|
||||
in this case too.
|
||||
that keyring, however all the constraints applying in KEYCTL_LINK apply in
|
||||
this case too.
|
||||
|
||||
The payload and plen arguments describe the payload data as for add_key().
|
||||
|
||||
@ -587,8 +587,39 @@ The keyctl syscall functions are:
|
||||
it, and the key must be uninstantiated.
|
||||
|
||||
If a keyring is specified (non-zero), the key will also be linked into
|
||||
that keyring, however all the constraints applying in KEYCTL_LINK apply
|
||||
in this case too.
|
||||
that keyring, however all the constraints applying in KEYCTL_LINK apply in
|
||||
this case too.
|
||||
|
||||
|
||||
(*) Set the default request-key destination keyring.
|
||||
|
||||
long keyctl(KEYCTL_SET_REQKEY_KEYRING, int reqkey_defl);
|
||||
|
||||
This sets the default keyring to which implicitly requested keys will be
|
||||
attached for this thread. reqkey_defl should be one of these constants:
|
||||
|
||||
CONSTANT VALUE NEW DEFAULT KEYRING
|
||||
====================================== ====== =======================
|
||||
KEY_REQKEY_DEFL_NO_CHANGE -1 No change
|
||||
KEY_REQKEY_DEFL_DEFAULT 0 Default[1]
|
||||
KEY_REQKEY_DEFL_THREAD_KEYRING 1 Thread keyring
|
||||
KEY_REQKEY_DEFL_PROCESS_KEYRING 2 Process keyring
|
||||
KEY_REQKEY_DEFL_SESSION_KEYRING 3 Session keyring
|
||||
KEY_REQKEY_DEFL_USER_KEYRING 4 User keyring
|
||||
KEY_REQKEY_DEFL_USER_SESSION_KEYRING 5 User session keyring
|
||||
KEY_REQKEY_DEFL_GROUP_KEYRING 6 Group keyring
|
||||
|
||||
The old default will be returned if successful and error EINVAL will be
|
||||
returned if reqkey_defl is not one of the above values.
|
||||
|
||||
The default keyring can be overridden by the keyring indicated to the
|
||||
request_key() system call.
|
||||
|
||||
Note that this setting is inherited across fork/exec.
|
||||
|
||||
[1] The default default is: the thread keyring if there is one, otherwise
|
||||
the process keyring if there is one, otherwise the session keyring if
|
||||
there is one, otherwise the user default session keyring.
|
||||
|
||||
|
||||
===============
|
||||
@ -601,17 +632,14 @@ be broken down into two areas: keys and key types.
|
||||
Dealing with keys is fairly straightforward. Firstly, the kernel service
|
||||
registers its type, then it searches for a key of that type. It should retain
|
||||
the key as long as it has need of it, and then it should release it. For a
|
||||
filesystem or device file, a search would probably be performed during the
|
||||
open call, and the key released upon close. How to deal with conflicting keys
|
||||
due to two different users opening the same file is left to the filesystem
|
||||
author to solve.
|
||||
filesystem or device file, a search would probably be performed during the open
|
||||
call, and the key released upon close. How to deal with conflicting keys due to
|
||||
two different users opening the same file is left to the filesystem author to
|
||||
solve.
|
||||
|
||||
When accessing a key's payload data, key->lock should be at least read locked,
|
||||
or else the data may be changed by an update being performed from userspace
|
||||
whilst the driver or filesystem is trying to access it. If no update method is
|
||||
supplied, then the key's payload may be accessed without holding a lock as
|
||||
there is no way to change it, provided it can be guaranteed that the key's
|
||||
type definition won't go away.
|
||||
When accessing a key's payload contents, certain precautions must be taken to
|
||||
prevent access vs modification races. See the section "Notes on accessing
|
||||
payload contents" for more information.
|
||||
|
||||
(*) To search for a key, call:
|
||||
|
||||
@ -629,6 +657,9 @@ type definition won't go away.
|
||||
Should the function fail error ENOKEY, EKEYEXPIRED or EKEYREVOKED will be
|
||||
returned.
|
||||
|
||||
If successful, the key will have been attached to the default keyring for
|
||||
implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING.
|
||||
|
||||
|
||||
(*) When it is no longer required, the key should be released using:
|
||||
|
||||
@ -690,6 +721,54 @@ type definition won't go away.
|
||||
void unregister_key_type(struct key_type *type);
|
||||
|
||||
|
||||
===================================
|
||||
NOTES ON ACCESSING PAYLOAD CONTENTS
|
||||
===================================
|
||||
|
||||
The simplest payload is just a number in key->payload.value. In this case,
|
||||
there's no need to indulge in RCU or locking when accessing the payload.
|
||||
|
||||
More complex payload contents must be allocated and a pointer to them set in
|
||||
key->payload.data. One of the following ways must be selected to access the
|
||||
data:
|
||||
|
||||
(1) Unmodifyable key type.
|
||||
|
||||
If the key type does not have a modify method, then the key's payload can
|
||||
be accessed without any form of locking, provided that it's known to be
|
||||
instantiated (uninstantiated keys cannot be "found").
|
||||
|
||||
(2) The key's semaphore.
|
||||
|
||||
The semaphore could be used to govern access to the payload and to control
|
||||
the payload pointer. It must be write-locked for modifications and would
|
||||
have to be read-locked for general access. The disadvantage of doing this
|
||||
is that the accessor may be required to sleep.
|
||||
|
||||
(3) RCU.
|
||||
|
||||
RCU must be used when the semaphore isn't already held; if the semaphore
|
||||
is held then the contents can't change under you unexpectedly as the
|
||||
semaphore must still be used to serialise modifications to the key. The
|
||||
key management code takes care of this for the key type.
|
||||
|
||||
However, this means using:
|
||||
|
||||
rcu_read_lock() ... rcu_dereference() ... rcu_read_unlock()
|
||||
|
||||
to read the pointer, and:
|
||||
|
||||
rcu_dereference() ... rcu_assign_pointer() ... call_rcu()
|
||||
|
||||
to set the pointer and dispose of the old contents after a grace period.
|
||||
Note that only the key type should ever modify a key's payload.
|
||||
|
||||
Furthermore, an RCU controlled payload must hold a struct rcu_head for the
|
||||
use of call_rcu() and, if the payload is of variable size, the length of
|
||||
the payload. key->datalen cannot be relied upon to be consistent with the
|
||||
payload just dereferenced if the key's semaphore is not held.
|
||||
|
||||
|
||||
===================
|
||||
DEFINING A KEY TYPE
|
||||
===================
|
||||
@ -717,15 +796,15 @@ The structure has a number of fields, some of which are mandatory:
|
||||
|
||||
int key_payload_reserve(struct key *key, size_t datalen);
|
||||
|
||||
With the revised data length. Error EDQUOT will be returned if this is
|
||||
not viable.
|
||||
With the revised data length. Error EDQUOT will be returned if this is not
|
||||
viable.
|
||||
|
||||
|
||||
(*) int (*instantiate)(struct key *key, const void *data, size_t datalen);
|
||||
|
||||
This method is called to attach a payload to a key during construction.
|
||||
The payload attached need not bear any relation to the data passed to
|
||||
this function.
|
||||
The payload attached need not bear any relation to the data passed to this
|
||||
function.
|
||||
|
||||
If the amount of data attached to the key differs from the size in
|
||||
keytype->def_datalen, then key_payload_reserve() should be called.
|
||||
@ -734,38 +813,47 @@ The structure has a number of fields, some of which are mandatory:
|
||||
The fact that KEY_FLAG_INSTANTIATED is not set in key->flags prevents
|
||||
anything else from gaining access to the key.
|
||||
|
||||
This method may sleep if it wishes.
|
||||
It is safe to sleep in this method.
|
||||
|
||||
|
||||
(*) int (*duplicate)(struct key *key, const struct key *source);
|
||||
|
||||
If this type of key can be duplicated, then this method should be
|
||||
provided. It is called to copy the payload attached to the source into
|
||||
the new key. The data length on the new key will have been updated and
|
||||
the quota adjusted already.
|
||||
provided. It is called to copy the payload attached to the source into the
|
||||
new key. The data length on the new key will have been updated and the
|
||||
quota adjusted already.
|
||||
|
||||
This method will be called with the source key's semaphore read-locked to
|
||||
prevent its payload from being changed. It is safe to sleep here.
|
||||
prevent its payload from being changed, thus RCU constraints need not be
|
||||
applied to the source key.
|
||||
|
||||
This method does not have to lock the destination key in order to attach a
|
||||
payload. The fact that KEY_FLAG_INSTANTIATED is not set in key->flags
|
||||
prevents anything else from gaining access to the key.
|
||||
|
||||
It is safe to sleep in this method.
|
||||
|
||||
|
||||
(*) int (*update)(struct key *key, const void *data, size_t datalen);
|
||||
|
||||
If this type of key can be updated, then this method should be
|
||||
provided. It is called to update a key's payload from the blob of data
|
||||
provided.
|
||||
If this type of key can be updated, then this method should be provided.
|
||||
It is called to update a key's payload from the blob of data provided.
|
||||
|
||||
key_payload_reserve() should be called if the data length might change
|
||||
before any changes are actually made. Note that if this succeeds, the
|
||||
type is committed to changing the key because it's already been altered,
|
||||
so all memory allocation must be done first.
|
||||
before any changes are actually made. Note that if this succeeds, the type
|
||||
is committed to changing the key because it's already been altered, so all
|
||||
memory allocation must be done first.
|
||||
|
||||
key_payload_reserve() should be called with the key->lock write locked,
|
||||
and the changes to the key's attached payload should be made before the
|
||||
key is locked.
|
||||
The key will have its semaphore write-locked before this method is called,
|
||||
but this only deters other writers; any changes to the key's payload must
|
||||
be made under RCU conditions, and call_rcu() must be used to dispose of
|
||||
the old payload.
|
||||
|
||||
The key will have its semaphore write-locked before this method is
|
||||
called. Any changes to the key should be made with the key's rwlock
|
||||
write-locked also. It is safe to sleep here.
|
||||
key_payload_reserve() should be called before the changes are made, but
|
||||
after all allocations and other potentially failing function calls are
|
||||
made.
|
||||
|
||||
It is safe to sleep in this method.
|
||||
|
||||
|
||||
(*) int (*match)(const struct key *key, const void *desc);
|
||||
@ -782,12 +870,12 @@ The structure has a number of fields, some of which are mandatory:
|
||||
|
||||
(*) void (*destroy)(struct key *key);
|
||||
|
||||
This method is optional. It is called to discard the payload data on a
|
||||
key when it is being destroyed.
|
||||
This method is optional. It is called to discard the payload data on a key
|
||||
when it is being destroyed.
|
||||
|
||||
This method does not need to lock the key; it can consider the key as
|
||||
being inaccessible. Note that the key's type may have changed before this
|
||||
function is called.
|
||||
This method does not need to lock the key to access the payload; it can
|
||||
consider the key as being inaccessible at this time. Note that the key's
|
||||
type may have been changed before this function is called.
|
||||
|
||||
It is not safe to sleep in this method; the caller may hold spinlocks.
|
||||
|
||||
@ -797,26 +885,31 @@ The structure has a number of fields, some of which are mandatory:
|
||||
This method is optional. It is called during /proc/keys reading to
|
||||
summarise a key's description and payload in text form.
|
||||
|
||||
This method will be called with the key's rwlock read-locked. This will
|
||||
prevent the key's payload and state changing; also the description should
|
||||
not change. This also means it is not safe to sleep in this method.
|
||||
This method will be called with the RCU read lock held. rcu_dereference()
|
||||
should be used to read the payload pointer if the payload is to be
|
||||
accessed. key->datalen cannot be trusted to stay consistent with the
|
||||
contents of the payload.
|
||||
|
||||
The description will not change, though the key's state may.
|
||||
|
||||
It is not safe to sleep in this method; the RCU read lock is held by the
|
||||
caller.
|
||||
|
||||
|
||||
(*) long (*read)(const struct key *key, char __user *buffer, size_t buflen);
|
||||
|
||||
This method is optional. It is called by KEYCTL_READ to translate the
|
||||
key's payload into something a blob of data for userspace to deal
|
||||
with. Ideally, the blob should be in the same format as that passed in to
|
||||
the instantiate and update methods.
|
||||
key's payload into something a blob of data for userspace to deal with.
|
||||
Ideally, the blob should be in the same format as that passed in to the
|
||||
instantiate and update methods.
|
||||
|
||||
If successful, the blob size that could be produced should be returned
|
||||
rather than the size copied.
|
||||
|
||||
This method will be called with the key's semaphore read-locked. This
|
||||
will prevent the key's payload changing. It is not necessary to also
|
||||
read-lock key->lock when accessing the key's payload. It is safe to sleep
|
||||
in this method, such as might happen when the userspace buffer is
|
||||
accessed.
|
||||
This method will be called with the key's semaphore read-locked. This will
|
||||
prevent the key's payload changing. It is not necessary to use RCU locking
|
||||
when accessing the key's payload. It is safe to sleep in this method, such
|
||||
as might happen when the userspace buffer is accessed.
|
||||
|
||||
|
||||
============================
|
||||
@ -853,8 +946,8 @@ If it returns with the key remaining in the unconstructed state, the key will
|
||||
be marked as being negative, it will be added to the session keyring, and an
|
||||
error will be returned to the key requestor.
|
||||
|
||||
Supplementary information may be provided from whoever or whatever invoked
|
||||
this service. This will be passed as the <callout_info> parameter. If no such
|
||||
Supplementary information may be provided from whoever or whatever invoked this
|
||||
service. This will be passed as the <callout_info> parameter. If no such
|
||||
information was made available, then "-" will be passed as this parameter
|
||||
instead.
|
||||
|
||||
|
@ -304,57 +304,6 @@ tcp_low_latency - BOOLEAN
|
||||
changed would be a Beowulf compute cluster.
|
||||
Default: 0
|
||||
|
||||
tcp_westwood - BOOLEAN
|
||||
Enable TCP Westwood+ congestion control algorithm.
|
||||
TCP Westwood+ is a sender-side only modification of the TCP Reno
|
||||
protocol stack that optimizes the performance of TCP congestion
|
||||
control. It is based on end-to-end bandwidth estimation to set
|
||||
congestion window and slow start threshold after a congestion
|
||||
episode. Using this estimation, TCP Westwood+ adaptively sets a
|
||||
slow start threshold and a congestion window which takes into
|
||||
account the bandwidth used at the time congestion is experienced.
|
||||
TCP Westwood+ significantly increases fairness wrt TCP Reno in
|
||||
wired networks and throughput over wireless links.
|
||||
Default: 0
|
||||
|
||||
tcp_vegas_cong_avoid - BOOLEAN
|
||||
Enable TCP Vegas congestion avoidance algorithm.
|
||||
TCP Vegas is a sender-side only change to TCP that anticipates
|
||||
the onset of congestion by estimating the bandwidth. TCP Vegas
|
||||
adjusts the sending rate by modifying the congestion
|
||||
window. TCP Vegas should provide less packet loss, but it is
|
||||
not as aggressive as TCP Reno.
|
||||
Default:0
|
||||
|
||||
tcp_bic - BOOLEAN
|
||||
Enable BIC TCP congestion control algorithm.
|
||||
BIC-TCP is a sender-side only change that ensures a linear RTT
|
||||
fairness under large windows while offering both scalability and
|
||||
bounded TCP-friendliness. The protocol combines two schemes
|
||||
called additive increase and binary search increase. When the
|
||||
congestion window is large, additive increase with a large
|
||||
increment ensures linear RTT fairness as well as good
|
||||
scalability. Under small congestion windows, binary search
|
||||
increase provides TCP friendliness.
|
||||
Default: 0
|
||||
|
||||
tcp_bic_low_window - INTEGER
|
||||
Sets the threshold window (in packets) where BIC TCP starts to
|
||||
adjust the congestion window. Below this threshold BIC TCP behaves
|
||||
the same as the default TCP Reno.
|
||||
Default: 14
|
||||
|
||||
tcp_bic_fast_convergence - BOOLEAN
|
||||
Forces BIC TCP to more quickly respond to changes in congestion
|
||||
window. Allows two flows sharing the same connection to converge
|
||||
more rapidly.
|
||||
Default: 1
|
||||
|
||||
tcp_default_win_scale - INTEGER
|
||||
Sets the minimum window scale TCP will negotiate for on all
|
||||
conections.
|
||||
Default: 7
|
||||
|
||||
tcp_tso_win_divisor - INTEGER
|
||||
This allows control over what percentage of the congestion window
|
||||
can be consumed by a single TSO frame.
|
||||
@ -368,6 +317,11 @@ tcp_frto - BOOLEAN
|
||||
where packet loss is typically due to random radio interference
|
||||
rather than intermediate router congestion.
|
||||
|
||||
tcp_congestion_control - STRING
|
||||
Set the congestion control algorithm to be used for new
|
||||
connections. The algorithm "reno" is always available, but
|
||||
additional choices may be available based on kernel configuration.
|
||||
|
||||
somaxconn - INTEGER
|
||||
Limit of socket listen() backlog, known in userspace as SOMAXCONN.
|
||||
Defaults to 128. See also tcp_max_syn_backlog for additional tuning
|
||||
|
@ -1,5 +1,72 @@
|
||||
How the new TCP output machine [nyi] works.
|
||||
TCP protocol
|
||||
============
|
||||
|
||||
Last updated: 21 June 2005
|
||||
|
||||
Contents
|
||||
========
|
||||
|
||||
- Congestion control
|
||||
- How the new TCP output machine [nyi] works
|
||||
|
||||
Congestion control
|
||||
==================
|
||||
|
||||
The following variables are used in the tcp_sock for congestion control:
|
||||
snd_cwnd The size of the congestion window
|
||||
snd_ssthresh Slow start threshold. We are in slow start if
|
||||
snd_cwnd is less than this.
|
||||
snd_cwnd_cnt A counter used to slow down the rate of increase
|
||||
once we exceed slow start threshold.
|
||||
snd_cwnd_clamp This is the maximum size that snd_cwnd can grow to.
|
||||
snd_cwnd_stamp Timestamp for when congestion window last validated.
|
||||
snd_cwnd_used Used as a highwater mark for how much of the
|
||||
congestion window is in use. It is used to adjust
|
||||
snd_cwnd down when the link is limited by the
|
||||
application rather than the network.
|
||||
|
||||
As of 2.6.13, Linux supports pluggable congestion control algorithms.
|
||||
A congestion control mechanism can be registered through functions in
|
||||
tcp_cong.c. The functions used by the congestion control mechanism are
|
||||
registered via passing a tcp_congestion_ops struct to
|
||||
tcp_register_congestion_control. As a minimum name, ssthresh,
|
||||
cong_avoid, min_cwnd must be valid.
|
||||
|
||||
Private data for a congestion control mechanism is stored in tp->ca_priv.
|
||||
tcp_ca(tp) returns a pointer to this space. This is preallocated space - it
|
||||
is important to check the size of your private data will fit this space, or
|
||||
alternatively space could be allocated elsewhere and a pointer to it could
|
||||
be stored here.
|
||||
|
||||
There are three kinds of congestion control algorithms currently: The
|
||||
simplest ones are derived from TCP reno (highspeed, scalable) and just
|
||||
provide an alternative the congestion window calculation. More complex
|
||||
ones like BIC try to look at other events to provide better
|
||||
heuristics. There are also round trip time based algorithms like
|
||||
Vegas and Westwood+.
|
||||
|
||||
Good TCP congestion control is a complex problem because the algorithm
|
||||
needs to maintain fairness and performance. Please review current
|
||||
research and RFC's before developing new modules.
|
||||
|
||||
The method that is used to determine which congestion control mechanism is
|
||||
determined by the setting of the sysctl net.ipv4.tcp_congestion_control.
|
||||
The default congestion control will be the last one registered (LIFO);
|
||||
so if you built everything as modules. the default will be reno. If you
|
||||
build with the default's from Kconfig, then BIC will be builtin (not a module)
|
||||
and it will end up the default.
|
||||
|
||||
If you really want a particular default value then you will need
|
||||
to set it with the sysctl. If you use a sysctl, the module will be autoloaded
|
||||
if needed and you will get the expected protocol. If you ask for an
|
||||
unknown congestion method, then the sysctl attempt will fail.
|
||||
|
||||
If you remove a tcp congestion control module, then you will get the next
|
||||
available one. Since reno can not be built as a module, and can not be
|
||||
deleted, it will always be available.
|
||||
|
||||
How the new TCP output machine [nyi] works.
|
||||
===========================================
|
||||
|
||||
Data is kept on a single queue. The skb->users flag tells us if the frame is
|
||||
one that has been queued already. To add a frame we throw it on the end. Ack
|
||||
|
@ -49,6 +49,7 @@ show up in /proc/sys/kernel:
|
||||
- shmmax [ sysv ipc ]
|
||||
- shmmni
|
||||
- stop-a [ SPARC only ]
|
||||
- suid_dumpable
|
||||
- sysrq ==> Documentation/sysrq.txt
|
||||
- tainted
|
||||
- threads-max
|
||||
@ -300,6 +301,25 @@ kernel. This value defaults to SHMMAX.
|
||||
|
||||
==============================================================
|
||||
|
||||
suid_dumpable:
|
||||
|
||||
This value can be used to query and set the core dump mode for setuid
|
||||
or otherwise protected/tainted binaries. The modes are
|
||||
|
||||
0 - (default) - traditional behaviour. Any process which has changed
|
||||
privilege levels or is execute only will not be dumped
|
||||
1 - (debug) - all processes dump core when possible. The core dump is
|
||||
owned by the current user and no security is applied. This is
|
||||
intended for system debugging situations only. Ptrace is unchecked.
|
||||
2 - (suidsafe) - any binary which normally would not be dumped is dumped
|
||||
readable by root only. This allows the end user to remove
|
||||
such a dump but not access it directly. For security reasons
|
||||
core dumps in this mode will not overwrite one another or
|
||||
other files. This mode is appropriate when adminstrators are
|
||||
attempting to debug problems in a normal environment.
|
||||
|
||||
==============================================================
|
||||
|
||||
tainted:
|
||||
|
||||
Non-zero if the kernel has been tainted. Numeric values, which
|
||||
|
@ -22,7 +22,7 @@ copy of the structure. You must not re-register over the top of the line
|
||||
discipline even with the same data or your computer again will be eaten by
|
||||
demons.
|
||||
|
||||
In order to remove a line discipline call tty_register_ldisc passing NULL.
|
||||
In order to remove a line discipline call tty_unregister_ldisc().
|
||||
In ancient times this always worked. In modern times the function will
|
||||
return -EBUSY if the ldisc is currently in use. Since the ldisc referencing
|
||||
code manages the module counts this should not usually be a concern.
|
||||
|
@ -119,3 +119,17 @@ card=117 - NGS NGSTV+
|
||||
card=118 - LMLBT4
|
||||
card=119 - Tekram M205 PRO
|
||||
card=120 - Conceptronic CONTVFMi
|
||||
card=121 - Euresys Picolo Tetra
|
||||
card=122 - Spirit TV Tuner
|
||||
card=123 - AVerMedia AVerTV DVB-T 771
|
||||
card=124 - AverMedia AverTV DVB-T 761
|
||||
card=125 - MATRIX Vision Sigma-SQ
|
||||
card=126 - MATRIX Vision Sigma-SLC
|
||||
card=127 - APAC Viewcomp 878(AMAX)
|
||||
card=128 - DVICO FusionHDTV DVB-T Lite
|
||||
card=129 - V-Gear MyVCD
|
||||
card=130 - Super TV Tuner
|
||||
card=131 - Tibet Systems 'Progress DVR' CS16
|
||||
card=132 - Kodicom 4400R (master)
|
||||
card=133 - Kodicom 4400R (slave)
|
||||
card=134 - Adlink RTV24
|
||||
|
29
Documentation/video4linux/CARDLIST.cx88
Normal file
29
Documentation/video4linux/CARDLIST.cx88
Normal file
@ -0,0 +1,29 @@
|
||||
card=0 - UNKNOWN/GENERIC
|
||||
card=1 - Hauppauge WinTV 34xxx models
|
||||
card=2 - GDI Black Gold
|
||||
card=3 - PixelView
|
||||
card=4 - ATI TV Wonder Pro
|
||||
card=5 - Leadtek Winfast 2000XP Expert
|
||||
card=6 - AverTV Studio 303 (M126)
|
||||
card=7 - MSI TV-@nywhere Master
|
||||
card=8 - Leadtek Winfast DV2000
|
||||
card=9 - Leadtek PVR 2000
|
||||
card=10 - IODATA GV-VCP3/PCI
|
||||
card=11 - Prolink PlayTV PVR
|
||||
card=12 - ASUS PVR-416
|
||||
card=13 - MSI TV-@nywhere
|
||||
card=14 - KWorld/VStream XPert DVB-T
|
||||
card=15 - DVICO FusionHDTV DVB-T1
|
||||
card=16 - KWorld LTV883RF
|
||||
card=17 - DViCO - FusionHDTV 3 Gold
|
||||
card=18 - Hauppauge Nova-T DVB-T
|
||||
card=19 - Conexant DVB-T reference design
|
||||
card=20 - Provideo PV259
|
||||
card=21 - DVICO FusionHDTV DVB-T Plus
|
||||
card=22 - digitalnow DNTV Live! DVB-T
|
||||
card=23 - pcHDTV HD3000 HDTV
|
||||
card=24 - Hauppauge WinTV 28xxx (Roslyn) models
|
||||
card=25 - Digital-Logic MICROSPACE Entertainment Center (MEC)
|
||||
card=26 - IODATA GV/BCTV7E
|
||||
card=27 - PixelView PlayTV Ultra Pro (Stereo)
|
||||
card=28 - DViCO - FusionHDTV 3 Gold-T
|
@ -20,16 +20,37 @@
|
||||
19 -> Compro VideoMate TV [185b:c100]
|
||||
20 -> Matrox CronosPlus [102B:48d0]
|
||||
21 -> 10MOONS PCI TV CAPTURE CARD [1131:2001]
|
||||
22 -> Medion 2819/ AverMedia M156 [1461:a70b,1461:2115]
|
||||
22 -> AverMedia M156 / Medion 2819 [1461:a70b]
|
||||
23 -> BMK MPEX Tuner
|
||||
24 -> KNC One TV-Station DVR [1894:a006]
|
||||
25 -> ASUS TV-FM 7133 [1043:4843]
|
||||
26 -> Pinnacle PCTV Stereo (saa7134) [11bd:002b]
|
||||
27 -> Manli MuchTV M-TV002
|
||||
28 -> Manli MuchTV M-TV001
|
||||
27 -> Manli MuchTV M-TV002/Behold TV 403 FM
|
||||
28 -> Manli MuchTV M-TV001/Behold TV 401
|
||||
29 -> Nagase Sangyo TransGear 3000TV [1461:050c]
|
||||
30 -> Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) [1019:4cb4]
|
||||
31 -> Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM) [1019:4cb5]
|
||||
32 -> AVACS SmartTV
|
||||
33 -> AVerMedia DVD EZMaker [1461:10ff]
|
||||
34 -> LifeView FlyTV Platinum33 mini [5168:0212]
|
||||
34 -> Noval Prime TV 7133
|
||||
35 -> AverMedia AverTV Studio 305 [1461:2115]
|
||||
37 -> Items MuchTV Plus / IT-005
|
||||
38 -> Terratec Cinergy 200 TV [153B:1152]
|
||||
39 -> LifeView FlyTV Platinum Mini [5168:0212]
|
||||
40 -> Compro VideoMate TV PVR/FM [185b:c100]
|
||||
41 -> Compro VideoMate TV Gold+ [185b:c100]
|
||||
42 -> Sabrent SBT-TVFM (saa7130)
|
||||
43 -> :Zolid Xpert TV7134
|
||||
44 -> Empire PCI TV-Radio LE
|
||||
45 -> Avermedia AVerTV Studio 307 [1461:9715]
|
||||
46 -> AVerMedia Cardbus TV/Radio [1461:d6ee]
|
||||
47 -> Terratec Cinergy 400 mobile [153b:1162]
|
||||
48 -> Terratec Cinergy 600 TV MK3 [153B:1158]
|
||||
49 -> Compro VideoMate Gold+ Pal [185b:c200]
|
||||
50 -> Pinnacle PCTV 300i DVB-T + PAL [11bd:002d]
|
||||
51 -> ProVideo PV952 [1540:9524]
|
||||
52 -> AverMedia AverTV/305 [1461:2108]
|
||||
54 -> LifeView FlyTV Platinum FM [5168:0214,1489:0214]
|
||||
55 -> LifeView FlyDVB-T DUO [5168:0306]
|
||||
56 -> Avermedia AVerTV 307 [1461:a70a]
|
||||
57 -> Avermedia AVerTV GO 007 FM [1461:f31f]
|
||||
|
@ -44,3 +44,18 @@ tuner=42 - Philips 1236D ATSC/NTSC daul in
|
||||
tuner=43 - Philips NTSC MK3 (FM1236MK3 or FM1236/F)
|
||||
tuner=44 - Philips 4 in 1 (ATI TV Wonder Pro/Conexant)
|
||||
tuner=45 - Microtune 4049 FM5
|
||||
tuner=46 - Panasonic VP27s/ENGE4324D
|
||||
tuner=47 - LG NTSC (TAPE series)
|
||||
tuner=48 - Tenna TNF 8831 BGFF)
|
||||
tuner=49 - Microtune 4042 FI5 ATSC/NTSC dual in
|
||||
tuner=50 - TCL 2002N
|
||||
tuner=51 - Philips PAL/SECAM_D (FM 1256 I-H3)
|
||||
tuner=52 - Thomson DDT 7610 (ATSC/NTSC)
|
||||
tuner=53 - Philips FQ1286
|
||||
tuner=54 - tda8290+75
|
||||
tuner=55 - LG PAL (TAPE series)
|
||||
tuner=56 - Philips PAL/SECAM multi (FQ1216AME MK4)
|
||||
tuner=57 - Philips FQ1236A MK4
|
||||
tuner=58 - Ymec TVision TVF-8531MF
|
||||
tuner=59 - Ymec TVision TVF-5533MF
|
||||
tuner=60 - Thomson DDT 7611 (ATSC/NTSC)
|
||||
|
54
Documentation/video4linux/hauppauge-wintv-cx88-ir.txt
Normal file
54
Documentation/video4linux/hauppauge-wintv-cx88-ir.txt
Normal file
@ -0,0 +1,54 @@
|
||||
The controls for the mux are GPIO [0,1] for source, and GPIO 2 for muting.
|
||||
|
||||
GPIO0 GPIO1
|
||||
0 0 TV Audio
|
||||
1 0 FM radio
|
||||
0 1 Line-In
|
||||
1 1 Mono tuner bypass or CD passthru (tuner specific)
|
||||
|
||||
GPIO 16(i believe) is tied to the IR port (if present).
|
||||
|
||||
------------------------------------------------------------------------------------
|
||||
|
||||
>From the data sheet:
|
||||
Register 24'h20004 PCI Interrupt Status
|
||||
bit [18] IR_SMP_INT Set when 32 input samples have been collected over
|
||||
gpio[16] pin into GP_SAMPLE register.
|
||||
|
||||
What's missing from the data sheet:
|
||||
|
||||
Setup 4KHz sampling rate (roughly 2x oversampled; good enough for our RC5
|
||||
compat remote)
|
||||
set register 0x35C050 to 0xa80a80
|
||||
|
||||
enable sampling
|
||||
set register 0x35C054 to 0x5
|
||||
|
||||
Of course, enable the IRQ bit 18 in the interrupt mask register .(and
|
||||
provide for a handler)
|
||||
|
||||
GP_SAMPLE register is at 0x35C058
|
||||
|
||||
Bits are then right shifted into the GP_SAMPLE register at the specified
|
||||
rate; you get an interrupt when a full DWORD is recieved.
|
||||
You need to recover the actual RC5 bits out of the (oversampled) IR sensor
|
||||
bits. (Hint: look for the 0/1and 1/0 crossings of the RC5 bi-phase data) An
|
||||
actual raw RC5 code will span 2-3 DWORDS, depending on the actual alignment.
|
||||
|
||||
I'm pretty sure when no IR signal is present the receiver is always in a
|
||||
marking state(1); but stray light, etc can cause intermittent noise values
|
||||
as well. Remember, this is a free running sample of the IR receiver state
|
||||
over time, so don't assume any sample starts at any particular place.
|
||||
|
||||
http://www.atmel.com/dyn/resources/prod_documents/doc2817.pdf
|
||||
This data sheet (google search) seems to have a lovely description of the
|
||||
RC5 basics
|
||||
|
||||
http://users.pandora.be/nenya/electronics/rc5/ and more data
|
||||
|
||||
http://www.ee.washington.edu/circuit_archive/text/ir_decode.txt
|
||||
and even a reference to how to decode a bi-phase data stream.
|
||||
|
||||
http://www.xs4all.nl/~sbp/knowledge/ir/rc5.htm
|
||||
still more info
|
||||
|
42
Documentation/video4linux/lifeview.txt
Normal file
42
Documentation/video4linux/lifeview.txt
Normal file
@ -0,0 +1,42 @@
|
||||
collecting data about the lifeview models and the config coding on
|
||||
gpio pins 0-9 ...
|
||||
==================================================================
|
||||
|
||||
bt878:
|
||||
LR50 rev. Q ("PARTS: 7031505116), Tuner wurde als Nr. 5 erkannt, Eingänge
|
||||
SVideo, TV, Composite, Audio, Remote. CP9..1=100001001 (1: 0-Ohm-Widerstand
|
||||
gegen GND unbestückt; 0: bestückt)
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
saa7134:
|
||||
/* LifeView FlyTV Platinum FM (LR214WF) */
|
||||
/* "Peter Missel <peter.missel@onlinehome.de> */
|
||||
.name = "LifeView FlyTV Platinum FM",
|
||||
/* GP27 MDT2005 PB4 pin 10 */
|
||||
/* GP26 MDT2005 PB3 pin 9 */
|
||||
/* GP25 MDT2005 PB2 pin 8 */
|
||||
/* GP23 MDT2005 PB1 pin 7 */
|
||||
/* GP22 MDT2005 PB0 pin 6 */
|
||||
/* GP21 MDT2005 PB5 pin 11 */
|
||||
/* GP20 MDT2005 PB6 pin 12 */
|
||||
/* GP19 MDT2005 PB7 pin 13 */
|
||||
/* nc MDT2005 PA3 pin 2 */
|
||||
/* Remote MDT2005 PA2 pin 1 */
|
||||
/* GP18 MDT2005 PA1 pin 18 */
|
||||
/* nc MDT2005 PA0 pin 17 strap low */
|
||||
|
||||
/* GP17 Strap "GP7"=High */
|
||||
/* GP16 Strap "GP6"=High
|
||||
0=Radio 1=TV
|
||||
Drives SA630D ENCH1 and HEF4052 A1 pins
|
||||
to do FM radio through SIF input */
|
||||
/* GP15 nc */
|
||||
/* GP14 nc */
|
||||
/* GP13 nc */
|
||||
/* GP12 Strap "GP5" = High */
|
||||
/* GP11 Strap "GP4" = High */
|
||||
/* GP10 Strap "GP3" = High */
|
||||
/* GP09 Strap "GP2" = Low */
|
||||
/* GP08 Strap "GP1" = Low */
|
||||
/* GP07.00 nc */
|
37
Documentation/video4linux/not-in-cx2388x-datasheet.txt
Normal file
37
Documentation/video4linux/not-in-cx2388x-datasheet.txt
Normal file
@ -0,0 +1,37 @@
|
||||
=================================================================================
|
||||
MO_OUTPUT_FORMAT (0x310164)
|
||||
|
||||
Previous default from DScaler: 0x1c1f0008
|
||||
Digit 8: 31-28
|
||||
28: PREVREMOD = 1
|
||||
|
||||
Digit 7: 27-24 (0xc = 12 = b1100 )
|
||||
27: COMBALT = 1
|
||||
26: PAL_INV_PHASE
|
||||
(DScaler apparently set this to 1, resulted in sucky picture)
|
||||
|
||||
Digits 6,5: 23-16
|
||||
25-16: COMB_RANGE = 0x1f [default] (9 bits -> max 512)
|
||||
|
||||
Digit 4: 15-12
|
||||
15: DISIFX = 0
|
||||
14: INVCBF = 0
|
||||
13: DISADAPT = 0
|
||||
12: NARROWADAPT = 0
|
||||
|
||||
Digit 3: 11-8
|
||||
11: FORCE2H
|
||||
10: FORCEREMD
|
||||
9: NCHROMAEN
|
||||
8: NREMODEN
|
||||
|
||||
Digit 2: 7-4
|
||||
7-6: YCORE
|
||||
5-4: CCORE
|
||||
|
||||
Digit 1: 3-0
|
||||
3: RANGE = 1
|
||||
2: HACTEXT
|
||||
1: HSFMT
|
||||
|
||||
=================================================================================
|
24
MAINTAINERS
24
MAINTAINERS
@ -304,7 +304,7 @@ S: Maintained
|
||||
ARM/PT DIGITAL BOARD PORT
|
||||
P: Stefan Eletzhofer
|
||||
M: stefan.eletzhofer@eletztrick.de
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
W: http://www.arm.linux.org.uk/
|
||||
S: Maintained
|
||||
|
||||
@ -317,21 +317,21 @@ S: Maintained
|
||||
ARM/STRONGARM110 PORT
|
||||
P: Russell King
|
||||
M: rmk@arm.linux.org.uk
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
W: http://www.arm.linux.org.uk/
|
||||
S: Maintained
|
||||
|
||||
ARM/S3C2410 ARM ARCHITECTURE
|
||||
P: Ben Dooks
|
||||
M: ben-s3c2410@fluff.org
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
W: http://www.fluff.org/ben/linux/
|
||||
S: Maintained
|
||||
|
||||
ARM/S3C2440 ARM ARCHITECTURE
|
||||
P: Ben Dooks
|
||||
M: ben-s3c2440@fluff.org
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
W: http://www.fluff.org/ben/linux/
|
||||
S: Maintained
|
||||
|
||||
@ -504,6 +504,13 @@ L: bonding-devel@lists.sourceforge.net
|
||||
W: http://sourceforge.net/projects/bonding/
|
||||
S: Supported
|
||||
|
||||
BROADBAND PROCESSOR ARCHITECTURE
|
||||
P: Arnd Bergmann
|
||||
M: arnd@arndb.de
|
||||
L: linuxppc64-dev@ozlabs.org
|
||||
W: http://linuxppc64.org
|
||||
S: Supported
|
||||
|
||||
BTTV VIDEO4LINUX DRIVER
|
||||
P: Gerd Knorr
|
||||
M: kraxel@bytesex.org
|
||||
@ -1853,7 +1860,7 @@ S: Maintained
|
||||
PXA2xx SUPPORT
|
||||
P: Nicolas Pitre
|
||||
M: nico@cam.org
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
S: Maintained
|
||||
|
||||
QLOGIC QLA2XXX FC-SCSI DRIVER
|
||||
@ -2138,6 +2145,11 @@ W: http://tpmdd.sourceforge.net
|
||||
L: tpmdd-devel@lists.sourceforge.net
|
||||
S: Maintained
|
||||
|
||||
TENSILICA XTENSA PORT (xtensa):
|
||||
P: Chris Zankel
|
||||
M: chris@zankel.net
|
||||
S: Maintained
|
||||
|
||||
UltraSPARC (sparc64):
|
||||
P: David S. Miller
|
||||
M: davem@davemloft.net
|
||||
@ -2155,7 +2167,7 @@ SHARP LH SUPPORT (LH7952X & LH7A40X)
|
||||
P: Marc Singer
|
||||
M: elf@buici.com
|
||||
W: http://projects.buici.com/arm
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
S: Maintained
|
||||
|
||||
SPARC (sparc32):
|
||||
|
2
Makefile
2
Makefile
@ -518,7 +518,7 @@ CFLAGS += $(call add-align,CONFIG_CC_ALIGN_LOOPS,-loops)
|
||||
CFLAGS += $(call add-align,CONFIG_CC_ALIGN_JUMPS,-jumps)
|
||||
|
||||
ifdef CONFIG_FRAME_POINTER
|
||||
CFLAGS += -fno-omit-frame-pointer
|
||||
CFLAGS += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,)
|
||||
else
|
||||
CFLAGS += -fomit-frame-pointer
|
||||
endif
|
||||
|
@ -509,7 +509,7 @@ config NR_CPUS
|
||||
depends on SMP
|
||||
default "64"
|
||||
|
||||
config DISCONTIGMEM
|
||||
config ARCH_DISCONTIGMEM_ENABLE
|
||||
bool "Discontiguous Memory Support (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL
|
||||
help
|
||||
@ -518,6 +518,8 @@ config DISCONTIGMEM
|
||||
or have huge holes in the physical address space for other reasons.
|
||||
See <file:Documentation/vm/numa> for more.
|
||||
|
||||
source "mm/Kconfig"
|
||||
|
||||
config NUMA
|
||||
bool "NUMA Support (EXPERIMENTAL)"
|
||||
depends on DISCONTIGMEM
|
||||
|
@ -96,7 +96,7 @@ CONFIG_ALPHA_CORE_AGP=y
|
||||
CONFIG_ALPHA_BROKEN_IRQ_MASK=y
|
||||
CONFIG_EISA=y
|
||||
# CONFIG_SMP is not set
|
||||
# CONFIG_DISCONTIGMEM is not set
|
||||
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
|
||||
CONFIG_VERBOSE_MCHECK=y
|
||||
CONFIG_VERBOSE_MCHECK_ON=1
|
||||
CONFIG_PCI_LEGACY_PROC=y
|
||||
|
@ -327,8 +327,6 @@ void __init mem_init(void)
|
||||
extern char _text, _etext, _data, _edata;
|
||||
extern char __init_begin, __init_end;
|
||||
unsigned long nid, i;
|
||||
struct page * lmem_map;
|
||||
|
||||
high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
|
||||
|
||||
reservedpages = 0;
|
||||
@ -338,10 +336,10 @@ void __init mem_init(void)
|
||||
*/
|
||||
totalram_pages += free_all_bootmem_node(NODE_DATA(nid));
|
||||
|
||||
lmem_map = node_mem_map(nid);
|
||||
pfn = NODE_DATA(nid)->node_start_pfn;
|
||||
for (i = 0; i < node_spanned_pages(nid); i++, pfn++)
|
||||
if (page_is_ram(pfn) && PageReserved(lmem_map+i))
|
||||
if (page_is_ram(pfn) &&
|
||||
PageReserved(nid_page_nr(nid, i)))
|
||||
reservedpages++;
|
||||
}
|
||||
|
||||
@ -373,18 +371,18 @@ show_mem(void)
|
||||
show_free_areas();
|
||||
printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
|
||||
for_each_online_node(nid) {
|
||||
struct page * lmem_map = node_mem_map(nid);
|
||||
i = node_spanned_pages(nid);
|
||||
while (i-- > 0) {
|
||||
struct page *page = nid_page_nr(nid, i);
|
||||
total++;
|
||||
if (PageReserved(lmem_map+i))
|
||||
if (PageReserved(page))
|
||||
reserved++;
|
||||
else if (PageSwapCache(lmem_map+i))
|
||||
else if (PageSwapCache(page))
|
||||
cached++;
|
||||
else if (!page_count(lmem_map+i))
|
||||
else if (!page_count(page))
|
||||
free++;
|
||||
else
|
||||
shared += page_count(lmem_map + i) - 1;
|
||||
shared += page_count(page) - 1;
|
||||
}
|
||||
}
|
||||
printk("%ld pages of RAM\n",total);
|
||||
|
@ -346,7 +346,7 @@ config PREEMPT
|
||||
Say Y here if you are building a kernel for a desktop, embedded
|
||||
or real-time system. Say N if you are unsure.
|
||||
|
||||
config DISCONTIGMEM
|
||||
config ARCH_DISCONTIGMEM_ENABLE
|
||||
bool
|
||||
default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
|
||||
help
|
||||
@ -355,6 +355,8 @@ config DISCONTIGMEM
|
||||
or have huge holes in the physical address space for other reasons.
|
||||
See <file:Documentation/vm/numa> for more.
|
||||
|
||||
source "mm/Kconfig"
|
||||
|
||||
config LEDS
|
||||
bool "Timer and CPU usage LEDs"
|
||||
depends on ARCH_CDB89712 || ARCH_CO285 || ARCH_EBSA110 || \
|
||||
|
@ -21,8 +21,8 @@
|
||||
#
|
||||
|
||||
# User may have a custom install script
|
||||
if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi
|
||||
if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi
|
||||
if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
|
||||
if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi
|
||||
|
||||
if [ "$(basename $2)" = "zImage" ]; then
|
||||
# Compressed install
|
||||
|
@ -1,14 +1,13 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.12-rc1-bk2
|
||||
# Sun Mar 27 17:47:45 2005
|
||||
# Linux kernel version: 2.6.12-git4
|
||||
# Wed Jun 22 15:56:42 2005
|
||||
#
|
||||
CONFIG_ARM=y
|
||||
CONFIG_MMU=y
|
||||
CONFIG_UID16=y
|
||||
CONFIG_RWSEM_GENERIC_SPINLOCK=y
|
||||
CONFIG_GENERIC_CALIBRATE_DELAY=y
|
||||
CONFIG_GENERIC_IOMAP=y
|
||||
|
||||
#
|
||||
# Code maturity level options
|
||||
@ -17,6 +16,7 @@ CONFIG_EXPERIMENTAL=y
|
||||
# CONFIG_CLEAN_COMPILE is not set
|
||||
CONFIG_BROKEN=y
|
||||
CONFIG_BROKEN_ON_SMP=y
|
||||
CONFIG_INIT_ENV_ARG_LIMIT=32
|
||||
|
||||
#
|
||||
# General setup
|
||||
@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=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
|
||||
@ -81,6 +83,7 @@ CONFIG_ARCH_S3C2410=y
|
||||
# CONFIG_ARCH_VERSATILE is not set
|
||||
# CONFIG_ARCH_IMX is not set
|
||||
# CONFIG_ARCH_H720X is not set
|
||||
# CONFIG_ARCH_AAEC2000 is not set
|
||||
|
||||
#
|
||||
# S3C24XX Implementations
|
||||
@ -134,6 +137,7 @@ CONFIG_CPU_TLB_V4WBI=y
|
||||
#
|
||||
# Bus support
|
||||
#
|
||||
CONFIG_ISA_DMA_API=y
|
||||
|
||||
#
|
||||
# PCCARD (PCMCIA/CardBus) support
|
||||
@ -143,7 +147,9 @@ CONFIG_CPU_TLB_V4WBI=y
|
||||
#
|
||||
# Kernel Features
|
||||
#
|
||||
# CONFIG_SMP is not set
|
||||
# CONFIG_PREEMPT is not set
|
||||
# CONFIG_DISCONTIGMEM is not set
|
||||
CONFIG_ALIGNMENT_TRAP=y
|
||||
|
||||
#
|
||||
@ -297,7 +303,6 @@ CONFIG_PARPORT_1284=y
|
||||
#
|
||||
# Block devices
|
||||
#
|
||||
# CONFIG_BLK_DEV_FD is not set
|
||||
# CONFIG_PARIDE is not set
|
||||
# CONFIG_BLK_DEV_COW_COMMON is not set
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
@ -359,6 +364,7 @@ CONFIG_BLK_DEV_IDE_BAST=y
|
||||
#
|
||||
# Fusion MPT device support
|
||||
#
|
||||
# CONFIG_FUSION is not set
|
||||
|
||||
#
|
||||
# IEEE 1394 (FireWire) support
|
||||
@ -378,10 +384,11 @@ CONFIG_NET=y
|
||||
# Networking options
|
||||
#
|
||||
# CONFIG_PACKET is not set
|
||||
# CONFIG_NETLINK_DEV is not set
|
||||
CONFIG_UNIX=y
|
||||
# CONFIG_NET_KEY is not set
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_FIB_HASH=y
|
||||
# CONFIG_IP_FIB_TRIE is not set
|
||||
# CONFIG_IP_MULTICAST is not set
|
||||
# CONFIG_IP_ADVANCED_ROUTER is not set
|
||||
CONFIG_IP_PNP=y
|
||||
@ -443,8 +450,9 @@ CONFIG_NETDEVICES=y
|
||||
# Ethernet (10 or 100Mbit)
|
||||
#
|
||||
CONFIG_NET_ETHERNET=y
|
||||
# CONFIG_MII is not set
|
||||
CONFIG_MII=m
|
||||
# CONFIG_SMC91X is not set
|
||||
CONFIG_DM9000=m
|
||||
|
||||
#
|
||||
# Ethernet (1000 Mbit)
|
||||
@ -521,7 +529,6 @@ CONFIG_SERIO_SERPORT=y
|
||||
CONFIG_SERIO_LIBPS2=y
|
||||
# CONFIG_SERIO_RAW is not set
|
||||
# CONFIG_GAMEPORT is not set
|
||||
CONFIG_SOUND_GAMEPORT=y
|
||||
|
||||
#
|
||||
# Character devices
|
||||
@ -605,7 +612,6 @@ CONFIG_S3C2410_RTC=y
|
||||
#
|
||||
# TPM devices
|
||||
#
|
||||
# CONFIG_TCG_TPM is not set
|
||||
|
||||
#
|
||||
# I2C support
|
||||
@ -654,6 +660,7 @@ CONFIG_SENSORS_LM78=m
|
||||
CONFIG_SENSORS_LM85=m
|
||||
# CONFIG_SENSORS_LM87 is not set
|
||||
# CONFIG_SENSORS_LM90 is not set
|
||||
# CONFIG_SENSORS_LM92 is not set
|
||||
# CONFIG_SENSORS_MAX1619 is not set
|
||||
# CONFIG_SENSORS_PC87360 is not set
|
||||
# CONFIG_SENSORS_SMSC47B397 is not set
|
||||
@ -665,6 +672,7 @@ CONFIG_SENSORS_LM85=m
|
||||
#
|
||||
# Other I2C Chip support
|
||||
#
|
||||
# CONFIG_SENSORS_DS1337 is not set
|
||||
CONFIG_SENSORS_EEPROM=m
|
||||
# CONFIG_SENSORS_PCF8574 is not set
|
||||
# CONFIG_SENSORS_PCF8591 is not set
|
||||
@ -696,8 +704,10 @@ CONFIG_FB=y
|
||||
# CONFIG_FB_CFB_COPYAREA is not set
|
||||
# CONFIG_FB_CFB_IMAGEBLIT is not set
|
||||
# CONFIG_FB_SOFT_CURSOR is not set
|
||||
# CONFIG_FB_MACMODES is not set
|
||||
CONFIG_FB_MODE_HELPERS=y
|
||||
# CONFIG_FB_TILEBLITTING is not set
|
||||
# CONFIG_FB_S1D13XXX is not set
|
||||
# CONFIG_FB_VIRTUAL is not set
|
||||
|
||||
#
|
||||
@ -782,7 +792,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
|
||||
#
|
||||
CONFIG_PROC_FS=y
|
||||
CONFIG_SYSFS=y
|
||||
# CONFIG_DEVFS_FS is not set
|
||||
# CONFIG_DEVPTS_FS_XATTR is not set
|
||||
# CONFIG_TMPFS is not set
|
||||
# CONFIG_HUGETLBFS is not set
|
||||
|
@ -40,6 +40,8 @@
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
#include <asm/arch/gpio.h>
|
||||
|
||||
static DEFINE_SPINLOCK(ixp2000_slowport_lock);
|
||||
static unsigned long ixp2000_slowport_irq_flags;
|
||||
|
||||
@ -179,7 +181,7 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
|
||||
/* clear timer 1 */
|
||||
ixp2000_reg_write(IXP2000_T1_CLR, 1);
|
||||
|
||||
|
||||
while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) {
|
||||
timer_tick(regs);
|
||||
next_jiffy_time -= ticks_per_jiffy;
|
||||
@ -238,35 +240,40 @@ void __init ixp2000_init_time(unsigned long tick_rate)
|
||||
/*************************************************************************
|
||||
* GPIO helpers
|
||||
*************************************************************************/
|
||||
static unsigned long GPIO_IRQ_rising_edge;
|
||||
static unsigned long GPIO_IRQ_falling_edge;
|
||||
static unsigned long GPIO_IRQ_rising_edge;
|
||||
static unsigned long GPIO_IRQ_level_low;
|
||||
static unsigned long GPIO_IRQ_level_high;
|
||||
|
||||
void gpio_line_config(int line, int style)
|
||||
static void update_gpio_int_csrs(void)
|
||||
{
|
||||
ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge);
|
||||
ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge);
|
||||
ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low);
|
||||
ixp2000_reg_write(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high);
|
||||
}
|
||||
|
||||
void gpio_line_config(int line, int direction)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
if (direction == GPIO_OUT) {
|
||||
irq_desc[line + IRQ_IXP2000_GPIO0].valid = 0;
|
||||
|
||||
if(style == GPIO_OUT) {
|
||||
/* if it's an output, it ain't an interrupt anymore */
|
||||
ixp2000_reg_write(IXP2000_GPIO_PDSR, (1 << line));
|
||||
GPIO_IRQ_falling_edge &= ~(1 << line);
|
||||
GPIO_IRQ_rising_edge &= ~(1 << line);
|
||||
GPIO_IRQ_level_low &= ~(1 << line);
|
||||
GPIO_IRQ_level_high &= ~(1 << line);
|
||||
ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge);
|
||||
ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge);
|
||||
ixp2000_reg_write(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high);
|
||||
ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low);
|
||||
irq_desc[line+IRQ_IXP2000_GPIO0].valid = 0;
|
||||
} else if(style == GPIO_IN) {
|
||||
ixp2000_reg_write(IXP2000_GPIO_PDCR, (1 << line));
|
||||
update_gpio_int_csrs();
|
||||
|
||||
ixp2000_reg_write(IXP2000_GPIO_PDSR, 1 << line);
|
||||
} else if (direction == GPIO_IN) {
|
||||
ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line);
|
||||
}
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@ -285,9 +292,50 @@ static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irqdesc *desc, str
|
||||
}
|
||||
}
|
||||
|
||||
static int ixp2000_GPIO_irq_type(unsigned int irq, unsigned int type)
|
||||
{
|
||||
int line = irq - IRQ_IXP2000_GPIO0;
|
||||
|
||||
/*
|
||||
* First, configure this GPIO line as an input.
|
||||
*/
|
||||
ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line);
|
||||
|
||||
/*
|
||||
* Then, set the proper trigger type.
|
||||
*/
|
||||
if (type & IRQT_FALLING)
|
||||
GPIO_IRQ_falling_edge |= 1 << line;
|
||||
else
|
||||
GPIO_IRQ_falling_edge &= ~(1 << line);
|
||||
if (type & IRQT_RISING)
|
||||
GPIO_IRQ_rising_edge |= 1 << line;
|
||||
else
|
||||
GPIO_IRQ_rising_edge &= ~(1 << line);
|
||||
if (type & IRQT_LOW)
|
||||
GPIO_IRQ_level_low |= 1 << line;
|
||||
else
|
||||
GPIO_IRQ_level_low &= ~(1 << line);
|
||||
if (type & IRQT_HIGH)
|
||||
GPIO_IRQ_level_high |= 1 << line;
|
||||
else
|
||||
GPIO_IRQ_level_high &= ~(1 << line);
|
||||
update_gpio_int_csrs();
|
||||
|
||||
/*
|
||||
* Finally, mark the corresponding IRQ as valid.
|
||||
*/
|
||||
irq_desc[irq].valid = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ixp2000_GPIO_irq_mask_ack(unsigned int irq)
|
||||
{
|
||||
ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
|
||||
|
||||
ixp2000_reg_write(IXP2000_GPIO_EDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
|
||||
ixp2000_reg_write(IXP2000_GPIO_LDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
|
||||
ixp2000_reg_write(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0)));
|
||||
}
|
||||
|
||||
@ -302,6 +350,7 @@ static void ixp2000_GPIO_irq_unmask(unsigned int irq)
|
||||
}
|
||||
|
||||
static struct irqchip ixp2000_GPIO_irq_chip = {
|
||||
.type = ixp2000_GPIO_irq_type,
|
||||
.ack = ixp2000_GPIO_irq_mask_ack,
|
||||
.mask = ixp2000_GPIO_irq_mask,
|
||||
.unmask = ixp2000_GPIO_irq_unmask
|
||||
@ -338,7 +387,7 @@ static void ixp2000_irq_mask(unsigned int irq)
|
||||
|
||||
static void ixp2000_irq_unmask(unsigned int irq)
|
||||
{
|
||||
ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << irq));
|
||||
ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << irq));
|
||||
}
|
||||
|
||||
static struct irqchip ixp2000_irq_chip = {
|
||||
@ -375,16 +424,16 @@ void __init ixp2000_init_irq(void)
|
||||
* our mask/unmask code much simpler.
|
||||
*/
|
||||
for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) {
|
||||
if((1 << irq) & IXP2000_VALID_IRQ_MASK) {
|
||||
if ((1 << irq) & IXP2000_VALID_IRQ_MASK) {
|
||||
set_irq_chip(irq, &ixp2000_irq_chip);
|
||||
set_irq_handler(irq, do_level_IRQ);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
} else set_irq_flags(irq, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* GPIO IRQs are invalid until someone sets the interrupt mode
|
||||
* by calling gpio_line_set();
|
||||
* by calling set_irq_type().
|
||||
*/
|
||||
for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) {
|
||||
set_irq_chip(irq, &ixp2000_GPIO_irq_chip);
|
||||
|
@ -141,7 +141,15 @@ static struct map_desc ixp4xx_io_desc[] __initdata = {
|
||||
.physical = IXP4XX_PCI_CFG_BASE_PHYS,
|
||||
.length = IXP4XX_PCI_CFG_REGION_SIZE,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
#ifdef CONFIG_DEBUG_LL
|
||||
{ /* Debug UART mapping */
|
||||
.virtual = IXP4XX_DEBUG_UART_BASE_VIRT,
|
||||
.physical = IXP4XX_DEBUG_UART_BASE_PHYS,
|
||||
.length = IXP4XX_DEBUG_UART_REGION_SIZE,
|
||||
.type = MT_DEVICE
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
void __init ixp4xx_map_io(void)
|
||||
|
@ -26,6 +26,7 @@
|
||||
* 03-Mar-2005 BJD Ensured that bast-cpld.h is included
|
||||
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
|
||||
* 14-Mar-2006 BJD Updated for __iomem changes
|
||||
* 22-Jun-2006 BJD Added DM9000 platform information
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@ -35,6 +36,7 @@
|
||||
#include <linux/timer.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/dm9000.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
@ -53,6 +55,7 @@
|
||||
#include <asm/arch/regs-serial.h>
|
||||
#include <asm/arch/regs-gpio.h>
|
||||
#include <asm/arch/regs-mem.h>
|
||||
#include <asm/arch/regs-lcd.h>
|
||||
#include <asm/arch/nand.h>
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
@ -112,7 +115,6 @@ static struct map_desc bast_iodesc[] __initdata = {
|
||||
{ VA_C2(BAST_VA_ISAMEM), PA_CS2(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
|
||||
{ VA_C2(BAST_VA_ASIXNET), PA_CS3(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE },
|
||||
{ VA_C2(BAST_VA_SUPERIO), PA_CS2(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
|
||||
{ VA_C2(BAST_VA_DM9000), PA_CS2(BAST_PA_DM9000), SZ_1M, MT_DEVICE },
|
||||
{ VA_C2(BAST_VA_IDEPRI), PA_CS3(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE },
|
||||
{ VA_C2(BAST_VA_IDESEC), PA_CS3(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
|
||||
{ VA_C2(BAST_VA_IDEPRIAUX), PA_CS3(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
|
||||
@ -123,7 +125,6 @@ static struct map_desc bast_iodesc[] __initdata = {
|
||||
{ VA_C3(BAST_VA_ISAMEM), PA_CS3(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
|
||||
{ VA_C3(BAST_VA_ASIXNET), PA_CS3(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE },
|
||||
{ VA_C3(BAST_VA_SUPERIO), PA_CS3(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
|
||||
{ VA_C3(BAST_VA_DM9000), PA_CS3(BAST_PA_DM9000), SZ_1M, MT_DEVICE },
|
||||
{ VA_C3(BAST_VA_IDEPRI), PA_CS3(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE },
|
||||
{ VA_C3(BAST_VA_IDESEC), PA_CS3(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
|
||||
{ VA_C3(BAST_VA_IDEPRIAUX), PA_CS3(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
|
||||
@ -134,7 +135,6 @@ static struct map_desc bast_iodesc[] __initdata = {
|
||||
{ VA_C4(BAST_VA_ISAMEM), PA_CS4(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
|
||||
{ VA_C4(BAST_VA_ASIXNET), PA_CS5(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE },
|
||||
{ VA_C4(BAST_VA_SUPERIO), PA_CS4(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
|
||||
{ VA_C4(BAST_VA_DM9000), PA_CS4(BAST_PA_DM9000), SZ_1M, MT_DEVICE },
|
||||
{ VA_C4(BAST_VA_IDEPRI), PA_CS5(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE },
|
||||
{ VA_C4(BAST_VA_IDESEC), PA_CS5(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
|
||||
{ VA_C4(BAST_VA_IDEPRIAUX), PA_CS5(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
|
||||
@ -145,7 +145,6 @@ static struct map_desc bast_iodesc[] __initdata = {
|
||||
{ VA_C5(BAST_VA_ISAMEM), PA_CS5(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
|
||||
{ VA_C5(BAST_VA_ASIXNET), PA_CS5(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE },
|
||||
{ VA_C5(BAST_VA_SUPERIO), PA_CS5(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
|
||||
{ VA_C5(BAST_VA_DM9000), PA_CS5(BAST_PA_DM9000), SZ_1M, MT_DEVICE },
|
||||
{ VA_C5(BAST_VA_IDEPRI), PA_CS5(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE },
|
||||
{ VA_C5(BAST_VA_IDESEC), PA_CS5(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
|
||||
{ VA_C5(BAST_VA_IDEPRIAUX), PA_CS5(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
|
||||
@ -313,6 +312,45 @@ static struct s3c2410_platform_nand bast_nand_info = {
|
||||
.select_chip = bast_nand_select,
|
||||
};
|
||||
|
||||
/* DM9000 */
|
||||
|
||||
static struct resource bast_dm9k_resource[] = {
|
||||
[0] = {
|
||||
.start = S3C2410_CS5 + BAST_PA_DM9000,
|
||||
.end = S3C2410_CS5 + BAST_PA_DM9000 + 3,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
[1] = {
|
||||
.start = S3C2410_CS5 + BAST_PA_DM9000 + 0x40,
|
||||
.end = S3C2410_CS5 + BAST_PA_DM9000 + 0x40 + 0x3f,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_DM9000,
|
||||
.end = IRQ_DM9000,
|
||||
.flags = IORESOURCE_IRQ
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/* for the moment we limit ourselves to 16bit IO until some
|
||||
* better IO routines can be written and tested
|
||||
*/
|
||||
|
||||
struct dm9000_plat_data bast_dm9k_platdata = {
|
||||
.flags = DM9000_PLATF_16BITONLY
|
||||
};
|
||||
|
||||
static struct platform_device bast_device_dm9k = {
|
||||
.name = "dm9000",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(bast_dm9k_resource),
|
||||
.resource = bast_dm9k_resource,
|
||||
.dev = {
|
||||
.platform_data = &bast_dm9k_platdata,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* Standard BAST devices */
|
||||
|
||||
@ -324,7 +362,8 @@ static struct platform_device *bast_devices[] __initdata = {
|
||||
&s3c_device_iis,
|
||||
&s3c_device_rtc,
|
||||
&s3c_device_nand,
|
||||
&bast_device_nor
|
||||
&bast_device_nor,
|
||||
&bast_device_dm9k,
|
||||
};
|
||||
|
||||
static struct clk *bast_clocks[] = {
|
||||
|
@ -27,6 +27,7 @@
|
||||
* 10-Feb-2005 BJD Added power-off capability
|
||||
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
|
||||
* 14-Mar-2006 BJD void __iomem fixes
|
||||
* 22-Jun-2006 BJD Added DM9000 platform information
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@ -35,6 +36,7 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/dm9000.h>
|
||||
|
||||
#include <linux/serial.h>
|
||||
#include <linux/tty.h>
|
||||
@ -98,28 +100,24 @@ static struct map_desc vr1000_iodesc[] __initdata = {
|
||||
* are only 8bit */
|
||||
|
||||
/* slow, byte */
|
||||
{ VA_C2(VR1000_VA_DM9000), PA_CS2(VR1000_PA_DM9000), SZ_1M, MT_DEVICE },
|
||||
{ VA_C2(VR1000_VA_IDEPRI), PA_CS3(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE },
|
||||
{ VA_C2(VR1000_VA_IDESEC), PA_CS3(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE },
|
||||
{ VA_C2(VR1000_VA_IDEPRIAUX), PA_CS3(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
|
||||
{ VA_C2(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
|
||||
|
||||
/* slow, word */
|
||||
{ VA_C3(VR1000_VA_DM9000), PA_CS3(VR1000_PA_DM9000), SZ_1M, MT_DEVICE },
|
||||
{ VA_C3(VR1000_VA_IDEPRI), PA_CS3(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE },
|
||||
{ VA_C3(VR1000_VA_IDESEC), PA_CS3(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE },
|
||||
{ VA_C3(VR1000_VA_IDEPRIAUX), PA_CS3(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
|
||||
{ VA_C3(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
|
||||
|
||||
/* fast, byte */
|
||||
{ VA_C4(VR1000_VA_DM9000), PA_CS4(VR1000_PA_DM9000), SZ_1M, MT_DEVICE },
|
||||
{ VA_C4(VR1000_VA_IDEPRI), PA_CS5(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE },
|
||||
{ VA_C4(VR1000_VA_IDESEC), PA_CS5(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE },
|
||||
{ VA_C4(VR1000_VA_IDEPRIAUX), PA_CS5(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
|
||||
{ VA_C4(VR1000_VA_IDESECAUX), PA_CS5(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
|
||||
|
||||
/* fast, word */
|
||||
{ VA_C5(VR1000_VA_DM9000), PA_CS5(VR1000_PA_DM9000), SZ_1M, MT_DEVICE },
|
||||
{ VA_C5(VR1000_VA_IDEPRI), PA_CS5(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE },
|
||||
{ VA_C5(VR1000_VA_IDESEC), PA_CS5(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE },
|
||||
{ VA_C5(VR1000_VA_IDEPRIAUX), PA_CS5(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
|
||||
@ -246,6 +244,74 @@ static struct platform_device vr1000_nor = {
|
||||
.resource = vr1000_nor_resource,
|
||||
};
|
||||
|
||||
/* DM9000 ethernet devices */
|
||||
|
||||
static struct resource vr1000_dm9k0_resource[] = {
|
||||
[0] = {
|
||||
.start = S3C2410_CS5 + VR1000_PA_DM9000,
|
||||
.end = S3C2410_CS5 + VR1000_PA_DM9000 + 3,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
[1] = {
|
||||
.start = S3C2410_CS5 + VR1000_PA_DM9000 + 0x40,
|
||||
.end = S3C2410_CS5 + VR1000_PA_DM9000 + 0x7f,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_VR1000_DM9000A,
|
||||
.end = IRQ_VR1000_DM9000A,
|
||||
.flags = IORESOURCE_IRQ
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static struct resource vr1000_dm9k1_resource[] = {
|
||||
[0] = {
|
||||
.start = S3C2410_CS5 + VR1000_PA_DM9000 + 0x80,
|
||||
.end = S3C2410_CS5 + VR1000_PA_DM9000 + 0x83,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
[1] = {
|
||||
.start = S3C2410_CS5 + VR1000_PA_DM9000 + 0xC0,
|
||||
.end = S3C2410_CS5 + VR1000_PA_DM9000 + 0xFF,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_VR1000_DM9000N,
|
||||
.end = IRQ_VR1000_DM9000N,
|
||||
.flags = IORESOURCE_IRQ
|
||||
}
|
||||
};
|
||||
|
||||
/* for the moment we limit ourselves to 16bit IO until some
|
||||
* better IO routines can be written and tested
|
||||
*/
|
||||
|
||||
struct dm9000_plat_data vr1000_dm9k_platdata = {
|
||||
.flags = DM9000_PLATF_16BITONLY,
|
||||
};
|
||||
|
||||
static struct platform_device vr1000_dm9k0 = {
|
||||
.name = "dm9000",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(vr1000_dm9k0_resource),
|
||||
.resource = vr1000_dm9k0_resource,
|
||||
.dev = {
|
||||
.platform_data = &vr1000_dm9k_platdata,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device vr1000_dm9k1 = {
|
||||
.name = "dm9000",
|
||||
.id = 1,
|
||||
.num_resources = ARRAY_SIZE(vr1000_dm9k1_resource),
|
||||
.resource = vr1000_dm9k1_resource,
|
||||
.dev = {
|
||||
.platform_data = &vr1000_dm9k_platdata,
|
||||
}
|
||||
};
|
||||
|
||||
/* devices for this board */
|
||||
|
||||
static struct platform_device *vr1000_devices[] __initdata = {
|
||||
&s3c_device_usb,
|
||||
@ -253,8 +319,11 @@ static struct platform_device *vr1000_devices[] __initdata = {
|
||||
&s3c_device_wdt,
|
||||
&s3c_device_i2c,
|
||||
&s3c_device_iis,
|
||||
&s3c_device_adc,
|
||||
&serial_device,
|
||||
&vr1000_nor,
|
||||
&vr1000_dm9k0,
|
||||
&vr1000_dm9k1
|
||||
};
|
||||
|
||||
static struct clk *vr1000_clocks[] = {
|
||||
|
@ -132,8 +132,8 @@ ENTRY(cpu_v6_switch_mm)
|
||||
* 100x 1 0 1 r/o no acc
|
||||
* 10x0 1 0 1 r/o no acc
|
||||
* 1011 0 0 1 r/w no acc
|
||||
* 110x 1 1 0 r/o r/o
|
||||
* 11x0 1 1 0 r/o r/o
|
||||
* 110x 0 1 0 r/w r/o
|
||||
* 11x0 0 1 0 r/w r/o
|
||||
* 1111 0 1 1 r/w r/w
|
||||
*/
|
||||
ENTRY(cpu_v6_set_pte)
|
||||
@ -150,7 +150,7 @@ ENTRY(cpu_v6_set_pte)
|
||||
tst r1, #L_PTE_USER
|
||||
orrne r2, r2, #AP1 | nG
|
||||
tstne r2, #APX
|
||||
eorne r2, r2, #AP0
|
||||
bicne r2, r2, #APX | AP0
|
||||
|
||||
tst r1, #L_PTE_YOUNG
|
||||
biceq r2, r2, #APX | AP1 | AP0
|
||||
|
@ -563,8 +563,14 @@ static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b )
|
||||
bits64 rem0, rem1, term0, term1;
|
||||
bits64 z;
|
||||
if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF );
|
||||
b0 = b>>32;
|
||||
z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32;
|
||||
b0 = b>>32; /* hence b0 is 32 bits wide now */
|
||||
if ( b0<<32 <= a0 ) {
|
||||
z = LIT64( 0xFFFFFFFF00000000 );
|
||||
} else {
|
||||
z = a0;
|
||||
do_div( z, b0 );
|
||||
z <<= 32;
|
||||
}
|
||||
mul64To128( b, z, &term0, &term1 );
|
||||
sub128( a0, a1, term0, term1, &rem0, &rem1 );
|
||||
while ( ( (sbits64) rem0 ) < 0 ) {
|
||||
@ -573,7 +579,12 @@ static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b )
|
||||
add128( rem0, rem1, b0, b1, &rem0, &rem1 );
|
||||
}
|
||||
rem0 = ( rem0<<32 ) | ( rem1>>32 );
|
||||
z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0;
|
||||
if ( b0<<32 <= rem0 ) {
|
||||
z |= 0xFFFFFFFF;
|
||||
} else {
|
||||
do_div( rem0, b0 );
|
||||
z |= rem0;
|
||||
}
|
||||
return z;
|
||||
|
||||
}
|
||||
@ -601,6 +612,7 @@ static bits32 estimateSqrt32( int16 aExp, bits32 a )
|
||||
};
|
||||
int8 index;
|
||||
bits32 z;
|
||||
bits64 A;
|
||||
|
||||
index = ( a>>27 ) & 15;
|
||||
if ( aExp & 1 ) {
|
||||
@ -614,7 +626,9 @@ static bits32 estimateSqrt32( int16 aExp, bits32 a )
|
||||
z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
|
||||
if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 );
|
||||
}
|
||||
return ( (bits32) ( ( ( (bits64) a )<<31 ) / z ) ) + ( z>>1 );
|
||||
A = ( (bits64) a )<<31;
|
||||
do_div( A, z );
|
||||
return ( (bits32) A ) + ( z>>1 );
|
||||
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,8 @@ this code that are retained.
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include "fpa11.h"
|
||||
//#include "milieu.h"
|
||||
//#include "softfloat.h"
|
||||
@ -1331,7 +1333,11 @@ float32 float32_div( float32 a, float32 b )
|
||||
aSig >>= 1;
|
||||
++zExp;
|
||||
}
|
||||
zSig = ( ( (bits64) aSig )<<32 ) / bSig;
|
||||
{
|
||||
bits64 tmp = ( (bits64) aSig )<<32;
|
||||
do_div( tmp, bSig );
|
||||
zSig = tmp;
|
||||
}
|
||||
if ( ( zSig & 0x3F ) == 0 ) {
|
||||
zSig |= ( ( (bits64) bSig ) * zSig != ( (bits64) aSig )<<32 );
|
||||
}
|
||||
@ -1397,7 +1403,9 @@ float32 float32_rem( float32 a, float32 b )
|
||||
q = ( bSig <= aSig );
|
||||
if ( q ) aSig -= bSig;
|
||||
if ( 0 < expDiff ) {
|
||||
q = ( ( (bits64) aSig )<<32 ) / bSig;
|
||||
bits64 tmp = ( (bits64) aSig )<<32;
|
||||
do_div( tmp, bSig );
|
||||
q = tmp;
|
||||
q >>= 32 - expDiff;
|
||||
bSig >>= 2;
|
||||
aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
|
||||
|
@ -179,6 +179,8 @@ config CMDLINE
|
||||
time by entering them here. As a minimum, you should specify the
|
||||
memory size and the root device (e.g., mem=64M root=/dev/nfs).
|
||||
|
||||
source "mm/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
source "drivers/base/Kconfig"
|
||||
|
@ -23,8 +23,8 @@
|
||||
|
||||
# User may have a custom install script
|
||||
|
||||
if [ -x /sbin/installkernel ]; then
|
||||
exec /sbin/installkernel "$@"
|
||||
if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then
|
||||
exec /sbin/${CROSS_COMPILE}installkernel "$@"
|
||||
fi
|
||||
|
||||
if [ "$2" = "zImage" ]; then
|
||||
|
@ -74,6 +74,8 @@ config PREEMPT
|
||||
Say Y here if you are building a kernel for a desktop, embedded
|
||||
or real-time system. Say N if you are unsure.
|
||||
|
||||
source mm/Kconfig
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Hardware setup"
|
||||
|
@ -74,6 +74,8 @@ config HIGHPTE
|
||||
with a lot of RAM, this can be wasteful of precious low memory.
|
||||
Setting this option will put user-space page tables in high memory.
|
||||
|
||||
source "mm/Kconfig"
|
||||
|
||||
choice
|
||||
prompt "uClinux kernel load address"
|
||||
depends on !MMU
|
||||
|
@ -180,4 +180,7 @@ config CPU_H8S
|
||||
config PREEMPT
|
||||
bool "Preemptible Kernel"
|
||||
default n
|
||||
|
||||
source "mm/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
@ -245,12 +245,12 @@ static unsigned short *getnextpc(struct task_struct *child, unsigned short *pc)
|
||||
addr = h8300_get_reg(child, regno-1+PT_ER1);
|
||||
return (unsigned short *)addr;
|
||||
case relb:
|
||||
if ((inst = 0x55) || isbranch(child,inst & 0x0f))
|
||||
if (inst == 0x55 || isbranch(child,inst & 0x0f))
|
||||
pc = (unsigned short *)((unsigned long)pc +
|
||||
((signed char)(*fetch_p)));
|
||||
return pc+1; /* skip myself */
|
||||
case relw:
|
||||
if ((inst = 0x5c) || isbranch(child,(*fetch_p & 0xf0) >> 4))
|
||||
if (inst == 0x5c || isbranch(child,(*fetch_p & 0xf0) >> 4))
|
||||
pc = (unsigned short *)((unsigned long)pc +
|
||||
((signed short)(*(pc+1))));
|
||||
return pc+2; /* skip myself */
|
||||
|
@ -68,7 +68,6 @@ config X86_VOYAGER
|
||||
|
||||
config X86_NUMAQ
|
||||
bool "NUMAQ (IBM/Sequent)"
|
||||
select DISCONTIGMEM
|
||||
select NUMA
|
||||
help
|
||||
This option is used for getting Linux to run on a (IBM/Sequent) NUMA
|
||||
@ -783,26 +782,49 @@ comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support"
|
||||
comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI"
|
||||
depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI)
|
||||
|
||||
config DISCONTIGMEM
|
||||
bool
|
||||
depends on NUMA
|
||||
default y
|
||||
|
||||
config HAVE_ARCH_BOOTMEM_NODE
|
||||
bool
|
||||
depends on NUMA
|
||||
default y
|
||||
|
||||
config HAVE_MEMORY_PRESENT
|
||||
config ARCH_HAVE_MEMORY_PRESENT
|
||||
bool
|
||||
depends on DISCONTIGMEM
|
||||
default y
|
||||
|
||||
config NEED_NODE_MEMMAP_SIZE
|
||||
bool
|
||||
depends on DISCONTIGMEM
|
||||
depends on DISCONTIGMEM || SPARSEMEM
|
||||
default y
|
||||
|
||||
config HAVE_ARCH_ALLOC_REMAP
|
||||
bool
|
||||
depends on NUMA
|
||||
default y
|
||||
|
||||
config ARCH_DISCONTIGMEM_ENABLE
|
||||
def_bool y
|
||||
depends on NUMA
|
||||
|
||||
config ARCH_DISCONTIGMEM_DEFAULT
|
||||
def_bool y
|
||||
depends on NUMA
|
||||
|
||||
config ARCH_SPARSEMEM_ENABLE
|
||||
def_bool y
|
||||
depends on NUMA
|
||||
|
||||
config ARCH_SELECT_MEMORY_MODEL
|
||||
def_bool y
|
||||
depends on ARCH_SPARSEMEM_ENABLE
|
||||
|
||||
source "mm/Kconfig"
|
||||
|
||||
config HAVE_ARCH_EARLY_PFN_TO_NID
|
||||
bool
|
||||
default y
|
||||
depends on NUMA
|
||||
|
||||
config HIGHPTE
|
||||
bool "Allocate 3rd-level pagetables from highmem"
|
||||
depends on HIGHMEM4G || HIGHMEM64G
|
||||
@ -939,6 +961,8 @@ config SECCOMP
|
||||
|
||||
If unsure, say Y. Only embedded should say N here.
|
||||
|
||||
source kernel/Kconfig.hz
|
||||
|
||||
endmenu
|
||||
|
||||
|
||||
|
@ -17,6 +17,13 @@
|
||||
# 20050320 Kianusch Sayah Karadji <kianusch@sk-tech.net>
|
||||
# Added support for GEODE CPU
|
||||
|
||||
HAS_BIARCH := $(call cc-option-yn, -m32)
|
||||
ifeq ($(HAS_BIARCH),y)
|
||||
AS := $(AS) --32
|
||||
LD := $(LD) -m elf_i386
|
||||
CC := $(CC) -m32
|
||||
endif
|
||||
|
||||
LDFLAGS := -m elf_i386
|
||||
OBJCOPYFLAGS := -O binary -R .note -R .comment -S
|
||||
LDFLAGS_vmlinux :=
|
||||
|
@ -21,8 +21,8 @@
|
||||
|
||||
# User may have a custom install script
|
||||
|
||||
if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi
|
||||
if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi
|
||||
if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
|
||||
if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi
|
||||
|
||||
# Default install - same as make zlilo
|
||||
|
||||
|
@ -1133,7 +1133,7 @@ inline void smp_local_timer_interrupt(struct pt_regs * regs)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
update_process_times(user_mode(regs));
|
||||
update_process_times(user_mode_vm(regs));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -635,7 +635,7 @@ void __init cpu_init (void)
|
||||
|
||||
/* Clear all 6 debug registers: */
|
||||
|
||||
#define CD(register) __asm__("movl %0,%%db" #register ::"r"(0) );
|
||||
#define CD(register) set_debugreg(0, register)
|
||||
|
||||
CD(0); CD(1); CD(2); CD(3); /* no db4 and db5 */; CD(6); CD(7);
|
||||
|
||||
|
@ -375,6 +375,19 @@ int mtrr_add_page(unsigned long base, unsigned long size,
|
||||
return error;
|
||||
}
|
||||
|
||||
static int mtrr_check(unsigned long base, unsigned long size)
|
||||
{
|
||||
if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
|
||||
printk(KERN_WARNING
|
||||
"mtrr: size and base must be multiples of 4 kiB\n");
|
||||
printk(KERN_DEBUG
|
||||
"mtrr: size: 0x%lx base: 0x%lx\n", size, base);
|
||||
dump_stack();
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mtrr_add - Add a memory type region
|
||||
* @base: Physical base address of region
|
||||
@ -415,11 +428,8 @@ int
|
||||
mtrr_add(unsigned long base, unsigned long size, unsigned int type,
|
||||
char increment)
|
||||
{
|
||||
if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
|
||||
printk(KERN_WARNING "mtrr: size and base must be multiples of 4 kiB\n");
|
||||
printk(KERN_DEBUG "mtrr: size: 0x%lx base: 0x%lx\n", size, base);
|
||||
if (mtrr_check(base, size))
|
||||
return -EINVAL;
|
||||
}
|
||||
return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
|
||||
increment);
|
||||
}
|
||||
@ -511,11 +521,8 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
|
||||
int
|
||||
mtrr_del(int reg, unsigned long base, unsigned long size)
|
||||
{
|
||||
if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
|
||||
printk(KERN_INFO "mtrr: size and base must be multiples of 4 kiB\n");
|
||||
printk(KERN_DEBUG "mtrr: size: 0x%lx base: 0x%lx\n", size, base);
|
||||
if (mtrr_check(base, size))
|
||||
return -EINVAL;
|
||||
}
|
||||
return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
seq_printf(m, "stepping\t: unknown\n");
|
||||
|
||||
if ( cpu_has(c, X86_FEATURE_TSC) ) {
|
||||
seq_printf(m, "cpu MHz\t\t: %lu.%03lu\n",
|
||||
seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
|
||||
cpu_khz / 1000, (cpu_khz % 1000));
|
||||
}
|
||||
|
||||
|
@ -1,97 +1,17 @@
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/user.h>
|
||||
#include <linux/elfcore.h>
|
||||
#include <linux/mca.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/in6.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/apm_bios.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/time.h>
|
||||
|
||||
#include <asm/semaphore.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/i387.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/checksum.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/delay.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mmx.h>
|
||||
#include <asm/desc.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/nmi.h>
|
||||
#include <asm/ist.h>
|
||||
#include <asm/kdebug.h>
|
||||
|
||||
extern void dump_thread(struct pt_regs *, struct user *);
|
||||
extern spinlock_t rtc_lock;
|
||||
|
||||
/* This is definitely a GPL-only symbol */
|
||||
EXPORT_SYMBOL_GPL(cpu_gdt_table);
|
||||
|
||||
#if defined(CONFIG_APM_MODULE)
|
||||
extern void machine_real_restart(unsigned char *, int);
|
||||
EXPORT_SYMBOL(machine_real_restart);
|
||||
extern void default_idle(void);
|
||||
EXPORT_SYMBOL(default_idle);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
|
||||
extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
|
||||
extern struct drive_info_struct drive_info;
|
||||
EXPORT_SYMBOL(drive_info);
|
||||
#endif
|
||||
|
||||
extern unsigned long cpu_khz;
|
||||
extern unsigned long get_cmos_time(void);
|
||||
|
||||
/* platform dependent support */
|
||||
EXPORT_SYMBOL(boot_cpu_data);
|
||||
#ifdef CONFIG_DISCONTIGMEM
|
||||
EXPORT_SYMBOL(node_data);
|
||||
EXPORT_SYMBOL(physnode_map);
|
||||
#endif
|
||||
#ifdef CONFIG_X86_NUMAQ
|
||||
EXPORT_SYMBOL(xquad_portio);
|
||||
#endif
|
||||
EXPORT_SYMBOL(dump_thread);
|
||||
EXPORT_SYMBOL(dump_fpu);
|
||||
EXPORT_SYMBOL_GPL(kernel_fpu_begin);
|
||||
EXPORT_SYMBOL(__ioremap);
|
||||
EXPORT_SYMBOL(ioremap_nocache);
|
||||
EXPORT_SYMBOL(iounmap);
|
||||
EXPORT_SYMBOL(kernel_thread);
|
||||
EXPORT_SYMBOL(pm_idle);
|
||||
EXPORT_SYMBOL(pm_power_off);
|
||||
EXPORT_SYMBOL(get_cmos_time);
|
||||
EXPORT_SYMBOL(cpu_khz);
|
||||
EXPORT_SYMBOL(apm_info);
|
||||
|
||||
EXPORT_SYMBOL(__down_failed);
|
||||
EXPORT_SYMBOL(__down_failed_interruptible);
|
||||
EXPORT_SYMBOL(__down_failed_trylock);
|
||||
EXPORT_SYMBOL(__up_wakeup);
|
||||
/* Networking helper routines. */
|
||||
EXPORT_SYMBOL(csum_partial_copy_generic);
|
||||
/* Delay loops */
|
||||
EXPORT_SYMBOL(__ndelay);
|
||||
EXPORT_SYMBOL(__udelay);
|
||||
EXPORT_SYMBOL(__delay);
|
||||
EXPORT_SYMBOL(__const_udelay);
|
||||
|
||||
EXPORT_SYMBOL(__get_user_1);
|
||||
EXPORT_SYMBOL(__get_user_2);
|
||||
@ -105,87 +25,11 @@ EXPORT_SYMBOL(__put_user_8);
|
||||
EXPORT_SYMBOL(strpbrk);
|
||||
EXPORT_SYMBOL(strstr);
|
||||
|
||||
EXPORT_SYMBOL(strncpy_from_user);
|
||||
EXPORT_SYMBOL(__strncpy_from_user);
|
||||
EXPORT_SYMBOL(clear_user);
|
||||
EXPORT_SYMBOL(__clear_user);
|
||||
EXPORT_SYMBOL(__copy_from_user_ll);
|
||||
EXPORT_SYMBOL(__copy_to_user_ll);
|
||||
EXPORT_SYMBOL(strnlen_user);
|
||||
|
||||
EXPORT_SYMBOL(dma_alloc_coherent);
|
||||
EXPORT_SYMBOL(dma_free_coherent);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
EXPORT_SYMBOL(pci_mem_start);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCI_BIOS
|
||||
EXPORT_SYMBOL(pcibios_set_irq_routing);
|
||||
EXPORT_SYMBOL(pcibios_get_irq_routing_table);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_USE_3DNOW
|
||||
EXPORT_SYMBOL(_mmx_memcpy);
|
||||
EXPORT_SYMBOL(mmx_clear_page);
|
||||
EXPORT_SYMBOL(mmx_copy_page);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_HT
|
||||
EXPORT_SYMBOL(smp_num_siblings);
|
||||
EXPORT_SYMBOL(cpu_sibling_map);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
EXPORT_SYMBOL(cpu_data);
|
||||
EXPORT_SYMBOL(cpu_online_map);
|
||||
EXPORT_SYMBOL(cpu_callout_map);
|
||||
extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
|
||||
extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
|
||||
EXPORT_SYMBOL(__write_lock_failed);
|
||||
EXPORT_SYMBOL(__read_lock_failed);
|
||||
|
||||
/* Global SMP stuff */
|
||||
EXPORT_SYMBOL(smp_call_function);
|
||||
|
||||
/* TLB flushing */
|
||||
EXPORT_SYMBOL(flush_tlb_page);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MCA
|
||||
EXPORT_SYMBOL(machine_id);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VT
|
||||
EXPORT_SYMBOL(screen_info);
|
||||
#endif
|
||||
|
||||
EXPORT_SYMBOL(get_wchan);
|
||||
|
||||
EXPORT_SYMBOL(rtc_lock);
|
||||
|
||||
EXPORT_SYMBOL_GPL(set_nmi_callback);
|
||||
EXPORT_SYMBOL_GPL(unset_nmi_callback);
|
||||
|
||||
EXPORT_SYMBOL(register_die_notifier);
|
||||
#ifdef CONFIG_HAVE_DEC_LOCK
|
||||
EXPORT_SYMBOL(_atomic_dec_and_lock);
|
||||
#endif
|
||||
|
||||
EXPORT_SYMBOL(__PAGE_KERNEL);
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
EXPORT_SYMBOL(kmap);
|
||||
EXPORT_SYMBOL(kunmap);
|
||||
EXPORT_SYMBOL(kmap_atomic);
|
||||
EXPORT_SYMBOL(kunmap_atomic);
|
||||
EXPORT_SYMBOL(kmap_atomic_to_page);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
|
||||
EXPORT_SYMBOL(ist_info);
|
||||
#endif
|
||||
|
||||
EXPORT_SYMBOL(csum_partial);
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/i387.h>
|
||||
#include <asm/math_emu.h>
|
||||
@ -79,6 +80,7 @@ void kernel_fpu_begin(void)
|
||||
}
|
||||
clts();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kernel_fpu_begin);
|
||||
|
||||
void restore_fpu( struct task_struct *tsk )
|
||||
{
|
||||
@ -526,6 +528,7 @@ int dump_fpu( struct pt_regs *regs, struct user_i387_struct *fpu )
|
||||
|
||||
return fpvalid;
|
||||
}
|
||||
EXPORT_SYMBOL(dump_fpu);
|
||||
|
||||
int dump_task_fpu(struct task_struct *tsk, struct user_i387_struct *fpu)
|
||||
{
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include <linux/mc146818rtc.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/sysdev.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/smp.h>
|
||||
@ -812,6 +812,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
|
||||
}
|
||||
return best_guess;
|
||||
}
|
||||
EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
|
||||
|
||||
/*
|
||||
* This function currently is only a helper for the i386 smp boot process where
|
||||
@ -1658,6 +1659,12 @@ static void __init setup_ioapic_ids_from_mpc(void)
|
||||
unsigned char old_id;
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* Don't check I/O APIC IDs for xAPIC systems. They have
|
||||
* no meaning without the serial APIC bus.
|
||||
*/
|
||||
if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && boot_cpu_data.x86 < 15))
|
||||
return;
|
||||
/*
|
||||
* This is broken; anything with a real cpu count has to
|
||||
* circumvent this idiocy regardless.
|
||||
@ -1684,10 +1691,6 @@ static void __init setup_ioapic_ids_from_mpc(void)
|
||||
mp_ioapics[apic].mpc_apicid = reg_00.bits.ID;
|
||||
}
|
||||
|
||||
/* Don't check I/O APIC IDs for some xAPIC systems. They have
|
||||
* no meaning without the serial APIC bus. */
|
||||
if (NO_IOAPIC_CHECK)
|
||||
continue;
|
||||
/*
|
||||
* Sanity check, is the ID really free? Every APIC in a
|
||||
* system must have a unique ID or we get lots of nice
|
||||
|
@ -23,6 +23,9 @@
|
||||
* Rusty Russell).
|
||||
* 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes
|
||||
* interface to access function arguments.
|
||||
* 2005-May Hien Nguyen <hien@us.ibm.com>, Jim Keniston
|
||||
* <jkenisto@us.ibm.com> and Prasanna S Panchamukhi
|
||||
* <prasanna@in.ibm.com> added function-return probes.
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
@ -30,15 +33,14 @@
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/preempt.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/kdebug.h>
|
||||
#include <asm/desc.h>
|
||||
|
||||
/* kprobe_status settings */
|
||||
#define KPROBE_HIT_ACTIVE 0x00000001
|
||||
#define KPROBE_HIT_SS 0x00000002
|
||||
|
||||
static struct kprobe *current_kprobe;
|
||||
static unsigned long kprobe_status, kprobe_old_eflags, kprobe_saved_eflags;
|
||||
static struct kprobe *kprobe_prev;
|
||||
static unsigned long kprobe_status_prev, kprobe_old_eflags_prev, kprobe_saved_eflags_prev;
|
||||
static struct pt_regs jprobe_saved_regs;
|
||||
static long *jprobe_saved_esp;
|
||||
/* copy of the kernel stack at the probe fire time */
|
||||
@ -68,16 +70,50 @@ int arch_prepare_kprobe(struct kprobe *p)
|
||||
void arch_copy_kprobe(struct kprobe *p)
|
||||
{
|
||||
memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
|
||||
p->opcode = *p->addr;
|
||||
}
|
||||
|
||||
void arch_arm_kprobe(struct kprobe *p)
|
||||
{
|
||||
*p->addr = BREAKPOINT_INSTRUCTION;
|
||||
flush_icache_range((unsigned long) p->addr,
|
||||
(unsigned long) p->addr + sizeof(kprobe_opcode_t));
|
||||
}
|
||||
|
||||
void arch_disarm_kprobe(struct kprobe *p)
|
||||
{
|
||||
*p->addr = p->opcode;
|
||||
flush_icache_range((unsigned long) p->addr,
|
||||
(unsigned long) p->addr + sizeof(kprobe_opcode_t));
|
||||
}
|
||||
|
||||
void arch_remove_kprobe(struct kprobe *p)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
|
||||
static inline void save_previous_kprobe(void)
|
||||
{
|
||||
*p->addr = p->opcode;
|
||||
regs->eip = (unsigned long)p->addr;
|
||||
kprobe_prev = current_kprobe;
|
||||
kprobe_status_prev = kprobe_status;
|
||||
kprobe_old_eflags_prev = kprobe_old_eflags;
|
||||
kprobe_saved_eflags_prev = kprobe_saved_eflags;
|
||||
}
|
||||
|
||||
static inline void restore_previous_kprobe(void)
|
||||
{
|
||||
current_kprobe = kprobe_prev;
|
||||
kprobe_status = kprobe_status_prev;
|
||||
kprobe_old_eflags = kprobe_old_eflags_prev;
|
||||
kprobe_saved_eflags = kprobe_saved_eflags_prev;
|
||||
}
|
||||
|
||||
static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
current_kprobe = p;
|
||||
kprobe_saved_eflags = kprobe_old_eflags
|
||||
= (regs->eflags & (TF_MASK | IF_MASK));
|
||||
if (is_IF_modifier(p->opcode))
|
||||
kprobe_saved_eflags &= ~IF_MASK;
|
||||
}
|
||||
|
||||
static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
|
||||
@ -91,6 +127,50 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
|
||||
regs->eip = (unsigned long)&p->ainsn.insn;
|
||||
}
|
||||
|
||||
struct task_struct *arch_get_kprobe_task(void *ptr)
|
||||
{
|
||||
return ((struct thread_info *) (((unsigned long) ptr) &
|
||||
(~(THREAD_SIZE -1))))->task;
|
||||
}
|
||||
|
||||
void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
|
||||
{
|
||||
unsigned long *sara = (unsigned long *)®s->esp;
|
||||
struct kretprobe_instance *ri;
|
||||
static void *orig_ret_addr;
|
||||
|
||||
/*
|
||||
* Save the return address when the return probe hits
|
||||
* the first time, and use it to populate the (krprobe
|
||||
* instance)->ret_addr for subsequent return probes at
|
||||
* the same addrress since stack address would have
|
||||
* the kretprobe_trampoline by then.
|
||||
*/
|
||||
if (((void*) *sara) != kretprobe_trampoline)
|
||||
orig_ret_addr = (void*) *sara;
|
||||
|
||||
if ((ri = get_free_rp_inst(rp)) != NULL) {
|
||||
ri->rp = rp;
|
||||
ri->stack_addr = sara;
|
||||
ri->ret_addr = orig_ret_addr;
|
||||
add_rp_inst(ri);
|
||||
/* Replace the return addr with trampoline addr */
|
||||
*sara = (unsigned long) &kretprobe_trampoline;
|
||||
} else {
|
||||
rp->nmissed++;
|
||||
}
|
||||
}
|
||||
|
||||
void arch_kprobe_flush_task(struct task_struct *tk)
|
||||
{
|
||||
struct kretprobe_instance *ri;
|
||||
while ((ri = get_rp_inst_tsk(tk)) != NULL) {
|
||||
*((unsigned long *)(ri->stack_addr)) =
|
||||
(unsigned long) ri->ret_addr;
|
||||
recycle_rp_inst(ri);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupts are disabled on entry as trap3 is an interrupt gate and they
|
||||
* remain disabled thorough out this function.
|
||||
@ -127,8 +207,18 @@ static int kprobe_handler(struct pt_regs *regs)
|
||||
unlock_kprobes();
|
||||
goto no_kprobe;
|
||||
}
|
||||
disarm_kprobe(p, regs);
|
||||
ret = 1;
|
||||
/* We have reentered the kprobe_handler(), since
|
||||
* another probe was hit while within the handler.
|
||||
* We here save the original kprobes variables and
|
||||
* just single step on the instruction of the new probe
|
||||
* without calling any user handlers.
|
||||
*/
|
||||
save_previous_kprobe();
|
||||
set_current_kprobe(p, regs);
|
||||
p->nmissed++;
|
||||
prepare_singlestep(p, regs);
|
||||
kprobe_status = KPROBE_REENTER;
|
||||
return 1;
|
||||
} else {
|
||||
p = current_kprobe;
|
||||
if (p->break_handler && p->break_handler(p, regs)) {
|
||||
@ -163,11 +253,7 @@ static int kprobe_handler(struct pt_regs *regs)
|
||||
}
|
||||
|
||||
kprobe_status = KPROBE_HIT_ACTIVE;
|
||||
current_kprobe = p;
|
||||
kprobe_saved_eflags = kprobe_old_eflags
|
||||
= (regs->eflags & (TF_MASK | IF_MASK));
|
||||
if (is_IF_modifier(p->opcode))
|
||||
kprobe_saved_eflags &= ~IF_MASK;
|
||||
set_current_kprobe(p, regs);
|
||||
|
||||
if (p->pre_handler && p->pre_handler(p, regs))
|
||||
/* handler has already set things up, so skip ss setup */
|
||||
@ -183,6 +269,55 @@ no_kprobe:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* For function-return probes, init_kprobes() establishes a probepoint
|
||||
* here. When a retprobed function returns, this probe is hit and
|
||||
* trampoline_probe_handler() runs, calling the kretprobe's handler.
|
||||
*/
|
||||
void kretprobe_trampoline_holder(void)
|
||||
{
|
||||
asm volatile ( ".global kretprobe_trampoline\n"
|
||||
"kretprobe_trampoline: \n"
|
||||
"nop\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when we hit the probe point at kretprobe_trampoline
|
||||
*/
|
||||
int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct task_struct *tsk;
|
||||
struct kretprobe_instance *ri;
|
||||
struct hlist_head *head;
|
||||
struct hlist_node *node;
|
||||
unsigned long *sara = ((unsigned long *) ®s->esp) - 1;
|
||||
|
||||
tsk = arch_get_kprobe_task(sara);
|
||||
head = kretprobe_inst_table_head(tsk);
|
||||
|
||||
hlist_for_each_entry(ri, node, head, hlist) {
|
||||
if (ri->stack_addr == sara && ri->rp) {
|
||||
if (ri->rp->handler)
|
||||
ri->rp->handler(ri, regs);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void trampoline_post_handler(struct kprobe *p, struct pt_regs *regs,
|
||||
unsigned long flags)
|
||||
{
|
||||
struct kretprobe_instance *ri;
|
||||
/* RA already popped */
|
||||
unsigned long *sara = ((unsigned long *)®s->esp) - 1;
|
||||
|
||||
while ((ri = get_rp_inst(sara))) {
|
||||
regs->eip = (unsigned long)ri->ret_addr;
|
||||
recycle_rp_inst(ri);
|
||||
}
|
||||
regs->eflags &= ~TF_MASK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called after single-stepping. p->addr is the address of the
|
||||
* instruction whose first byte has been replaced by the "int 3"
|
||||
@ -263,13 +398,22 @@ static inline int post_kprobe_handler(struct pt_regs *regs)
|
||||
if (!kprobe_running())
|
||||
return 0;
|
||||
|
||||
if (current_kprobe->post_handler)
|
||||
if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
|
||||
kprobe_status = KPROBE_HIT_SSDONE;
|
||||
current_kprobe->post_handler(current_kprobe, regs, 0);
|
||||
}
|
||||
|
||||
resume_execution(current_kprobe, regs);
|
||||
if (current_kprobe->post_handler != trampoline_post_handler)
|
||||
resume_execution(current_kprobe, regs);
|
||||
regs->eflags |= kprobe_saved_eflags;
|
||||
|
||||
/*Restore back the original saved kprobes variables and continue. */
|
||||
if (kprobe_status == KPROBE_REENTER) {
|
||||
restore_previous_kprobe();
|
||||
goto out;
|
||||
}
|
||||
unlock_kprobes();
|
||||
out:
|
||||
preempt_enable_no_resched();
|
||||
|
||||
/*
|
||||
|
@ -914,7 +914,10 @@ void __init mp_register_ioapic (
|
||||
mp_ioapics[idx].mpc_apicaddr = address;
|
||||
|
||||
set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
|
||||
mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id);
|
||||
if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 < 15))
|
||||
mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id);
|
||||
else
|
||||
mp_ioapics[idx].mpc_apicid = id;
|
||||
mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx);
|
||||
|
||||
/*
|
||||
@ -1055,11 +1058,20 @@ void __init mp_config_acpi_legacy_irqs (void)
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_GSI_NUM 4096
|
||||
|
||||
int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
|
||||
{
|
||||
int ioapic = -1;
|
||||
int ioapic_pin = 0;
|
||||
int idx, bit = 0;
|
||||
static int pci_irq = 16;
|
||||
/*
|
||||
* Mapping between Global System Interrups, which
|
||||
* represent all possible interrupts, and IRQs
|
||||
* assigned to actual devices.
|
||||
*/
|
||||
static int gsi_to_irq[MAX_GSI_NUM];
|
||||
|
||||
#ifdef CONFIG_ACPI_BUS
|
||||
/* Don't set up the ACPI SCI because it's already set up */
|
||||
@ -1094,11 +1106,26 @@ int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
|
||||
if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
|
||||
Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
|
||||
mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
|
||||
return gsi;
|
||||
return gsi_to_irq[gsi];
|
||||
}
|
||||
|
||||
mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
|
||||
|
||||
if (edge_level) {
|
||||
/*
|
||||
* For PCI devices assign IRQs in order, avoiding gaps
|
||||
* due to unused I/O APIC pins.
|
||||
*/
|
||||
int irq = gsi;
|
||||
if (gsi < MAX_GSI_NUM) {
|
||||
gsi = pci_irq++;
|
||||
gsi_to_irq[irq] = gsi;
|
||||
} else {
|
||||
printk(KERN_ERR "GSI %u is too high\n", gsi);
|
||||
return gsi;
|
||||
}
|
||||
}
|
||||
|
||||
io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
|
||||
edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
|
||||
active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);
|
||||
|
@ -28,8 +28,7 @@
|
||||
#include <linux/sysctl.h>
|
||||
|
||||
#include <asm/smp.h>
|
||||
#include <asm/mtrr.h>
|
||||
#include <asm/mpspec.h>
|
||||
#include <asm/div64.h>
|
||||
#include <asm/nmi.h>
|
||||
|
||||
#include "mach_traps.h"
|
||||
@ -324,6 +323,16 @@ static void clear_msr_range(unsigned int base, unsigned int n)
|
||||
wrmsr(base+i, 0, 0);
|
||||
}
|
||||
|
||||
static inline void write_watchdog_counter(const char *descr)
|
||||
{
|
||||
u64 count = (u64)cpu_khz * 1000;
|
||||
|
||||
do_div(count, nmi_hz);
|
||||
if(descr)
|
||||
Dprintk("setting %s to -0x%08Lx\n", descr, count);
|
||||
wrmsrl(nmi_perfctr_msr, 0 - count);
|
||||
}
|
||||
|
||||
static void setup_k7_watchdog(void)
|
||||
{
|
||||
unsigned int evntsel;
|
||||
@ -339,8 +348,7 @@ static void setup_k7_watchdog(void)
|
||||
| K7_NMI_EVENT;
|
||||
|
||||
wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
|
||||
Dprintk("setting K7_PERFCTR0 to %08lx\n", -(cpu_khz/nmi_hz*1000));
|
||||
wrmsr(MSR_K7_PERFCTR0, -(cpu_khz/nmi_hz*1000), -1);
|
||||
write_watchdog_counter("K7_PERFCTR0");
|
||||
apic_write(APIC_LVTPC, APIC_DM_NMI);
|
||||
evntsel |= K7_EVNTSEL_ENABLE;
|
||||
wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
|
||||
@ -361,8 +369,7 @@ static void setup_p6_watchdog(void)
|
||||
| P6_NMI_EVENT;
|
||||
|
||||
wrmsr(MSR_P6_EVNTSEL0, evntsel, 0);
|
||||
Dprintk("setting P6_PERFCTR0 to %08lx\n", -(cpu_khz/nmi_hz*1000));
|
||||
wrmsr(MSR_P6_PERFCTR0, -(cpu_khz/nmi_hz*1000), 0);
|
||||
write_watchdog_counter("P6_PERFCTR0");
|
||||
apic_write(APIC_LVTPC, APIC_DM_NMI);
|
||||
evntsel |= P6_EVNTSEL0_ENABLE;
|
||||
wrmsr(MSR_P6_EVNTSEL0, evntsel, 0);
|
||||
@ -402,8 +409,7 @@ static int setup_p4_watchdog(void)
|
||||
|
||||
wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0);
|
||||
wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0);
|
||||
Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz/nmi_hz*1000));
|
||||
wrmsr(MSR_P4_IQ_COUNTER0, -(cpu_khz/nmi_hz*1000), -1);
|
||||
write_watchdog_counter("P4_IQ_COUNTER0");
|
||||
apic_write(APIC_LVTPC, APIC_DM_NMI);
|
||||
wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0);
|
||||
return 1;
|
||||
@ -518,7 +524,7 @@ void nmi_watchdog_tick (struct pt_regs * regs)
|
||||
* other P6 variant */
|
||||
apic_write(APIC_LVTPC, APIC_DM_NMI);
|
||||
}
|
||||
wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1);
|
||||
write_watchdog_counter(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
struct dma_coherent_mem {
|
||||
@ -54,6 +55,7 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(dma_alloc_coherent);
|
||||
|
||||
void dma_free_coherent(struct device *dev, size_t size,
|
||||
void *vaddr, dma_addr_t dma_handle)
|
||||
@ -68,6 +70,7 @@ void dma_free_coherent(struct device *dev, size_t size,
|
||||
} else
|
||||
free_pages((unsigned long)vaddr, order);
|
||||
}
|
||||
EXPORT_SYMBOL(dma_free_coherent);
|
||||
|
||||
int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
|
||||
dma_addr_t device_addr, size_t size, int flags)
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/kprobes.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/pgtable.h>
|
||||
@ -73,6 +74,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
|
||||
* Powermanagement idle function, if any..
|
||||
*/
|
||||
void (*pm_idle)(void);
|
||||
EXPORT_SYMBOL(pm_idle);
|
||||
static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
|
||||
|
||||
void disable_hlt(void)
|
||||
@ -105,6 +107,9 @@ void default_idle(void)
|
||||
cpu_relax();
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_APM_MODULE
|
||||
EXPORT_SYMBOL(default_idle);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On SMP it's slightly faster (but much more power-consuming!)
|
||||
@ -262,7 +267,7 @@ void show_regs(struct pt_regs * regs)
|
||||
printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
|
||||
print_symbol("EIP is at %s\n", regs->eip);
|
||||
|
||||
if (regs->xcs & 3)
|
||||
if (user_mode(regs))
|
||||
printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
|
||||
printk(" EFLAGS: %08lx %s (%s)\n",
|
||||
regs->eflags, print_tainted(), system_utsname.release);
|
||||
@ -325,6 +330,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
|
||||
/* Ok, create the new process.. */
|
||||
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(kernel_thread);
|
||||
|
||||
/*
|
||||
* Free current thread data structures etc..
|
||||
@ -334,6 +340,13 @@ void exit_thread(void)
|
||||
struct task_struct *tsk = current;
|
||||
struct thread_struct *t = &tsk->thread;
|
||||
|
||||
/*
|
||||
* Remove function-return probe instances associated with this task
|
||||
* and put them back on the free list. Do not insert an exit probe for
|
||||
* this function, it will be disabled by kprobe_flush_task if you do.
|
||||
*/
|
||||
kprobe_flush_task(tsk);
|
||||
|
||||
/* The process may have allocated an io port bitmap... nuke it. */
|
||||
if (unlikely(NULL != t->io_bitmap_ptr)) {
|
||||
int cpu = get_cpu();
|
||||
@ -357,6 +370,13 @@ void flush_thread(void)
|
||||
{
|
||||
struct task_struct *tsk = current;
|
||||
|
||||
/*
|
||||
* Remove function-return probe instances associated with this task
|
||||
* and put them back on the free list. Do not insert an exit probe for
|
||||
* this function, it will be disabled by kprobe_flush_task if you do.
|
||||
*/
|
||||
kprobe_flush_task(tsk);
|
||||
|
||||
memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
|
||||
memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
|
||||
/*
|
||||
@ -508,6 +528,7 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
|
||||
|
||||
dump->u_fpvalid = dump_fpu (regs, &dump->i387);
|
||||
}
|
||||
EXPORT_SYMBOL(dump_thread);
|
||||
|
||||
/*
|
||||
* Capture the user space registers if the task is not running (in user space)
|
||||
@ -627,13 +648,13 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
|
||||
* Now maybe reload the debug registers
|
||||
*/
|
||||
if (unlikely(next->debugreg[7])) {
|
||||
loaddebug(next, 0);
|
||||
loaddebug(next, 1);
|
||||
loaddebug(next, 2);
|
||||
loaddebug(next, 3);
|
||||
set_debugreg(current->thread.debugreg[0], 0);
|
||||
set_debugreg(current->thread.debugreg[1], 1);
|
||||
set_debugreg(current->thread.debugreg[2], 2);
|
||||
set_debugreg(current->thread.debugreg[3], 3);
|
||||
/* no 4 and 5 */
|
||||
loaddebug(next, 6);
|
||||
loaddebug(next, 7);
|
||||
set_debugreg(current->thread.debugreg[6], 6);
|
||||
set_debugreg(current->thread.debugreg[7], 7);
|
||||
}
|
||||
|
||||
if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr))
|
||||
@ -731,6 +752,7 @@ unsigned long get_wchan(struct task_struct *p)
|
||||
} while (count++ < 16);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(get_wchan);
|
||||
|
||||
/*
|
||||
* sys_alloc_thread_area: get a yet unused TLS descriptor index.
|
||||
|
@ -668,7 +668,7 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
|
||||
info.si_code = TRAP_BRKPT;
|
||||
|
||||
/* User-mode eip? */
|
||||
info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
|
||||
info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
|
||||
|
||||
/* Send us the fakey SIGTRAP */
|
||||
force_sig_info(SIGTRAP, &info, tsk);
|
||||
|
@ -2,6 +2,7 @@
|
||||
* linux/arch/i386/kernel/reboot.c
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
@ -19,6 +20,7 @@
|
||||
* Power off function, if any
|
||||
*/
|
||||
void (*pm_power_off)(void);
|
||||
EXPORT_SYMBOL(pm_power_off);
|
||||
|
||||
static int reboot_mode;
|
||||
static int reboot_thru_bios;
|
||||
@ -295,6 +297,9 @@ void machine_real_restart(unsigned char *code, int length)
|
||||
:
|
||||
: "i" ((void *) (0x1000 - sizeof (real_mode_switch) - 100)));
|
||||
}
|
||||
#ifdef CONFIG_APM_MODULE
|
||||
EXPORT_SYMBOL(machine_real_restart);
|
||||
#endif
|
||||
|
||||
void machine_restart(char * __unused)
|
||||
{
|
||||
|
@ -23,8 +23,10 @@
|
||||
* This file handles the architecture-dependent parts of initialization
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/mmzone.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/acpi.h>
|
||||
@ -73,6 +75,7 @@ EXPORT_SYMBOL(efi_enabled);
|
||||
struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
|
||||
/* common cpu data for all cpus */
|
||||
struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
|
||||
EXPORT_SYMBOL(boot_cpu_data);
|
||||
|
||||
unsigned long mmu_cr4_features;
|
||||
|
||||
@ -90,12 +93,18 @@ extern acpi_interrupt_flags acpi_sci_flags;
|
||||
|
||||
/* for MCA, but anyone else can use it if they want */
|
||||
unsigned int machine_id;
|
||||
#ifdef CONFIG_MCA
|
||||
EXPORT_SYMBOL(machine_id);
|
||||
#endif
|
||||
unsigned int machine_submodel_id;
|
||||
unsigned int BIOS_revision;
|
||||
unsigned int mca_pentium_flag;
|
||||
|
||||
/* For PCI or other memory-mapped resources */
|
||||
unsigned long pci_mem_start = 0x10000000;
|
||||
#ifdef CONFIG_PCI
|
||||
EXPORT_SYMBOL(pci_mem_start);
|
||||
#endif
|
||||
|
||||
/* Boot loader ID as an integer, for the benefit of proc_dointvec */
|
||||
int bootloader_type;
|
||||
@ -107,14 +116,26 @@ static unsigned int highmem_pages = -1;
|
||||
* Setup options
|
||||
*/
|
||||
struct drive_info_struct { char dummy[32]; } drive_info;
|
||||
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || \
|
||||
defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
|
||||
EXPORT_SYMBOL(drive_info);
|
||||
#endif
|
||||
struct screen_info screen_info;
|
||||
#ifdef CONFIG_VT
|
||||
EXPORT_SYMBOL(screen_info);
|
||||
#endif
|
||||
struct apm_info apm_info;
|
||||
EXPORT_SYMBOL(apm_info);
|
||||
struct sys_desc_table_struct {
|
||||
unsigned short length;
|
||||
unsigned char table[0];
|
||||
};
|
||||
struct edid_info edid_info;
|
||||
struct ist_info ist_info;
|
||||
#if defined(CONFIG_X86_SPEEDSTEP_SMI) || \
|
||||
defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
|
||||
EXPORT_SYMBOL(ist_info);
|
||||
#endif
|
||||
struct e820map e820;
|
||||
|
||||
extern void early_cpu_init(void);
|
||||
@ -1022,7 +1043,7 @@ static void __init reserve_ebda_region(void)
|
||||
reserve_bootmem(addr, PAGE_SIZE);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_DISCONTIGMEM
|
||||
#ifndef CONFIG_NEED_MULTIPLE_NODES
|
||||
void __init setup_bootmem_allocator(void);
|
||||
static unsigned long __init setup_memory(void)
|
||||
{
|
||||
@ -1072,9 +1093,9 @@ void __init zone_sizes_init(void)
|
||||
free_area_init(zones_size);
|
||||
}
|
||||
#else
|
||||
extern unsigned long setup_memory(void);
|
||||
extern unsigned long __init setup_memory(void);
|
||||
extern void zone_sizes_init(void);
|
||||
#endif /* !CONFIG_DISCONTIGMEM */
|
||||
#endif /* !CONFIG_NEED_MULTIPLE_NODES */
|
||||
|
||||
void __init setup_bootmem_allocator(void)
|
||||
{
|
||||
@ -1475,6 +1496,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
#endif
|
||||
paging_init();
|
||||
remapped_pgdat_init();
|
||||
sparse_init();
|
||||
zone_sizes_init();
|
||||
|
||||
/*
|
||||
|
@ -346,8 +346,8 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
|
||||
extern void __user __kernel_sigreturn;
|
||||
extern void __user __kernel_rt_sigreturn;
|
||||
|
||||
static void setup_frame(int sig, struct k_sigaction *ka,
|
||||
sigset_t *set, struct pt_regs * regs)
|
||||
static int setup_frame(int sig, struct k_sigaction *ka,
|
||||
sigset_t *set, struct pt_regs * regs)
|
||||
{
|
||||
void __user *restorer;
|
||||
struct sigframe __user *frame;
|
||||
@ -429,13 +429,14 @@ static void setup_frame(int sig, struct k_sigaction *ka,
|
||||
current->comm, current->pid, frame, regs->eip, frame->pretcode);
|
||||
#endif
|
||||
|
||||
return;
|
||||
return 1;
|
||||
|
||||
give_sigsegv:
|
||||
force_sigsegv(sig, current);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
sigset_t *set, struct pt_regs * regs)
|
||||
{
|
||||
void __user *restorer;
|
||||
@ -522,20 +523,23 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
current->comm, current->pid, frame, regs->eip, frame->pretcode);
|
||||
#endif
|
||||
|
||||
return;
|
||||
return 1;
|
||||
|
||||
give_sigsegv:
|
||||
force_sigsegv(sig, current);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, we're invoking a handler
|
||||
*/
|
||||
|
||||
static void
|
||||
static int
|
||||
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
|
||||
sigset_t *oldset, struct pt_regs * regs)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Are we from a system call? */
|
||||
if (regs->orig_eax >= 0) {
|
||||
/* If so, check system call restarting.. */
|
||||
@ -569,17 +573,19 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
|
||||
|
||||
/* Set up the stack frame */
|
||||
if (ka->sa.sa_flags & SA_SIGINFO)
|
||||
setup_rt_frame(sig, ka, info, oldset, regs);
|
||||
ret = setup_rt_frame(sig, ka, info, oldset, regs);
|
||||
else
|
||||
setup_frame(sig, ka, oldset, regs);
|
||||
ret = setup_frame(sig, ka, oldset, regs);
|
||||
|
||||
if (!(ka->sa.sa_flags & SA_NODEFER)) {
|
||||
if (ret && !(ka->sa.sa_flags & SA_NODEFER)) {
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
|
||||
sigaddset(¤t->blocked,sig);
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -599,7 +605,7 @@ int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset)
|
||||
* kernel mode. Just return without doing anything
|
||||
* if so.
|
||||
*/
|
||||
if ((regs->xcs & 3) != 3)
|
||||
if (!user_mode(regs))
|
||||
return 1;
|
||||
|
||||
if (current->flags & PF_FREEZE) {
|
||||
@ -618,12 +624,11 @@ int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset)
|
||||
* inside the kernel.
|
||||
*/
|
||||
if (unlikely(current->thread.debugreg[7])) {
|
||||
loaddebug(¤t->thread, 7);
|
||||
set_debugreg(current->thread.debugreg[7], 7);
|
||||
}
|
||||
|
||||
/* Whee! Actually deliver the signal. */
|
||||
handle_signal(signr, &info, &ka, oldset, regs);
|
||||
return 1;
|
||||
return handle_signal(signr, &info, &ka, oldset, regs);
|
||||
}
|
||||
|
||||
no_signal:
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <linux/mc146818rtc.h>
|
||||
#include <linux/cache.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/mtrr.h>
|
||||
#include <asm/tlbflush.h>
|
||||
@ -452,6 +453,7 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
|
||||
|
||||
preempt_enable();
|
||||
}
|
||||
EXPORT_SYMBOL(flush_tlb_page);
|
||||
|
||||
static void do_flush_tlb_all(void* info)
|
||||
{
|
||||
@ -547,6 +549,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(smp_call_function);
|
||||
|
||||
static void stop_this_cpu (void * dummy)
|
||||
{
|
||||
|
@ -60,6 +60,9 @@ static int __initdata smp_b_stepping;
|
||||
|
||||
/* Number of siblings per CPU package */
|
||||
int smp_num_siblings = 1;
|
||||
#ifdef CONFIG_X86_HT
|
||||
EXPORT_SYMBOL(smp_num_siblings);
|
||||
#endif
|
||||
int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
|
||||
EXPORT_SYMBOL(phys_proc_id);
|
||||
int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */
|
||||
@ -67,13 +70,16 @@ EXPORT_SYMBOL(cpu_core_id);
|
||||
|
||||
/* bitmap of online cpus */
|
||||
cpumask_t cpu_online_map;
|
||||
EXPORT_SYMBOL(cpu_online_map);
|
||||
|
||||
cpumask_t cpu_callin_map;
|
||||
cpumask_t cpu_callout_map;
|
||||
EXPORT_SYMBOL(cpu_callout_map);
|
||||
static cpumask_t smp_commenced_mask;
|
||||
|
||||
/* Per CPU bogomips and other parameters */
|
||||
struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
|
||||
EXPORT_SYMBOL(cpu_data);
|
||||
|
||||
u8 x86_cpu_to_apicid[NR_CPUS] =
|
||||
{ [0 ... NR_CPUS-1] = 0xff };
|
||||
@ -199,7 +205,7 @@ static void __init synchronize_tsc_bp (void)
|
||||
unsigned long long t0;
|
||||
unsigned long long sum, avg;
|
||||
long long delta;
|
||||
unsigned long one_usec;
|
||||
unsigned int one_usec;
|
||||
int buggy = 0;
|
||||
|
||||
printk(KERN_INFO "checking TSC synchronization across %u CPUs: ", num_booting_cpus());
|
||||
@ -885,8 +891,14 @@ static void smp_tune_scheduling (void)
|
||||
static int boot_cpu_logical_apicid;
|
||||
/* Where the IO area was mapped on multiquad, always 0 otherwise */
|
||||
void *xquad_portio;
|
||||
#ifdef CONFIG_X86_NUMAQ
|
||||
EXPORT_SYMBOL(xquad_portio);
|
||||
#endif
|
||||
|
||||
cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
|
||||
#ifdef CONFIG_X86_HT
|
||||
EXPORT_SYMBOL(cpu_sibling_map);
|
||||
#endif
|
||||
cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
|
||||
EXPORT_SYMBOL(cpu_core_map);
|
||||
|
||||
|
@ -77,11 +77,13 @@ u64 jiffies_64 = INITIAL_JIFFIES;
|
||||
|
||||
EXPORT_SYMBOL(jiffies_64);
|
||||
|
||||
unsigned long cpu_khz; /* Detected as we calibrate the TSC */
|
||||
unsigned int cpu_khz; /* Detected as we calibrate the TSC */
|
||||
EXPORT_SYMBOL(cpu_khz);
|
||||
|
||||
extern unsigned long wall_jiffies;
|
||||
|
||||
DEFINE_SPINLOCK(rtc_lock);
|
||||
EXPORT_SYMBOL(rtc_lock);
|
||||
|
||||
DEFINE_SPINLOCK(i8253_lock);
|
||||
EXPORT_SYMBOL(i8253_lock);
|
||||
@ -324,6 +326,8 @@ unsigned long get_cmos_time(void)
|
||||
|
||||
return retval;
|
||||
}
|
||||
EXPORT_SYMBOL(get_cmos_time);
|
||||
|
||||
static void sync_cmos_clock(unsigned long dummy);
|
||||
|
||||
static struct timer_list sync_cmos_timer =
|
||||
|
@ -139,6 +139,15 @@ bad_calibration:
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
unsigned long read_timer_tsc(void)
|
||||
{
|
||||
unsigned long retval;
|
||||
rdtscl(retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/* calculate cpu_khz */
|
||||
void init_cpu_khz(void)
|
||||
{
|
||||
@ -154,7 +163,8 @@ void init_cpu_khz(void)
|
||||
:"=a" (cpu_khz), "=d" (edx)
|
||||
:"r" (tsc_quotient),
|
||||
"0" (eax), "1" (edx));
|
||||
printk("Detected %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000);
|
||||
printk("Detected %u.%03u MHz processor.\n",
|
||||
cpu_khz / 1000, cpu_khz % 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,3 +64,12 @@ struct timer_opts* __init select_timer(void)
|
||||
panic("select_timer: Cannot find a suitable timer\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int read_current_timer(unsigned long *timer_val)
|
||||
{
|
||||
if (cur_timer->read_timer) {
|
||||
*timer_val = cur_timer->read_timer();
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ static int __init init_hpet(char* override)
|
||||
{ unsigned long eax=0, edx=1000;
|
||||
ASM_DIV64_REG(cpu_khz, edx, tsc_quotient,
|
||||
eax, edx);
|
||||
printk("Detected %lu.%03lu MHz processor.\n",
|
||||
printk("Detected %u.%03u MHz processor.\n",
|
||||
cpu_khz / 1000, cpu_khz % 1000);
|
||||
}
|
||||
set_cyc2ns_scale(cpu_khz/1000);
|
||||
@ -186,6 +186,7 @@ static struct timer_opts timer_hpet = {
|
||||
.get_offset = get_offset_hpet,
|
||||
.monotonic_clock = monotonic_clock_hpet,
|
||||
.delay = delay_hpet,
|
||||
.read_timer = read_timer_tsc,
|
||||
};
|
||||
|
||||
struct init_timer_opts __initdata timer_hpet_init = {
|
||||
|
@ -246,6 +246,7 @@ static struct timer_opts timer_pmtmr = {
|
||||
.get_offset = get_offset_pmtmr,
|
||||
.monotonic_clock = monotonic_clock_pmtmr,
|
||||
.delay = delay_pmtmr,
|
||||
.read_timer = read_timer_tsc,
|
||||
};
|
||||
|
||||
struct init_timer_opts __initdata timer_pmtmr_init = {
|
||||
|
@ -256,7 +256,7 @@ static unsigned long loops_per_jiffy_ref = 0;
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
static unsigned long fast_gettimeoffset_ref = 0;
|
||||
static unsigned long cpu_khz_ref = 0;
|
||||
static unsigned int cpu_khz_ref = 0;
|
||||
#endif
|
||||
|
||||
static int
|
||||
@ -323,7 +323,7 @@ static inline void cpufreq_delayed_get(void) { return; }
|
||||
int recalibrate_cpu_khz(void)
|
||||
{
|
||||
#ifndef CONFIG_SMP
|
||||
unsigned long cpu_khz_old = cpu_khz;
|
||||
unsigned int cpu_khz_old = cpu_khz;
|
||||
|
||||
if (cpu_has_tsc) {
|
||||
init_cpu_khz();
|
||||
@ -534,7 +534,8 @@ static int __init init_tsc(char* override)
|
||||
:"=a" (cpu_khz), "=d" (edx)
|
||||
:"r" (tsc_quotient),
|
||||
"0" (eax), "1" (edx));
|
||||
printk("Detected %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000);
|
||||
printk("Detected %u.%03u MHz processor.\n",
|
||||
cpu_khz / 1000, cpu_khz % 1000);
|
||||
}
|
||||
set_cyc2ns_scale(cpu_khz/1000);
|
||||
return 0;
|
||||
@ -572,6 +573,7 @@ static struct timer_opts timer_tsc = {
|
||||
.get_offset = get_offset_tsc,
|
||||
.monotonic_clock = monotonic_clock_tsc,
|
||||
.delay = delay_tsc,
|
||||
.read_timer = read_timer_tsc,
|
||||
};
|
||||
|
||||
struct init_timer_opts __initdata timer_tsc_init = {
|
||||
|
@ -104,6 +104,7 @@ int register_die_notifier(struct notifier_block *nb)
|
||||
spin_unlock_irqrestore(&die_notifier_lock, flags);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(register_die_notifier);
|
||||
|
||||
static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
|
||||
{
|
||||
@ -209,7 +210,7 @@ void show_registers(struct pt_regs *regs)
|
||||
|
||||
esp = (unsigned long) (®s->esp);
|
||||
ss = __KERNEL_DS;
|
||||
if (regs->xcs & 3) {
|
||||
if (user_mode(regs)) {
|
||||
in_kernel = 0;
|
||||
esp = regs->esp;
|
||||
ss = regs->xss & 0xffff;
|
||||
@ -265,7 +266,7 @@ static void handle_BUG(struct pt_regs *regs)
|
||||
char c;
|
||||
unsigned long eip;
|
||||
|
||||
if (regs->xcs & 3)
|
||||
if (user_mode(regs))
|
||||
goto no_bug; /* Not in kernel */
|
||||
|
||||
eip = regs->eip;
|
||||
@ -353,7 +354,7 @@ void die(const char * str, struct pt_regs * regs, long err)
|
||||
|
||||
static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
|
||||
{
|
||||
if (!(regs->eflags & VM_MASK) && !(3 & regs->xcs))
|
||||
if (!user_mode_vm(regs))
|
||||
die(str, regs, err);
|
||||
}
|
||||
|
||||
@ -366,7 +367,7 @@ static void do_trap(int trapnr, int signr, char *str, int vm86,
|
||||
goto trap_signal;
|
||||
}
|
||||
|
||||
if (!(regs->xcs & 3))
|
||||
if (!user_mode(regs))
|
||||
goto kernel_trap;
|
||||
|
||||
trap_signal: {
|
||||
@ -488,7 +489,7 @@ fastcall void do_general_protection(struct pt_regs * regs, long error_code)
|
||||
if (regs->eflags & VM_MASK)
|
||||
goto gp_in_vm86;
|
||||
|
||||
if (!(regs->xcs & 3))
|
||||
if (!user_mode(regs))
|
||||
goto gp_in_kernel;
|
||||
|
||||
current->thread.error_code = error_code;
|
||||
@ -636,11 +637,13 @@ void set_nmi_callback(nmi_callback_t callback)
|
||||
{
|
||||
nmi_callback = callback;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(set_nmi_callback);
|
||||
|
||||
void unset_nmi_callback(void)
|
||||
{
|
||||
nmi_callback = dummy_nmi_callback;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(unset_nmi_callback);
|
||||
|
||||
#ifdef CONFIG_KPROBES
|
||||
fastcall void do_int3(struct pt_regs *regs, long error_code)
|
||||
@ -682,7 +685,7 @@ fastcall void do_debug(struct pt_regs * regs, long error_code)
|
||||
unsigned int condition;
|
||||
struct task_struct *tsk = current;
|
||||
|
||||
__asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
|
||||
get_debugreg(condition, 6);
|
||||
|
||||
if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
|
||||
SIGTRAP) == NOTIFY_STOP)
|
||||
@ -713,7 +716,7 @@ fastcall void do_debug(struct pt_regs * regs, long error_code)
|
||||
* check for kernel mode by just checking the CPL
|
||||
* of CS.
|
||||
*/
|
||||
if ((regs->xcs & 3) == 0)
|
||||
if (!user_mode(regs))
|
||||
goto clear_TF_reenable;
|
||||
}
|
||||
|
||||
@ -724,9 +727,7 @@ fastcall void do_debug(struct pt_regs * regs, long error_code)
|
||||
* the signal is delivered.
|
||||
*/
|
||||
clear_dr7:
|
||||
__asm__("movl %0,%%db7"
|
||||
: /* no output */
|
||||
: "r" (0));
|
||||
set_debugreg(0, 7);
|
||||
return;
|
||||
|
||||
debug_vm86:
|
||||
|
@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
|
||||
@ -38,3 +39,4 @@ slow_path:
|
||||
spin_unlock(lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(_atomic_dec_and_lock);
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <linux/config.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/delay.h>
|
||||
#include <asm/timer.h>
|
||||
@ -47,3 +48,8 @@ void __ndelay(unsigned long nsecs)
|
||||
{
|
||||
__const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(__delay);
|
||||
EXPORT_SYMBOL(__const_udelay);
|
||||
EXPORT_SYMBOL(__udelay);
|
||||
EXPORT_SYMBOL(__ndelay);
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/i387.h>
|
||||
|
||||
@ -397,3 +398,7 @@ void mmx_copy_page(void *to, void *from)
|
||||
else
|
||||
fast_copy_page(to, from);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(_mmx_memcpy);
|
||||
EXPORT_SYMBOL(mmx_clear_page);
|
||||
EXPORT_SYMBOL(mmx_copy_page);
|
||||
|
@ -84,6 +84,7 @@ __strncpy_from_user(char *dst, const char __user *src, long count)
|
||||
__do_strncpy_from_user(dst, src, count, res);
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL(__strncpy_from_user);
|
||||
|
||||
/**
|
||||
* strncpy_from_user: - Copy a NUL terminated string from userspace.
|
||||
@ -111,7 +112,7 @@ strncpy_from_user(char *dst, const char __user *src, long count)
|
||||
__do_strncpy_from_user(dst, src, count, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(strncpy_from_user);
|
||||
|
||||
/*
|
||||
* Zero Userspace
|
||||
@ -157,6 +158,7 @@ clear_user(void __user *to, unsigned long n)
|
||||
__do_clear_user(to, n);
|
||||
return n;
|
||||
}
|
||||
EXPORT_SYMBOL(clear_user);
|
||||
|
||||
/**
|
||||
* __clear_user: - Zero a block of memory in user space, with less checking.
|
||||
@ -175,6 +177,7 @@ __clear_user(void __user *to, unsigned long n)
|
||||
__do_clear_user(to, n);
|
||||
return n;
|
||||
}
|
||||
EXPORT_SYMBOL(__clear_user);
|
||||
|
||||
/**
|
||||
* strlen_user: - Get the size of a string in user space.
|
||||
@ -218,6 +221,7 @@ long strnlen_user(const char __user *s, long n)
|
||||
:"cc");
|
||||
return res & mask;
|
||||
}
|
||||
EXPORT_SYMBOL(strnlen_user);
|
||||
|
||||
#ifdef CONFIG_X86_INTEL_USERCOPY
|
||||
static unsigned long
|
||||
@ -570,6 +574,7 @@ survive:
|
||||
n = __copy_user_intel(to, from, n);
|
||||
return n;
|
||||
}
|
||||
EXPORT_SYMBOL(__copy_to_user_ll);
|
||||
|
||||
unsigned long
|
||||
__copy_from_user_ll(void *to, const void __user *from, unsigned long n)
|
||||
@ -581,6 +586,7 @@ __copy_from_user_ll(void *to, const void __user *from, unsigned long n)
|
||||
n = __copy_user_zeroing_intel(to, from, n);
|
||||
return n;
|
||||
}
|
||||
EXPORT_SYMBOL(__copy_from_user_ll);
|
||||
|
||||
/**
|
||||
* copy_to_user: - Copy a block of data into user space.
|
||||
|
@ -1288,7 +1288,7 @@ smp_local_timer_interrupt(struct pt_regs * regs)
|
||||
per_cpu(prof_counter, cpu);
|
||||
}
|
||||
|
||||
update_process_times(user_mode(regs));
|
||||
update_process_times(user_mode_vm(regs));
|
||||
}
|
||||
|
||||
if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
obj-y := init.o pgtable.o fault.o ioremap.o extable.o pageattr.o mmap.o
|
||||
|
||||
obj-$(CONFIG_DISCONTIGMEM) += discontig.o
|
||||
obj-$(CONFIG_NUMA) += discontig.o
|
||||
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
|
||||
obj-$(CONFIG_HIGHMEM) += highmem.o
|
||||
obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap.o
|
||||
|
@ -29,12 +29,14 @@
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/initrd.h>
|
||||
#include <linux/nodemask.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/e820.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/mmzone.h>
|
||||
#include <bios_ebda.h>
|
||||
|
||||
struct pglist_data *node_data[MAX_NUMNODES];
|
||||
EXPORT_SYMBOL(node_data);
|
||||
bootmem_data_t node0_bdata;
|
||||
|
||||
/*
|
||||
@ -42,12 +44,16 @@ bootmem_data_t node0_bdata;
|
||||
* populated the following initialisation.
|
||||
*
|
||||
* 1) node_online_map - the map of all nodes configured (online) in the system
|
||||
* 2) physnode_map - the mapping between a pfn and owning node
|
||||
* 3) node_start_pfn - the starting page frame number for a node
|
||||
* 2) node_start_pfn - the starting page frame number for a node
|
||||
* 3) node_end_pfn - the ending page fram number for a node
|
||||
*/
|
||||
unsigned long node_start_pfn[MAX_NUMNODES];
|
||||
unsigned long node_end_pfn[MAX_NUMNODES];
|
||||
|
||||
|
||||
#ifdef CONFIG_DISCONTIGMEM
|
||||
/*
|
||||
* 4) physnode_map - the mapping between a pfn and owning node
|
||||
* physnode_map keeps track of the physical memory layout of a generic
|
||||
* numa node on a 256Mb break (each element of the array will
|
||||
* represent 256Mb of memory and will be marked by the node id. so,
|
||||
@ -59,6 +65,7 @@ bootmem_data_t node0_bdata;
|
||||
* physnode_map[8- ] = -1;
|
||||
*/
|
||||
s8 physnode_map[MAX_ELEMENTS] = { [0 ... (MAX_ELEMENTS - 1)] = -1};
|
||||
EXPORT_SYMBOL(physnode_map);
|
||||
|
||||
void memory_present(int nid, unsigned long start, unsigned long end)
|
||||
{
|
||||
@ -85,9 +92,7 @@ unsigned long node_memmap_size_bytes(int nid, unsigned long start_pfn,
|
||||
|
||||
return (nr_pages + 1) * sizeof(struct page);
|
||||
}
|
||||
|
||||
unsigned long node_start_pfn[MAX_NUMNODES];
|
||||
unsigned long node_end_pfn[MAX_NUMNODES];
|
||||
#endif
|
||||
|
||||
extern unsigned long find_max_low_pfn(void);
|
||||
extern void find_max_pfn(void);
|
||||
@ -108,6 +113,9 @@ unsigned long node_remap_offset[MAX_NUMNODES];
|
||||
void *node_remap_start_vaddr[MAX_NUMNODES];
|
||||
void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
|
||||
|
||||
void *node_remap_end_vaddr[MAX_NUMNODES];
|
||||
void *node_remap_alloc_vaddr[MAX_NUMNODES];
|
||||
|
||||
/*
|
||||
* FLAT - support for basic PC memory model with discontig enabled, essentially
|
||||
* a single node with all available processors in it with a flat
|
||||
@ -146,6 +154,21 @@ static void __init find_max_pfn_node(int nid)
|
||||
BUG();
|
||||
}
|
||||
|
||||
/* Find the owning node for a pfn. */
|
||||
int early_pfn_to_nid(unsigned long pfn)
|
||||
{
|
||||
int nid;
|
||||
|
||||
for_each_node(nid) {
|
||||
if (node_end_pfn[nid] == 0)
|
||||
break;
|
||||
if (node_start_pfn[nid] <= pfn && node_end_pfn[nid] >= pfn)
|
||||
return nid;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate memory for the pg_data_t for this node via a crude pre-bootmem
|
||||
* method. For node zero take this from the bottom of memory, for
|
||||
@ -163,6 +186,21 @@ static void __init allocate_pgdat(int nid)
|
||||
}
|
||||
}
|
||||
|
||||
void *alloc_remap(int nid, unsigned long size)
|
||||
{
|
||||
void *allocation = node_remap_alloc_vaddr[nid];
|
||||
|
||||
size = ALIGN(size, L1_CACHE_BYTES);
|
||||
|
||||
if (!allocation || (allocation + size) >= node_remap_end_vaddr[nid])
|
||||
return 0;
|
||||
|
||||
node_remap_alloc_vaddr[nid] += size;
|
||||
memset(allocation, 0, size);
|
||||
|
||||
return allocation;
|
||||
}
|
||||
|
||||
void __init remap_numa_kva(void)
|
||||
{
|
||||
void *vaddr;
|
||||
@ -170,8 +208,6 @@ void __init remap_numa_kva(void)
|
||||
int node;
|
||||
|
||||
for_each_online_node(node) {
|
||||
if (node == 0)
|
||||
continue;
|
||||
for (pfn=0; pfn < node_remap_size[node]; pfn += PTRS_PER_PTE) {
|
||||
vaddr = node_remap_start_vaddr[node]+(pfn<<PAGE_SHIFT);
|
||||
set_pmd_pfn((ulong) vaddr,
|
||||
@ -185,13 +221,9 @@ static unsigned long calculate_numa_remap_pages(void)
|
||||
{
|
||||
int nid;
|
||||
unsigned long size, reserve_pages = 0;
|
||||
unsigned long pfn;
|
||||
|
||||
for_each_online_node(nid) {
|
||||
if (nid == 0)
|
||||
continue;
|
||||
if (!node_remap_size[nid])
|
||||
continue;
|
||||
|
||||
/*
|
||||
* The acpi/srat node info can show hot-add memroy zones
|
||||
* where memory could be added but not currently present.
|
||||
@ -208,11 +240,24 @@ static unsigned long calculate_numa_remap_pages(void)
|
||||
size = (size + LARGE_PAGE_BYTES - 1) / LARGE_PAGE_BYTES;
|
||||
/* now the roundup is correct, convert to PAGE_SIZE pages */
|
||||
size = size * PTRS_PER_PTE;
|
||||
|
||||
/*
|
||||
* Validate the region we are allocating only contains valid
|
||||
* pages.
|
||||
*/
|
||||
for (pfn = node_end_pfn[nid] - size;
|
||||
pfn < node_end_pfn[nid]; pfn++)
|
||||
if (!page_is_ram(pfn))
|
||||
break;
|
||||
|
||||
if (pfn != node_end_pfn[nid])
|
||||
size = 0;
|
||||
|
||||
printk("Reserving %ld pages of KVA for lmem_map of node %d\n",
|
||||
size, nid);
|
||||
node_remap_size[nid] = size;
|
||||
reserve_pages += size;
|
||||
node_remap_offset[nid] = reserve_pages;
|
||||
reserve_pages += size;
|
||||
printk("Shrinking node %d from %ld pages to %ld pages\n",
|
||||
nid, node_end_pfn[nid], node_end_pfn[nid] - size);
|
||||
node_end_pfn[nid] -= size;
|
||||
@ -265,12 +310,18 @@ unsigned long __init setup_memory(void)
|
||||
(ulong) pfn_to_kaddr(max_low_pfn));
|
||||
for_each_online_node(nid) {
|
||||
node_remap_start_vaddr[nid] = pfn_to_kaddr(
|
||||
(highstart_pfn + reserve_pages) - node_remap_offset[nid]);
|
||||
highstart_pfn + node_remap_offset[nid]);
|
||||
/* Init the node remap allocator */
|
||||
node_remap_end_vaddr[nid] = node_remap_start_vaddr[nid] +
|
||||
(node_remap_size[nid] * PAGE_SIZE);
|
||||
node_remap_alloc_vaddr[nid] = node_remap_start_vaddr[nid] +
|
||||
ALIGN(sizeof(pg_data_t), PAGE_SIZE);
|
||||
|
||||
allocate_pgdat(nid);
|
||||
printk ("node %d will remap to vaddr %08lx - %08lx\n", nid,
|
||||
(ulong) node_remap_start_vaddr[nid],
|
||||
(ulong) pfn_to_kaddr(highstart_pfn + reserve_pages
|
||||
- node_remap_offset[nid] + node_remap_size[nid]));
|
||||
(ulong) pfn_to_kaddr(highstart_pfn
|
||||
+ node_remap_offset[nid] + node_remap_size[nid]));
|
||||
}
|
||||
printk("High memory starts at vaddr %08lx\n",
|
||||
(ulong) pfn_to_kaddr(highstart_pfn));
|
||||
@ -333,23 +384,9 @@ void __init zone_sizes_init(void)
|
||||
}
|
||||
|
||||
zholes_size = get_zholes_size(nid);
|
||||
/*
|
||||
* We let the lmem_map for node 0 be allocated from the
|
||||
* normal bootmem allocator, but other nodes come from the
|
||||
* remapped KVA area - mbligh
|
||||
*/
|
||||
if (!nid)
|
||||
free_area_init_node(nid, NODE_DATA(nid),
|
||||
zones_size, start, zholes_size);
|
||||
else {
|
||||
unsigned long lmem_map;
|
||||
lmem_map = (unsigned long)node_remap_start_vaddr[nid];
|
||||
lmem_map += sizeof(pg_data_t) + PAGE_SIZE - 1;
|
||||
lmem_map &= PAGE_MASK;
|
||||
NODE_DATA(nid)->node_mem_map = (struct page *)lmem_map;
|
||||
free_area_init_node(nid, NODE_DATA(nid), zones_size,
|
||||
start, zholes_size);
|
||||
}
|
||||
|
||||
free_area_init_node(nid, NODE_DATA(nid), zones_size, start,
|
||||
zholes_size);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -358,24 +395,26 @@ void __init set_highmem_pages_init(int bad_ppro)
|
||||
{
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
struct zone *zone;
|
||||
struct page *page;
|
||||
|
||||
for_each_zone(zone) {
|
||||
unsigned long node_pfn, node_high_size, zone_start_pfn;
|
||||
struct page * zone_mem_map;
|
||||
|
||||
unsigned long node_pfn, zone_start_pfn, zone_end_pfn;
|
||||
|
||||
if (!is_highmem(zone))
|
||||
continue;
|
||||
|
||||
printk("Initializing %s for node %d\n", zone->name,
|
||||
zone->zone_pgdat->node_id);
|
||||
|
||||
node_high_size = zone->spanned_pages;
|
||||
zone_mem_map = zone->zone_mem_map;
|
||||
zone_start_pfn = zone->zone_start_pfn;
|
||||
zone_end_pfn = zone_start_pfn + zone->spanned_pages;
|
||||
|
||||
for (node_pfn = 0; node_pfn < node_high_size; node_pfn++) {
|
||||
one_highpage_init((struct page *)(zone_mem_map + node_pfn),
|
||||
zone_start_pfn + node_pfn, bad_ppro);
|
||||
printk("Initializing %s for node %d (%08lx:%08lx)\n",
|
||||
zone->name, zone->zone_pgdat->node_id,
|
||||
zone_start_pfn, zone_end_pfn);
|
||||
|
||||
for (node_pfn = zone_start_pfn; node_pfn < zone_end_pfn; node_pfn++) {
|
||||
if (!pfn_valid(node_pfn))
|
||||
continue;
|
||||
page = pfn_to_page(node_pfn);
|
||||
one_highpage_init(page, node_pfn, bad_ppro);
|
||||
}
|
||||
}
|
||||
totalram_pages += totalhigh_pages;
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
void *kmap(struct page *page)
|
||||
{
|
||||
@ -87,3 +88,8 @@ struct page *kmap_atomic_to_page(void *ptr)
|
||||
return pte_page(*pte);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(kmap);
|
||||
EXPORT_SYMBOL(kunmap);
|
||||
EXPORT_SYMBOL(kmap_atomic);
|
||||
EXPORT_SYMBOL(kunmap_atomic);
|
||||
EXPORT_SYMBOL(kmap_atomic_to_page);
|
||||
|
@ -191,7 +191,7 @@ static inline int page_kills_ppro(unsigned long pagenr)
|
||||
|
||||
extern int is_available_memory(efi_memory_desc_t *);
|
||||
|
||||
static inline int page_is_ram(unsigned long pagenr)
|
||||
int page_is_ram(unsigned long pagenr)
|
||||
{
|
||||
int i;
|
||||
unsigned long addr, end;
|
||||
@ -276,7 +276,9 @@ void __init one_highpage_init(struct page *page, int pfn, int bad_ppro)
|
||||
SetPageReserved(page);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_DISCONTIGMEM
|
||||
#ifdef CONFIG_NUMA
|
||||
extern void set_highmem_pages_init(int);
|
||||
#else
|
||||
static void __init set_highmem_pages_init(int bad_ppro)
|
||||
{
|
||||
int pfn;
|
||||
@ -284,9 +286,7 @@ static void __init set_highmem_pages_init(int bad_ppro)
|
||||
one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro);
|
||||
totalram_pages += totalhigh_pages;
|
||||
}
|
||||
#else
|
||||
extern void set_highmem_pages_init(int);
|
||||
#endif /* !CONFIG_DISCONTIGMEM */
|
||||
#endif /* CONFIG_FLATMEM */
|
||||
|
||||
#else
|
||||
#define kmap_init() do { } while (0)
|
||||
@ -295,12 +295,13 @@ extern void set_highmem_pages_init(int);
|
||||
#endif /* CONFIG_HIGHMEM */
|
||||
|
||||
unsigned long long __PAGE_KERNEL = _PAGE_KERNEL;
|
||||
EXPORT_SYMBOL(__PAGE_KERNEL);
|
||||
unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
|
||||
|
||||
#ifndef CONFIG_DISCONTIGMEM
|
||||
#define remap_numa_kva() do {} while (0)
|
||||
#else
|
||||
#ifdef CONFIG_NUMA
|
||||
extern void __init remap_numa_kva(void);
|
||||
#else
|
||||
#define remap_numa_kva() do {} while (0)
|
||||
#endif
|
||||
|
||||
static void __init pagetable_init (void)
|
||||
@ -525,7 +526,7 @@ static void __init set_max_mapnr_init(void)
|
||||
#else
|
||||
num_physpages = max_low_pfn;
|
||||
#endif
|
||||
#ifndef CONFIG_DISCONTIGMEM
|
||||
#ifdef CONFIG_FLATMEM
|
||||
max_mapnr = num_physpages;
|
||||
#endif
|
||||
}
|
||||
@ -539,7 +540,7 @@ void __init mem_init(void)
|
||||
int tmp;
|
||||
int bad_ppro;
|
||||
|
||||
#ifndef CONFIG_DISCONTIGMEM
|
||||
#ifdef CONFIG_FLATMEM
|
||||
if (!mem_map)
|
||||
BUG();
|
||||
#endif
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/cacheflush.h>
|
||||
@ -165,7 +166,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
|
||||
}
|
||||
return (void __iomem *) (offset + (char __iomem *)addr);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(__ioremap);
|
||||
|
||||
/**
|
||||
* ioremap_nocache - map bus memory into CPU space
|
||||
@ -222,6 +223,7 @@ void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size)
|
||||
|
||||
return p;
|
||||
}
|
||||
EXPORT_SYMBOL(ioremap_nocache);
|
||||
|
||||
void iounmap(volatile void __iomem *addr)
|
||||
{
|
||||
@ -255,6 +257,7 @@ out_unlock:
|
||||
write_unlock(&vmlist_lock);
|
||||
kfree(p);
|
||||
}
|
||||
EXPORT_SYMBOL(iounmap);
|
||||
|
||||
void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
|
||||
{
|
||||
|
@ -30,13 +30,14 @@ void show_mem(void)
|
||||
struct page *page;
|
||||
pg_data_t *pgdat;
|
||||
unsigned long i;
|
||||
struct page_state ps;
|
||||
|
||||
printk("Mem-info:\n");
|
||||
show_free_areas();
|
||||
printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
|
||||
for_each_pgdat(pgdat) {
|
||||
for (i = 0; i < pgdat->node_spanned_pages; ++i) {
|
||||
page = pgdat->node_mem_map + i;
|
||||
page = pgdat_page_nr(pgdat, i);
|
||||
total++;
|
||||
if (PageHighMem(page))
|
||||
highmem++;
|
||||
@ -53,6 +54,13 @@ void show_mem(void)
|
||||
printk("%d reserved pages\n",reserved);
|
||||
printk("%d pages shared\n",shared);
|
||||
printk("%d pages swap cached\n",cached);
|
||||
|
||||
get_page_state(&ps);
|
||||
printk("%lu pages dirty\n", ps.nr_dirty);
|
||||
printk("%lu pages writeback\n", ps.nr_writeback);
|
||||
printk("%lu pages mapped\n", ps.nr_mapped);
|
||||
printk("%lu pages slab\n", ps.nr_slab);
|
||||
printk("%lu pages pagetables\n", ps.nr_page_table_pages);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -91,7 +91,7 @@ x86_backtrace(struct pt_regs * const regs, unsigned int depth)
|
||||
head = (struct frame_head *)regs->ebp;
|
||||
#endif
|
||||
|
||||
if (!user_mode(regs)) {
|
||||
if (!user_mode_vm(regs)) {
|
||||
while (depth-- && valid_kernel_stack(head, regs))
|
||||
head = dump_backtrace(head);
|
||||
return;
|
||||
|
@ -226,6 +226,24 @@ static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, i
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The VIA pirq rules are nibble-based, like ALI,
|
||||
* but without the ugly irq number munging.
|
||||
* However, for 82C586, nibble map is different .
|
||||
*/
|
||||
static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
|
||||
{
|
||||
static unsigned int pirqmap[4] = { 3, 2, 5, 1 };
|
||||
return read_config_nybble(router, 0x55, pirqmap[pirq-1]);
|
||||
}
|
||||
|
||||
static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
|
||||
{
|
||||
static unsigned int pirqmap[4] = { 3, 2, 5, 1 };
|
||||
write_config_nybble(router, 0x55, pirqmap[pirq-1], irq);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* ITE 8330G pirq rules are nibble-based
|
||||
* FIXME: pirqmap may be { 1, 0, 3, 2 },
|
||||
@ -512,6 +530,10 @@ static __init int via_router_probe(struct irq_router *r, struct pci_dev *router,
|
||||
switch(device)
|
||||
{
|
||||
case PCI_DEVICE_ID_VIA_82C586_0:
|
||||
r->name = "VIA";
|
||||
r->get = pirq_via586_get;
|
||||
r->set = pirq_via586_set;
|
||||
return 1;
|
||||
case PCI_DEVICE_ID_VIA_82C596:
|
||||
case PCI_DEVICE_ID_VIA_82C686:
|
||||
case PCI_DEVICE_ID_VIA_8231:
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include "pci.h"
|
||||
#include "pci-functions.h"
|
||||
|
||||
@ -456,7 +457,7 @@ struct irq_routing_table * __devinit pcibios_get_irq_routing_table(void)
|
||||
free_page(page);
|
||||
return rt;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(pcibios_get_irq_routing_table);
|
||||
|
||||
int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
|
||||
{
|
||||
@ -473,6 +474,7 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
|
||||
"S" (&pci_indirect));
|
||||
return !(ret & 0xff00);
|
||||
}
|
||||
EXPORT_SYMBOL(pcibios_set_irq_routing);
|
||||
|
||||
static int __init pci_pcbios_init(void)
|
||||
{
|
||||
|
@ -94,13 +94,13 @@ static void fix_processor_context(void)
|
||||
* Now maybe reload the debug registers
|
||||
*/
|
||||
if (current->thread.debugreg[7]){
|
||||
loaddebug(¤t->thread, 0);
|
||||
loaddebug(¤t->thread, 1);
|
||||
loaddebug(¤t->thread, 2);
|
||||
loaddebug(¤t->thread, 3);
|
||||
/* no 4 and 5 */
|
||||
loaddebug(¤t->thread, 6);
|
||||
loaddebug(¤t->thread, 7);
|
||||
set_debugreg(current->thread.debugreg[0], 0);
|
||||
set_debugreg(current->thread.debugreg[1], 1);
|
||||
set_debugreg(current->thread.debugreg[2], 2);
|
||||
set_debugreg(current->thread.debugreg[3], 3);
|
||||
/* no 4 and 5 */
|
||||
set_debugreg(current->thread.debugreg[6], 6);
|
||||
set_debugreg(current->thread.debugreg[7], 7);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -161,6 +161,8 @@ config IA64_PAGE_SIZE_64KB
|
||||
|
||||
endchoice
|
||||
|
||||
source kernel/Kconfig.hz
|
||||
|
||||
config IA64_BRL_EMU
|
||||
bool
|
||||
depends on ITANIUM
|
||||
@ -197,7 +199,7 @@ config HOLES_IN_ZONE
|
||||
bool
|
||||
default y if VIRTUAL_MEM_MAP
|
||||
|
||||
config DISCONTIGMEM
|
||||
config ARCH_DISCONTIGMEM_ENABLE
|
||||
bool "Discontiguous memory support"
|
||||
depends on (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB) && NUMA && VIRTUAL_MEM_MAP
|
||||
default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA
|
||||
@ -300,6 +302,8 @@ config PREEMPT
|
||||
Say Y here if you are building a kernel for a desktop, embedded
|
||||
or real-time system. Say N if you are unsure.
|
||||
|
||||
source "mm/Kconfig"
|
||||
|
||||
config HAVE_DEC_LOCK
|
||||
bool
|
||||
depends on (SMP || PREEMPT)
|
||||
|
@ -2,6 +2,17 @@ menu "Kernel hacking"
|
||||
|
||||
source "lib/Kconfig.debug"
|
||||
|
||||
config KPROBES
|
||||
bool "Kprobes"
|
||||
depends on DEBUG_KERNEL
|
||||
help
|
||||
Kprobes allows you to trap at almost any kernel address and
|
||||
execute a callback function. register_kprobe() establishes
|
||||
a probepoint and specifies the callback. Kprobes is useful
|
||||
for kernel debugging, non-intrusive instrumentation and testing.
|
||||
If in doubt, say "N".
|
||||
|
||||
|
||||
choice
|
||||
prompt "Physical memory granularity"
|
||||
default IA64_GRANULE_64MB
|
||||
|
@ -78,7 +78,7 @@ CONFIG_IA64_L1_CACHE_SHIFT=7
|
||||
CONFIG_NUMA=y
|
||||
CONFIG_VIRTUAL_MEM_MAP=y
|
||||
CONFIG_HOLES_IN_ZONE=y
|
||||
CONFIG_DISCONTIGMEM=y
|
||||
CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
|
||||
# CONFIG_IA64_CYCLONE is not set
|
||||
CONFIG_IOSAPIC=y
|
||||
CONFIG_IA64_SGI_SN_SIM=y
|
||||
|
@ -84,7 +84,7 @@ CONFIG_IA64_L1_CACHE_SHIFT=7
|
||||
CONFIG_NUMA=y
|
||||
CONFIG_VIRTUAL_MEM_MAP=y
|
||||
CONFIG_HOLES_IN_ZONE=y
|
||||
CONFIG_DISCONTIGMEM=y
|
||||
CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
|
||||
CONFIG_IA64_CYCLONE=y
|
||||
CONFIG_IOSAPIC=y
|
||||
CONFIG_FORCE_MAX_ZONEORDER=18
|
||||
|
@ -241,7 +241,7 @@ typedef struct compat_siginfo {
|
||||
|
||||
/* POSIX.1b timers */
|
||||
struct {
|
||||
timer_t _tid; /* timer id */
|
||||
compat_timer_t _tid; /* timer id */
|
||||
int _overrun; /* overrun count */
|
||||
char _pad[sizeof(unsigned int) - sizeof(int)];
|
||||
compat_sigval_t _sigval; /* same as below */
|
||||
|
@ -20,6 +20,7 @@ obj-$(CONFIG_SMP) += smp.o smpboot.o domain.o
|
||||
obj-$(CONFIG_PERFMON) += perfmon_default_smpl.o
|
||||
obj-$(CONFIG_IA64_CYCLONE) += cyclone.o
|
||||
obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o
|
||||
obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o
|
||||
obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o
|
||||
mca_recovery-y += mca_drv.o mca_drv_asm.o
|
||||
|
||||
|
61
arch/ia64/kernel/jprobes.S
Normal file
61
arch/ia64/kernel/jprobes.S
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Jprobe specific operations
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) Intel Corporation, 2005
|
||||
*
|
||||
* 2005-May Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
|
||||
* <anil.s.keshavamurthy@intel.com> initial implementation
|
||||
*
|
||||
* Jprobes (a.k.a. "jump probes" which is built on-top of kprobes) allow a
|
||||
* probe to be inserted into the beginning of a function call. The fundamental
|
||||
* difference between a jprobe and a kprobe is the jprobe handler is executed
|
||||
* in the same context as the target function, while the kprobe handlers
|
||||
* are executed in interrupt context.
|
||||
*
|
||||
* For jprobes we initially gain control by placing a break point in the
|
||||
* first instruction of the targeted function. When we catch that specific
|
||||
* break, we:
|
||||
* * set the return address to our jprobe_inst_return() function
|
||||
* * jump to the jprobe handler function
|
||||
*
|
||||
* Since we fixed up the return address, the jprobe handler will return to our
|
||||
* jprobe_inst_return() function, giving us control again. At this point we
|
||||
* are back in the parents frame marker, so we do yet another call to our
|
||||
* jprobe_break() function to fix up the frame marker as it would normally
|
||||
* exist in the target function.
|
||||
*
|
||||
* Our jprobe_return function then transfers control back to kprobes.c by
|
||||
* executing a break instruction using one of our reserved numbers. When we
|
||||
* catch that break in kprobes.c, we continue like we do for a normal kprobe
|
||||
* by single stepping the emulated instruction, and then returning execution
|
||||
* to the correct location.
|
||||
*/
|
||||
#include <asm/asmmacro.h>
|
||||
|
||||
/*
|
||||
* void jprobe_break(void)
|
||||
*/
|
||||
ENTRY(jprobe_break)
|
||||
break.m 0x80300
|
||||
END(jprobe_break)
|
||||
|
||||
/*
|
||||
* void jprobe_inst_return(void)
|
||||
*/
|
||||
GLOBAL_ENTRY(jprobe_inst_return)
|
||||
br.call.sptk.many b0=jprobe_break
|
||||
END(jprobe_inst_return)
|
601
arch/ia64/kernel/kprobes.c
Normal file
601
arch/ia64/kernel/kprobes.c
Normal file
@ -0,0 +1,601 @@
|
||||
/*
|
||||
* Kernel Probes (KProbes)
|
||||
* arch/ia64/kernel/kprobes.c
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) IBM Corporation, 2002, 2004
|
||||
* Copyright (C) Intel Corporation, 2005
|
||||
*
|
||||
* 2005-Apr Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
|
||||
* <anil.s.keshavamurthy@intel.com> adapted from i386
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/preempt.h>
|
||||
#include <linux/moduleloader.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/kdebug.h>
|
||||
|
||||
extern void jprobe_inst_return(void);
|
||||
|
||||
/* kprobe_status settings */
|
||||
#define KPROBE_HIT_ACTIVE 0x00000001
|
||||
#define KPROBE_HIT_SS 0x00000002
|
||||
|
||||
static struct kprobe *current_kprobe, *kprobe_prev;
|
||||
static unsigned long kprobe_status, kprobe_status_prev;
|
||||
static struct pt_regs jprobe_saved_regs;
|
||||
|
||||
enum instruction_type {A, I, M, F, B, L, X, u};
|
||||
static enum instruction_type bundle_encoding[32][3] = {
|
||||
{ M, I, I }, /* 00 */
|
||||
{ M, I, I }, /* 01 */
|
||||
{ M, I, I }, /* 02 */
|
||||
{ M, I, I }, /* 03 */
|
||||
{ M, L, X }, /* 04 */
|
||||
{ M, L, X }, /* 05 */
|
||||
{ u, u, u }, /* 06 */
|
||||
{ u, u, u }, /* 07 */
|
||||
{ M, M, I }, /* 08 */
|
||||
{ M, M, I }, /* 09 */
|
||||
{ M, M, I }, /* 0A */
|
||||
{ M, M, I }, /* 0B */
|
||||
{ M, F, I }, /* 0C */
|
||||
{ M, F, I }, /* 0D */
|
||||
{ M, M, F }, /* 0E */
|
||||
{ M, M, F }, /* 0F */
|
||||
{ M, I, B }, /* 10 */
|
||||
{ M, I, B }, /* 11 */
|
||||
{ M, B, B }, /* 12 */
|
||||
{ M, B, B }, /* 13 */
|
||||
{ u, u, u }, /* 14 */
|
||||
{ u, u, u }, /* 15 */
|
||||
{ B, B, B }, /* 16 */
|
||||
{ B, B, B }, /* 17 */
|
||||
{ M, M, B }, /* 18 */
|
||||
{ M, M, B }, /* 19 */
|
||||
{ u, u, u }, /* 1A */
|
||||
{ u, u, u }, /* 1B */
|
||||
{ M, F, B }, /* 1C */
|
||||
{ M, F, B }, /* 1D */
|
||||
{ u, u, u }, /* 1E */
|
||||
{ u, u, u }, /* 1F */
|
||||
};
|
||||
|
||||
/*
|
||||
* In this function we check to see if the instruction
|
||||
* is IP relative instruction and update the kprobe
|
||||
* inst flag accordingly
|
||||
*/
|
||||
static void update_kprobe_inst_flag(uint template, uint slot, uint major_opcode,
|
||||
unsigned long kprobe_inst, struct kprobe *p)
|
||||
{
|
||||
p->ainsn.inst_flag = 0;
|
||||
p->ainsn.target_br_reg = 0;
|
||||
|
||||
if (bundle_encoding[template][slot] == B) {
|
||||
switch (major_opcode) {
|
||||
case INDIRECT_CALL_OPCODE:
|
||||
p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
|
||||
p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
|
||||
break;
|
||||
case IP_RELATIVE_PREDICT_OPCODE:
|
||||
case IP_RELATIVE_BRANCH_OPCODE:
|
||||
p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
|
||||
break;
|
||||
case IP_RELATIVE_CALL_OPCODE:
|
||||
p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
|
||||
p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
|
||||
p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
|
||||
break;
|
||||
}
|
||||
} else if (bundle_encoding[template][slot] == X) {
|
||||
switch (major_opcode) {
|
||||
case LONG_CALL_OPCODE:
|
||||
p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
|
||||
p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* In this function we check to see if the instruction
|
||||
* on which we are inserting kprobe is supported.
|
||||
* Returns 0 if supported
|
||||
* Returns -EINVAL if unsupported
|
||||
*/
|
||||
static int unsupported_inst(uint template, uint slot, uint major_opcode,
|
||||
unsigned long kprobe_inst, struct kprobe *p)
|
||||
{
|
||||
unsigned long addr = (unsigned long)p->addr;
|
||||
|
||||
if (bundle_encoding[template][slot] == I) {
|
||||
switch (major_opcode) {
|
||||
case 0x0: //I_UNIT_MISC_OPCODE:
|
||||
/*
|
||||
* Check for Integer speculation instruction
|
||||
* - Bit 33-35 to be equal to 0x1
|
||||
*/
|
||||
if (((kprobe_inst >> 33) & 0x7) == 1) {
|
||||
printk(KERN_WARNING
|
||||
"Kprobes on speculation inst at <0x%lx> not supported\n",
|
||||
addr);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* IP relative mov instruction
|
||||
* - Bit 27-35 to be equal to 0x30
|
||||
*/
|
||||
if (((kprobe_inst >> 27) & 0x1FF) == 0x30) {
|
||||
printk(KERN_WARNING
|
||||
"Kprobes on \"mov r1=ip\" at <0x%lx> not supported\n",
|
||||
addr);
|
||||
return -EINVAL;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* In this function we check to see if the instruction
|
||||
* (qp) cmpx.crel.ctype p1,p2=r2,r3
|
||||
* on which we are inserting kprobe is cmp instruction
|
||||
* with ctype as unc.
|
||||
*/
|
||||
static uint is_cmp_ctype_unc_inst(uint template, uint slot, uint major_opcode,
|
||||
unsigned long kprobe_inst)
|
||||
{
|
||||
cmp_inst_t cmp_inst;
|
||||
uint ctype_unc = 0;
|
||||
|
||||
if (!((bundle_encoding[template][slot] == I) ||
|
||||
(bundle_encoding[template][slot] == M)))
|
||||
goto out;
|
||||
|
||||
if (!((major_opcode == 0xC) || (major_opcode == 0xD) ||
|
||||
(major_opcode == 0xE)))
|
||||
goto out;
|
||||
|
||||
cmp_inst.l = kprobe_inst;
|
||||
if ((cmp_inst.f.x2 == 0) || (cmp_inst.f.x2 == 1)) {
|
||||
/* Integere compare - Register Register (A6 type)*/
|
||||
if ((cmp_inst.f.tb == 0) && (cmp_inst.f.ta == 0)
|
||||
&&(cmp_inst.f.c == 1))
|
||||
ctype_unc = 1;
|
||||
} else if ((cmp_inst.f.x2 == 2)||(cmp_inst.f.x2 == 3)) {
|
||||
/* Integere compare - Immediate Register (A8 type)*/
|
||||
if ((cmp_inst.f.ta == 0) &&(cmp_inst.f.c == 1))
|
||||
ctype_unc = 1;
|
||||
}
|
||||
out:
|
||||
return ctype_unc;
|
||||
}
|
||||
|
||||
/*
|
||||
* In this function we override the bundle with
|
||||
* the break instruction at the given slot.
|
||||
*/
|
||||
static void prepare_break_inst(uint template, uint slot, uint major_opcode,
|
||||
unsigned long kprobe_inst, struct kprobe *p)
|
||||
{
|
||||
unsigned long break_inst = BREAK_INST;
|
||||
bundle_t *bundle = &p->ainsn.insn.bundle;
|
||||
|
||||
/*
|
||||
* Copy the original kprobe_inst qualifying predicate(qp)
|
||||
* to the break instruction iff !is_cmp_ctype_unc_inst
|
||||
* because for cmp instruction with ctype equal to unc,
|
||||
* which is a special instruction always needs to be
|
||||
* executed regradless of qp
|
||||
*/
|
||||
if (!is_cmp_ctype_unc_inst(template, slot, major_opcode, kprobe_inst))
|
||||
break_inst |= (0x3f & kprobe_inst);
|
||||
|
||||
switch (slot) {
|
||||
case 0:
|
||||
bundle->quad0.slot0 = break_inst;
|
||||
break;
|
||||
case 1:
|
||||
bundle->quad0.slot1_p0 = break_inst;
|
||||
bundle->quad1.slot1_p1 = break_inst >> (64-46);
|
||||
break;
|
||||
case 2:
|
||||
bundle->quad1.slot2 = break_inst;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the instruction flag, so that we can
|
||||
* emulate the instruction properly after we
|
||||
* single step on original instruction
|
||||
*/
|
||||
update_kprobe_inst_flag(template, slot, major_opcode, kprobe_inst, p);
|
||||
}
|
||||
|
||||
static inline void get_kprobe_inst(bundle_t *bundle, uint slot,
|
||||
unsigned long *kprobe_inst, uint *major_opcode)
|
||||
{
|
||||
unsigned long kprobe_inst_p0, kprobe_inst_p1;
|
||||
unsigned int template;
|
||||
|
||||
template = bundle->quad0.template;
|
||||
|
||||
switch (slot) {
|
||||
case 0:
|
||||
*major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT);
|
||||
*kprobe_inst = bundle->quad0.slot0;
|
||||
break;
|
||||
case 1:
|
||||
*major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT);
|
||||
kprobe_inst_p0 = bundle->quad0.slot1_p0;
|
||||
kprobe_inst_p1 = bundle->quad1.slot1_p1;
|
||||
*kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46));
|
||||
break;
|
||||
case 2:
|
||||
*major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT);
|
||||
*kprobe_inst = bundle->quad1.slot2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int valid_kprobe_addr(int template, int slot, unsigned long addr)
|
||||
{
|
||||
if ((slot > 2) || ((bundle_encoding[template][1] == L) && slot > 1)) {
|
||||
printk(KERN_WARNING "Attempting to insert unaligned kprobe at 0x%lx\n",
|
||||
addr);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void save_previous_kprobe(void)
|
||||
{
|
||||
kprobe_prev = current_kprobe;
|
||||
kprobe_status_prev = kprobe_status;
|
||||
}
|
||||
|
||||
static inline void restore_previous_kprobe(void)
|
||||
{
|
||||
current_kprobe = kprobe_prev;
|
||||
kprobe_status = kprobe_status_prev;
|
||||
}
|
||||
|
||||
static inline void set_current_kprobe(struct kprobe *p)
|
||||
{
|
||||
current_kprobe = p;
|
||||
}
|
||||
|
||||
int arch_prepare_kprobe(struct kprobe *p)
|
||||
{
|
||||
unsigned long addr = (unsigned long) p->addr;
|
||||
unsigned long *kprobe_addr = (unsigned long *)(addr & ~0xFULL);
|
||||
unsigned long kprobe_inst=0;
|
||||
unsigned int slot = addr & 0xf, template, major_opcode = 0;
|
||||
bundle_t *bundle = &p->ainsn.insn.bundle;
|
||||
|
||||
memcpy(&p->opcode.bundle, kprobe_addr, sizeof(bundle_t));
|
||||
memcpy(&p->ainsn.insn.bundle, kprobe_addr, sizeof(bundle_t));
|
||||
|
||||
template = bundle->quad0.template;
|
||||
|
||||
if(valid_kprobe_addr(template, slot, addr))
|
||||
return -EINVAL;
|
||||
|
||||
/* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */
|
||||
if (slot == 1 && bundle_encoding[template][1] == L)
|
||||
slot++;
|
||||
|
||||
/* Get kprobe_inst and major_opcode from the bundle */
|
||||
get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode);
|
||||
|
||||
if (unsupported_inst(template, slot, major_opcode, kprobe_inst, p))
|
||||
return -EINVAL;
|
||||
|
||||
prepare_break_inst(template, slot, major_opcode, kprobe_inst, p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void arch_arm_kprobe(struct kprobe *p)
|
||||
{
|
||||
unsigned long addr = (unsigned long)p->addr;
|
||||
unsigned long arm_addr = addr & ~0xFULL;
|
||||
|
||||
memcpy((char *)arm_addr, &p->ainsn.insn.bundle, sizeof(bundle_t));
|
||||
flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
|
||||
}
|
||||
|
||||
void arch_disarm_kprobe(struct kprobe *p)
|
||||
{
|
||||
unsigned long addr = (unsigned long)p->addr;
|
||||
unsigned long arm_addr = addr & ~0xFULL;
|
||||
|
||||
/* p->opcode contains the original unaltered bundle */
|
||||
memcpy((char *) arm_addr, (char *) &p->opcode.bundle, sizeof(bundle_t));
|
||||
flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
|
||||
}
|
||||
|
||||
void arch_remove_kprobe(struct kprobe *p)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* We are resuming execution after a single step fault, so the pt_regs
|
||||
* structure reflects the register state after we executed the instruction
|
||||
* located in the kprobe (p->ainsn.insn.bundle). We still need to adjust
|
||||
* the ip to point back to the original stack address. To set the IP address
|
||||
* to original stack address, handle the case where we need to fixup the
|
||||
* relative IP address and/or fixup branch register.
|
||||
*/
|
||||
static void resume_execution(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
unsigned long bundle_addr = ((unsigned long) (&p->opcode.bundle)) & ~0xFULL;
|
||||
unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL;
|
||||
unsigned long template;
|
||||
int slot = ((unsigned long)p->addr & 0xf);
|
||||
|
||||
template = p->opcode.bundle.quad0.template;
|
||||
|
||||
if (slot == 1 && bundle_encoding[template][1] == L)
|
||||
slot = 2;
|
||||
|
||||
if (p->ainsn.inst_flag) {
|
||||
|
||||
if (p->ainsn.inst_flag & INST_FLAG_FIX_RELATIVE_IP_ADDR) {
|
||||
/* Fix relative IP address */
|
||||
regs->cr_iip = (regs->cr_iip - bundle_addr) + resume_addr;
|
||||
}
|
||||
|
||||
if (p->ainsn.inst_flag & INST_FLAG_FIX_BRANCH_REG) {
|
||||
/*
|
||||
* Fix target branch register, software convention is
|
||||
* to use either b0 or b6 or b7, so just checking
|
||||
* only those registers
|
||||
*/
|
||||
switch (p->ainsn.target_br_reg) {
|
||||
case 0:
|
||||
if ((regs->b0 == bundle_addr) ||
|
||||
(regs->b0 == bundle_addr + 0x10)) {
|
||||
regs->b0 = (regs->b0 - bundle_addr) +
|
||||
resume_addr;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if ((regs->b6 == bundle_addr) ||
|
||||
(regs->b6 == bundle_addr + 0x10)) {
|
||||
regs->b6 = (regs->b6 - bundle_addr) +
|
||||
resume_addr;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if ((regs->b7 == bundle_addr) ||
|
||||
(regs->b7 == bundle_addr + 0x10)) {
|
||||
regs->b7 = (regs->b7 - bundle_addr) +
|
||||
resume_addr;
|
||||
}
|
||||
break;
|
||||
} /* end switch */
|
||||
}
|
||||
goto turn_ss_off;
|
||||
}
|
||||
|
||||
if (slot == 2) {
|
||||
if (regs->cr_iip == bundle_addr + 0x10) {
|
||||
regs->cr_iip = resume_addr + 0x10;
|
||||
}
|
||||
} else {
|
||||
if (regs->cr_iip == bundle_addr) {
|
||||
regs->cr_iip = resume_addr;
|
||||
}
|
||||
}
|
||||
|
||||
turn_ss_off:
|
||||
/* Turn off Single Step bit */
|
||||
ia64_psr(regs)->ss = 0;
|
||||
}
|
||||
|
||||
static void prepare_ss(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
unsigned long bundle_addr = (unsigned long) &p->opcode.bundle;
|
||||
unsigned long slot = (unsigned long)p->addr & 0xf;
|
||||
|
||||
/* Update instruction pointer (IIP) and slot number (IPSR.ri) */
|
||||
regs->cr_iip = bundle_addr & ~0xFULL;
|
||||
|
||||
if (slot > 2)
|
||||
slot = 0;
|
||||
|
||||
ia64_psr(regs)->ri = slot;
|
||||
|
||||
/* turn on single stepping */
|
||||
ia64_psr(regs)->ss = 1;
|
||||
}
|
||||
|
||||
static int pre_kprobes_handler(struct die_args *args)
|
||||
{
|
||||
struct kprobe *p;
|
||||
int ret = 0;
|
||||
struct pt_regs *regs = args->regs;
|
||||
kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs);
|
||||
|
||||
preempt_disable();
|
||||
|
||||
/* Handle recursion cases */
|
||||
if (kprobe_running()) {
|
||||
p = get_kprobe(addr);
|
||||
if (p) {
|
||||
if (kprobe_status == KPROBE_HIT_SS) {
|
||||
unlock_kprobes();
|
||||
goto no_kprobe;
|
||||
}
|
||||
/* We have reentered the pre_kprobe_handler(), since
|
||||
* another probe was hit while within the handler.
|
||||
* We here save the original kprobes variables and
|
||||
* just single step on the instruction of the new probe
|
||||
* without calling any user handlers.
|
||||
*/
|
||||
save_previous_kprobe();
|
||||
set_current_kprobe(p);
|
||||
p->nmissed++;
|
||||
prepare_ss(p, regs);
|
||||
kprobe_status = KPROBE_REENTER;
|
||||
return 1;
|
||||
} else if (args->err == __IA64_BREAK_JPROBE) {
|
||||
/*
|
||||
* jprobe instrumented function just completed
|
||||
*/
|
||||
p = current_kprobe;
|
||||
if (p->break_handler && p->break_handler(p, regs)) {
|
||||
goto ss_probe;
|
||||
}
|
||||
} else {
|
||||
/* Not our break */
|
||||
goto no_kprobe;
|
||||
}
|
||||
}
|
||||
|
||||
lock_kprobes();
|
||||
p = get_kprobe(addr);
|
||||
if (!p) {
|
||||
unlock_kprobes();
|
||||
goto no_kprobe;
|
||||
}
|
||||
|
||||
kprobe_status = KPROBE_HIT_ACTIVE;
|
||||
set_current_kprobe(p);
|
||||
|
||||
if (p->pre_handler && p->pre_handler(p, regs))
|
||||
/*
|
||||
* Our pre-handler is specifically requesting that we just
|
||||
* do a return. This is handling the case where the
|
||||
* pre-handler is really our special jprobe pre-handler.
|
||||
*/
|
||||
return 1;
|
||||
|
||||
ss_probe:
|
||||
prepare_ss(p, regs);
|
||||
kprobe_status = KPROBE_HIT_SS;
|
||||
return 1;
|
||||
|
||||
no_kprobe:
|
||||
preempt_enable_no_resched();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int post_kprobes_handler(struct pt_regs *regs)
|
||||
{
|
||||
if (!kprobe_running())
|
||||
return 0;
|
||||
|
||||
if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
|
||||
kprobe_status = KPROBE_HIT_SSDONE;
|
||||
current_kprobe->post_handler(current_kprobe, regs, 0);
|
||||
}
|
||||
|
||||
resume_execution(current_kprobe, regs);
|
||||
|
||||
/*Restore back the original saved kprobes variables and continue. */
|
||||
if (kprobe_status == KPROBE_REENTER) {
|
||||
restore_previous_kprobe();
|
||||
goto out;
|
||||
}
|
||||
|
||||
unlock_kprobes();
|
||||
|
||||
out:
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int kprobes_fault_handler(struct pt_regs *regs, int trapnr)
|
||||
{
|
||||
if (!kprobe_running())
|
||||
return 0;
|
||||
|
||||
if (current_kprobe->fault_handler &&
|
||||
current_kprobe->fault_handler(current_kprobe, regs, trapnr))
|
||||
return 1;
|
||||
|
||||
if (kprobe_status & KPROBE_HIT_SS) {
|
||||
resume_execution(current_kprobe, regs);
|
||||
unlock_kprobes();
|
||||
preempt_enable_no_resched();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
|
||||
void *data)
|
||||
{
|
||||
struct die_args *args = (struct die_args *)data;
|
||||
switch(val) {
|
||||
case DIE_BREAK:
|
||||
if (pre_kprobes_handler(args))
|
||||
return NOTIFY_STOP;
|
||||
break;
|
||||
case DIE_SS:
|
||||
if (post_kprobes_handler(args->regs))
|
||||
return NOTIFY_STOP;
|
||||
break;
|
||||
case DIE_PAGE_FAULT:
|
||||
if (kprobes_fault_handler(args->regs, args->trapnr))
|
||||
return NOTIFY_STOP;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||
unsigned long addr = ((struct fnptr *)(jp->entry))->ip;
|
||||
|
||||
/* save architectural state */
|
||||
jprobe_saved_regs = *regs;
|
||||
|
||||
/* after rfi, execute the jprobe instrumented function */
|
||||
regs->cr_iip = addr & ~0xFULL;
|
||||
ia64_psr(regs)->ri = addr & 0xf;
|
||||
regs->r1 = ((struct fnptr *)(jp->entry))->gp;
|
||||
|
||||
/*
|
||||
* fix the return address to our jprobe_inst_return() function
|
||||
* in the jprobes.S file
|
||||
*/
|
||||
regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
*regs = jprobe_saved_regs;
|
||||
return 1;
|
||||
}
|
@ -21,12 +21,26 @@
|
||||
#include <asm/intrinsics.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/kdebug.h>
|
||||
|
||||
extern spinlock_t timerlist_lock;
|
||||
|
||||
fpswa_interface_t *fpswa_interface;
|
||||
EXPORT_SYMBOL(fpswa_interface);
|
||||
|
||||
struct notifier_block *ia64die_chain;
|
||||
static DEFINE_SPINLOCK(die_notifier_lock);
|
||||
|
||||
int register_die_notifier(struct notifier_block *nb)
|
||||
{
|
||||
int err = 0;
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&die_notifier_lock, flags);
|
||||
err = notifier_chain_register(&ia64die_chain, nb);
|
||||
spin_unlock_irqrestore(&die_notifier_lock, flags);
|
||||
return err;
|
||||
}
|
||||
|
||||
void __init
|
||||
trap_init (void)
|
||||
{
|
||||
@ -137,6 +151,10 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
|
||||
|
||||
switch (break_num) {
|
||||
case 0: /* unknown error (used by GCC for __builtin_abort()) */
|
||||
if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
|
||||
== NOTIFY_STOP) {
|
||||
return;
|
||||
}
|
||||
die_if_kernel("bugcheck!", regs, break_num);
|
||||
sig = SIGILL; code = ILL_ILLOPC;
|
||||
break;
|
||||
@ -189,6 +207,15 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
|
||||
sig = SIGILL; code = __ILL_BNDMOD;
|
||||
break;
|
||||
|
||||
case 0x80200:
|
||||
case 0x80300:
|
||||
if (notify_die(DIE_BREAK, "kprobe", regs, break_num, TRAP_BRKPT, SIGTRAP)
|
||||
== NOTIFY_STOP) {
|
||||
return;
|
||||
}
|
||||
sig = SIGTRAP; code = TRAP_BRKPT;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (break_num < 0x40000 || break_num > 0x100000)
|
||||
die_if_kernel("Bad break", regs, break_num);
|
||||
@ -548,7 +575,11 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
|
||||
#endif
|
||||
break;
|
||||
case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
|
||||
case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;
|
||||
case 36:
|
||||
if (notify_die(DIE_SS, "ss", ®s, vector,
|
||||
vector, SIGTRAP) == NOTIFY_STOP)
|
||||
return;
|
||||
siginfo.si_code = TRAP_TRACE; ifa = 0; break;
|
||||
}
|
||||
siginfo.si_signo = SIGTRAP;
|
||||
siginfo.si_errno = 0;
|
||||
|
@ -560,14 +560,15 @@ void show_mem(void)
|
||||
int shared = 0, cached = 0, reserved = 0;
|
||||
printk("Node ID: %d\n", pgdat->node_id);
|
||||
for(i = 0; i < pgdat->node_spanned_pages; i++) {
|
||||
struct page *page = pgdat_page_nr(pgdat, i);
|
||||
if (!ia64_pfn_valid(pgdat->node_start_pfn+i))
|
||||
continue;
|
||||
if (PageReserved(pgdat->node_mem_map+i))
|
||||
if (PageReserved(page))
|
||||
reserved++;
|
||||
else if (PageSwapCache(pgdat->node_mem_map+i))
|
||||
else if (PageSwapCache(page))
|
||||
cached++;
|
||||
else if (page_count(pgdat->node_mem_map+i))
|
||||
shared += page_count(pgdat->node_mem_map+i)-1;
|
||||
else if (page_count(page))
|
||||
shared += page_count(page)-1;
|
||||
}
|
||||
total_present += present;
|
||||
total_reserved += reserved;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <asm/processor.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/kdebug.h>
|
||||
|
||||
extern void die (char *, struct pt_regs *, long);
|
||||
|
||||
@ -102,6 +103,13 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
|
||||
goto bad_area_no_up;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is to handle the kprobes on user space access instructions
|
||||
*/
|
||||
if (notify_die(DIE_PAGE_FAULT, "page fault", regs, code, TRAP_BRKPT,
|
||||
SIGSEGV) == NOTIFY_STOP)
|
||||
return;
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
|
||||
vma = find_vma_prev(mm, address, &prev_vma);
|
||||
|
@ -172,11 +172,13 @@ config NOHIGHMEM
|
||||
bool
|
||||
default y
|
||||
|
||||
config DISCONTIGMEM
|
||||
config ARCH_DISCONTIGMEM_ENABLE
|
||||
bool "Internal RAM Support"
|
||||
depends on CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP
|
||||
default y
|
||||
|
||||
source "mm/Kconfig"
|
||||
|
||||
config IRAM_START
|
||||
hex "Internal memory start address (hex)"
|
||||
default "00f00000"
|
||||
|
@ -49,7 +49,7 @@ void show_mem(void)
|
||||
printk("Free swap: %6ldkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
|
||||
for_each_pgdat(pgdat) {
|
||||
for (i = 0; i < pgdat->node_spanned_pages; ++i) {
|
||||
page = pgdat->node_mem_map + i;
|
||||
page = pgdat_page_nr(pgdat, i);
|
||||
total++;
|
||||
if (PageHighMem(page))
|
||||
highmem++;
|
||||
@ -152,7 +152,7 @@ int __init reservedpages_count(void)
|
||||
reservedpages = 0;
|
||||
for_each_online_node(nid)
|
||||
for (i = 0 ; i < MAX_LOW_PFN(nid) - START_PFN(nid) ; i++)
|
||||
if (PageReserved(NODE_DATA(nid)->node_mem_map + i))
|
||||
if (PageReserved(nid_page_nr(nid, i)))
|
||||
reservedpages++;
|
||||
|
||||
return reservedpages;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user