提交 38b22b6e 编写于 作者: A Anton Altaparmakov

Automerge with /usr/src/ntfs-2.6.git.

...@@ -63,7 +63,7 @@ o PPP 2.4.0 # pppd --version ...@@ -63,7 +63,7 @@ o PPP 2.4.0 # pppd --version
o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version
o nfs-utils 1.0.5 # showmount --version o nfs-utils 1.0.5 # showmount --version
o procps 3.2.0 # ps --version o procps 3.2.0 # ps --version
o oprofile 0.5.3 # oprofiled --version o oprofile 0.9 # oprofiled --version
Kernel compilation Kernel compilation
================== ==================
......
...@@ -49,7 +49,7 @@ installmandocs: mandocs ...@@ -49,7 +49,7 @@ installmandocs: mandocs
KERNELDOC = scripts/kernel-doc KERNELDOC = scripts/kernel-doc
DOCPROC = scripts/basic/docproc DOCPROC = scripts/basic/docproc
XMLTOFLAGS = -m Documentation/DocBook/stylesheet.xsl XMLTOFLAGS = -m $(srctree)/Documentation/DocBook/stylesheet.xsl
#XMLTOFLAGS += --skip-validation #XMLTOFLAGS += --skip-validation
### ###
......
...@@ -266,7 +266,7 @@ X!Ekernel/module.c ...@@ -266,7 +266,7 @@ X!Ekernel/module.c
<chapter id="hardware"> <chapter id="hardware">
<title>Hardware Interfaces</title> <title>Hardware Interfaces</title>
<sect1><title>Interrupt Handling</title> <sect1><title>Interrupt Handling</title>
!Iarch/i386/kernel/irq.c !Ikernel/irq/manage.c
</sect1> </sect1>
<sect1><title>Resources Management</title> <sect1><title>Resources Management</title>
......
...@@ -2,4 +2,5 @@ ...@@ -2,4 +2,5 @@
<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0"> <stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0">
<param name="chunk.quietly">1</param> <param name="chunk.quietly">1</param>
<param name="funcsynopsis.style">ansi</param> <param name="funcsynopsis.style">ansi</param>
<param name="funcsynopsis.tabular.threshold">80</param>
</stylesheet> </stylesheet>
...@@ -25,9 +25,10 @@ subject and I can't cover it all here! ...@@ -25,9 +25,10 @@ subject and I can't cover it all here!
Configuration 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 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 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. 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. ...@@ -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. The message handler does not provide any user-level interfaces.
Kernel code (like the watchdog) can still use it. If you need access 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 from userland, you need to select 'Device interface for IPMI' if you
want access through a device driver. Another interface is also want access through a device driver.
available, you may select 'IPMI sockets' in the 'Networking Support'
main menu. This provides a socket interface to IPMI. You may select The driver interface depends on your hardware. If your system
both of these at the same time, they will both work together. 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
The driver interface depends on your hardware. If you have a board will generally be either "KCS", "SMIC", or "BT", consult your hardware
with a standard interface (These will generally be either "KCS", manual), choose the 'IPMI SI handler' option. A driver also exists
"SMIC", or "BT", consult your hardware manual), choose the 'IPMI SI for direct I2C access to the IPMI management controller. Some boards
handler' option. A driver also exists for direct I2C access to the support this, but it is unknown if it will work on every board. For
IPMI management controller. Some boards support this, but it is this, choose 'IPMI SMBus handler', but be ready to try to do some
unknown if it will work on every board. For this, choose 'IPMI SMBus figuring to see if it will work on your system if the SMBIOS/APCI
handler', but be ready to try to do some figuring to see if it will information is wrong or not present. It is fairly safe to have both
work. these enabled and let the drivers auto-detect what is present.
There is also a KCS-only driver interface supplied, but it is
depracated in favor of the SI interface.
You should generally enable ACPI on your system, as systems with IPMI 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 If you have a standard interface and the board manufacturer has done
their job correctly, the IPMI controller should be automatically their job correctly, the IPMI controller should be automatically
detect (via ACPI or SMBIOS tables) and should just work. Sadly, many detected (via ACPI or SMBIOS tables) and should just work. Sadly,
boards do not have this information. The driver attempts standard many boards do not have this information. The driver attempts
defaults, but they may not work. If you fall into this situation, you standard defaults, but they may not work. If you fall into this
need to read the section below named 'The SI Driver' on how to situation, you need to read the section below named 'The SI Driver' or
hand-configure your system. "The SMBus Driver" on how to hand-configure your system.
IPMI defines a standard watchdog timer. You can enable this with the IPMI defines a standard watchdog timer. You can enable this with the
'IPMI Watchdog Timer' config option. If you compile the driver into '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 ...@@ -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 Cards' menu, enable 'Watchdog Timer Support', and enable the option
'Disable watchdog shutdown on close'. '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 Basic Design
------------ ------------
...@@ -80,7 +90,7 @@ Basic Design ...@@ -80,7 +90,7 @@ Basic Design
The Linux IPMI driver is designed to be very modular and flexible, you 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 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 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 ipmi_msghandler - This is the central piece of software for the IPMI
system. It handles all messages, message timing, and responses. The 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 ...@@ -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 driver, each open file for this device ties in to the message handler
as an IPMI user. as an IPMI user.
ipmi_si - A driver for various system interfaces. This supports ipmi_si - A driver for various system interfaces. This supports KCS,
KCS, SMIC, and may support BT in the future. Unless you have your own SMIC, and BT interfaces. Unless you have an SMBus interface or your
custom interface, you probably need to use this. own custom interface, you probably need to use this.
ipmi_smb - A driver for accessing BMCs on the SMBus. It uses the 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 I2C kernel driver's SMBus interfaces to send and receive IPMI messages
over the SMBus. over the SMBus.
af_ipmi - A network socket interface to IPMI. This doesn't take up ipmi_watchdog - IPMI requires systems to have a very capable watchdog
a character device in your system. timer. This driver implements the standard Linux watchdog timer
interface on top of the IPMI message handler.
ipmi_poweroff - Some systems support the ability to be turned off via
IPMI commands.
Note that the KCS-only interface ahs been removed. 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 Much documentation for the interface is in the include files. The
IPMI include files are: IPMI include files are:
...@@ -424,7 +442,7 @@ at module load time (for a module) with: ...@@ -424,7 +442,7 @@ at module load time (for a module) with:
modprobe ipmi_smb.o modprobe ipmi_smb.o
addr=<adapter1>,<i2caddr1>[,<adapter2>,<i2caddr2>[,...]] addr=<adapter1>,<i2caddr1>[,<adapter2>,<i2caddr2>[,...]]
dbg=<flags1>,<flags2>... 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 The addresses are specified in pairs, the first is the adapter ID and the
second is the I2C address on that adapter. 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 ...@@ -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 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 for the driver, but makes it consistent with the rest of the watchdog
drivers in Linux. 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 ...@@ -27,9 +27,13 @@ dump output readprofile -m /boot/System.map > captured_profile
Oprofile 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 CONFIG_PROFILING=y and CONFIG_OPROFILE=y & reboot on new kernel
./configure --with-kernel-support ./configure --with-kernel-support
make install make install
...@@ -46,7 +50,7 @@ start opcontrol --start ...@@ -46,7 +50,7 @@ start opcontrol --start
stop opcontrol --stop stop opcontrol --stop
dump output opreport > output_file 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. A reset is needed to clear old statistics, which survive a reboot.
...@@ -111,6 +111,7 @@ mkdep ...@@ -111,6 +111,7 @@ mkdep
mktables mktables
modpost modpost
modversions.h* modversions.h*
offset.h
offsets.h offsets.h
oui.c* oui.c*
parse.c* parse.c*
......
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 The framework provides generic functions (mostly kernel API calls), such as:
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, version 2.
- 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 Supported devices USB1.1
======================== ========================
...@@ -55,22 +79,34 @@ Others: ...@@ -55,22 +79,34 @@ Others:
- Grandtec USB DVB-T - Grandtec USB DVB-T
http://www.grand.com.tw/ http://www.grand.com.tw/
- Avermedia AverTV DVBT USB (2) - AVerMedia AverTV DVBT USB
http://www.avermedia.com/ http://www.avermedia.com/
- DiBcom USB DVB-T reference device (non-public) - DiBcom USB DVB-T reference device (non-public)
Supported devices USB2.0 Supported devices USB2.0-only
======================== =============================
- Twinhan MagicBox II (2) - Twinhan MagicBox II
http://www.twinhan.com/product_terrestrial_7.asp 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 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.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) - Artec T1 USB TVBOX (FX2) (2)
...@@ -81,14 +117,24 @@ Supported devices USB2.0 ...@@ -81,14 +117,24 @@ Supported devices USB2.0
- DiBcom USB2.0 DVB-T reference device (non-public) - 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. 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-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-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 2005-01-13 - moved the mirrored pid_filter_table back to dvb-dibusb
- first almost working version for HanfTek UMT-010 - first almost working version for HanfTek UMT-010
- found out, that Yakumo/HAMA/Typhoon are predessors of the HanfTek UMT-010 - found out, that Yakumo/HAMA/Typhoon are predessors of the HanfTek UMT-010
...@@ -99,7 +145,7 @@ Supported devices USB2.0 ...@@ -99,7 +145,7 @@ Supported devices USB2.0
2004-12-26 - refactored the dibusb-driver, splitted into separate files 2004-12-26 - refactored the dibusb-driver, splitted into separate files
- i2c-probing enabled - i2c-probing enabled
2004-12-06 - possibility for demod i2c-address probing 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 2004-11-23 - merged changes from DiB3000MC_ver2.1
- revised the debugging - revised the debugging
- possibility to deliver the complete TS for USB2.0 - possibility to deliver the complete TS for USB2.0
...@@ -127,8 +173,8 @@ Supported devices USB2.0 ...@@ -127,8 +173,8 @@ Supported devices USB2.0
CTS Portable (Chinese Television System) CTS Portable (Chinese Television System)
2004-07-08 - firmware-extraction-2.422-problem solved, driver is now working 2004-07-08 - firmware-extraction-2.422-problem solved, driver is now working
properly with firmware extracted from 2.422 properly with firmware extracted from 2.422
- #if for 2.6.4 (dvb), compile issue - #if for 2.6.4 (dvb), compile issue
- changed firmware handling, see vp7041.txt sec 1.1 - changed firmware handling, see vp7041.txt sec 1.1
2004-07-02 - some tuner modifications, v0.1, cleanups, first public 2004-07-02 - some tuner modifications, v0.1, cleanups, first public
2004-06-28 - now using the dvb_dmx_swfilter_packets, everything 2004-06-28 - now using the dvb_dmx_swfilter_packets, everything
runs fine now runs fine now
...@@ -139,38 +185,27 @@ Supported devices USB2.0 ...@@ -139,38 +185,27 @@ Supported devices USB2.0
2004-05-11 - start writing the driver 2004-05-11 - start writing the driver
1. How to use? 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 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) for USB1.1 (AN2135) you need: dvb-usb-dibusb-5.0.0.11.fw
http://www.linuxtv.org/downloads/firmware/dvb-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 (AN2235) (a few Artec T1 devices) The files can be found on http://www.linuxtv.org/download/firmware/ .
http://www.linuxtv.org/downloads/firmware/dvb-dibusb-an2235-1.fw
for USB2.0 (FX2) Hauppauge, DiBcom We do not have the permission (yet) to publish the following firmware-files.
http://www.linuxtv.org/downloads/firmware/dvb-dibusb-6.0.0.5.fw You'll need to extract them from the windows drivers.
for USB2.0 ADSTech/Kworld USB2.0 You should be able to use "get_dvb_firmware dvb-usb" to get the firmware:
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
for USB1.1 (AN2235) (a few Artec T1 devices): dvb-usb-dibusb-an2235-01.fw
for USB2.0 Hauppauge: dvb-usb-nova-t-usb2-01.fw
for USB2.0 ADSTech/Kworld USB2.0: dvb-usb-adstech-usb2-01.fw
for USB2.0 Yakumo/Typhoon/Hama: dvb-usb-dtt200u-01.fw
1.2. Compiling 1.2. Compiling
...@@ -178,6 +213,9 @@ Since the driver is in the linux kernel, activating the driver in ...@@ -178,6 +213,9 @@ Since the driver is in the linux kernel, activating the driver in
your favorite config-environment should sufficient. I recommend your favorite config-environment should sufficient. I recommend
to compile the driver as module. Hotplug does the rest. 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 1.3. Loading the drivers
Hotplug is able to load the driver, when it is needed (because you plugged 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. ...@@ -188,15 +226,13 @@ from withing the dvb-kernel cvs repository.
first have a look, which debug level are available: first have a look, which debug level are available:
modinfo dib3000mb modinfo dvb-usb
modinfo dib3000-common modinfo dvb-usb-vp7045
modinfo dib3000mc etc.
modinfo dvb-dibusb
modprobe dib3000-common debug=<level> modprobe dvb-usb debug=<level>
modprobe dib3000mb debug=<level> modprobe dvb-usb-vp7045 debug=<level>
modprobe dib3000mc debug=<level> etc.
modprobe dvb-dibusb debug=<level>
should do the trick. should do the trick.
...@@ -204,52 +240,32 @@ When the driver is loaded successfully, the firmware file was in ...@@ -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 the right place and the device is connected, the "Power"-LED should be
turned on. turned on.
At this point you should be able to start a dvb-capable application. For myself At this point you should be able to start a dvb-capable application. I'm use
I used mplayer, dvbscan, tzap and kaxtv, they are working. Using the device (t|s)zap, mplayer and dvbscan to test the basics. VDR-xine provides the
in vdr is working now also. long-term test scenario.
2. Known problems and bugs 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 2.1. Adding support for devices
It is not possible to determine the range of devices based on the DiBcom TODO
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.
2.2. USB1.1 Bandwidth limitation 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. 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 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), 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 but watching a channel while recording another channel on the same
frequency simply does not work very well. This applies to all USB1.1 frequency simply does not work very well. This applies to all USB1.1
DVB-T devices, not just dibusb) DVB-T devices, not just the dvb-usb-devices)
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.
The bug, where the TS is distorted by a heavy usage of the device is gone 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 working like charm now with VDR. Sometimes I even was able to record a channel
and watch another one. and watch another one.
...@@ -258,7 +274,7 @@ and watch another one. ...@@ -258,7 +274,7 @@ and watch another one.
Patches, comments and suggestions are very very welcome. Patches, comments and suggestions are very very welcome.
3. Acknowledgements 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 providing specs, code and help, on which the dvb-dibusb, dib3000mb and
dib3000mc are based. dib3000mc are based.
...@@ -270,9 +286,16 @@ Patches, comments and suggestions are very very welcome. ...@@ -270,9 +286,16 @@ Patches, comments and suggestions are very very welcome.
Bernd Wagner for helping with huge bug reports and discussions. 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. 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 Some guys on the linux-dvb mailing list for encouraging me
Peter Schildmann >peter.schildmann-nospam-at-web.de< for his Peter Schildmann >peter.schildmann-nospam-at-web.de< for his
...@@ -282,4 +305,4 @@ Patches, comments and suggestions are very very welcome. ...@@ -282,4 +305,4 @@ Patches, comments and suggestions are very very welcome.
Ulf Hermenau for helping me out with traditional chinese. Ulf Hermenau for helping me out with traditional chinese.
André Smoktun and Christian Frömmel for supporting me with André Smoktun and Christian Frömmel for supporting me with
hardware and listening to my problems very patient hardware and listening to my problems very patient.
...@@ -66,6 +66,14 @@ Who: Paul E. McKenney <paulmck@us.ibm.com> ...@@ -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, What: IEEE1394 Audio and Music Data Transmission Protocol driver,
Connection Management Procedures driver Connection Management Procedures driver
When: November 2005 When: November 2005
...@@ -86,6 +94,16 @@ Who: Jody McIntyre <scjody@steamballoon.com> ...@@ -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 What: i2c sysfs name change: in1_ref, vid deprecated in favour of cpu0_vid
When: November 2005 When: November 2005
Files: drivers/i2c/chips/adm1025.c, drivers/i2c/chips/adm1026.c Files: drivers/i2c/chips/adm1025.c, drivers/i2c/chips/adm1026.c
......
...@@ -58,6 +58,8 @@ noacl Don't support POSIX ACLs. ...@@ -58,6 +58,8 @@ noacl Don't support POSIX ACLs.
nobh Do not attach buffer_heads to file pagecache. 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. grpquota,noquota,quota,usrquota Quota options are silently ignored by ext2.
......
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.
此差异已折叠。
...@@ -304,57 +304,6 @@ tcp_low_latency - BOOLEAN ...@@ -304,57 +304,6 @@ tcp_low_latency - BOOLEAN
changed would be a Beowulf compute cluster. changed would be a Beowulf compute cluster.
Default: 0 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 tcp_tso_win_divisor - INTEGER
This allows control over what percentage of the congestion window This allows control over what percentage of the congestion window
can be consumed by a single TSO frame. can be consumed by a single TSO frame.
...@@ -368,6 +317,11 @@ tcp_frto - BOOLEAN ...@@ -368,6 +317,11 @@ tcp_frto - BOOLEAN
where packet loss is typically due to random radio interference where packet loss is typically due to random radio interference
rather than intermediate router congestion. 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 somaxconn - INTEGER
Limit of socket listen() backlog, known in userspace as SOMAXCONN. Limit of socket listen() backlog, known in userspace as SOMAXCONN.
Defaults to 128. See also tcp_max_syn_backlog for additional tuning Defaults to 128. See also tcp_max_syn_backlog for additional tuning
......
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 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 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: ...@@ -49,6 +49,7 @@ show up in /proc/sys/kernel:
- shmmax [ sysv ipc ] - shmmax [ sysv ipc ]
- shmmni - shmmni
- stop-a [ SPARC only ] - stop-a [ SPARC only ]
- suid_dumpable
- sysrq ==> Documentation/sysrq.txt - sysrq ==> Documentation/sysrq.txt
- tainted - tainted
- threads-max - threads-max
...@@ -300,6 +301,25 @@ kernel. This value defaults to SHMMAX. ...@@ -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: tainted:
Non-zero if the kernel has been tainted. Numeric values, which 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 ...@@ -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 discipline even with the same data or your computer again will be eaten by
demons. 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 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 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. code manages the module counts this should not usually be a concern.
......
...@@ -119,3 +119,17 @@ card=117 - NGS NGSTV+ ...@@ -119,3 +119,17 @@ card=117 - NGS NGSTV+
card=118 - LMLBT4 card=118 - LMLBT4
card=119 - Tekram M205 PRO card=119 - Tekram M205 PRO
card=120 - Conceptronic CONTVFMi 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
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 @@ ...@@ -20,16 +20,37 @@
19 -> Compro VideoMate TV [185b:c100] 19 -> Compro VideoMate TV [185b:c100]
20 -> Matrox CronosPlus [102B:48d0] 20 -> Matrox CronosPlus [102B:48d0]
21 -> 10MOONS PCI TV CAPTURE CARD [1131:2001] 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 23 -> BMK MPEX Tuner
24 -> KNC One TV-Station DVR [1894:a006] 24 -> KNC One TV-Station DVR [1894:a006]
25 -> ASUS TV-FM 7133 [1043:4843] 25 -> ASUS TV-FM 7133 [1043:4843]
26 -> Pinnacle PCTV Stereo (saa7134) [11bd:002b] 26 -> Pinnacle PCTV Stereo (saa7134) [11bd:002b]
27 -> Manli MuchTV M-TV002 27 -> Manli MuchTV M-TV002/Behold TV 403 FM
28 -> Manli MuchTV M-TV001 28 -> Manli MuchTV M-TV001/Behold TV 401
29 -> Nagase Sangyo TransGear 3000TV [1461:050c] 29 -> Nagase Sangyo TransGear 3000TV [1461:050c]
30 -> Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) [1019:4cb4] 30 -> Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) [1019:4cb4]
31 -> Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM) [1019:4cb5] 31 -> Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM) [1019:4cb5]
32 -> AVACS SmartTV 32 -> AVACS SmartTV
33 -> AVerMedia DVD EZMaker [1461:10ff] 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 ...@@ -44,3 +44,18 @@ tuner=42 - Philips 1236D ATSC/NTSC daul in
tuner=43 - Philips NTSC MK3 (FM1236MK3 or FM1236/F) tuner=43 - Philips NTSC MK3 (FM1236MK3 or FM1236/F)
tuner=44 - Philips 4 in 1 (ATI TV Wonder Pro/Conexant) tuner=44 - Philips 4 in 1 (ATI TV Wonder Pro/Conexant)
tuner=45 - Microtune 4049 FM5 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)
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
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 */
=================================================================================
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
=================================================================================
...@@ -304,7 +304,7 @@ S: Maintained ...@@ -304,7 +304,7 @@ S: Maintained
ARM/PT DIGITAL BOARD PORT ARM/PT DIGITAL BOARD PORT
P: Stefan Eletzhofer P: Stefan Eletzhofer
M: stefan.eletzhofer@eletztrick.de 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/ W: http://www.arm.linux.org.uk/
S: Maintained S: Maintained
...@@ -317,21 +317,21 @@ S: Maintained ...@@ -317,21 +317,21 @@ S: Maintained
ARM/STRONGARM110 PORT ARM/STRONGARM110 PORT
P: Russell King P: Russell King
M: rmk@arm.linux.org.uk 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/ W: http://www.arm.linux.org.uk/
S: Maintained S: Maintained
ARM/S3C2410 ARM ARCHITECTURE ARM/S3C2410 ARM ARCHITECTURE
P: Ben Dooks P: Ben Dooks
M: ben-s3c2410@fluff.org 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/ W: http://www.fluff.org/ben/linux/
S: Maintained S: Maintained
ARM/S3C2440 ARM ARCHITECTURE ARM/S3C2440 ARM ARCHITECTURE
P: Ben Dooks P: Ben Dooks
M: ben-s3c2440@fluff.org 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/ W: http://www.fluff.org/ben/linux/
S: Maintained S: Maintained
...@@ -504,6 +504,13 @@ L: bonding-devel@lists.sourceforge.net ...@@ -504,6 +504,13 @@ L: bonding-devel@lists.sourceforge.net
W: http://sourceforge.net/projects/bonding/ W: http://sourceforge.net/projects/bonding/
S: Supported 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 BTTV VIDEO4LINUX DRIVER
P: Gerd Knorr P: Gerd Knorr
M: kraxel@bytesex.org M: kraxel@bytesex.org
...@@ -1853,7 +1860,7 @@ S: Maintained ...@@ -1853,7 +1860,7 @@ S: Maintained
PXA2xx SUPPORT PXA2xx SUPPORT
P: Nicolas Pitre P: Nicolas Pitre
M: nico@cam.org 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 S: Maintained
QLOGIC QLA2XXX FC-SCSI DRIVER QLOGIC QLA2XXX FC-SCSI DRIVER
...@@ -2138,6 +2145,11 @@ W: http://tpmdd.sourceforge.net ...@@ -2138,6 +2145,11 @@ W: http://tpmdd.sourceforge.net
L: tpmdd-devel@lists.sourceforge.net L: tpmdd-devel@lists.sourceforge.net
S: Maintained S: Maintained
TENSILICA XTENSA PORT (xtensa):
P: Chris Zankel
M: chris@zankel.net
S: Maintained
UltraSPARC (sparc64): UltraSPARC (sparc64):
P: David S. Miller P: David S. Miller
M: davem@davemloft.net M: davem@davemloft.net
...@@ -2155,7 +2167,7 @@ SHARP LH SUPPORT (LH7952X & LH7A40X) ...@@ -2155,7 +2167,7 @@ SHARP LH SUPPORT (LH7952X & LH7A40X)
P: Marc Singer P: Marc Singer
M: elf@buici.com M: elf@buici.com
W: http://projects.buici.com/arm 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 S: Maintained
SPARC (sparc32): SPARC (sparc32):
......
...@@ -518,7 +518,7 @@ CFLAGS += $(call add-align,CONFIG_CC_ALIGN_LOOPS,-loops) ...@@ -518,7 +518,7 @@ CFLAGS += $(call add-align,CONFIG_CC_ALIGN_LOOPS,-loops)
CFLAGS += $(call add-align,CONFIG_CC_ALIGN_JUMPS,-jumps) CFLAGS += $(call add-align,CONFIG_CC_ALIGN_JUMPS,-jumps)
ifdef CONFIG_FRAME_POINTER ifdef CONFIG_FRAME_POINTER
CFLAGS += -fno-omit-frame-pointer CFLAGS += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,)
else else
CFLAGS += -fomit-frame-pointer CFLAGS += -fomit-frame-pointer
endif endif
......
...@@ -509,7 +509,7 @@ config NR_CPUS ...@@ -509,7 +509,7 @@ config NR_CPUS
depends on SMP depends on SMP
default "64" default "64"
config DISCONTIGMEM config ARCH_DISCONTIGMEM_ENABLE
bool "Discontiguous Memory Support (EXPERIMENTAL)" bool "Discontiguous Memory Support (EXPERIMENTAL)"
depends on EXPERIMENTAL depends on EXPERIMENTAL
help help
...@@ -518,6 +518,8 @@ config DISCONTIGMEM ...@@ -518,6 +518,8 @@ config DISCONTIGMEM
or have huge holes in the physical address space for other reasons. or have huge holes in the physical address space for other reasons.
See <file:Documentation/vm/numa> for more. See <file:Documentation/vm/numa> for more.
source "mm/Kconfig"
config NUMA config NUMA
bool "NUMA Support (EXPERIMENTAL)" bool "NUMA Support (EXPERIMENTAL)"
depends on DISCONTIGMEM depends on DISCONTIGMEM
......
...@@ -96,7 +96,7 @@ CONFIG_ALPHA_CORE_AGP=y ...@@ -96,7 +96,7 @@ CONFIG_ALPHA_CORE_AGP=y
CONFIG_ALPHA_BROKEN_IRQ_MASK=y CONFIG_ALPHA_BROKEN_IRQ_MASK=y
CONFIG_EISA=y CONFIG_EISA=y
# CONFIG_SMP is not set # CONFIG_SMP is not set
# CONFIG_DISCONTIGMEM is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
CONFIG_VERBOSE_MCHECK=y CONFIG_VERBOSE_MCHECK=y
CONFIG_VERBOSE_MCHECK_ON=1 CONFIG_VERBOSE_MCHECK_ON=1
CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_LEGACY_PROC=y
......
...@@ -327,8 +327,6 @@ void __init mem_init(void) ...@@ -327,8 +327,6 @@ void __init mem_init(void)
extern char _text, _etext, _data, _edata; extern char _text, _etext, _data, _edata;
extern char __init_begin, __init_end; extern char __init_begin, __init_end;
unsigned long nid, i; unsigned long nid, i;
struct page * lmem_map;
high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
reservedpages = 0; reservedpages = 0;
...@@ -338,10 +336,10 @@ void __init mem_init(void) ...@@ -338,10 +336,10 @@ void __init mem_init(void)
*/ */
totalram_pages += free_all_bootmem_node(NODE_DATA(nid)); totalram_pages += free_all_bootmem_node(NODE_DATA(nid));
lmem_map = node_mem_map(nid);
pfn = NODE_DATA(nid)->node_start_pfn; pfn = NODE_DATA(nid)->node_start_pfn;
for (i = 0; i < node_spanned_pages(nid); i++, 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++; reservedpages++;
} }
...@@ -373,18 +371,18 @@ show_mem(void) ...@@ -373,18 +371,18 @@ show_mem(void)
show_free_areas(); show_free_areas();
printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
for_each_online_node(nid) { for_each_online_node(nid) {
struct page * lmem_map = node_mem_map(nid);
i = node_spanned_pages(nid); i = node_spanned_pages(nid);
while (i-- > 0) { while (i-- > 0) {
struct page *page = nid_page_nr(nid, i);
total++; total++;
if (PageReserved(lmem_map+i)) if (PageReserved(page))
reserved++; reserved++;
else if (PageSwapCache(lmem_map+i)) else if (PageSwapCache(page))
cached++; cached++;
else if (!page_count(lmem_map+i)) else if (!page_count(page))
free++; free++;
else else
shared += page_count(lmem_map + i) - 1; shared += page_count(page) - 1;
} }
} }
printk("%ld pages of RAM\n",total); printk("%ld pages of RAM\n",total);
......
...@@ -346,7 +346,7 @@ config PREEMPT ...@@ -346,7 +346,7 @@ config PREEMPT
Say Y here if you are building a kernel for a desktop, embedded Say Y here if you are building a kernel for a desktop, embedded
or real-time system. Say N if you are unsure. or real-time system. Say N if you are unsure.
config DISCONTIGMEM config ARCH_DISCONTIGMEM_ENABLE
bool bool
default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
help help
...@@ -355,6 +355,8 @@ config DISCONTIGMEM ...@@ -355,6 +355,8 @@ config DISCONTIGMEM
or have huge holes in the physical address space for other reasons. or have huge holes in the physical address space for other reasons.
See <file:Documentation/vm/numa> for more. See <file:Documentation/vm/numa> for more.
source "mm/Kconfig"
config LEDS config LEDS
bool "Timer and CPU usage LEDs" bool "Timer and CPU usage LEDs"
depends on ARCH_CDB89712 || ARCH_CO285 || ARCH_EBSA110 || \ depends on ARCH_CDB89712 || ARCH_CO285 || ARCH_EBSA110 || \
......
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
# #
# User may have a custom install script # User may have a custom install script
if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi
if [ "$(basename $2)" = "zImage" ]; then if [ "$(basename $2)" = "zImage" ]; then
# Compressed install # Compressed install
......
# #
# Automatically generated make config: don't edit # Automatically generated make config: don't edit
# Linux kernel version: 2.6.12-rc1-bk2 # Linux kernel version: 2.6.12-git4
# Sun Mar 27 17:47:45 2005 # Wed Jun 22 15:56:42 2005
# #
CONFIG_ARM=y CONFIG_ARM=y
CONFIG_MMU=y CONFIG_MMU=y
CONFIG_UID16=y CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_IOMAP=y
# #
# Code maturity level options # Code maturity level options
...@@ -17,6 +16,7 @@ CONFIG_EXPERIMENTAL=y ...@@ -17,6 +16,7 @@ CONFIG_EXPERIMENTAL=y
# CONFIG_CLEAN_COMPILE is not set # CONFIG_CLEAN_COMPILE is not set
CONFIG_BROKEN=y CONFIG_BROKEN=y
CONFIG_BROKEN_ON_SMP=y CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
# #
# General setup # General setup
...@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y ...@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
CONFIG_KALLSYMS=y CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_BASE_FULL=y CONFIG_BASE_FULL=y
CONFIG_FUTEX=y CONFIG_FUTEX=y
CONFIG_EPOLL=y CONFIG_EPOLL=y
...@@ -81,6 +83,7 @@ CONFIG_ARCH_S3C2410=y ...@@ -81,6 +83,7 @@ CONFIG_ARCH_S3C2410=y
# CONFIG_ARCH_VERSATILE is not set # CONFIG_ARCH_VERSATILE is not set
# CONFIG_ARCH_IMX is not set # CONFIG_ARCH_IMX is not set
# CONFIG_ARCH_H720X is not set # CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_AAEC2000 is not set
# #
# S3C24XX Implementations # S3C24XX Implementations
...@@ -134,6 +137,7 @@ CONFIG_CPU_TLB_V4WBI=y ...@@ -134,6 +137,7 @@ CONFIG_CPU_TLB_V4WBI=y
# #
# Bus support # Bus support
# #
CONFIG_ISA_DMA_API=y
# #
# PCCARD (PCMCIA/CardBus) support # PCCARD (PCMCIA/CardBus) support
...@@ -143,7 +147,9 @@ CONFIG_CPU_TLB_V4WBI=y ...@@ -143,7 +147,9 @@ CONFIG_CPU_TLB_V4WBI=y
# #
# Kernel Features # Kernel Features
# #
# CONFIG_SMP is not set
# CONFIG_PREEMPT is not set # CONFIG_PREEMPT is not set
# CONFIG_DISCONTIGMEM is not set
CONFIG_ALIGNMENT_TRAP=y CONFIG_ALIGNMENT_TRAP=y
# #
...@@ -297,7 +303,6 @@ CONFIG_PARPORT_1284=y ...@@ -297,7 +303,6 @@ CONFIG_PARPORT_1284=y
# #
# Block devices # Block devices
# #
# CONFIG_BLK_DEV_FD is not set
# CONFIG_PARIDE is not set # CONFIG_PARIDE is not set
# CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_LOOP=y
...@@ -359,6 +364,7 @@ CONFIG_BLK_DEV_IDE_BAST=y ...@@ -359,6 +364,7 @@ CONFIG_BLK_DEV_IDE_BAST=y
# #
# Fusion MPT device support # Fusion MPT device support
# #
# CONFIG_FUSION is not set
# #
# IEEE 1394 (FireWire) support # IEEE 1394 (FireWire) support
...@@ -378,10 +384,11 @@ CONFIG_NET=y ...@@ -378,10 +384,11 @@ CONFIG_NET=y
# Networking options # Networking options
# #
# CONFIG_PACKET is not set # CONFIG_PACKET is not set
# CONFIG_NETLINK_DEV is not set
CONFIG_UNIX=y CONFIG_UNIX=y
# CONFIG_NET_KEY is not set # CONFIG_NET_KEY is not set
CONFIG_INET=y CONFIG_INET=y
CONFIG_IP_FIB_HASH=y
# CONFIG_IP_FIB_TRIE is not set
# CONFIG_IP_MULTICAST is not set # CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_PNP=y CONFIG_IP_PNP=y
...@@ -443,8 +450,9 @@ CONFIG_NETDEVICES=y ...@@ -443,8 +450,9 @@ CONFIG_NETDEVICES=y
# Ethernet (10 or 100Mbit) # Ethernet (10 or 100Mbit)
# #
CONFIG_NET_ETHERNET=y CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set CONFIG_MII=m
# CONFIG_SMC91X is not set # CONFIG_SMC91X is not set
CONFIG_DM9000=m
# #
# Ethernet (1000 Mbit) # Ethernet (1000 Mbit)
...@@ -521,7 +529,6 @@ CONFIG_SERIO_SERPORT=y ...@@ -521,7 +529,6 @@ CONFIG_SERIO_SERPORT=y
CONFIG_SERIO_LIBPS2=y CONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set # CONFIG_SERIO_RAW is not set
# CONFIG_GAMEPORT is not set # CONFIG_GAMEPORT is not set
CONFIG_SOUND_GAMEPORT=y
# #
# Character devices # Character devices
...@@ -605,7 +612,6 @@ CONFIG_S3C2410_RTC=y ...@@ -605,7 +612,6 @@ CONFIG_S3C2410_RTC=y
# #
# TPM devices # TPM devices
# #
# CONFIG_TCG_TPM is not set
# #
# I2C support # I2C support
...@@ -654,6 +660,7 @@ CONFIG_SENSORS_LM78=m ...@@ -654,6 +660,7 @@ CONFIG_SENSORS_LM78=m
CONFIG_SENSORS_LM85=m CONFIG_SENSORS_LM85=m
# CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM87 is not set
# CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_SMSC47B397 is not set
...@@ -665,6 +672,7 @@ CONFIG_SENSORS_LM85=m ...@@ -665,6 +672,7 @@ CONFIG_SENSORS_LM85=m
# #
# Other I2C Chip support # Other I2C Chip support
# #
# CONFIG_SENSORS_DS1337 is not set
CONFIG_SENSORS_EEPROM=m CONFIG_SENSORS_EEPROM=m
# CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCF8574 is not set
# CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_PCF8591 is not set
...@@ -696,8 +704,10 @@ CONFIG_FB=y ...@@ -696,8 +704,10 @@ CONFIG_FB=y
# CONFIG_FB_CFB_COPYAREA is not set # CONFIG_FB_CFB_COPYAREA is not set
# CONFIG_FB_CFB_IMAGEBLIT is not set # CONFIG_FB_CFB_IMAGEBLIT is not set
# CONFIG_FB_SOFT_CURSOR is not set # CONFIG_FB_SOFT_CURSOR is not set
# CONFIG_FB_MACMODES is not set
CONFIG_FB_MODE_HELPERS=y CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_TILEBLITTING is not set # CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set # CONFIG_FB_VIRTUAL is not set
# #
...@@ -782,7 +792,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ...@@ -782,7 +792,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# #
CONFIG_PROC_FS=y CONFIG_PROC_FS=y
CONFIG_SYSFS=y CONFIG_SYSFS=y
# CONFIG_DEVFS_FS is not set
# CONFIG_DEVPTS_FS_XATTR is not set # CONFIG_DEVPTS_FS_XATTR is not set
# CONFIG_TMPFS is not set # CONFIG_TMPFS is not set
# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLBFS is not set
......
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <asm/arch/gpio.h>
static DEFINE_SPINLOCK(ixp2000_slowport_lock); static DEFINE_SPINLOCK(ixp2000_slowport_lock);
static unsigned long ixp2000_slowport_irq_flags; 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) ...@@ -179,7 +181,7 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* clear timer 1 */ /* clear timer 1 */
ixp2000_reg_write(IXP2000_T1_CLR, 1); ixp2000_reg_write(IXP2000_T1_CLR, 1);
while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) { while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) {
timer_tick(regs); timer_tick(regs);
next_jiffy_time -= ticks_per_jiffy; next_jiffy_time -= ticks_per_jiffy;
...@@ -238,35 +240,40 @@ void __init ixp2000_init_time(unsigned long tick_rate) ...@@ -238,35 +240,40 @@ void __init ixp2000_init_time(unsigned long tick_rate)
/************************************************************************* /*************************************************************************
* GPIO helpers * GPIO helpers
*************************************************************************/ *************************************************************************/
static unsigned long GPIO_IRQ_rising_edge;
static unsigned long GPIO_IRQ_falling_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_low;
static unsigned long GPIO_IRQ_level_high; 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; unsigned long flags;
local_irq_save(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 */ /* 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_falling_edge &= ~(1 << line);
GPIO_IRQ_rising_edge &= ~(1 << line); GPIO_IRQ_rising_edge &= ~(1 << line);
GPIO_IRQ_level_low &= ~(1 << line); GPIO_IRQ_level_low &= ~(1 << line);
GPIO_IRQ_level_high &= ~(1 << line); GPIO_IRQ_level_high &= ~(1 << line);
ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge); update_gpio_int_csrs();
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_PDSR, 1 << line);
ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low); } else if (direction == GPIO_IN) {
irq_desc[line+IRQ_IXP2000_GPIO0].valid = 0; ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line);
} else if(style == GPIO_IN) {
ixp2000_reg_write(IXP2000_GPIO_PDCR, (1 << line));
} }
local_irq_restore(flags); local_irq_restore(flags);
} }
/************************************************************************* /*************************************************************************
...@@ -285,9 +292,50 @@ static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irqdesc *desc, str ...@@ -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) 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_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))); ixp2000_reg_write(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0)));
} }
...@@ -302,6 +350,7 @@ static void ixp2000_GPIO_irq_unmask(unsigned int irq) ...@@ -302,6 +350,7 @@ static void ixp2000_GPIO_irq_unmask(unsigned int irq)
} }
static struct irqchip ixp2000_GPIO_irq_chip = { static struct irqchip ixp2000_GPIO_irq_chip = {
.type = ixp2000_GPIO_irq_type,
.ack = ixp2000_GPIO_irq_mask_ack, .ack = ixp2000_GPIO_irq_mask_ack,
.mask = ixp2000_GPIO_irq_mask, .mask = ixp2000_GPIO_irq_mask,
.unmask = ixp2000_GPIO_irq_unmask .unmask = ixp2000_GPIO_irq_unmask
...@@ -338,7 +387,7 @@ static void ixp2000_irq_mask(unsigned int irq) ...@@ -338,7 +387,7 @@ static void ixp2000_irq_mask(unsigned int irq)
static void ixp2000_irq_unmask(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 = { static struct irqchip ixp2000_irq_chip = {
...@@ -375,16 +424,16 @@ void __init ixp2000_init_irq(void) ...@@ -375,16 +424,16 @@ void __init ixp2000_init_irq(void)
* our mask/unmask code much simpler. * our mask/unmask code much simpler.
*/ */
for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) { 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_chip(irq, &ixp2000_irq_chip);
set_irq_handler(irq, do_level_IRQ); set_irq_handler(irq, do_level_IRQ);
set_irq_flags(irq, IRQF_VALID); set_irq_flags(irq, IRQF_VALID);
} else set_irq_flags(irq, 0); } else set_irq_flags(irq, 0);
} }
/* /*
* GPIO IRQs are invalid until someone sets the interrupt mode * 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++) { for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) {
set_irq_chip(irq, &ixp2000_GPIO_irq_chip); set_irq_chip(irq, &ixp2000_GPIO_irq_chip);
......
...@@ -141,7 +141,15 @@ static struct map_desc ixp4xx_io_desc[] __initdata = { ...@@ -141,7 +141,15 @@ static struct map_desc ixp4xx_io_desc[] __initdata = {
.physical = IXP4XX_PCI_CFG_BASE_PHYS, .physical = IXP4XX_PCI_CFG_BASE_PHYS,
.length = IXP4XX_PCI_CFG_REGION_SIZE, .length = IXP4XX_PCI_CFG_REGION_SIZE,
.type = MT_DEVICE .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) void __init ixp4xx_map_io(void)
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
* 03-Mar-2005 BJD Ensured that bast-cpld.h is included * 03-Mar-2005 BJD Ensured that bast-cpld.h is included
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
* 14-Mar-2006 BJD Updated for __iomem changes * 14-Mar-2006 BJD Updated for __iomem changes
* 22-Jun-2006 BJD Added DM9000 platform information
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -35,6 +36,7 @@ ...@@ -35,6 +36,7 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/dm9000.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
...@@ -53,6 +55,7 @@ ...@@ -53,6 +55,7 @@
#include <asm/arch/regs-serial.h> #include <asm/arch/regs-serial.h>
#include <asm/arch/regs-gpio.h> #include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-mem.h> #include <asm/arch/regs-mem.h>
#include <asm/arch/regs-lcd.h>
#include <asm/arch/nand.h> #include <asm/arch/nand.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
...@@ -112,7 +115,6 @@ static struct map_desc bast_iodesc[] __initdata = { ...@@ -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_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_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_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_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_IDESEC), PA_CS3(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
{ VA_C2(BAST_VA_IDEPRIAUX), PA_CS3(BAST_PA_IDEPRIAUX), 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 = { ...@@ -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_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_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_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_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_IDESEC), PA_CS3(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
{ VA_C3(BAST_VA_IDEPRIAUX), PA_CS3(BAST_PA_IDEPRIAUX), 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 = { ...@@ -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_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_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_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_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_IDESEC), PA_CS5(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
{ VA_C4(BAST_VA_IDEPRIAUX), PA_CS5(BAST_PA_IDEPRIAUX), 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 = { ...@@ -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_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_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_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_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_IDESEC), PA_CS5(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
{ VA_C5(BAST_VA_IDEPRIAUX), PA_CS5(BAST_PA_IDEPRIAUX), 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 = { ...@@ -313,6 +312,45 @@ static struct s3c2410_platform_nand bast_nand_info = {
.select_chip = bast_nand_select, .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 */ /* Standard BAST devices */
...@@ -324,7 +362,8 @@ static struct platform_device *bast_devices[] __initdata = { ...@@ -324,7 +362,8 @@ static struct platform_device *bast_devices[] __initdata = {
&s3c_device_iis, &s3c_device_iis,
&s3c_device_rtc, &s3c_device_rtc,
&s3c_device_nand, &s3c_device_nand,
&bast_device_nor &bast_device_nor,
&bast_device_dm9k,
}; };
static struct clk *bast_clocks[] = { static struct clk *bast_clocks[] = {
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
* 10-Feb-2005 BJD Added power-off capability * 10-Feb-2005 BJD Added power-off capability
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
* 14-Mar-2006 BJD void __iomem fixes * 14-Mar-2006 BJD void __iomem fixes
* 22-Jun-2006 BJD Added DM9000 platform information
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -35,6 +36,7 @@ ...@@ -35,6 +36,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/dm9000.h>
#include <linux/serial.h> #include <linux/serial.h>
#include <linux/tty.h> #include <linux/tty.h>
...@@ -98,28 +100,24 @@ static struct map_desc vr1000_iodesc[] __initdata = { ...@@ -98,28 +100,24 @@ static struct map_desc vr1000_iodesc[] __initdata = {
* are only 8bit */ * are only 8bit */
/* slow, byte */ /* 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_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_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_IDEPRIAUX), PA_CS3(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
{ VA_C2(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE }, { VA_C2(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
/* slow, word */ /* 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_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_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_IDEPRIAUX), PA_CS3(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
{ VA_C3(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE }, { VA_C3(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
/* fast, byte */ /* 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_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_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_IDEPRIAUX), PA_CS5(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
{ VA_C4(VR1000_VA_IDESECAUX), PA_CS5(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE }, { VA_C4(VR1000_VA_IDESECAUX), PA_CS5(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
/* fast, word */ /* 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_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_IDESEC), PA_CS5(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE },
{ VA_C5(VR1000_VA_IDEPRIAUX), PA_CS5(VR1000_PA_IDEPRIAUX), 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 = { ...@@ -246,6 +244,74 @@ static struct platform_device vr1000_nor = {
.resource = vr1000_nor_resource, .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 = { static struct platform_device *vr1000_devices[] __initdata = {
&s3c_device_usb, &s3c_device_usb,
...@@ -253,8 +319,11 @@ static struct platform_device *vr1000_devices[] __initdata = { ...@@ -253,8 +319,11 @@ static struct platform_device *vr1000_devices[] __initdata = {
&s3c_device_wdt, &s3c_device_wdt,
&s3c_device_i2c, &s3c_device_i2c,
&s3c_device_iis, &s3c_device_iis,
&s3c_device_adc,
&serial_device, &serial_device,
&vr1000_nor, &vr1000_nor,
&vr1000_dm9k0,
&vr1000_dm9k1
}; };
static struct clk *vr1000_clocks[] = { static struct clk *vr1000_clocks[] = {
......
...@@ -132,8 +132,8 @@ ENTRY(cpu_v6_switch_mm) ...@@ -132,8 +132,8 @@ ENTRY(cpu_v6_switch_mm)
* 100x 1 0 1 r/o no acc * 100x 1 0 1 r/o no acc
* 10x0 1 0 1 r/o no acc * 10x0 1 0 1 r/o no acc
* 1011 0 0 1 r/w no acc * 1011 0 0 1 r/w no acc
* 110x 1 1 0 r/o r/o * 110x 0 1 0 r/w r/o
* 11x0 1 1 0 r/o r/o * 11x0 0 1 0 r/w r/o
* 1111 0 1 1 r/w r/w * 1111 0 1 1 r/w r/w
*/ */
ENTRY(cpu_v6_set_pte) ENTRY(cpu_v6_set_pte)
...@@ -150,7 +150,7 @@ ENTRY(cpu_v6_set_pte) ...@@ -150,7 +150,7 @@ ENTRY(cpu_v6_set_pte)
tst r1, #L_PTE_USER tst r1, #L_PTE_USER
orrne r2, r2, #AP1 | nG orrne r2, r2, #AP1 | nG
tstne r2, #APX tstne r2, #APX
eorne r2, r2, #AP0 bicne r2, r2, #APX | AP0
tst r1, #L_PTE_YOUNG tst r1, #L_PTE_YOUNG
biceq r2, r2, #APX | AP1 | AP0 biceq r2, r2, #APX | AP1 | AP0
......
...@@ -563,8 +563,14 @@ static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b ) ...@@ -563,8 +563,14 @@ static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b )
bits64 rem0, rem1, term0, term1; bits64 rem0, rem1, term0, term1;
bits64 z; bits64 z;
if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF ); if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF );
b0 = b>>32; b0 = b>>32; /* hence b0 is 32 bits wide now */
z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32; if ( b0<<32 <= a0 ) {
z = LIT64( 0xFFFFFFFF00000000 );
} else {
z = a0;
do_div( z, b0 );
z <<= 32;
}
mul64To128( b, z, &term0, &term1 ); mul64To128( b, z, &term0, &term1 );
sub128( a0, a1, term0, term1, &rem0, &rem1 ); sub128( a0, a1, term0, term1, &rem0, &rem1 );
while ( ( (sbits64) rem0 ) < 0 ) { while ( ( (sbits64) rem0 ) < 0 ) {
...@@ -573,7 +579,12 @@ static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b ) ...@@ -573,7 +579,12 @@ static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b )
add128( rem0, rem1, b0, b1, &rem0, &rem1 ); add128( rem0, rem1, b0, b1, &rem0, &rem1 );
} }
rem0 = ( rem0<<32 ) | ( rem1>>32 ); 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; return z;
} }
...@@ -601,6 +612,7 @@ static bits32 estimateSqrt32( int16 aExp, bits32 a ) ...@@ -601,6 +612,7 @@ static bits32 estimateSqrt32( int16 aExp, bits32 a )
}; };
int8 index; int8 index;
bits32 z; bits32 z;
bits64 A;
index = ( a>>27 ) & 15; index = ( a>>27 ) & 15;
if ( aExp & 1 ) { if ( aExp & 1 ) {
...@@ -614,7 +626,9 @@ static bits32 estimateSqrt32( int16 aExp, bits32 a ) ...@@ -614,7 +626,9 @@ static bits32 estimateSqrt32( int16 aExp, bits32 a )
z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 ); z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 ); 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. ...@@ -28,6 +28,8 @@ this code that are retained.
=============================================================================== ===============================================================================
*/ */
#include <asm/div64.h>
#include "fpa11.h" #include "fpa11.h"
//#include "milieu.h" //#include "milieu.h"
//#include "softfloat.h" //#include "softfloat.h"
...@@ -1331,7 +1333,11 @@ float32 float32_div( float32 a, float32 b ) ...@@ -1331,7 +1333,11 @@ float32 float32_div( float32 a, float32 b )
aSig >>= 1; aSig >>= 1;
++zExp; ++zExp;
} }
zSig = ( ( (bits64) aSig )<<32 ) / bSig; {
bits64 tmp = ( (bits64) aSig )<<32;
do_div( tmp, bSig );
zSig = tmp;
}
if ( ( zSig & 0x3F ) == 0 ) { if ( ( zSig & 0x3F ) == 0 ) {
zSig |= ( ( (bits64) bSig ) * zSig != ( (bits64) aSig )<<32 ); zSig |= ( ( (bits64) bSig ) * zSig != ( (bits64) aSig )<<32 );
} }
...@@ -1397,7 +1403,9 @@ float32 float32_rem( float32 a, float32 b ) ...@@ -1397,7 +1403,9 @@ float32 float32_rem( float32 a, float32 b )
q = ( bSig <= aSig ); q = ( bSig <= aSig );
if ( q ) aSig -= bSig; if ( q ) aSig -= bSig;
if ( 0 < expDiff ) { if ( 0 < expDiff ) {
q = ( ( (bits64) aSig )<<32 ) / bSig; bits64 tmp = ( (bits64) aSig )<<32;
do_div( tmp, bSig );
q = tmp;
q >>= 32 - expDiff; q >>= 32 - expDiff;
bSig >>= 2; bSig >>= 2;
aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
......
...@@ -179,6 +179,8 @@ config CMDLINE ...@@ -179,6 +179,8 @@ config CMDLINE
time by entering them here. As a minimum, you should specify the 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). memory size and the root device (e.g., mem=64M root=/dev/nfs).
source "mm/Kconfig"
endmenu endmenu
source "drivers/base/Kconfig" source "drivers/base/Kconfig"
......
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
# User may have a custom install script # User may have a custom install script
if [ -x /sbin/installkernel ]; then if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then
exec /sbin/installkernel "$@" exec /sbin/${CROSS_COMPILE}installkernel "$@"
fi fi
if [ "$2" = "zImage" ]; then if [ "$2" = "zImage" ]; then
......
...@@ -74,6 +74,8 @@ config PREEMPT ...@@ -74,6 +74,8 @@ config PREEMPT
Say Y here if you are building a kernel for a desktop, embedded Say Y here if you are building a kernel for a desktop, embedded
or real-time system. Say N if you are unsure. or real-time system. Say N if you are unsure.
source mm/Kconfig
endmenu endmenu
menu "Hardware setup" menu "Hardware setup"
......
...@@ -74,6 +74,8 @@ config HIGHPTE ...@@ -74,6 +74,8 @@ config HIGHPTE
with a lot of RAM, this can be wasteful of precious low memory. 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. Setting this option will put user-space page tables in high memory.
source "mm/Kconfig"
choice choice
prompt "uClinux kernel load address" prompt "uClinux kernel load address"
depends on !MMU depends on !MMU
......
...@@ -180,4 +180,7 @@ config CPU_H8S ...@@ -180,4 +180,7 @@ config CPU_H8S
config PREEMPT config PREEMPT
bool "Preemptible Kernel" bool "Preemptible Kernel"
default n default n
source "mm/Kconfig"
endmenu endmenu
...@@ -245,12 +245,12 @@ static unsigned short *getnextpc(struct task_struct *child, unsigned short *pc) ...@@ -245,12 +245,12 @@ static unsigned short *getnextpc(struct task_struct *child, unsigned short *pc)
addr = h8300_get_reg(child, regno-1+PT_ER1); addr = h8300_get_reg(child, regno-1+PT_ER1);
return (unsigned short *)addr; return (unsigned short *)addr;
case relb: case relb:
if ((inst = 0x55) || isbranch(child,inst & 0x0f)) if (inst == 0x55 || isbranch(child,inst & 0x0f))
pc = (unsigned short *)((unsigned long)pc + pc = (unsigned short *)((unsigned long)pc +
((signed char)(*fetch_p))); ((signed char)(*fetch_p)));
return pc+1; /* skip myself */ return pc+1; /* skip myself */
case relw: 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 + pc = (unsigned short *)((unsigned long)pc +
((signed short)(*(pc+1)))); ((signed short)(*(pc+1))));
return pc+2; /* skip myself */ return pc+2; /* skip myself */
......
...@@ -68,7 +68,6 @@ config X86_VOYAGER ...@@ -68,7 +68,6 @@ config X86_VOYAGER
config X86_NUMAQ config X86_NUMAQ
bool "NUMAQ (IBM/Sequent)" bool "NUMAQ (IBM/Sequent)"
select DISCONTIGMEM
select NUMA select NUMA
help help
This option is used for getting Linux to run on a (IBM/Sequent) NUMA This option is used for getting Linux to run on a (IBM/Sequent) NUMA
...@@ -783,25 +782,48 @@ comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support" ...@@ -783,25 +782,48 @@ comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support"
comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI" comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI"
depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI) depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI)
config DISCONTIGMEM
bool
depends on NUMA
default y
config HAVE_ARCH_BOOTMEM_NODE config HAVE_ARCH_BOOTMEM_NODE
bool bool
depends on NUMA depends on NUMA
default y default y
config HAVE_MEMORY_PRESENT config ARCH_HAVE_MEMORY_PRESENT
bool bool
depends on DISCONTIGMEM depends on DISCONTIGMEM
default y default y
config NEED_NODE_MEMMAP_SIZE config NEED_NODE_MEMMAP_SIZE
bool 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 default y
depends on NUMA
config HIGHPTE config HIGHPTE
bool "Allocate 3rd-level pagetables from highmem" bool "Allocate 3rd-level pagetables from highmem"
...@@ -939,6 +961,8 @@ config SECCOMP ...@@ -939,6 +961,8 @@ config SECCOMP
If unsure, say Y. Only embedded should say N here. If unsure, say Y. Only embedded should say N here.
source kernel/Kconfig.hz
endmenu endmenu
......
...@@ -17,6 +17,13 @@ ...@@ -17,6 +17,13 @@
# 20050320 Kianusch Sayah Karadji <kianusch@sk-tech.net> # 20050320 Kianusch Sayah Karadji <kianusch@sk-tech.net>
# Added support for GEODE CPU # 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 LDFLAGS := -m elf_i386
OBJCOPYFLAGS := -O binary -R .note -R .comment -S OBJCOPYFLAGS := -O binary -R .note -R .comment -S
LDFLAGS_vmlinux := LDFLAGS_vmlinux :=
......
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
# User may have a custom install script # User may have a custom install script
if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi
# Default install - same as make zlilo # Default install - same as make zlilo
......
...@@ -1133,7 +1133,7 @@ inline void smp_local_timer_interrupt(struct pt_regs * regs) ...@@ -1133,7 +1133,7 @@ inline void smp_local_timer_interrupt(struct pt_regs * regs)
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
update_process_times(user_mode(regs)); update_process_times(user_mode_vm(regs));
#endif #endif
} }
......
...@@ -635,7 +635,7 @@ void __init cpu_init (void) ...@@ -635,7 +635,7 @@ void __init cpu_init (void)
/* Clear all 6 debug registers: */ /* 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); 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, ...@@ -375,6 +375,19 @@ int mtrr_add_page(unsigned long base, unsigned long size,
return error; 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 * mtrr_add - Add a memory type region
* @base: Physical base address of region * @base: Physical base address of region
...@@ -415,11 +428,8 @@ int ...@@ -415,11 +428,8 @@ int
mtrr_add(unsigned long base, unsigned long size, unsigned int type, mtrr_add(unsigned long base, unsigned long size, unsigned int type,
char increment) char increment)
{ {
if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) { if (mtrr_check(base, size))
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);
return -EINVAL; return -EINVAL;
}
return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type, return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
increment); increment);
} }
...@@ -511,11 +521,8 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) ...@@ -511,11 +521,8 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
int int
mtrr_del(int reg, unsigned long base, unsigned long size) mtrr_del(int reg, unsigned long base, unsigned long size)
{ {
if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) { if (mtrr_check(base, size))
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);
return -EINVAL; return -EINVAL;
}
return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT); 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) ...@@ -86,7 +86,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "stepping\t: unknown\n"); seq_printf(m, "stepping\t: unknown\n");
if ( cpu_has(c, X86_FEATURE_TSC) ) { 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)); cpu_khz / 1000, (cpu_khz % 1000));
} }
......
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.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/checksum.h>
#include <asm/io.h>
#include <asm/delay.h>
#include <asm/irq.h>
#include <asm/mmx.h>
#include <asm/desc.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 */ /* This is definitely a GPL-only symbol */
EXPORT_SYMBOL_GPL(cpu_gdt_table); 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);
EXPORT_SYMBOL(__down_failed_interruptible); EXPORT_SYMBOL(__down_failed_interruptible);
EXPORT_SYMBOL(__down_failed_trylock); EXPORT_SYMBOL(__down_failed_trylock);
EXPORT_SYMBOL(__up_wakeup); EXPORT_SYMBOL(__up_wakeup);
/* Networking helper routines. */ /* Networking helper routines. */
EXPORT_SYMBOL(csum_partial_copy_generic); 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_1);
EXPORT_SYMBOL(__get_user_2); EXPORT_SYMBOL(__get_user_2);
...@@ -105,87 +25,11 @@ EXPORT_SYMBOL(__put_user_8); ...@@ -105,87 +25,11 @@ EXPORT_SYMBOL(__put_user_8);
EXPORT_SYMBOL(strpbrk); EXPORT_SYMBOL(strpbrk);
EXPORT_SYMBOL(strstr); 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 #ifdef CONFIG_SMP
EXPORT_SYMBOL(cpu_data); extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
EXPORT_SYMBOL(cpu_online_map); extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
EXPORT_SYMBOL(cpu_callout_map);
EXPORT_SYMBOL(__write_lock_failed); EXPORT_SYMBOL(__write_lock_failed);
EXPORT_SYMBOL(__read_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 #endif
EXPORT_SYMBOL(csum_partial); EXPORT_SYMBOL(csum_partial);
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/module.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/i387.h> #include <asm/i387.h>
#include <asm/math_emu.h> #include <asm/math_emu.h>
...@@ -79,6 +80,7 @@ void kernel_fpu_begin(void) ...@@ -79,6 +80,7 @@ void kernel_fpu_begin(void)
} }
clts(); clts();
} }
EXPORT_SYMBOL_GPL(kernel_fpu_begin);
void restore_fpu( struct task_struct *tsk ) void restore_fpu( struct task_struct *tsk )
{ {
...@@ -526,6 +528,7 @@ int dump_fpu( struct pt_regs *regs, struct user_i387_struct *fpu ) ...@@ -526,6 +528,7 @@ int dump_fpu( struct pt_regs *regs, struct user_i387_struct *fpu )
return fpvalid; return fpvalid;
} }
EXPORT_SYMBOL(dump_fpu);
int dump_task_fpu(struct task_struct *tsk, struct user_i387_struct *fpu) int dump_task_fpu(struct task_struct *tsk, struct user_i387_struct *fpu)
{ {
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include <linux/mc146818rtc.h> #include <linux/mc146818rtc.h>
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/module.h>
#include <linux/sysdev.h> #include <linux/sysdev.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/smp.h> #include <asm/smp.h>
...@@ -812,6 +812,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) ...@@ -812,6 +812,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
} }
return best_guess; 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 * 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) ...@@ -1658,6 +1659,12 @@ static void __init setup_ioapic_ids_from_mpc(void)
unsigned char old_id; unsigned char old_id;
unsigned long flags; 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 * This is broken; anything with a real cpu count has to
* circumvent this idiocy regardless. * circumvent this idiocy regardless.
...@@ -1684,10 +1691,6 @@ static void __init setup_ioapic_ids_from_mpc(void) ...@@ -1684,10 +1691,6 @@ static void __init setup_ioapic_ids_from_mpc(void)
mp_ioapics[apic].mpc_apicid = reg_00.bits.ID; 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 * Sanity check, is the ID really free? Every APIC in a
* system must have a unique ID or we get lots of nice * system must have a unique ID or we get lots of nice
......
...@@ -23,6 +23,9 @@ ...@@ -23,6 +23,9 @@
* Rusty Russell). * Rusty Russell).
* 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes
* interface to access function arguments. * 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> #include <linux/config.h>
...@@ -30,15 +33,14 @@ ...@@ -30,15 +33,14 @@
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/preempt.h> #include <linux/preempt.h>
#include <asm/cacheflush.h>
#include <asm/kdebug.h> #include <asm/kdebug.h>
#include <asm/desc.h> #include <asm/desc.h>
/* kprobe_status settings */
#define KPROBE_HIT_ACTIVE 0x00000001
#define KPROBE_HIT_SS 0x00000002
static struct kprobe *current_kprobe; static struct kprobe *current_kprobe;
static unsigned long kprobe_status, kprobe_old_eflags, kprobe_saved_eflags; 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 struct pt_regs jprobe_saved_regs;
static long *jprobe_saved_esp; static long *jprobe_saved_esp;
/* copy of the kernel stack at the probe fire time */ /* copy of the kernel stack at the probe fire time */
...@@ -68,16 +70,50 @@ int arch_prepare_kprobe(struct kprobe *p) ...@@ -68,16 +70,50 @@ int arch_prepare_kprobe(struct kprobe *p)
void arch_copy_kprobe(struct kprobe *p) void arch_copy_kprobe(struct kprobe *p)
{ {
memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
p->opcode = *p->addr;
} }
void arch_remove_kprobe(struct kprobe *p) 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));
} }
static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs) void arch_disarm_kprobe(struct kprobe *p)
{ {
*p->addr = p->opcode; *p->addr = p->opcode;
regs->eip = (unsigned long)p->addr; 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 save_previous_kprobe(void)
{
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) 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) ...@@ -91,6 +127,50 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
regs->eip = (unsigned long)&p->ainsn.insn; 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 *)&regs->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 * Interrupts are disabled on entry as trap3 is an interrupt gate and they
* remain disabled thorough out this function. * remain disabled thorough out this function.
...@@ -127,8 +207,18 @@ static int kprobe_handler(struct pt_regs *regs) ...@@ -127,8 +207,18 @@ static int kprobe_handler(struct pt_regs *regs)
unlock_kprobes(); unlock_kprobes();
goto no_kprobe; goto no_kprobe;
} }
disarm_kprobe(p, regs); /* We have reentered the kprobe_handler(), since
ret = 1; * 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 { } else {
p = current_kprobe; p = current_kprobe;
if (p->break_handler && p->break_handler(p, regs)) { if (p->break_handler && p->break_handler(p, regs)) {
...@@ -163,11 +253,7 @@ static int kprobe_handler(struct pt_regs *regs) ...@@ -163,11 +253,7 @@ static int kprobe_handler(struct pt_regs *regs)
} }
kprobe_status = KPROBE_HIT_ACTIVE; kprobe_status = KPROBE_HIT_ACTIVE;
current_kprobe = p; set_current_kprobe(p, regs);
kprobe_saved_eflags = kprobe_old_eflags
= (regs->eflags & (TF_MASK | IF_MASK));
if (is_IF_modifier(p->opcode))
kprobe_saved_eflags &= ~IF_MASK;
if (p->pre_handler && p->pre_handler(p, regs)) if (p->pre_handler && p->pre_handler(p, regs))
/* handler has already set things up, so skip ss setup */ /* handler has already set things up, so skip ss setup */
...@@ -183,6 +269,55 @@ static int kprobe_handler(struct pt_regs *regs) ...@@ -183,6 +269,55 @@ static int kprobe_handler(struct pt_regs *regs)
return ret; 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 *) &regs->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 *)&regs->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 * Called after single-stepping. p->addr is the address of the
* instruction whose first byte has been replaced by the "int 3" * 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) ...@@ -263,13 +398,22 @@ static inline int post_kprobe_handler(struct pt_regs *regs)
if (!kprobe_running()) if (!kprobe_running())
return 0; 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); 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; 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(); unlock_kprobes();
out:
preempt_enable_no_resched(); preempt_enable_no_resched();
/* /*
......
...@@ -914,7 +914,10 @@ void __init mp_register_ioapic ( ...@@ -914,7 +914,10 @@ void __init mp_register_ioapic (
mp_ioapics[idx].mpc_apicaddr = address; mp_ioapics[idx].mpc_apicaddr = address;
set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, 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); mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx);
/* /*
...@@ -1055,11 +1058,20 @@ void __init mp_config_acpi_legacy_irqs (void) ...@@ -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 mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
{ {
int ioapic = -1; int ioapic = -1;
int ioapic_pin = 0; int ioapic_pin = 0;
int idx, bit = 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 #ifdef CONFIG_ACPI_BUS
/* Don't set up the ACPI SCI because it's already set up */ /* 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) ...@@ -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]) { if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
mp_ioapic_routing[ioapic].apic_id, ioapic_pin); mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
return gsi; return gsi_to_irq[gsi];
} }
mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); 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, io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1, edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1); active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);
......
...@@ -28,8 +28,7 @@ ...@@ -28,8 +28,7 @@
#include <linux/sysctl.h> #include <linux/sysctl.h>
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/mtrr.h> #include <asm/div64.h>
#include <asm/mpspec.h>
#include <asm/nmi.h> #include <asm/nmi.h>
#include "mach_traps.h" #include "mach_traps.h"
...@@ -324,6 +323,16 @@ static void clear_msr_range(unsigned int base, unsigned int n) ...@@ -324,6 +323,16 @@ static void clear_msr_range(unsigned int base, unsigned int n)
wrmsr(base+i, 0, 0); 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) static void setup_k7_watchdog(void)
{ {
unsigned int evntsel; unsigned int evntsel;
...@@ -339,8 +348,7 @@ static void setup_k7_watchdog(void) ...@@ -339,8 +348,7 @@ static void setup_k7_watchdog(void)
| K7_NMI_EVENT; | K7_NMI_EVENT;
wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
Dprintk("setting K7_PERFCTR0 to %08lx\n", -(cpu_khz/nmi_hz*1000)); write_watchdog_counter("K7_PERFCTR0");
wrmsr(MSR_K7_PERFCTR0, -(cpu_khz/nmi_hz*1000), -1);
apic_write(APIC_LVTPC, APIC_DM_NMI); apic_write(APIC_LVTPC, APIC_DM_NMI);
evntsel |= K7_EVNTSEL_ENABLE; evntsel |= K7_EVNTSEL_ENABLE;
wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
...@@ -361,8 +369,7 @@ static void setup_p6_watchdog(void) ...@@ -361,8 +369,7 @@ static void setup_p6_watchdog(void)
| P6_NMI_EVENT; | P6_NMI_EVENT;
wrmsr(MSR_P6_EVNTSEL0, evntsel, 0); wrmsr(MSR_P6_EVNTSEL0, evntsel, 0);
Dprintk("setting P6_PERFCTR0 to %08lx\n", -(cpu_khz/nmi_hz*1000)); write_watchdog_counter("P6_PERFCTR0");
wrmsr(MSR_P6_PERFCTR0, -(cpu_khz/nmi_hz*1000), 0);
apic_write(APIC_LVTPC, APIC_DM_NMI); apic_write(APIC_LVTPC, APIC_DM_NMI);
evntsel |= P6_EVNTSEL0_ENABLE; evntsel |= P6_EVNTSEL0_ENABLE;
wrmsr(MSR_P6_EVNTSEL0, evntsel, 0); wrmsr(MSR_P6_EVNTSEL0, evntsel, 0);
...@@ -402,8 +409,7 @@ static int setup_p4_watchdog(void) ...@@ -402,8 +409,7 @@ static int setup_p4_watchdog(void)
wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0); wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0);
wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 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)); write_watchdog_counter("P4_IQ_COUNTER0");
wrmsr(MSR_P4_IQ_COUNTER0, -(cpu_khz/nmi_hz*1000), -1);
apic_write(APIC_LVTPC, APIC_DM_NMI); apic_write(APIC_LVTPC, APIC_DM_NMI);
wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0);
return 1; return 1;
...@@ -518,7 +524,7 @@ void nmi_watchdog_tick (struct pt_regs * regs) ...@@ -518,7 +524,7 @@ void nmi_watchdog_tick (struct pt_regs * regs)
* other P6 variant */ * other P6 variant */
apic_write(APIC_LVTPC, APIC_DM_NMI); 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 @@ ...@@ -11,6 +11,7 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/module.h>
#include <asm/io.h> #include <asm/io.h>
struct dma_coherent_mem { struct dma_coherent_mem {
...@@ -54,6 +55,7 @@ void *dma_alloc_coherent(struct device *dev, size_t size, ...@@ -54,6 +55,7 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
} }
return ret; return ret;
} }
EXPORT_SYMBOL(dma_alloc_coherent);
void dma_free_coherent(struct device *dev, size_t size, void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle) void *vaddr, dma_addr_t dma_handle)
...@@ -68,6 +70,7 @@ void dma_free_coherent(struct device *dev, size_t size, ...@@ -68,6 +70,7 @@ void dma_free_coherent(struct device *dev, size_t size,
} else } else
free_pages((unsigned long)vaddr, order); free_pages((unsigned long)vaddr, order);
} }
EXPORT_SYMBOL(dma_free_coherent);
int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
dma_addr_t device_addr, size_t size, int flags) dma_addr_t device_addr, size_t size, int flags)
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <linux/kallsyms.h> #include <linux/kallsyms.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/kprobes.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
...@@ -73,6 +74,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk) ...@@ -73,6 +74,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
* Powermanagement idle function, if any.. * Powermanagement idle function, if any..
*/ */
void (*pm_idle)(void); void (*pm_idle)(void);
EXPORT_SYMBOL(pm_idle);
static DEFINE_PER_CPU(unsigned int, cpu_idle_state); static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
void disable_hlt(void) void disable_hlt(void)
...@@ -105,6 +107,9 @@ void default_idle(void) ...@@ -105,6 +107,9 @@ void default_idle(void)
cpu_relax(); cpu_relax();
} }
} }
#ifdef CONFIG_APM_MODULE
EXPORT_SYMBOL(default_idle);
#endif
/* /*
* On SMP it's slightly faster (but much more power-consuming!) * On SMP it's slightly faster (but much more power-consuming!)
...@@ -262,7 +267,7 @@ void show_regs(struct pt_regs * regs) ...@@ -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()); printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
print_symbol("EIP is at %s\n", regs->eip); 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(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
printk(" EFLAGS: %08lx %s (%s)\n", printk(" EFLAGS: %08lx %s (%s)\n",
regs->eflags, print_tainted(), system_utsname.release); regs->eflags, print_tainted(), system_utsname.release);
...@@ -325,6 +330,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) ...@@ -325,6 +330,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
/* Ok, create the new process.. */ /* Ok, create the new process.. */
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL); return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
} }
EXPORT_SYMBOL(kernel_thread);
/* /*
* Free current thread data structures etc.. * Free current thread data structures etc..
...@@ -334,6 +340,13 @@ void exit_thread(void) ...@@ -334,6 +340,13 @@ void exit_thread(void)
struct task_struct *tsk = current; struct task_struct *tsk = current;
struct thread_struct *t = &tsk->thread; 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. */ /* The process may have allocated an io port bitmap... nuke it. */
if (unlikely(NULL != t->io_bitmap_ptr)) { if (unlikely(NULL != t->io_bitmap_ptr)) {
int cpu = get_cpu(); int cpu = get_cpu();
...@@ -357,6 +370,13 @@ void flush_thread(void) ...@@ -357,6 +370,13 @@ void flush_thread(void)
{ {
struct task_struct *tsk = current; 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.debugreg, 0, sizeof(unsigned long)*8);
memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); 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) ...@@ -508,6 +528,7 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
dump->u_fpvalid = dump_fpu (regs, &dump->i387); 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) * 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 ...@@ -627,13 +648,13 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
* Now maybe reload the debug registers * Now maybe reload the debug registers
*/ */
if (unlikely(next->debugreg[7])) { if (unlikely(next->debugreg[7])) {
loaddebug(next, 0); set_debugreg(current->thread.debugreg[0], 0);
loaddebug(next, 1); set_debugreg(current->thread.debugreg[1], 1);
loaddebug(next, 2); set_debugreg(current->thread.debugreg[2], 2);
loaddebug(next, 3); set_debugreg(current->thread.debugreg[3], 3);
/* no 4 and 5 */ /* no 4 and 5 */
loaddebug(next, 6); set_debugreg(current->thread.debugreg[6], 6);
loaddebug(next, 7); set_debugreg(current->thread.debugreg[7], 7);
} }
if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr))
...@@ -731,6 +752,7 @@ unsigned long get_wchan(struct task_struct *p) ...@@ -731,6 +752,7 @@ unsigned long get_wchan(struct task_struct *p)
} while (count++ < 16); } while (count++ < 16);
return 0; return 0;
} }
EXPORT_SYMBOL(get_wchan);
/* /*
* sys_alloc_thread_area: get a yet unused TLS descriptor index. * 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) ...@@ -668,7 +668,7 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
info.si_code = TRAP_BRKPT; info.si_code = TRAP_BRKPT;
/* User-mode eip? */ /* 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 */ /* Send us the fakey SIGTRAP */
force_sig_info(SIGTRAP, &info, tsk); force_sig_info(SIGTRAP, &info, tsk);
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* linux/arch/i386/kernel/reboot.c * linux/arch/i386/kernel/reboot.c
*/ */
#include <linux/config.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -19,6 +20,7 @@ ...@@ -19,6 +20,7 @@
* Power off function, if any * Power off function, if any
*/ */
void (*pm_power_off)(void); void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);
static int reboot_mode; static int reboot_mode;
static int reboot_thru_bios; static int reboot_thru_bios;
...@@ -295,6 +297,9 @@ void machine_real_restart(unsigned char *code, int length) ...@@ -295,6 +297,9 @@ void machine_real_restart(unsigned char *code, int length)
: :
: "i" ((void *) (0x1000 - sizeof (real_mode_switch) - 100))); : "i" ((void *) (0x1000 - sizeof (real_mode_switch) - 100)));
} }
#ifdef CONFIG_APM_MODULE
EXPORT_SYMBOL(machine_real_restart);
#endif
void machine_restart(char * __unused) void machine_restart(char * __unused)
{ {
......
...@@ -23,8 +23,10 @@ ...@@ -23,8 +23,10 @@
* This file handles the architecture-dependent parts of initialization * This file handles the architecture-dependent parts of initialization
*/ */
#include <linux/config.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/mmzone.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/acpi.h> #include <linux/acpi.h>
...@@ -73,6 +75,7 @@ EXPORT_SYMBOL(efi_enabled); ...@@ -73,6 +75,7 @@ EXPORT_SYMBOL(efi_enabled);
struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
/* common cpu data for all cpus */ /* common cpu data for all cpus */
struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; 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; unsigned long mmu_cr4_features;
...@@ -90,12 +93,18 @@ extern acpi_interrupt_flags acpi_sci_flags; ...@@ -90,12 +93,18 @@ extern acpi_interrupt_flags acpi_sci_flags;
/* for MCA, but anyone else can use it if they want */ /* for MCA, but anyone else can use it if they want */
unsigned int machine_id; unsigned int machine_id;
#ifdef CONFIG_MCA
EXPORT_SYMBOL(machine_id);
#endif
unsigned int machine_submodel_id; unsigned int machine_submodel_id;
unsigned int BIOS_revision; unsigned int BIOS_revision;
unsigned int mca_pentium_flag; unsigned int mca_pentium_flag;
/* For PCI or other memory-mapped resources */ /* For PCI or other memory-mapped resources */
unsigned long pci_mem_start = 0x10000000; 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 */ /* Boot loader ID as an integer, for the benefit of proc_dointvec */
int bootloader_type; int bootloader_type;
...@@ -107,14 +116,26 @@ static unsigned int highmem_pages = -1; ...@@ -107,14 +116,26 @@ static unsigned int highmem_pages = -1;
* Setup options * Setup options
*/ */
struct drive_info_struct { char dummy[32]; } drive_info; 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; struct screen_info screen_info;
#ifdef CONFIG_VT
EXPORT_SYMBOL(screen_info);
#endif
struct apm_info apm_info; struct apm_info apm_info;
EXPORT_SYMBOL(apm_info);
struct sys_desc_table_struct { struct sys_desc_table_struct {
unsigned short length; unsigned short length;
unsigned char table[0]; unsigned char table[0];
}; };
struct edid_info edid_info; struct edid_info edid_info;
struct ist_info ist_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; struct e820map e820;
extern void early_cpu_init(void); extern void early_cpu_init(void);
...@@ -1022,7 +1043,7 @@ static void __init reserve_ebda_region(void) ...@@ -1022,7 +1043,7 @@ static void __init reserve_ebda_region(void)
reserve_bootmem(addr, PAGE_SIZE); reserve_bootmem(addr, PAGE_SIZE);
} }
#ifndef CONFIG_DISCONTIGMEM #ifndef CONFIG_NEED_MULTIPLE_NODES
void __init setup_bootmem_allocator(void); void __init setup_bootmem_allocator(void);
static unsigned long __init setup_memory(void) static unsigned long __init setup_memory(void)
{ {
...@@ -1072,9 +1093,9 @@ void __init zone_sizes_init(void) ...@@ -1072,9 +1093,9 @@ void __init zone_sizes_init(void)
free_area_init(zones_size); free_area_init(zones_size);
} }
#else #else
extern unsigned long setup_memory(void); extern unsigned long __init setup_memory(void);
extern void zone_sizes_init(void); extern void zone_sizes_init(void);
#endif /* !CONFIG_DISCONTIGMEM */ #endif /* !CONFIG_NEED_MULTIPLE_NODES */
void __init setup_bootmem_allocator(void) void __init setup_bootmem_allocator(void)
{ {
...@@ -1475,6 +1496,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -1475,6 +1496,7 @@ void __init setup_arch(char **cmdline_p)
#endif #endif
paging_init(); paging_init();
remapped_pgdat_init(); remapped_pgdat_init();
sparse_init();
zone_sizes_init(); zone_sizes_init();
/* /*
......
...@@ -346,8 +346,8 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) ...@@ -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_sigreturn;
extern void __user __kernel_rt_sigreturn; extern void __user __kernel_rt_sigreturn;
static void setup_frame(int sig, struct k_sigaction *ka, static int setup_frame(int sig, struct k_sigaction *ka,
sigset_t *set, struct pt_regs * regs) sigset_t *set, struct pt_regs * regs)
{ {
void __user *restorer; void __user *restorer;
struct sigframe __user *frame; struct sigframe __user *frame;
...@@ -429,13 +429,14 @@ static void setup_frame(int sig, struct k_sigaction *ka, ...@@ -429,13 +429,14 @@ static void setup_frame(int sig, struct k_sigaction *ka,
current->comm, current->pid, frame, regs->eip, frame->pretcode); current->comm, current->pid, frame, regs->eip, frame->pretcode);
#endif #endif
return; return 1;
give_sigsegv: give_sigsegv:
force_sigsegv(sig, current); 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) sigset_t *set, struct pt_regs * regs)
{ {
void __user *restorer; void __user *restorer;
...@@ -522,20 +523,23 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -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); current->comm, current->pid, frame, regs->eip, frame->pretcode);
#endif #endif
return; return 1;
give_sigsegv: give_sigsegv:
force_sigsegv(sig, current); force_sigsegv(sig, current);
return 0;
} }
/* /*
* OK, we're invoking a handler * OK, we're invoking a handler
*/ */
static void static int
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
sigset_t *oldset, struct pt_regs * regs) sigset_t *oldset, struct pt_regs * regs)
{ {
int ret;
/* Are we from a system call? */ /* Are we from a system call? */
if (regs->orig_eax >= 0) { if (regs->orig_eax >= 0) {
/* If so, check system call restarting.. */ /* If so, check system call restarting.. */
...@@ -569,17 +573,19 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, ...@@ -569,17 +573,19 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
/* Set up the stack frame */ /* Set up the stack frame */
if (ka->sa.sa_flags & SA_SIGINFO) 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 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(&current->sighand->siglock); spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
sigaddset(&current->blocked,sig); sigaddset(&current->blocked,sig);
recalc_sigpending(); recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock); spin_unlock_irq(&current->sighand->siglock);
} }
return ret;
} }
/* /*
...@@ -599,7 +605,7 @@ int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset) ...@@ -599,7 +605,7 @@ int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset)
* kernel mode. Just return without doing anything * kernel mode. Just return without doing anything
* if so. * if so.
*/ */
if ((regs->xcs & 3) != 3) if (!user_mode(regs))
return 1; return 1;
if (current->flags & PF_FREEZE) { if (current->flags & PF_FREEZE) {
...@@ -618,12 +624,11 @@ int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset) ...@@ -618,12 +624,11 @@ int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset)
* inside the kernel. * inside the kernel.
*/ */
if (unlikely(current->thread.debugreg[7])) { if (unlikely(current->thread.debugreg[7])) {
loaddebug(&current->thread, 7); set_debugreg(current->thread.debugreg[7], 7);
} }
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
handle_signal(signr, &info, &ka, oldset, regs); return handle_signal(signr, &info, &ka, oldset, regs);
return 1;
} }
no_signal: no_signal:
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/mc146818rtc.h> #include <linux/mc146818rtc.h>
#include <linux/cache.h> #include <linux/cache.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/module.h>
#include <asm/mtrr.h> #include <asm/mtrr.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
...@@ -452,6 +453,7 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va) ...@@ -452,6 +453,7 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
preempt_enable(); preempt_enable();
} }
EXPORT_SYMBOL(flush_tlb_page);
static void do_flush_tlb_all(void* info) static void do_flush_tlb_all(void* info)
{ {
...@@ -547,6 +549,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, ...@@ -547,6 +549,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
return 0; return 0;
} }
EXPORT_SYMBOL(smp_call_function);
static void stop_this_cpu (void * dummy) static void stop_this_cpu (void * dummy)
{ {
......
...@@ -60,6 +60,9 @@ static int __initdata smp_b_stepping; ...@@ -60,6 +60,9 @@ static int __initdata smp_b_stepping;
/* Number of siblings per CPU package */ /* Number of siblings per CPU package */
int smp_num_siblings = 1; 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 */ int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
EXPORT_SYMBOL(phys_proc_id); EXPORT_SYMBOL(phys_proc_id);
int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */ int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */
...@@ -67,13 +70,16 @@ EXPORT_SYMBOL(cpu_core_id); ...@@ -67,13 +70,16 @@ EXPORT_SYMBOL(cpu_core_id);
/* bitmap of online cpus */ /* bitmap of online cpus */
cpumask_t cpu_online_map; cpumask_t cpu_online_map;
EXPORT_SYMBOL(cpu_online_map);
cpumask_t cpu_callin_map; cpumask_t cpu_callin_map;
cpumask_t cpu_callout_map; cpumask_t cpu_callout_map;
EXPORT_SYMBOL(cpu_callout_map);
static cpumask_t smp_commenced_mask; static cpumask_t smp_commenced_mask;
/* Per CPU bogomips and other parameters */ /* Per CPU bogomips and other parameters */
struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
EXPORT_SYMBOL(cpu_data);
u8 x86_cpu_to_apicid[NR_CPUS] = u8 x86_cpu_to_apicid[NR_CPUS] =
{ [0 ... NR_CPUS-1] = 0xff }; { [0 ... NR_CPUS-1] = 0xff };
...@@ -199,7 +205,7 @@ static void __init synchronize_tsc_bp (void) ...@@ -199,7 +205,7 @@ static void __init synchronize_tsc_bp (void)
unsigned long long t0; unsigned long long t0;
unsigned long long sum, avg; unsigned long long sum, avg;
long long delta; long long delta;
unsigned long one_usec; unsigned int one_usec;
int buggy = 0; int buggy = 0;
printk(KERN_INFO "checking TSC synchronization across %u CPUs: ", num_booting_cpus()); printk(KERN_INFO "checking TSC synchronization across %u CPUs: ", num_booting_cpus());
...@@ -885,8 +891,14 @@ static void smp_tune_scheduling (void) ...@@ -885,8 +891,14 @@ static void smp_tune_scheduling (void)
static int boot_cpu_logical_apicid; static int boot_cpu_logical_apicid;
/* Where the IO area was mapped on multiquad, always 0 otherwise */ /* Where the IO area was mapped on multiquad, always 0 otherwise */
void *xquad_portio; void *xquad_portio;
#ifdef CONFIG_X86_NUMAQ
EXPORT_SYMBOL(xquad_portio);
#endif
cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; 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; cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
EXPORT_SYMBOL(cpu_core_map); EXPORT_SYMBOL(cpu_core_map);
......
...@@ -77,11 +77,13 @@ u64 jiffies_64 = INITIAL_JIFFIES; ...@@ -77,11 +77,13 @@ u64 jiffies_64 = INITIAL_JIFFIES;
EXPORT_SYMBOL(jiffies_64); 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; extern unsigned long wall_jiffies;
DEFINE_SPINLOCK(rtc_lock); DEFINE_SPINLOCK(rtc_lock);
EXPORT_SYMBOL(rtc_lock);
DEFINE_SPINLOCK(i8253_lock); DEFINE_SPINLOCK(i8253_lock);
EXPORT_SYMBOL(i8253_lock); EXPORT_SYMBOL(i8253_lock);
...@@ -324,6 +326,8 @@ unsigned long get_cmos_time(void) ...@@ -324,6 +326,8 @@ unsigned long get_cmos_time(void)
return retval; return retval;
} }
EXPORT_SYMBOL(get_cmos_time);
static void sync_cmos_clock(unsigned long dummy); static void sync_cmos_clock(unsigned long dummy);
static struct timer_list sync_cmos_timer = static struct timer_list sync_cmos_timer =
......
...@@ -139,6 +139,15 @@ unsigned long __init calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr) ...@@ -139,6 +139,15 @@ unsigned long __init calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr)
} }
#endif #endif
unsigned long read_timer_tsc(void)
{
unsigned long retval;
rdtscl(retval);
return retval;
}
/* calculate cpu_khz */ /* calculate cpu_khz */
void init_cpu_khz(void) void init_cpu_khz(void)
{ {
...@@ -154,7 +163,8 @@ void init_cpu_khz(void) ...@@ -154,7 +163,8 @@ void init_cpu_khz(void)
:"=a" (cpu_khz), "=d" (edx) :"=a" (cpu_khz), "=d" (edx)
:"r" (tsc_quotient), :"r" (tsc_quotient),
"0" (eax), "1" (edx)); "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) ...@@ -64,3 +64,12 @@ struct timer_opts* __init select_timer(void)
panic("select_timer: Cannot find a suitable timer\n"); panic("select_timer: Cannot find a suitable timer\n");
return NULL; 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) ...@@ -158,7 +158,7 @@ static int __init init_hpet(char* override)
{ unsigned long eax=0, edx=1000; { unsigned long eax=0, edx=1000;
ASM_DIV64_REG(cpu_khz, edx, tsc_quotient, ASM_DIV64_REG(cpu_khz, edx, tsc_quotient,
eax, edx); eax, edx);
printk("Detected %lu.%03lu MHz processor.\n", printk("Detected %u.%03u MHz processor.\n",
cpu_khz / 1000, cpu_khz % 1000); cpu_khz / 1000, cpu_khz % 1000);
} }
set_cyc2ns_scale(cpu_khz/1000); set_cyc2ns_scale(cpu_khz/1000);
...@@ -186,6 +186,7 @@ static struct timer_opts timer_hpet = { ...@@ -186,6 +186,7 @@ static struct timer_opts timer_hpet = {
.get_offset = get_offset_hpet, .get_offset = get_offset_hpet,
.monotonic_clock = monotonic_clock_hpet, .monotonic_clock = monotonic_clock_hpet,
.delay = delay_hpet, .delay = delay_hpet,
.read_timer = read_timer_tsc,
}; };
struct init_timer_opts __initdata timer_hpet_init = { struct init_timer_opts __initdata timer_hpet_init = {
......
...@@ -246,6 +246,7 @@ static struct timer_opts timer_pmtmr = { ...@@ -246,6 +246,7 @@ static struct timer_opts timer_pmtmr = {
.get_offset = get_offset_pmtmr, .get_offset = get_offset_pmtmr,
.monotonic_clock = monotonic_clock_pmtmr, .monotonic_clock = monotonic_clock_pmtmr,
.delay = delay_pmtmr, .delay = delay_pmtmr,
.read_timer = read_timer_tsc,
}; };
struct init_timer_opts __initdata timer_pmtmr_init = { struct init_timer_opts __initdata timer_pmtmr_init = {
......
...@@ -256,7 +256,7 @@ static unsigned long loops_per_jiffy_ref = 0; ...@@ -256,7 +256,7 @@ static unsigned long loops_per_jiffy_ref = 0;
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
static unsigned long fast_gettimeoffset_ref = 0; static unsigned long fast_gettimeoffset_ref = 0;
static unsigned long cpu_khz_ref = 0; static unsigned int cpu_khz_ref = 0;
#endif #endif
static int static int
...@@ -323,7 +323,7 @@ static inline void cpufreq_delayed_get(void) { return; } ...@@ -323,7 +323,7 @@ static inline void cpufreq_delayed_get(void) { return; }
int recalibrate_cpu_khz(void) int recalibrate_cpu_khz(void)
{ {
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
unsigned long cpu_khz_old = cpu_khz; unsigned int cpu_khz_old = cpu_khz;
if (cpu_has_tsc) { if (cpu_has_tsc) {
init_cpu_khz(); init_cpu_khz();
...@@ -534,7 +534,8 @@ static int __init init_tsc(char* override) ...@@ -534,7 +534,8 @@ static int __init init_tsc(char* override)
:"=a" (cpu_khz), "=d" (edx) :"=a" (cpu_khz), "=d" (edx)
:"r" (tsc_quotient), :"r" (tsc_quotient),
"0" (eax), "1" (edx)); "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); set_cyc2ns_scale(cpu_khz/1000);
return 0; return 0;
...@@ -572,6 +573,7 @@ static struct timer_opts timer_tsc = { ...@@ -572,6 +573,7 @@ static struct timer_opts timer_tsc = {
.get_offset = get_offset_tsc, .get_offset = get_offset_tsc,
.monotonic_clock = monotonic_clock_tsc, .monotonic_clock = monotonic_clock_tsc,
.delay = delay_tsc, .delay = delay_tsc,
.read_timer = read_timer_tsc,
}; };
struct init_timer_opts __initdata timer_tsc_init = { struct init_timer_opts __initdata timer_tsc_init = {
......
...@@ -104,6 +104,7 @@ int register_die_notifier(struct notifier_block *nb) ...@@ -104,6 +104,7 @@ int register_die_notifier(struct notifier_block *nb)
spin_unlock_irqrestore(&die_notifier_lock, flags); spin_unlock_irqrestore(&die_notifier_lock, flags);
return err; return err;
} }
EXPORT_SYMBOL(register_die_notifier);
static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
{ {
...@@ -209,7 +210,7 @@ void show_registers(struct pt_regs *regs) ...@@ -209,7 +210,7 @@ void show_registers(struct pt_regs *regs)
esp = (unsigned long) (&regs->esp); esp = (unsigned long) (&regs->esp);
ss = __KERNEL_DS; ss = __KERNEL_DS;
if (regs->xcs & 3) { if (user_mode(regs)) {
in_kernel = 0; in_kernel = 0;
esp = regs->esp; esp = regs->esp;
ss = regs->xss & 0xffff; ss = regs->xss & 0xffff;
...@@ -265,7 +266,7 @@ static void handle_BUG(struct pt_regs *regs) ...@@ -265,7 +266,7 @@ static void handle_BUG(struct pt_regs *regs)
char c; char c;
unsigned long eip; unsigned long eip;
if (regs->xcs & 3) if (user_mode(regs))
goto no_bug; /* Not in kernel */ goto no_bug; /* Not in kernel */
eip = regs->eip; eip = regs->eip;
...@@ -353,7 +354,7 @@ void die(const char * str, struct pt_regs * regs, long err) ...@@ -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) 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); die(str, regs, err);
} }
...@@ -366,7 +367,7 @@ static void do_trap(int trapnr, int signr, char *str, int vm86, ...@@ -366,7 +367,7 @@ static void do_trap(int trapnr, int signr, char *str, int vm86,
goto trap_signal; goto trap_signal;
} }
if (!(regs->xcs & 3)) if (!user_mode(regs))
goto kernel_trap; goto kernel_trap;
trap_signal: { trap_signal: {
...@@ -488,7 +489,7 @@ fastcall void do_general_protection(struct pt_regs * regs, long error_code) ...@@ -488,7 +489,7 @@ fastcall void do_general_protection(struct pt_regs * regs, long error_code)
if (regs->eflags & VM_MASK) if (regs->eflags & VM_MASK)
goto gp_in_vm86; goto gp_in_vm86;
if (!(regs->xcs & 3)) if (!user_mode(regs))
goto gp_in_kernel; goto gp_in_kernel;
current->thread.error_code = error_code; current->thread.error_code = error_code;
...@@ -636,11 +637,13 @@ void set_nmi_callback(nmi_callback_t callback) ...@@ -636,11 +637,13 @@ void set_nmi_callback(nmi_callback_t callback)
{ {
nmi_callback = callback; nmi_callback = callback;
} }
EXPORT_SYMBOL_GPL(set_nmi_callback);
void unset_nmi_callback(void) void unset_nmi_callback(void)
{ {
nmi_callback = dummy_nmi_callback; nmi_callback = dummy_nmi_callback;
} }
EXPORT_SYMBOL_GPL(unset_nmi_callback);
#ifdef CONFIG_KPROBES #ifdef CONFIG_KPROBES
fastcall void do_int3(struct pt_regs *regs, long error_code) 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) ...@@ -682,7 +685,7 @@ fastcall void do_debug(struct pt_regs * regs, long error_code)
unsigned int condition; unsigned int condition;
struct task_struct *tsk = current; 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, if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
SIGTRAP) == NOTIFY_STOP) SIGTRAP) == NOTIFY_STOP)
...@@ -713,7 +716,7 @@ fastcall void do_debug(struct pt_regs * regs, long error_code) ...@@ -713,7 +716,7 @@ fastcall void do_debug(struct pt_regs * regs, long error_code)
* check for kernel mode by just checking the CPL * check for kernel mode by just checking the CPL
* of CS. * of CS.
*/ */
if ((regs->xcs & 3) == 0) if (!user_mode(regs))
goto clear_TF_reenable; goto clear_TF_reenable;
} }
...@@ -724,9 +727,7 @@ fastcall void do_debug(struct pt_regs * regs, long error_code) ...@@ -724,9 +727,7 @@ fastcall void do_debug(struct pt_regs * regs, long error_code)
* the signal is delivered. * the signal is delivered.
*/ */
clear_dr7: clear_dr7:
__asm__("movl %0,%%db7" set_debugreg(0, 7);
: /* no output */
: "r" (0));
return; return;
debug_vm86: debug_vm86:
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
*/ */
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/module.h>
#include <asm/atomic.h> #include <asm/atomic.h>
int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
...@@ -38,3 +39,4 @@ int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) ...@@ -38,3 +39,4 @@ int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
spin_unlock(lock); spin_unlock(lock);
return 0; return 0;
} }
EXPORT_SYMBOL(_atomic_dec_and_lock);
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/module.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/delay.h> #include <asm/delay.h>
#include <asm/timer.h> #include <asm/timer.h>
...@@ -47,3 +48,8 @@ void __ndelay(unsigned long nsecs) ...@@ -47,3 +48,8 @@ void __ndelay(unsigned long nsecs)
{ {
__const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ __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 @@ ...@@ -3,6 +3,7 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/hardirq.h> #include <linux/hardirq.h>
#include <linux/module.h>
#include <asm/i387.h> #include <asm/i387.h>
...@@ -397,3 +398,7 @@ void mmx_copy_page(void *to, void *from) ...@@ -397,3 +398,7 @@ void mmx_copy_page(void *to, void *from)
else else
fast_copy_page(to, from); 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) ...@@ -84,6 +84,7 @@ __strncpy_from_user(char *dst, const char __user *src, long count)
__do_strncpy_from_user(dst, src, count, res); __do_strncpy_from_user(dst, src, count, res);
return res; return res;
} }
EXPORT_SYMBOL(__strncpy_from_user);
/** /**
* strncpy_from_user: - Copy a NUL terminated string from userspace. * 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) ...@@ -111,7 +112,7 @@ strncpy_from_user(char *dst, const char __user *src, long count)
__do_strncpy_from_user(dst, src, count, res); __do_strncpy_from_user(dst, src, count, res);
return res; return res;
} }
EXPORT_SYMBOL(strncpy_from_user);
/* /*
* Zero Userspace * Zero Userspace
...@@ -157,6 +158,7 @@ clear_user(void __user *to, unsigned long n) ...@@ -157,6 +158,7 @@ clear_user(void __user *to, unsigned long n)
__do_clear_user(to, n); __do_clear_user(to, n);
return n; return n;
} }
EXPORT_SYMBOL(clear_user);
/** /**
* __clear_user: - Zero a block of memory in user space, with less checking. * __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) ...@@ -175,6 +177,7 @@ __clear_user(void __user *to, unsigned long n)
__do_clear_user(to, n); __do_clear_user(to, n);
return n; return n;
} }
EXPORT_SYMBOL(__clear_user);
/** /**
* strlen_user: - Get the size of a string in user space. * strlen_user: - Get the size of a string in user space.
...@@ -218,6 +221,7 @@ long strnlen_user(const char __user *s, long n) ...@@ -218,6 +221,7 @@ long strnlen_user(const char __user *s, long n)
:"cc"); :"cc");
return res & mask; return res & mask;
} }
EXPORT_SYMBOL(strnlen_user);
#ifdef CONFIG_X86_INTEL_USERCOPY #ifdef CONFIG_X86_INTEL_USERCOPY
static unsigned long static unsigned long
...@@ -570,6 +574,7 @@ unsigned long __copy_to_user_ll(void __user *to, const void *from, unsigned long ...@@ -570,6 +574,7 @@ unsigned long __copy_to_user_ll(void __user *to, const void *from, unsigned long
n = __copy_user_intel(to, from, n); n = __copy_user_intel(to, from, n);
return n; return n;
} }
EXPORT_SYMBOL(__copy_to_user_ll);
unsigned long unsigned long
__copy_from_user_ll(void *to, const void __user *from, unsigned long n) __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) ...@@ -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); n = __copy_user_zeroing_intel(to, from, n);
return n; return n;
} }
EXPORT_SYMBOL(__copy_from_user_ll);
/** /**
* copy_to_user: - Copy a block of data into user space. * copy_to_user: - Copy a block of data into user space.
......
...@@ -1288,7 +1288,7 @@ smp_local_timer_interrupt(struct pt_regs * regs) ...@@ -1288,7 +1288,7 @@ smp_local_timer_interrupt(struct pt_regs * regs)
per_cpu(prof_counter, cpu); 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) if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
obj-y := init.o pgtable.o fault.o ioremap.o extable.o pageattr.o mmap.o 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_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_HIGHMEM) += highmem.o obj-$(CONFIG_HIGHMEM) += highmem.o
obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap.o obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap.o
...@@ -29,12 +29,14 @@ ...@@ -29,12 +29,14 @@
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/initrd.h> #include <linux/initrd.h>
#include <linux/nodemask.h> #include <linux/nodemask.h>
#include <linux/module.h>
#include <asm/e820.h> #include <asm/e820.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mmzone.h> #include <asm/mmzone.h>
#include <bios_ebda.h> #include <bios_ebda.h>
struct pglist_data *node_data[MAX_NUMNODES]; struct pglist_data *node_data[MAX_NUMNODES];
EXPORT_SYMBOL(node_data);
bootmem_data_t node0_bdata; bootmem_data_t node0_bdata;
/* /*
...@@ -42,12 +44,16 @@ bootmem_data_t node0_bdata; ...@@ -42,12 +44,16 @@ bootmem_data_t node0_bdata;
* populated the following initialisation. * populated the following initialisation.
* *
* 1) node_online_map - the map of all nodes configured (online) in the system * 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 * 2) node_start_pfn - the starting page frame number for a node
* 3) node_start_pfn - the starting page frame number for a node
* 3) node_end_pfn - the ending page fram 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 * physnode_map keeps track of the physical memory layout of a generic
* numa node on a 256Mb break (each element of the array will * 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, * represent 256Mb of memory and will be marked by the node id. so,
...@@ -59,6 +65,7 @@ bootmem_data_t node0_bdata; ...@@ -59,6 +65,7 @@ bootmem_data_t node0_bdata;
* physnode_map[8- ] = -1; * physnode_map[8- ] = -1;
*/ */
s8 physnode_map[MAX_ELEMENTS] = { [0 ... (MAX_ELEMENTS - 1)] = -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) 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, ...@@ -85,9 +92,7 @@ unsigned long node_memmap_size_bytes(int nid, unsigned long start_pfn,
return (nr_pages + 1) * sizeof(struct page); return (nr_pages + 1) * sizeof(struct page);
} }
#endif
unsigned long node_start_pfn[MAX_NUMNODES];
unsigned long node_end_pfn[MAX_NUMNODES];
extern unsigned long find_max_low_pfn(void); extern unsigned long find_max_low_pfn(void);
extern void find_max_pfn(void); extern void find_max_pfn(void);
...@@ -108,6 +113,9 @@ unsigned long node_remap_offset[MAX_NUMNODES]; ...@@ -108,6 +113,9 @@ unsigned long node_remap_offset[MAX_NUMNODES];
void *node_remap_start_vaddr[MAX_NUMNODES]; void *node_remap_start_vaddr[MAX_NUMNODES];
void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags); 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 * FLAT - support for basic PC memory model with discontig enabled, essentially
* a single node with all available processors in it with a flat * 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) ...@@ -146,6 +154,21 @@ static void __init find_max_pfn_node(int nid)
BUG(); 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 * 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 * method. For node zero take this from the bottom of memory, for
...@@ -163,6 +186,21 @@ static void __init allocate_pgdat(int nid) ...@@ -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 __init remap_numa_kva(void)
{ {
void *vaddr; void *vaddr;
...@@ -170,8 +208,6 @@ void __init remap_numa_kva(void) ...@@ -170,8 +208,6 @@ void __init remap_numa_kva(void)
int node; int node;
for_each_online_node(node) { for_each_online_node(node) {
if (node == 0)
continue;
for (pfn=0; pfn < node_remap_size[node]; pfn += PTRS_PER_PTE) { for (pfn=0; pfn < node_remap_size[node]; pfn += PTRS_PER_PTE) {
vaddr = node_remap_start_vaddr[node]+(pfn<<PAGE_SHIFT); vaddr = node_remap_start_vaddr[node]+(pfn<<PAGE_SHIFT);
set_pmd_pfn((ulong) vaddr, set_pmd_pfn((ulong) vaddr,
...@@ -185,13 +221,9 @@ static unsigned long calculate_numa_remap_pages(void) ...@@ -185,13 +221,9 @@ static unsigned long calculate_numa_remap_pages(void)
{ {
int nid; int nid;
unsigned long size, reserve_pages = 0; unsigned long size, reserve_pages = 0;
unsigned long pfn;
for_each_online_node(nid) { 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 * The acpi/srat node info can show hot-add memroy zones
* where memory could be added but not currently present. * where memory could be added but not currently present.
...@@ -208,11 +240,24 @@ static unsigned long calculate_numa_remap_pages(void) ...@@ -208,11 +240,24 @@ static unsigned long calculate_numa_remap_pages(void)
size = (size + LARGE_PAGE_BYTES - 1) / LARGE_PAGE_BYTES; size = (size + LARGE_PAGE_BYTES - 1) / LARGE_PAGE_BYTES;
/* now the roundup is correct, convert to PAGE_SIZE pages */ /* now the roundup is correct, convert to PAGE_SIZE pages */
size = size * PTRS_PER_PTE; 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", printk("Reserving %ld pages of KVA for lmem_map of node %d\n",
size, nid); size, nid);
node_remap_size[nid] = size; node_remap_size[nid] = size;
reserve_pages += size;
node_remap_offset[nid] = reserve_pages; node_remap_offset[nid] = reserve_pages;
reserve_pages += size;
printk("Shrinking node %d from %ld pages to %ld pages\n", printk("Shrinking node %d from %ld pages to %ld pages\n",
nid, node_end_pfn[nid], node_end_pfn[nid] - size); nid, node_end_pfn[nid], node_end_pfn[nid] - size);
node_end_pfn[nid] -= size; node_end_pfn[nid] -= size;
...@@ -265,12 +310,18 @@ unsigned long __init setup_memory(void) ...@@ -265,12 +310,18 @@ unsigned long __init setup_memory(void)
(ulong) pfn_to_kaddr(max_low_pfn)); (ulong) pfn_to_kaddr(max_low_pfn));
for_each_online_node(nid) { for_each_online_node(nid) {
node_remap_start_vaddr[nid] = pfn_to_kaddr( 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); allocate_pgdat(nid);
printk ("node %d will remap to vaddr %08lx - %08lx\n", nid, printk ("node %d will remap to vaddr %08lx - %08lx\n", nid,
(ulong) node_remap_start_vaddr[nid], (ulong) node_remap_start_vaddr[nid],
(ulong) pfn_to_kaddr(highstart_pfn + reserve_pages (ulong) pfn_to_kaddr(highstart_pfn
- node_remap_offset[nid] + node_remap_size[nid])); + node_remap_offset[nid] + node_remap_size[nid]));
} }
printk("High memory starts at vaddr %08lx\n", printk("High memory starts at vaddr %08lx\n",
(ulong) pfn_to_kaddr(highstart_pfn)); (ulong) pfn_to_kaddr(highstart_pfn));
...@@ -333,23 +384,9 @@ void __init zone_sizes_init(void) ...@@ -333,23 +384,9 @@ void __init zone_sizes_init(void)
} }
zholes_size = get_zholes_size(nid); zholes_size = get_zholes_size(nid);
/*
* We let the lmem_map for node 0 be allocated from the free_area_init_node(nid, NODE_DATA(nid), zones_size, start,
* normal bootmem allocator, but other nodes come from the zholes_size);
* 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);
}
} }
return; return;
} }
...@@ -358,24 +395,26 @@ void __init set_highmem_pages_init(int bad_ppro) ...@@ -358,24 +395,26 @@ void __init set_highmem_pages_init(int bad_ppro)
{ {
#ifdef CONFIG_HIGHMEM #ifdef CONFIG_HIGHMEM
struct zone *zone; struct zone *zone;
struct page *page;
for_each_zone(zone) { for_each_zone(zone) {
unsigned long node_pfn, node_high_size, zone_start_pfn; unsigned long node_pfn, zone_start_pfn, zone_end_pfn;
struct page * zone_mem_map;
if (!is_highmem(zone)) if (!is_highmem(zone))
continue; 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_start_pfn = zone->zone_start_pfn;
zone_end_pfn = zone_start_pfn + zone->spanned_pages;
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 = 0; node_pfn < node_high_size; node_pfn++) { for (node_pfn = zone_start_pfn; node_pfn < zone_end_pfn; node_pfn++) {
one_highpage_init((struct page *)(zone_mem_map + node_pfn), if (!pfn_valid(node_pfn))
zone_start_pfn + node_pfn, bad_ppro); continue;
page = pfn_to_page(node_pfn);
one_highpage_init(page, node_pfn, bad_ppro);
} }
} }
totalram_pages += totalhigh_pages; totalram_pages += totalhigh_pages;
......
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/module.h>
void *kmap(struct page *page) void *kmap(struct page *page)
{ {
...@@ -87,3 +88,8 @@ struct page *kmap_atomic_to_page(void *ptr) ...@@ -87,3 +88,8 @@ struct page *kmap_atomic_to_page(void *ptr)
return pte_page(*pte); 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) ...@@ -191,7 +191,7 @@ static inline int page_kills_ppro(unsigned long pagenr)
extern int is_available_memory(efi_memory_desc_t *); 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; int i;
unsigned long addr, end; unsigned long addr, end;
...@@ -276,7 +276,9 @@ void __init one_highpage_init(struct page *page, int pfn, int bad_ppro) ...@@ -276,7 +276,9 @@ void __init one_highpage_init(struct page *page, int pfn, int bad_ppro)
SetPageReserved(page); 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) static void __init set_highmem_pages_init(int bad_ppro)
{ {
int pfn; int pfn;
...@@ -284,9 +286,7 @@ static void __init set_highmem_pages_init(int bad_ppro) ...@@ -284,9 +286,7 @@ static void __init set_highmem_pages_init(int bad_ppro)
one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro); one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro);
totalram_pages += totalhigh_pages; totalram_pages += totalhigh_pages;
} }
#else #endif /* CONFIG_FLATMEM */
extern void set_highmem_pages_init(int);
#endif /* !CONFIG_DISCONTIGMEM */
#else #else
#define kmap_init() do { } while (0) #define kmap_init() do { } while (0)
...@@ -295,12 +295,13 @@ extern void set_highmem_pages_init(int); ...@@ -295,12 +295,13 @@ extern void set_highmem_pages_init(int);
#endif /* CONFIG_HIGHMEM */ #endif /* CONFIG_HIGHMEM */
unsigned long long __PAGE_KERNEL = _PAGE_KERNEL; unsigned long long __PAGE_KERNEL = _PAGE_KERNEL;
EXPORT_SYMBOL(__PAGE_KERNEL);
unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC; unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
#ifndef CONFIG_DISCONTIGMEM #ifdef CONFIG_NUMA
#define remap_numa_kva() do {} while (0)
#else
extern void __init remap_numa_kva(void); extern void __init remap_numa_kva(void);
#else
#define remap_numa_kva() do {} while (0)
#endif #endif
static void __init pagetable_init (void) static void __init pagetable_init (void)
...@@ -525,7 +526,7 @@ static void __init set_max_mapnr_init(void) ...@@ -525,7 +526,7 @@ static void __init set_max_mapnr_init(void)
#else #else
num_physpages = max_low_pfn; num_physpages = max_low_pfn;
#endif #endif
#ifndef CONFIG_DISCONTIGMEM #ifdef CONFIG_FLATMEM
max_mapnr = num_physpages; max_mapnr = num_physpages;
#endif #endif
} }
...@@ -539,7 +540,7 @@ void __init mem_init(void) ...@@ -539,7 +540,7 @@ void __init mem_init(void)
int tmp; int tmp;
int bad_ppro; int bad_ppro;
#ifndef CONFIG_DISCONTIGMEM #ifdef CONFIG_FLATMEM
if (!mem_map) if (!mem_map)
BUG(); BUG();
#endif #endif
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/fixmap.h> #include <asm/fixmap.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
...@@ -165,7 +166,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l ...@@ -165,7 +166,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
} }
return (void __iomem *) (offset + (char __iomem *)addr); return (void __iomem *) (offset + (char __iomem *)addr);
} }
EXPORT_SYMBOL(__ioremap);
/** /**
* ioremap_nocache - map bus memory into CPU space * ioremap_nocache - map bus memory into CPU space
...@@ -222,6 +223,7 @@ void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size) ...@@ -222,6 +223,7 @@ void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size)
return p; return p;
} }
EXPORT_SYMBOL(ioremap_nocache);
void iounmap(volatile void __iomem *addr) void iounmap(volatile void __iomem *addr)
{ {
...@@ -255,6 +257,7 @@ void iounmap(volatile void __iomem *addr) ...@@ -255,6 +257,7 @@ void iounmap(volatile void __iomem *addr)
write_unlock(&vmlist_lock); write_unlock(&vmlist_lock);
kfree(p); kfree(p);
} }
EXPORT_SYMBOL(iounmap);
void __init *bt_ioremap(unsigned long phys_addr, unsigned long size) void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
{ {
......
...@@ -30,13 +30,14 @@ void show_mem(void) ...@@ -30,13 +30,14 @@ void show_mem(void)
struct page *page; struct page *page;
pg_data_t *pgdat; pg_data_t *pgdat;
unsigned long i; unsigned long i;
struct page_state ps;
printk("Mem-info:\n"); printk("Mem-info:\n");
show_free_areas(); show_free_areas();
printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
for_each_pgdat(pgdat) { for_each_pgdat(pgdat) {
for (i = 0; i < pgdat->node_spanned_pages; ++i) { for (i = 0; i < pgdat->node_spanned_pages; ++i) {
page = pgdat->node_mem_map + i; page = pgdat_page_nr(pgdat, i);
total++; total++;
if (PageHighMem(page)) if (PageHighMem(page))
highmem++; highmem++;
...@@ -53,6 +54,13 @@ void show_mem(void) ...@@ -53,6 +54,13 @@ void show_mem(void)
printk("%d reserved pages\n",reserved); printk("%d reserved pages\n",reserved);
printk("%d pages shared\n",shared); printk("%d pages shared\n",shared);
printk("%d pages swap cached\n",cached); 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) ...@@ -91,7 +91,7 @@ x86_backtrace(struct pt_regs * const regs, unsigned int depth)
head = (struct frame_head *)regs->ebp; head = (struct frame_head *)regs->ebp;
#endif #endif
if (!user_mode(regs)) { if (!user_mode_vm(regs)) {
while (depth-- && valid_kernel_stack(head, regs)) while (depth-- && valid_kernel_stack(head, regs))
head = dump_backtrace(head); head = dump_backtrace(head);
return; return;
......
...@@ -226,6 +226,24 @@ static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, i ...@@ -226,6 +226,24 @@ static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, i
return 1; 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 * ITE 8330G pirq rules are nibble-based
* FIXME: pirqmap may be { 1, 0, 3, 2 }, * 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, ...@@ -512,6 +530,10 @@ static __init int via_router_probe(struct irq_router *r, struct pci_dev *router,
switch(device) switch(device)
{ {
case PCI_DEVICE_ID_VIA_82C586_0: 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_82C596:
case PCI_DEVICE_ID_VIA_82C686: case PCI_DEVICE_ID_VIA_82C686:
case PCI_DEVICE_ID_VIA_8231: case PCI_DEVICE_ID_VIA_8231:
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h>
#include "pci.h" #include "pci.h"
#include "pci-functions.h" #include "pci-functions.h"
...@@ -456,7 +457,7 @@ struct irq_routing_table * __devinit pcibios_get_irq_routing_table(void) ...@@ -456,7 +457,7 @@ struct irq_routing_table * __devinit pcibios_get_irq_routing_table(void)
free_page(page); free_page(page);
return rt; return rt;
} }
EXPORT_SYMBOL(pcibios_get_irq_routing_table);
int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq) 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) ...@@ -473,6 +474,7 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
"S" (&pci_indirect)); "S" (&pci_indirect));
return !(ret & 0xff00); return !(ret & 0xff00);
} }
EXPORT_SYMBOL(pcibios_set_irq_routing);
static int __init pci_pcbios_init(void) static int __init pci_pcbios_init(void)
{ {
......
...@@ -94,13 +94,13 @@ static void fix_processor_context(void) ...@@ -94,13 +94,13 @@ static void fix_processor_context(void)
* Now maybe reload the debug registers * Now maybe reload the debug registers
*/ */
if (current->thread.debugreg[7]){ if (current->thread.debugreg[7]){
loaddebug(&current->thread, 0); set_debugreg(current->thread.debugreg[0], 0);
loaddebug(&current->thread, 1); set_debugreg(current->thread.debugreg[1], 1);
loaddebug(&current->thread, 2); set_debugreg(current->thread.debugreg[2], 2);
loaddebug(&current->thread, 3); set_debugreg(current->thread.debugreg[3], 3);
/* no 4 and 5 */ /* no 4 and 5 */
loaddebug(&current->thread, 6); set_debugreg(current->thread.debugreg[6], 6);
loaddebug(&current->thread, 7); set_debugreg(current->thread.debugreg[7], 7);
} }
} }
......
...@@ -161,6 +161,8 @@ config IA64_PAGE_SIZE_64KB ...@@ -161,6 +161,8 @@ config IA64_PAGE_SIZE_64KB
endchoice endchoice
source kernel/Kconfig.hz
config IA64_BRL_EMU config IA64_BRL_EMU
bool bool
depends on ITANIUM depends on ITANIUM
...@@ -197,7 +199,7 @@ config HOLES_IN_ZONE ...@@ -197,7 +199,7 @@ config HOLES_IN_ZONE
bool bool
default y if VIRTUAL_MEM_MAP default y if VIRTUAL_MEM_MAP
config DISCONTIGMEM config ARCH_DISCONTIGMEM_ENABLE
bool "Discontiguous memory support" bool "Discontiguous memory support"
depends on (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB) && NUMA && VIRTUAL_MEM_MAP 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 default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA
...@@ -300,6 +302,8 @@ config PREEMPT ...@@ -300,6 +302,8 @@ config PREEMPT
Say Y here if you are building a kernel for a desktop, embedded Say Y here if you are building a kernel for a desktop, embedded
or real-time system. Say N if you are unsure. or real-time system. Say N if you are unsure.
source "mm/Kconfig"
config HAVE_DEC_LOCK config HAVE_DEC_LOCK
bool bool
depends on (SMP || PREEMPT) depends on (SMP || PREEMPT)
......
...@@ -2,6 +2,17 @@ menu "Kernel hacking" ...@@ -2,6 +2,17 @@ menu "Kernel hacking"
source "lib/Kconfig.debug" 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 choice
prompt "Physical memory granularity" prompt "Physical memory granularity"
default IA64_GRANULE_64MB default IA64_GRANULE_64MB
......
...@@ -78,7 +78,7 @@ CONFIG_IA64_L1_CACHE_SHIFT=7 ...@@ -78,7 +78,7 @@ CONFIG_IA64_L1_CACHE_SHIFT=7
CONFIG_NUMA=y CONFIG_NUMA=y
CONFIG_VIRTUAL_MEM_MAP=y CONFIG_VIRTUAL_MEM_MAP=y
CONFIG_HOLES_IN_ZONE=y CONFIG_HOLES_IN_ZONE=y
CONFIG_DISCONTIGMEM=y CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
# CONFIG_IA64_CYCLONE is not set # CONFIG_IA64_CYCLONE is not set
CONFIG_IOSAPIC=y CONFIG_IOSAPIC=y
CONFIG_IA64_SGI_SN_SIM=y CONFIG_IA64_SGI_SN_SIM=y
......
...@@ -84,7 +84,7 @@ CONFIG_IA64_L1_CACHE_SHIFT=7 ...@@ -84,7 +84,7 @@ CONFIG_IA64_L1_CACHE_SHIFT=7
CONFIG_NUMA=y CONFIG_NUMA=y
CONFIG_VIRTUAL_MEM_MAP=y CONFIG_VIRTUAL_MEM_MAP=y
CONFIG_HOLES_IN_ZONE=y CONFIG_HOLES_IN_ZONE=y
CONFIG_DISCONTIGMEM=y CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
CONFIG_IA64_CYCLONE=y CONFIG_IA64_CYCLONE=y
CONFIG_IOSAPIC=y CONFIG_IOSAPIC=y
CONFIG_FORCE_MAX_ZONEORDER=18 CONFIG_FORCE_MAX_ZONEORDER=18
......
...@@ -241,7 +241,7 @@ typedef struct compat_siginfo { ...@@ -241,7 +241,7 @@ typedef struct compat_siginfo {
/* POSIX.1b timers */ /* POSIX.1b timers */
struct { struct {
timer_t _tid; /* timer id */ compat_timer_t _tid; /* timer id */
int _overrun; /* overrun count */ int _overrun; /* overrun count */
char _pad[sizeof(unsigned int) - sizeof(int)]; char _pad[sizeof(unsigned int) - sizeof(int)];
compat_sigval_t _sigval; /* same as below */ compat_sigval_t _sigval; /* same as below */
......
...@@ -20,6 +20,7 @@ obj-$(CONFIG_SMP) += smp.o smpboot.o domain.o ...@@ -20,6 +20,7 @@ obj-$(CONFIG_SMP) += smp.o smpboot.o domain.o
obj-$(CONFIG_PERFMON) += perfmon_default_smpl.o obj-$(CONFIG_PERFMON) += perfmon_default_smpl.o
obj-$(CONFIG_IA64_CYCLONE) += cyclone.o obj-$(CONFIG_IA64_CYCLONE) += cyclone.o
obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o
obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o
obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o
mca_recovery-y += mca_drv.o mca_drv_asm.o mca_recovery-y += mca_drv.o mca_drv_asm.o
......
/*
* 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)
此差异已折叠。
...@@ -21,12 +21,26 @@ ...@@ -21,12 +21,26 @@
#include <asm/intrinsics.h> #include <asm/intrinsics.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/kdebug.h>
extern spinlock_t timerlist_lock; extern spinlock_t timerlist_lock;
fpswa_interface_t *fpswa_interface; fpswa_interface_t *fpswa_interface;
EXPORT_SYMBOL(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 void __init
trap_init (void) trap_init (void)
{ {
...@@ -137,6 +151,10 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs) ...@@ -137,6 +151,10 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
switch (break_num) { switch (break_num) {
case 0: /* unknown error (used by GCC for __builtin_abort()) */ 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); die_if_kernel("bugcheck!", regs, break_num);
sig = SIGILL; code = ILL_ILLOPC; sig = SIGILL; code = ILL_ILLOPC;
break; break;
...@@ -189,6 +207,15 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs) ...@@ -189,6 +207,15 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
sig = SIGILL; code = __ILL_BNDMOD; sig = SIGILL; code = __ILL_BNDMOD;
break; 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: default:
if (break_num < 0x40000 || break_num > 0x100000) if (break_num < 0x40000 || break_num > 0x100000)
die_if_kernel("Bad break", regs, break_num); die_if_kernel("Bad break", regs, break_num);
...@@ -548,7 +575,11 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, ...@@ -548,7 +575,11 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
#endif #endif
break; break;
case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; 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", &regs, vector,
vector, SIGTRAP) == NOTIFY_STOP)
return;
siginfo.si_code = TRAP_TRACE; ifa = 0; break;
} }
siginfo.si_signo = SIGTRAP; siginfo.si_signo = SIGTRAP;
siginfo.si_errno = 0; siginfo.si_errno = 0;
......
...@@ -560,14 +560,15 @@ void show_mem(void) ...@@ -560,14 +560,15 @@ void show_mem(void)
int shared = 0, cached = 0, reserved = 0; int shared = 0, cached = 0, reserved = 0;
printk("Node ID: %d\n", pgdat->node_id); printk("Node ID: %d\n", pgdat->node_id);
for(i = 0; i < pgdat->node_spanned_pages; i++) { 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)) if (!ia64_pfn_valid(pgdat->node_start_pfn+i))
continue; continue;
if (PageReserved(pgdat->node_mem_map+i)) if (PageReserved(page))
reserved++; reserved++;
else if (PageSwapCache(pgdat->node_mem_map+i)) else if (PageSwapCache(page))
cached++; cached++;
else if (page_count(pgdat->node_mem_map+i)) else if (page_count(page))
shared += page_count(pgdat->node_mem_map+i)-1; shared += page_count(page)-1;
} }
total_present += present; total_present += present;
total_reserved += reserved; total_reserved += reserved;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/kdebug.h>
extern void die (char *, struct pt_regs *, long); 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 ...@@ -102,6 +103,13 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
goto bad_area_no_up; goto bad_area_no_up;
#endif #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); down_read(&mm->mmap_sem);
vma = find_vma_prev(mm, address, &prev_vma); vma = find_vma_prev(mm, address, &prev_vma);
......
...@@ -172,11 +172,13 @@ config NOHIGHMEM ...@@ -172,11 +172,13 @@ config NOHIGHMEM
bool bool
default y default y
config DISCONTIGMEM config ARCH_DISCONTIGMEM_ENABLE
bool "Internal RAM Support" bool "Internal RAM Support"
depends on CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP depends on CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP
default y default y
source "mm/Kconfig"
config IRAM_START config IRAM_START
hex "Internal memory start address (hex)" hex "Internal memory start address (hex)"
default "00f00000" default "00f00000"
......
...@@ -49,7 +49,7 @@ void show_mem(void) ...@@ -49,7 +49,7 @@ void show_mem(void)
printk("Free swap: %6ldkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); printk("Free swap: %6ldkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
for_each_pgdat(pgdat) { for_each_pgdat(pgdat) {
for (i = 0; i < pgdat->node_spanned_pages; ++i) { for (i = 0; i < pgdat->node_spanned_pages; ++i) {
page = pgdat->node_mem_map + i; page = pgdat_page_nr(pgdat, i);
total++; total++;
if (PageHighMem(page)) if (PageHighMem(page))
highmem++; highmem++;
...@@ -152,7 +152,7 @@ int __init reservedpages_count(void) ...@@ -152,7 +152,7 @@ int __init reservedpages_count(void)
reservedpages = 0; reservedpages = 0;
for_each_online_node(nid) for_each_online_node(nid)
for (i = 0 ; i < MAX_LOW_PFN(nid) - START_PFN(nid) ; i++) 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++; reservedpages++;
return reservedpages; return reservedpages;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册