Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git

This commit is contained in:
Christoph Hellwig 2005-05-27 01:16:24 -07:00 committed by Christoph Hellwig
commit b19312c4c8
445 changed files with 29121 additions and 9565 deletions

View File

@ -882,13 +882,12 @@ S: Blacksburg, Virginia 24061
S: USA
N: Randy Dunlap
E: rddunlap@osdl.org
E: rdunlap@xenotime.net
W: http://www.xenotime.net/linux/linux.html
W: http://www.linux-usb.org
D: Linux-USB subsystem, USB core/UHCI/printer/storage drivers
D: x86 SMP, ACPI, bootflag hacking
S: 12725 SW Millikan Way, Suite 400
S: Beaverton, Oregon 97005
S: (ask for current address)
S: USA
N: Bob Dunlop

View File

@ -252,8 +252,7 @@ in a tasks processor placement.
There is an exception to the above. If hotplug funtionality is used
to remove all the CPUs that are currently assigned to a cpuset,
then the kernel will automatically update the cpus_allowed of all
tasks attached to CPUs in that cpuset with the online CPUs of the
nearest parent cpuset that still has some CPUs online. When memory
tasks attached to CPUs in that cpuset to allow all CPUs. When memory
hotplug functionality for removing Memory Nodes is available, a
similar exception is expected to apply there as well. In general,
the kernel prefers to violate cpuset placement, over starving a task

View File

@ -0,0 +1,205 @@
This README escorted the skystar2-driver rewriting procedure. It describes the
state of the new flexcop-driver set and some internals are written down here
too.
This document hopefully describes things about the flexcop and its
device-offsprings. Goal was to write an easy-to-write and easy-to-read set of
drivers based on the skystar2.c and other information.
Remark: flexcop-pci.c was a copy of skystar2.c, but every line has been
touched and rewritten.
History & News
==============
2005-04-01 - correct USB ISOC transfers (thanks to Vadim Catana)
General coding processing
=========================
We should proceed as follows (as long as no one complains):
0) Think before start writing code!
1) rewriting the skystar2.c with the help of the flexcop register descriptions
and splitting up the files to a pci-bus-part and a flexcop-part.
The new driver will be called b2c2-flexcop-pci.ko/b2c2-flexcop-usb.ko for the
device-specific part and b2c2-flexcop.ko for the common flexcop-functions.
2) Search for errors in the leftover of flexcop-pci.c (compare with pluto2.c
and other pci drivers)
3) make some beautification (see 'Improvements when rewriting (refactoring) is
done')
4) Testing the new driver and maybe substitute the skystar2.c with it, to reach
a wider tester audience.
5) creating an usb-bus-part using the already written flexcop code for the pci
card.
Idea: create a kernel-object for the flexcop and export all important
functions. This option saves kernel-memory, but maybe a lot of functions have
to be exported to kernel namespace.
Current situation
=================
0) Done :)
1) Done (some minor issues left)
2) Done
3) Not ready yet, more information is necessary
4) next to be done (see the table below)
5) USB driver is working (yes, there are some minor issues)
What seems to be ready?
-----------------------
1) Rewriting
1a) i2c is cut off from the flexcop-pci.c and seems to work
1b) moved tuner and demod stuff from flexcop-pci.c to flexcop-tuner-fe.c
1c) moved lnb and diseqc stuff from flexcop-pci.c to flexcop-tuner-fe.c
1e) eeprom (reading MAC address)
1d) sram (no dynamic sll size detection (commented out) (using default as JJ told me))
1f) misc. register accesses for reading parameters (e.g. resetting, revision)
1g) pid/mac filter (flexcop-hw-filter.c)
1i) dvb-stuff initialization in flexcop.c (done)
1h) dma stuff (now just using the size-irq, instead of all-together, to be done)
1j) remove flexcop initialization from flexcop-pci.c completely (done)
1l) use a well working dma IRQ method (done, see 'Known bugs and problems and TODO')
1k) cleanup flexcop-files (remove unused EXPORT_SYMBOLs, make static from
non-static where possible, moved code to proper places)
2) Search for errors in the leftover of flexcop-pci.c (partially done)
5a) add MAC address reading
5c) feeding of ISOC data to the software demux (format of the isochronous data
and speed optimization, no real error) (thanks to Vadim Catana)
What to do in the near future?
--------------------------------------
(no special order here)
5) USB driver
5b) optimize isoc-transfer (submitting/killing isoc URBs when transfer is starting)
Testing changes
---------------
O = item is working
P = item is partially working
X = item is not working
N = item does not apply here
<empty field> = item need to be examined
| PCI | USB
item | mt352 | nxt2002 | stv0299 | mt312 | mt352 | nxt2002 | stv0299 | mt312
-------+-------+---------+---------+-------+-------+---------+---------+-------
1a) | O | | | | N | N | N | N
1b) | O | | | | | | O |
1c) | N | N | | | N | N | O |
1d) | O | O
1e) | O | O
1f) | P
1g) | O
1h) | P |
1i) | O | N
1j) | O | N
1l) | O | N
2) | O | N
5a) | N | O
5b)* | N |
5c) | N | O
* - not done yet
Known bugs and problems and TODO
--------------------------------
1g/h/l) when pid filtering is enabled on the pci card
DMA usage currently:
The DMA is splitted in 2 equal-sized subbuffers. The Flexcop writes to first
address and triggers an IRQ when it's full and starts writing to the second
address. When the second address is full, the IRQ is triggered again, and
the flexcop writes to first address again, and so on.
The buffersize of each address is currently 640*188 bytes.
Problem is, when using hw-pid-filtering and doing some low-bandwidth
operation (like scanning) the buffers won't be filled enough to trigger
the IRQ. That's why:
When PID filtering is activated, the timer IRQ is used. Every 1.97 ms the IRQ
is triggered. Is the current write address of DMA1 different to the one
during the last IRQ, then the data is passed to the demuxer.
There is an additional DMA-IRQ-method: packet count IRQ. This isn't
implemented correctly yet.
The solution is to disable HW PID filtering, but I don't know how the DVB
API software demux behaves on slow systems with 45MBit/s TS.
Solved bugs :)
--------------
1g) pid-filtering (somehow pid index 4 and 5 (EMM_PID and ECM_PID) aren't
working)
SOLUTION: also index 0 was affected, because net_translation is done for
these indexes by default
5b) isochronous transfer does only work in the first attempt (for the Sky2PC
USB, Air2PC is working) SOLUTION: the flexcop was going asleep and never really
woke up again (don't know if this need fixes, see
flexcop-fe-tuner.c:flexcop_sleep)
NEWS: when the driver is loaded and unloaded and loaded again (w/o doing
anything in the while the driver is loaded the first time), no transfers take
place anymore.
Improvements when rewriting (refactoring) is done
=================================================
- split sleeping of the flexcop (misc_204.ACPI3_sig = 1;) from lnb_control
(enable sleeping for other demods than dvb-s)
- add support for CableStar (stv0297 Microtune 203x/ALPS) (almost done, incompatibilities with the Nexus-CA)
Debugging
---------
- add verbose debugging to skystar2.c (dump the reg_dw_data) and compare it
with this flexcop, this is important, because i2c is now using the
flexcop_ibi_value union from flexcop-reg.h (do you have a better idea for
that, please tell us so).
Everything which is identical in the following table, can be put into a common
flexcop-module.
PCI USB
-------------------------------------------------------------------------------
Different:
Register access: accessing IO memory USB control message
I2C bus: I2C bus of the FC USB control message
Data transfer: DMA isochronous transfer
EEPROM transfer: through i2c bus not clear yet
Identical:
Streaming: accessing registers
PID Filtering: accessing registers
Sram destinations: accessing registers
Tuner/Demod: I2C bus
DVB-stuff: can be written for common use
Acknowledgements (just for the rewriting part)
================
Bjarne Steinsbo thought a lot in the first place of the pci part for this code
sharing idea.
Andreas Oberritter for providing a recent PCI initialization template
(pluto2.c).
Boleslaw Ciesielski for pointing out a problem with firmware loader.
Vadim Catana for correcting the USB transfer.
comments, critics and ideas to linux-dvb@linuxtv.org.

View File

@ -17,74 +17,53 @@ Because of this, you need to enable
"Device drivers" => "Multimedia devices"
=> "Video For Linux" => "BT848 Video For Linux"
Furthermore you need to enable
"Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices"
=> "DVB for Linux" "DVB Core Support" "Nebula/Pinnacle PCTV/TwinHan PCI Cards"
2) Loading Modules
==================
In general you need to load the bttv driver, which will handle the gpio and
i2c communication for us. Next you need the common dvb-bt8xx device driver
and one frontend driver.
The bttv driver will HANG YOUR SYSTEM IF YOU DO NOT SPECIFY THE CORRECT
CARD ID!
(If you don't get your card running and you suspect that the card id you're
using is wrong, have a look at "bttv-cards.c" for a list of possible card
ids.)
Pay attention to failures when you load the frontend drivers
(e.g. dmesg, /var/log/messages).
i2c communication for us, plus the common dvb-bt8xx device driver.
The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110) and
TwinHan (dst) are loaded automatically by the dvb-bt8xx device driver.
3a) Nebula / Pinnacle PCTV
--------------------------
$ modprobe bttv i2c_hw=1 card=0x68
$ modprobe dvb-bt8xx
For Nebula cards use the "nxt6000" frontend driver:
$ modprobe nxt6000
$ modprobe bttv (normally bttv is being loaded automatically by kmod)
$ modprobe dvb-bt8xx (or just place dvb-bt8xx in /etc/modules for automatic loading)
For Pinnacle PCTV cards use the "cx24110" frontend driver:
$ modprobe cx24110
3b) TwinHan
-----------
3b) TwinHan and Clones
--------------------------
$ modprobe bttv i2c_hw=1 card=0x71
$ modprobe dvb-bt8xx
$ modprobe dst
The value 0x71 will override the PCI type detection for dvb-bt8xx, which
is necessary for TwinHan cards.#
The value 0x71 will override the PCI type detection for dvb-bt8xx,
which is necessary for TwinHan cards.
If you're having an older card (blue color circuit) and card=0x71 locks your
machine, try using 0x68, too. If that does not work, ask on the DVB mailing list.
If you're having an older card (blue color circuit) and card=0x71 locks
your machine, try using 0x68, too. If that does not work, ask on the
mailing list.
The DST module takes a couple of useful parameters, in case the
dst drivers fails to detect your type of card correctly.
The DST module takes a couple of useful parameters.
dst_type takes values 0 (satellite), 1 (terrestial TV), 2 (cable).
verbose takes values 0 to 5. These values control the verbosity level.
dst_type_flags takes bit combined values:
1 = new tuner type packets. You can use this if your card is detected
and you have debug and you continually see the tuner packets not
working (make sure not a basic problem like dish alignment etc.)
debug takes values 0 and 1. You can either disable or enable debugging.
2 = TS 204. If your card tunes OK, but the picture is terrible, seemingly
breaking up in one half continually, and crc fails a lot, then
this is worth a try (or trying to turn off)
dst_addons takes values 0 and 0x20. A value of 0 means it is a FTA card.
0x20 means it has a Conditional Access slot.
4 = has symdiv. Some cards, mostly without new tuner packets, require
a symbol division algorithm. Doesn't apply to terrestial TV.
You can also specify a value to have the autodetected values turned off
(e.g. 0). The autodected values are determined bythe cards 'response
The autodected values are determined bythe cards 'response
string' which you can see in your logs e.g.
dst_check_ci: recognize DST-MOT
dst_get_device_id: Recognise [DSTMCI]
or
dst_check_ci: unable to recognize DSTXCI or STXCI
--
Authors: Richard Walker, Jamie Honan, Michael Hunold
Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham

219
Documentation/dvb/ci.txt Normal file
View File

@ -0,0 +1,219 @@
* For the user
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NOTE: This document describes the usage of the high level CI API as
in accordance to the Linux DVB API. This is a not a documentation for the,
existing low level CI API.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To utilize the High Level CI capabilities,
(1*) This point is valid only for the Twinhan/clones
For the Twinhan/Twinhan clones, the dst_ca module handles the CI
hardware handling.This module is loaded automatically if a CI
(Common Interface, that holds the CAM (Conditional Access Module)
is detected.
(2) one requires a userspace application, ca_zap. This small userland
application is in charge of sending the descrambling related information
to the CAM.
This application requires the following to function properly as of now.
(a) Tune to a valid channel, with szap.
eg: $ szap -c channels.conf -r "TMC" -x
(b) a channels.conf containing a valid PMT PID
eg: TMC:11996:h:0:27500:278:512:650:321
here 278 is a valid PMT PID. the rest of the values are the
same ones that szap uses.
(c) after running a szap, you have to run ca_zap, for the
descrambler to function,
eg: $ ca_zap patched_channels.conf "TMC"
The patched means a patch to apply to scan, such that scan can
generate a channels.conf_with pmt, which has this PMT PID info
(NOTE: szap cannot use this channels.conf with the PMT_PID)
(d) Hopeflly Enjoy your favourite subscribed channel as you do with
a FTA card.
(3) Currently ca_zap, and dst_test, both are meant for demonstration
purposes only, they can become full fledged applications if necessary.
* Cards that fall in this category
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
At present the cards that fall in this category are the Twinhan and it's
clones, these cards are available as VVMER, Tomato, Hercules, Orange and
so on.
* CI modules that are supported
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The CI module support is largely dependant upon the firmware on the cards
Some cards do support almost all of the available CI modules. There is
nothing much that can be done in order to make additional CI modules
working with these cards.
Modules that have been tested by this driver at present are
(1) Irdeto 1 and 2 from SCM
(2) Viaccess from SCM
(3) Dragoncam
* The High level CI API
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* For the programmer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
With the High Level CI approach any new card with almost any random
architecture can be implemented with this style, the definitions
insidethe switch statement can be easily adapted for any card, thereby
eliminating the need for any additional ioctls.
The disadvantage is that the driver/hardware has to manage the rest. For
the application programmer it would be as simple as sending/receiving an
array to/from the CI ioctls as defined in the Linux DVB API. No changes
have been made in the API to accomodate this feature.
* Why the need for another CI interface ?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is one of the most commonly asked question. Well a nice question.
Strictly speaking this is not a new interface.
The CI interface is defined in the DVB API in ca.h as
typedef struct ca_slot_info {
int num; /* slot number */
int type; /* CA interface this slot supports */
#define CA_CI 1 /* CI high level interface */
#define CA_CI_LINK 2 /* CI link layer level interface */
#define CA_CI_PHYS 4 /* CI physical layer level interface */
#define CA_DESCR 8 /* built-in descrambler */
#define CA_SC 128 /* simple smart card interface */
unsigned int flags;
#define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */
#define CA_CI_MODULE_READY 2
} ca_slot_info_t;
This CI interface follows the CI high level interface, which is not
implemented by most applications. Hence this area is revisited.
This CI interface is quite different in the case that it tries to
accomodate all other CI based devices, that fall into the other categories
This means that this CI interface handles the EN50221 style tags in the
Application layer only and no session management is taken care of by the
application. The driver/hardware will take care of all that.
This interface is purely an EN50221 interface exchanging APDU's. This
means that no session management, link layer or a transport layer do
exist in this case in the application to driver communication. It is
as simple as that. The driver/hardware has to take care of that.
With this High Level CI interface, the interface can be defined with the
regular ioctls.
All these ioctls are also valid for the High level CI interface
#define CA_RESET _IO('o', 128)
#define CA_GET_CAP _IOR('o', 129, ca_caps_t)
#define CA_GET_SLOT_INFO _IOR('o', 130, ca_slot_info_t)
#define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t)
#define CA_GET_MSG _IOR('o', 132, ca_msg_t)
#define CA_SEND_MSG _IOW('o', 133, ca_msg_t)
#define CA_SET_DESCR _IOW('o', 134, ca_descr_t)
#define CA_SET_PID _IOW('o', 135, ca_pid_t)
On querying the device, the device yields information thus
CA_GET_SLOT_INFO
----------------------------
Command = [info]
APP: Number=[1]
APP: Type=[1]
APP: flags=[1]
APP: CI High level interface
APP: CA/CI Module Present
CA_GET_CAP
----------------------------
Command = [caps]
APP: Slots=[1]
APP: Type=[1]
APP: Descrambler keys=[16]
APP: Type=[1]
CA_SEND_MSG
----------------------------
Descriptors(Program Level)=[ 09 06 06 04 05 50 ff f1]
Found CA descriptor @ program level
(20) ES type=[2] ES pid=[201] ES length =[0 (0x0)]
(25) ES type=[4] ES pid=[301] ES length =[0 (0x0)]
ca_message length is 25 (0x19) bytes
EN50221 CA MSG=[ 9f 80 32 19 03 01 2d d1 f0 08 01 09 06 06 04 05 50 ff f1 02 e0 c9 00 00 04 e1 2d 00 00]
Not all ioctl's are implemented in the driver from the API, the other
features of the hardware that cannot be implemented by the API are achieved
using the CA_GET_MSG and CA_SEND_MSG ioctls. An EN50221 style wrapper is
used to exchange the data to maintain compatibility with other hardware.
/* a message to/from a CI-CAM */
typedef struct ca_msg {
unsigned int index;
unsigned int type;
unsigned int length;
unsigned char msg[256];
} ca_msg_t;
The flow of data can be described thus,
App (User)
-----
parse
|
|
v
en50221 APDU (package)
--------------------------------------
| | | High Level CI driver
| | |
| v |
| en50221 APDU (unpackage) |
| | |
| | |
| v |
| sanity checks |
| | |
| | |
| v |
| do (H/W dep) |
--------------------------------------
| Hardware
|
v
The High Level CI interface uses the EN50221 DVB standard, following a
standard ensures futureproofness.

View File

@ -107,7 +107,7 @@ sub tda10045 {
sub tda10046 {
my $sourcefile = "tt_budget_217g.zip";
my $url = "http://www.technotrend.de/new/217g/$sourcefile";
my $hash = "a25b579e37109af60f4a36c37893957c";
my $hash = "6a7e1e2f2644b162ff0502367553c72d";
my $outfile = "dvb-fe-tda10046.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
@ -115,7 +115,7 @@ sub tda10046 {
wgetfile($sourcefile, $url);
unzip($sourcefile, $tmpdir);
extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x3f731, 24479, "$tmpdir/fwtmp");
extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x3f731, 24478, "$tmpdir/fwtmp");
verify("$tmpdir/fwtmp", $hash);
copy("$tmpdir/fwtmp", $outfile);

View File

@ -63,3 +63,23 @@ Why: Outside of Linux, the only implementations of anything even
people, who might be using implementations that I am not aware
of, to adjust to this upcoming change.
Who: Paul E. McKenney <paulmck@us.ibm.com>
---------------------------
What: IEEE1394 Audio and Music Data Transmission Protocol driver,
Connection Management Procedures driver
When: November 2005
Files: drivers/ieee1394/{amdtp,cmp}*
Why: These are incomplete, have never worked, and are better implemented
in userland via raw1394 (see http://freebob.sourceforge.net/ for
example.)
Who: Jody McIntyre <scjody@steamballoon.com>
---------------------------
What: raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN
When: November 2005
Why: Deprecated in favour of the new ioctl-based rawiso interface, which is
more efficient. You should really be using libraw1394 for raw1394
access anyway.
Who: Jody McIntyre <scjody@steamballoon.com>

View File

@ -7,7 +7,6 @@ that support it. For example, a given bus might look like this:
|-- 0000:17:00.0
| |-- class
| |-- config
| |-- detach_state
| |-- device
| |-- irq
| |-- local_cpus
@ -19,7 +18,7 @@ that support it. For example, a given bus might look like this:
| |-- subsystem_device
| |-- subsystem_vendor
| `-- vendor
`-- detach_state
`-- ...
The topmost element describes the PCI domain and bus number. In this case,
the domain number is 0000 and the bus number is 17 (both values are in hex).
@ -31,7 +30,6 @@ files, each with their own function.
---- --------
class PCI class (ascii, ro)
config PCI config space (binary, rw)
detach_state connection status (bool, rw)
device PCI device (ascii, ro)
irq IRQ number (ascii, ro)
local_cpus nearby CPU mask (cpumask, ro)
@ -85,4 +83,4 @@ useful return codes should be provided.
Legacy resources are protected by the HAVE_PCI_LEGACY define. Platforms
wishing to support legacy functionality should define it and provide
pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions.
pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions.

View File

@ -207,27 +207,6 @@ SYSTEM_SHUTDOWN, I do not understand this one too much. probably event
#READY_AFTER_RESUME
#
Driver Detach Power Management
The kernel now supports the ability to place a device in a low-power
state when it is detached from its driver, which happens when its
module is removed.
Each device contains a 'detach_state' file in its sysfs directory
which can be used to control this state. Reading from this file
displays what the current detach state is set to. This is 0 (On) by
default. A user may write a positive integer value to this file in the
range of 1-4 inclusive.
A value of 1-3 will indicate the device should be placed in that
low-power state, which will cause ->suspend() to be called for that
device. A value of 4 indicates that the device should be shutdown, so
->shutdown() will be called for that device.
The driver is responsible for reinitializing the device when the
module is re-inserted during it's ->probe() (or equivalent) method.
The driver core will not call any extra functions when binding the
device to the driver.
pm_message_t meaning

View File

@ -347,8 +347,8 @@ address that is created by firmware. An example vty-server sysfs entry
looks like the following:
Pow5:/sys/bus/vio/drivers/hvcs/30000004 # ls
. current_vty devspec name partner_vtys
.. detach_state index partner_clcs vterm_state
. current_vty devspec name partner_vtys
.. index partner_clcs vterm_state
Each entry is provided, by default with a "name" attribute. Reading the
"name" attribute will reveal the device type as shown in the following

View File

@ -25,6 +25,9 @@ APICs
noapictimer Don't set up the APIC timer
no_timer_check Don't check the IO-APIC timer. This can work around
problems with incorrect timer initialization on some boards.
Early Console
syntax: earlyprintk=vga

View File

@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 12
EXTRAVERSION =-rc3
EXTRAVERSION =-rc5
NAME=Woozy Numbat
# *DOCUMENTATION*
@ -530,7 +530,7 @@ endif
include $(srctree)/arch/$(ARCH)/Makefile
# arch Makefile may override CC so keep this after arch Makefile is included
NOSTDINC_FLAGS := -nostdinc -isystem $(shell $(CC) -print-file-name=include)
NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
CHECKFLAGS += $(NOSTDINC_FLAGS)
# warn about C99 declaration after statement

View File

@ -1150,16 +1150,13 @@ osf_usleep_thread(struct timeval32 __user *sleep, struct timeval32 __user *remai
if (get_tv32(&tmp, sleep))
goto fault;
ticks = tmp.tv_usec;
ticks = (ticks + (1000000 / HZ) - 1) / (1000000 / HZ);
ticks += tmp.tv_sec * HZ;
ticks = timeval_to_jiffies(&tmp);
current->state = TASK_INTERRUPTIBLE;
ticks = schedule_timeout(ticks);
if (remain) {
tmp.tv_sec = ticks / HZ;
tmp.tv_usec = ticks % HZ;
jiffies_to_timeval(ticks, &tmp);
if (put_tv32(remain, &tmp))
goto fault;
}

View File

@ -478,7 +478,7 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
{
unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate) * 2;
s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate);
printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n",
print_mhz(s3c2440_clk_upll.rate));

View File

@ -192,9 +192,11 @@ void __init s3c2440_map_io(struct map_desc *mach_desc, int size)
iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc));
iotable_init(mach_desc, size);
/* rename any peripherals used differing from the s3c2410 */
s3c_device_i2c.name = "s3c2440-i2c";
s3c_device_i2c.name = "s3c2440-i2c";
s3c_device_nand.name = "s3c2440-nand";
/* change irq for watchdog */
@ -225,7 +227,7 @@ void __init s3c2440_init_clocks(int xtal)
break;
case S3C2440_CLKDIVN_HDIVN_2:
hdiv = 1;
hdiv = 2;
break;
case S3C2440_CLKDIVN_HDIVN_4_8:

View File

@ -412,21 +412,20 @@ config CPU_BPREDICT_DISABLE
config TLS_REG_EMUL
bool
default y if (SMP || CPU_32v6) && (CPU_32v5 || CPU_32v4 || CPU_32v3)
default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3)
help
We might be running on an ARMv6+ processor which should have the TLS
register but for some reason we can't use it, or maybe an SMP system
using a pre-ARMv6 processor (there are apparently a few prototypes
like that in existence) and therefore access to that register must
be emulated.
An SMP system using a pre-ARMv6 processor (there are apparently
a few prototypes like that in existence) and therefore access to
that required register must be emulated.
config HAS_TLS_REG
bool
depends on CPU_32v6
default y if !TLS_REG_EMUL
depends on !TLS_REG_EMUL
default y if SMP || CPU_32v7
help
This selects support for the CP15 thread register.
It is defined to be available on ARMv6 or later. If a particular
ARMv6 or later CPU doesn't support it then it must omc;ide "select
TLS_REG_EMUL" along with its other caracteristics.
It is defined to be available on some ARMv6 processors (including
all SMP capable ARMv6's) or later processors. User space may
assume directly accessing that register and always obtain the
expected value only on ARMv7 and above.

View File

@ -1,80 +0,0 @@
/*
* linux/arch/arm/lib/copy_page-armv4mc.S
*
* Copyright (C) 1995-2001 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* ASM optimised string functions
*/
#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/constants.h>
.text
.align 5
/*
* ARMv4 mini-dcache optimised copy_user_page
*
* We flush the destination cache lines just before we write the data into the
* corresponding address. Since the Dcache is read-allocate, this removes the
* Dcache aliasing issue. The writes will be forwarded to the write buffer,
* and merged as appropriate.
*
* Note: We rely on all ARMv4 processors implementing the "invalidate D line"
* instruction. If your processor does not supply this, you have to write your
* own copy_user_page that does the right thing.
*/
ENTRY(v4_mc_copy_user_page)
stmfd sp!, {r4, lr} @ 2
mov r4, r0
mov r0, r1
bl map_page_minicache
mov r1, #PAGE_SZ/64 @ 1
ldmia r0!, {r2, r3, ip, lr} @ 4
1: mcr p15, 0, r4, c7, c6, 1 @ 1 invalidate D line
stmia r4!, {r2, r3, ip, lr} @ 4
ldmia r0!, {r2, r3, ip, lr} @ 4+1
stmia r4!, {r2, r3, ip, lr} @ 4
ldmia r0!, {r2, r3, ip, lr} @ 4
mcr p15, 0, r4, c7, c6, 1 @ 1 invalidate D line
stmia r4!, {r2, r3, ip, lr} @ 4
ldmia r0!, {r2, r3, ip, lr} @ 4
subs r1, r1, #1 @ 1
stmia r4!, {r2, r3, ip, lr} @ 4
ldmneia r0!, {r2, r3, ip, lr} @ 4
bne 1b @ 1
ldmfd sp!, {r4, pc} @ 3
.align 5
/*
* ARMv4 optimised clear_user_page
*
* Same story as above.
*/
ENTRY(v4_mc_clear_user_page)
str lr, [sp, #-4]!
mov r1, #PAGE_SZ/64 @ 1
mov r2, #0 @ 1
mov r3, #0 @ 1
mov ip, #0 @ 1
mov lr, #0 @ 1
1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line
stmia r0!, {r2, r3, ip, lr} @ 4
stmia r0!, {r2, r3, ip, lr} @ 4
mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line
stmia r0!, {r2, r3, ip, lr} @ 4
stmia r0!, {r2, r3, ip, lr} @ 4
subs r1, r1, #1 @ 1
bne 1b @ 1
ldr pc, [sp], #4
__INITDATA
.type v4_mc_user_fns, #object
ENTRY(v4_mc_user_fns)
.long v4_mc_clear_user_page
.long v4_mc_copy_user_page
.size v4_mc_user_fns, . - v4_mc_user_fns

111
arch/arm/mm/copypage-v4mc.c Normal file
View File

@ -0,0 +1,111 @@
/*
* linux/arch/arm/lib/copypage-armv4mc.S
*
* Copyright (C) 1995-2005 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This handles the mini data cache, as found on SA11x0 and XScale
* processors. When we copy a user page page, we map it in such a way
* that accesses to this page will not touch the main data cache, but
* will be cached in the mini data cache. This prevents us thrashing
* the main data cache on page faults.
*/
#include <linux/init.h>
#include <linux/mm.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
/*
* 0xffff8000 to 0xffffffff is reserved for any ARM architecture
* specific hacks for copying pages efficiently.
*/
#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
L_PTE_CACHEABLE)
#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
static DEFINE_SPINLOCK(minicache_lock);
/*
* ARMv4 mini-dcache optimised copy_user_page
*
* We flush the destination cache lines just before we write the data into the
* corresponding address. Since the Dcache is read-allocate, this removes the
* Dcache aliasing issue. The writes will be forwarded to the write buffer,
* and merged as appropriate.
*
* Note: We rely on all ARMv4 processors implementing the "invalidate D line"
* instruction. If your processor does not supply this, you have to write your
* own copy_user_page that does the right thing.
*/
static void __attribute__((naked))
mc_copy_user_page(void *from, void *to)
{
asm volatile(
"stmfd sp!, {r4, lr} @ 2\n\
mov r4, %2 @ 1\n\
ldmia %0!, {r2, r3, ip, lr} @ 4\n\
1: mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\
stmia %1!, {r2, r3, ip, lr} @ 4\n\
ldmia %0!, {r2, r3, ip, lr} @ 4+1\n\
stmia %1!, {r2, r3, ip, lr} @ 4\n\
ldmia %0!, {r2, r3, ip, lr} @ 4\n\
mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\
stmia %1!, {r2, r3, ip, lr} @ 4\n\
ldmia %0!, {r2, r3, ip, lr} @ 4\n\
subs r4, r4, #1 @ 1\n\
stmia %1!, {r2, r3, ip, lr} @ 4\n\
ldmneia %0!, {r2, r3, ip, lr} @ 4\n\
bne 1b @ 1\n\
ldmfd sp!, {r4, pc} @ 3"
:
: "r" (from), "r" (to), "I" (PAGE_SIZE / 64));
}
void v4_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
{
spin_lock(&minicache_lock);
set_pte(TOP_PTE(0xffff8000), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot));
flush_tlb_kernel_page(0xffff8000);
mc_copy_user_page((void *)0xffff8000, kto);
spin_unlock(&minicache_lock);
}
/*
* ARMv4 optimised clear_user_page
*/
void __attribute__((naked))
v4_mc_clear_user_page(void *kaddr, unsigned long vaddr)
{
asm volatile(
"str lr, [sp, #-4]!\n\
mov r1, %0 @ 1\n\
mov r2, #0 @ 1\n\
mov r3, #0 @ 1\n\
mov ip, #0 @ 1\n\
mov lr, #0 @ 1\n\
1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\
stmia r0!, {r2, r3, ip, lr} @ 4\n\
stmia r0!, {r2, r3, ip, lr} @ 4\n\
mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\
stmia r0!, {r2, r3, ip, lr} @ 4\n\
stmia r0!, {r2, r3, ip, lr} @ 4\n\
subs r1, r1, #1 @ 1\n\
bne 1b @ 1\n\
ldr pc, [sp], #4"
:
: "I" (PAGE_SIZE / 64));
}
struct cpu_user_fns v4_mc_user_fns __initdata = {
.cpu_clear_user_page = v4_mc_clear_user_page,
.cpu_copy_user_page = v4_mc_copy_user_page,
};

View File

@ -26,8 +26,8 @@
#define to_address (0xffffc000)
#define to_pgprot PAGE_KERNEL
static pte_t *from_pte;
static pte_t *to_pte;
#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
static DEFINE_SPINLOCK(v6_lock);
#define DCACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
@ -74,8 +74,8 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd
*/
spin_lock(&v6_lock);
set_pte(from_pte + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot));
set_pte(to_pte + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot));
set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot));
set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot));
from = from_address + (offset << PAGE_SHIFT);
to = to_address + (offset << PAGE_SHIFT);
@ -114,7 +114,7 @@ void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
*/
spin_lock(&v6_lock);
set_pte(to_pte + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot));
set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot));
flush_tlb_kernel_page(to);
clear_page((void *)to);
@ -129,21 +129,6 @@ struct cpu_user_fns v6_user_fns __initdata = {
static int __init v6_userpage_init(void)
{
if (cache_is_vipt_aliasing()) {
pgd_t *pgd;
pmd_t *pmd;
pgd = pgd_offset_k(from_address);
pmd = pmd_alloc(&init_mm, pgd, from_address);
if (!pmd)
BUG();
from_pte = pte_alloc_kernel(&init_mm, pmd, from_address);
if (!from_pte)
BUG();
to_pte = pte_alloc_kernel(&init_mm, pmd, to_address);
if (!to_pte)
BUG();
cpu_user.cpu_clear_user_page = v6_clear_user_page_aliasing;
cpu_user.cpu_copy_user_page = v6_copy_user_page_aliasing;
}
@ -151,5 +136,4 @@ static int __init v6_userpage_init(void)
return 0;
}
__initcall(v6_userpage_init);
core_initcall(v6_userpage_init);

View File

@ -13,6 +13,29 @@
#include <asm/cacheflush.h>
#include <asm/system.h>
#include <asm/tlbflush.h>
#ifdef CONFIG_CPU_CACHE_VIPT
#define ALIAS_FLUSH_START 0xffff4000
#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
{
unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
set_pte(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL));
flush_tlb_kernel_page(to);
asm( "mcrr p15, 0, %1, %0, c14\n"
" mcrr p15, 0, %1, %0, c5\n"
:
: "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES)
: "cc");
}
#else
#define flush_pfn_alias(pfn,vaddr) do { } while (0)
#endif
static void __flush_dcache_page(struct address_space *mapping, struct page *page)
{
@ -36,6 +59,18 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page
if (!mapping)
return;
/*
* This is a page cache page. If we have a VIPT cache, we
* only need to do one flush - which would be at the relevant
* userspace colour, which is congruent with page->index.
*/
if (cache_is_vipt()) {
if (cache_is_vipt_aliasing())
flush_pfn_alias(page_to_pfn(page),
page->index << PAGE_CACHE_SHIFT);
return;
}
/*
* There are possible user space mappings of this page:
* - VIVT cache: we need to also write back and invalidate all user
@ -57,8 +92,6 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page
continue;
offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
flush_cache_page(mpnt, mpnt->vm_start + offset, page_to_pfn(page));
if (cache_is_vipt())
break;
}
flush_dcache_mmap_unlock(mapping);
}

View File

@ -37,6 +37,8 @@ pgprot_t pgprot_kernel;
EXPORT_SYMBOL(pgprot_kernel);
pmd_t *top_pmd;
struct cachepolicy {
const char policy[16];
unsigned int cr_mask;
@ -142,6 +144,16 @@ __setup("noalign", noalign_setup);
#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)
static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)
{
return pmd_offset(pgd, virt);
}
static inline pmd_t *pmd_off_k(unsigned long virt)
{
return pmd_off(pgd_offset_k(virt), virt);
}
/*
* need to get a 16k page for level 1
*/
@ -220,7 +232,7 @@ void free_pgd_slow(pgd_t *pgd)
return;
/* pgd is always present and good */
pmd = (pmd_t *)pgd;
pmd = pmd_off(pgd, 0);
if (pmd_none(*pmd))
goto free;
if (pmd_bad(*pmd)) {
@ -246,9 +258,8 @@ void free_pgd_slow(pgd_t *pgd)
static inline void
alloc_init_section(unsigned long virt, unsigned long phys, int prot)
{
pmd_t *pmdp;
pmd_t *pmdp = pmd_off_k(virt);
pmdp = pmd_offset(pgd_offset_k(virt), virt);
if (virt & (1 << 20))
pmdp++;
@ -283,11 +294,9 @@ alloc_init_supersection(unsigned long virt, unsigned long phys, int prot)
static inline void
alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot)
{
pmd_t *pmdp;
pmd_t *pmdp = pmd_off_k(virt);
pte_t *ptep;
pmdp = pmd_offset(pgd_offset_k(virt), virt);
if (pmd_none(*pmdp)) {
unsigned long pmdval;
ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
@ -310,7 +319,7 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg
*/
static inline void clear_mapping(unsigned long virt)
{
pmd_clear(pmd_offset(pgd_offset_k(virt), virt));
pmd_clear(pmd_off_k(virt));
}
struct mem_types {
@ -578,7 +587,7 @@ void setup_mm_for_reboot(char mode)
PMD_TYPE_SECT;
if (cpu_arch <= CPU_ARCH_ARMv5)
pmdval |= PMD_BIT4;
pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT);
pmd = pmd_off(pgd, i << PGDIR_SHIFT);
pmd[0] = __pmd(pmdval);
pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
flush_pmd_entry(pmd);
@ -675,6 +684,8 @@ void __init memtable_init(struct meminfo *mi)
flush_cache_all();
flush_tlb_all();
top_pmd = pmd_off_k(0xffff0000);
}
/*

View File

@ -650,7 +650,7 @@ acpi_find_rsdp (void)
*/
rsdp_phys = acpi_scan_rsdp (0, 0x400);
if (!rsdp_phys)
rsdp_phys = acpi_scan_rsdp (0xE0000, 0xFFFFF);
rsdp_phys = acpi_scan_rsdp (0xE0000, 0x20000);
return rsdp_phys;
}

View File

@ -24,9 +24,6 @@ __asm__(".align 4\nvide: ret");
static void __init init_amd(struct cpuinfo_x86 *c)
{
#ifdef CONFIG_X86_SMP
int cpu = c == &boot_cpu_data ? 0 : c - cpu_data;
#endif
u32 l, h;
int mbytes = num_physpages >> (20-PAGE_SHIFT);
int r;
@ -198,14 +195,19 @@ static void __init init_amd(struct cpuinfo_x86 *c)
c->x86_num_cores = 1;
}
#ifdef CONFIG_X86_SMP
#ifdef CONFIG_X86_HT
/*
* On a AMD dual core setup the lower bits of the APIC id
* distingush the cores. Assumes number of cores is a power
* of two.
*/
if (c->x86_num_cores > 1) {
cpu_core_id[cpu] = cpu >> hweight32(c->x86_num_cores - 1);
int cpu = smp_processor_id();
unsigned bits = 0;
while ((1 << bits) < c->x86_num_cores)
bits++;
cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<<bits)-1);
phys_proc_id[cpu] >>= bits;
printk(KERN_INFO "CPU %d(%d) -> Core %d\n",
cpu, c->x86_num_cores, cpu_core_id[cpu]);
}

View File

@ -243,6 +243,10 @@ static void __init early_cpu_detect(void)
}
early_intel_workaround(c);
#ifdef CONFIG_X86_HT
phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff;
#endif
}
void __init generic_identify(struct cpuinfo_x86 * c)

View File

@ -888,6 +888,7 @@ void *xquad_portio;
cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
EXPORT_SYMBOL(cpu_core_map);
static void __init smp_boot_cpus(unsigned int max_cpus)
{

View File

@ -97,7 +97,6 @@ static void ack_vic_irq(unsigned int irq);
static void vic_enable_cpi(void);
static void do_boot_cpu(__u8 cpuid);
static void do_quad_bootstrap(void);
static inline void wrapper_smp_local_timer_interrupt(struct pt_regs *);
int hard_smp_processor_id(void);
@ -125,6 +124,14 @@ send_QIC_CPI(__u32 cpuset, __u8 cpi)
}
}
static inline void
wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
{
irq_enter();
smp_local_timer_interrupt(regs);
irq_exit();
}
static inline void
send_one_CPI(__u8 cpu, __u8 cpi)
{
@ -1249,14 +1256,6 @@ smp_vic_timer_interrupt(struct pt_regs *regs)
smp_local_timer_interrupt(regs);
}
static inline void
wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
{
irq_enter();
smp_local_timer_interrupt(regs);
irq_exit();
}
/* local (per CPU) timer interrupt. It does both profiling and
* process statistics/rescheduling.
*

View File

@ -238,19 +238,21 @@ void iounmap(volatile void __iomem *addr)
addr < phys_to_virt(ISA_END_ADDRESS))
return;
p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
write_lock(&vmlist_lock);
p = __remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
if (!p) {
printk("__iounmap: bad address %p\n", addr);
return;
printk("iounmap: bad address %p\n", addr);
goto out_unlock;
}
if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) {
/* p->size includes the guard page, but cpa doesn't like that */
change_page_attr(virt_to_page(__va(p->phys_addr)),
p->size >> PAGE_SHIFT,
PAGE_KERNEL);
global_flush_tlb();
}
out_unlock:
write_unlock(&vmlist_lock);
kfree(p);
}

View File

@ -253,7 +253,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci
#define MAX_PCIEROOT 6
static int quirk_aspm_offset[MAX_PCIEROOT << 3];
#define GET_INDEX(a, b) (((a - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + b)
#define GET_INDEX(a, b) ((((a) - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + ((b) & 7))
static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{

View File

@ -13,7 +13,6 @@
#define INCLUDES
#include "compat_ioctl.c"
#include <asm/ioctl32.h>
#define IOCTL_NR(a) ((a) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))

View File

@ -1,7 +1,7 @@
/*
* pmu.c, Power Management Unit routines for NEC VR4100 series.
*
* Copyright (C) 2003-2004 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
* Copyright (C) 2003-2005 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
*
* 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
@ -17,7 +17,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/smp.h>
#include <linux/types.h>
@ -27,20 +29,31 @@
#include <asm/reboot.h>
#include <asm/system.h>
#define PMUCNT2REG KSEG1ADDR(0x0f0000c6)
#define PMU_TYPE1_BASE 0x0b0000a0UL
#define PMU_TYPE1_SIZE 0x0eUL
#define PMU_TYPE2_BASE 0x0f0000c0UL
#define PMU_TYPE2_SIZE 0x10UL
#define PMUCNT2REG 0x06
#define SOFTRST 0x0010
static void __iomem *pmu_base;
#define pmu_read(offset) readw(pmu_base + (offset))
#define pmu_write(offset, value) writew((value), pmu_base + (offset))
static inline void software_reset(void)
{
uint16_t val;
uint16_t pmucnt2;
switch (current_cpu_data.cputype) {
case CPU_VR4122:
case CPU_VR4131:
case CPU_VR4133:
val = readw(PMUCNT2REG);
val |= SOFTRST;
writew(val, PMUCNT2REG);
pmucnt2 = pmu_read(PMUCNT2REG);
pmucnt2 |= SOFTRST;
pmu_write(PMUCNT2REG, pmucnt2);
break;
default:
break;
@ -71,6 +84,34 @@ static void vr41xx_power_off(void)
static int __init vr41xx_pmu_init(void)
{
unsigned long start, size;
switch (current_cpu_data.cputype) {
case CPU_VR4111:
case CPU_VR4121:
start = PMU_TYPE1_BASE;
size = PMU_TYPE1_SIZE;
break;
case CPU_VR4122:
case CPU_VR4131:
case CPU_VR4133:
start = PMU_TYPE2_BASE;
size = PMU_TYPE2_SIZE;
break;
default:
printk("Unexpected CPU of NEC VR4100 series\n");
return -ENODEV;
}
if (request_mem_region(start, size, "PMU") == NULL)
return -EBUSY;
pmu_base = ioremap(start, size);
if (pmu_base == NULL) {
release_mem_region(start, size);
return -EBUSY;
}
_machine_restart = vr41xx_restart;
_machine_halt = vr41xx_halt;
_machine_power_off = vr41xx_power_off;
@ -78,4 +119,4 @@ static int __init vr41xx_pmu_init(void)
return 0;
}
early_initcall(vr41xx_pmu_init);
core_initcall(vr41xx_pmu_init);

View File

@ -77,9 +77,11 @@ config 44x
bool "44x"
config POWER3
select PPC_FPU
bool "POWER3"
config POWER4
select PPC_FPU
bool "POWER4 and 970 (G5)"
config 8xx

View File

@ -330,8 +330,9 @@ interrupt_base:
/* If we are faulting a kernel address, we have to use the
* kernel page tables.
*/
andis. r11, r10, 0x8000
beq 3f
lis r11, TASK_SIZE@h
cmplw r10, r11
blt+ 3f
lis r11, swapper_pg_dir@h
ori r11, r11, swapper_pg_dir@l
@ -464,8 +465,9 @@ interrupt_base:
/* If we are faulting a kernel address, we have to use the
* kernel page tables.
*/
andis. r11, r10, 0x8000
beq 3f
lis r11, TASK_SIZE@h
cmplw r10, r11
blt+ 3f
lis r11, swapper_pg_dir@h
ori r11, r11, swapper_pg_dir@l
@ -533,8 +535,9 @@ interrupt_base:
/* If we are faulting a kernel address, we have to use the
* kernel page tables.
*/
andis. r11, r10, 0x8000
beq 3f
lis r11, TASK_SIZE@h
cmplw r10, r11
blt+ 3f
lis r11, swapper_pg_dir@h
ori r11, r11, swapper_pg_dir@l

View File

@ -499,7 +499,7 @@ static int __init set_preferred_console(void)
{
struct device_node *prom_stdout;
char *name;
int offset;
int offset = 0;
if (of_stdout_device == NULL)
return -ENODEV;
@ -753,6 +753,8 @@ void __init setup_arch(char **cmdline_p)
strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
*cmdline_p = cmd_line;
parse_early_param();
/* set up the bootmem stuff with available memory */
do_init_bootmem();
if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);

View File

@ -446,6 +446,7 @@ _GLOBAL(__copy_tofrom_user)
#ifdef CONFIG_8xx
/* Don't use prefetch on 8xx */
mtctr r0
li r0,0
53: COPY_16_BYTES_WITHEX(0)
bdnz 53b
@ -564,7 +565,9 @@ _GLOBAL(__copy_tofrom_user)
/* or write fault in cacheline loop */
105: li r9,1
92: li r3,LG_CACHELINE_BYTES
b 99f
mfctr r8
add r0,r0,r8
b 106f
/* read fault in final word loop */
108: li r9,0
b 93f
@ -585,7 +588,7 @@ _GLOBAL(__copy_tofrom_user)
* r5 + (ctr << r3), and r9 is 0 for read or 1 for write.
*/
99: mfctr r0
slw r3,r0,r3
106: slw r3,r0,r3
add. r3,r3,r5
beq 120f /* shouldn't happen */
cmpwi 0,r9,0

View File

@ -179,6 +179,7 @@ void free_initmem(void)
if (!have_of)
FREESEC(openfirmware);
printk("\n");
ppc_md.progress = NULL;
#undef FREESEC
}

View File

@ -479,7 +479,7 @@ void __init ipic_init(phys_addr_t phys_addr,
temp = 0;
for (i = 0 ; i < senses_count ; i++) {
if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) {
temp |= 1 << (16 - i);
temp |= 1 << (15 - i);
if (i != 0)
irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0;
else

View File

@ -61,6 +61,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
},
{ },
};
struct platform_device ppc_sys_platform_devices[] = {

View File

@ -61,6 +61,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ,
},
{ },
};
struct platform_device ppc_sys_platform_devices[] = {

View File

@ -557,12 +557,10 @@ static void __init openpic_initipi(u_int ipi, u_int pri, u_int vec)
*/
void openpic_cause_IPI(u_int ipi, cpumask_t cpumask)
{
cpumask_t phys;
DECL_THIS_CPU;
CHECK_THIS_CPU;
check_arg_ipi(ipi);
phys = physmask(cpumask);
openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi),
cpus_addr(physmask(cpumask))[0]);
}

View File

@ -262,6 +262,7 @@ config PPC_RTAS
config RTAS_PROC
bool "Proc interface to RTAS"
depends on PPC_RTAS
default y
config RTAS_FLASH
tristate "Firmware flash interface"

View File

@ -1,7 +1,7 @@
/*
* mf.c
* Copyright (C) 2001 Troy D. Armstrong IBM Corporation
* Copyright (C) 2004 Stephen Rothwell IBM Corporation
* Copyright (C) 2004-2005 Stephen Rothwell IBM Corporation
*
* This modules exists as an interface between a Linux secondary partition
* running on an iSeries and the primary partition's Virtual Service
@ -36,10 +36,12 @@
#include <asm/time.h>
#include <asm/uaccess.h>
#include <asm/paca.h>
#include <asm/iSeries/vio.h>
#include <asm/iSeries/mf.h>
#include <asm/iSeries/HvLpConfig.h>
#include <asm/iSeries/ItSpCommArea.h>
#include <asm/iSeries/ItLpQueue.h>
/*
* This is the structure layout for the Machine Facilites LPAR event
@ -696,36 +698,23 @@ static void get_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
complete(&rtc->com);
}
int mf_get_rtc(struct rtc_time *tm)
static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm)
{
struct ce_msg_comp_data ce_complete;
struct rtc_time_data rtc_data;
int rc;
memset(&ce_complete, 0, sizeof(ce_complete));
memset(&rtc_data, 0, sizeof(rtc_data));
init_completion(&rtc_data.com);
ce_complete.handler = &get_rtc_time_complete;
ce_complete.token = &rtc_data;
rc = signal_ce_msg_simple(0x40, &ce_complete);
if (rc)
return rc;
wait_for_completion(&rtc_data.com);
tm->tm_wday = 0;
tm->tm_yday = 0;
tm->tm_isdst = 0;
if (rtc_data.rc) {
if (rc) {
tm->tm_sec = 0;
tm->tm_min = 0;
tm->tm_hour = 0;
tm->tm_mday = 15;
tm->tm_mon = 5;
tm->tm_year = 52;
return rtc_data.rc;
return rc;
}
if ((rtc_data.ce_msg.ce_msg[2] == 0xa9) ||
(rtc_data.ce_msg.ce_msg[2] == 0xaf)) {
if ((ce_msg[2] == 0xa9) ||
(ce_msg[2] == 0xaf)) {
/* TOD clock is not set */
tm->tm_sec = 1;
tm->tm_min = 1;
@ -736,7 +725,6 @@ int mf_get_rtc(struct rtc_time *tm)
mf_set_rtc(tm);
}
{
u8 *ce_msg = rtc_data.ce_msg.ce_msg;
u8 year = ce_msg[5];
u8 sec = ce_msg[6];
u8 min = ce_msg[7];
@ -765,6 +753,63 @@ int mf_get_rtc(struct rtc_time *tm)
return 0;
}
int mf_get_rtc(struct rtc_time *tm)
{
struct ce_msg_comp_data ce_complete;
struct rtc_time_data rtc_data;
int rc;
memset(&ce_complete, 0, sizeof(ce_complete));
memset(&rtc_data, 0, sizeof(rtc_data));
init_completion(&rtc_data.com);
ce_complete.handler = &get_rtc_time_complete;
ce_complete.token = &rtc_data;
rc = signal_ce_msg_simple(0x40, &ce_complete);
if (rc)
return rc;
wait_for_completion(&rtc_data.com);
return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
}
struct boot_rtc_time_data {
int busy;
struct ce_msg_data ce_msg;
int rc;
};
static void get_boot_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
{
struct boot_rtc_time_data *rtc = token;
memcpy(&rtc->ce_msg, ce_msg, sizeof(rtc->ce_msg));
rtc->rc = 0;
rtc->busy = 0;
}
int mf_get_boot_rtc(struct rtc_time *tm)
{
struct ce_msg_comp_data ce_complete;
struct boot_rtc_time_data rtc_data;
int rc;
memset(&ce_complete, 0, sizeof(ce_complete));
memset(&rtc_data, 0, sizeof(rtc_data));
rtc_data.busy = 1;
ce_complete.handler = &get_boot_rtc_time_complete;
ce_complete.token = &rtc_data;
rc = signal_ce_msg_simple(0x40, &ce_complete);
if (rc)
return rc;
/* We need to poll here as we are not yet taking interrupts */
while (rtc_data.busy) {
extern unsigned long lpevent_count;
struct ItLpQueue *lpq = get_paca()->lpqueue_ptr;
if (lpq && ItLpQueue_isLpIntPending(lpq))
lpevent_count += ItLpQueue_process(lpq, NULL);
}
return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
}
int mf_set_rtc(struct rtc_time *tm)
{
char ce_time[12];

View File

@ -326,13 +326,6 @@ static void __devinit smp_xics_setup_cpu(int cpu)
cpu_clear(cpu, of_spin_map);
/*
* Put the calling processor into the GIQ. This is really only
* necessary from a secondary thread as the OF start-cpu interface
* performs this function for us on primary threads.
*/
rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
(1UL << interrupt_server_size) - 1 - default_distrib_server, 1);
}
static DEFINE_SPINLOCK(timebase_lock);

View File

@ -68,6 +68,7 @@ extern struct smp_ops_t *smp_ops;
static void (*pmac_tb_freeze)(int freeze);
static struct device_node *pmac_tb_clock_chip_host;
static u8 pmac_tb_pulsar_addr;
static DEFINE_SPINLOCK(timebase_lock);
static unsigned long timebase;
@ -106,12 +107,9 @@ static void smp_core99_pulsar_tb_freeze(int freeze)
u8 data;
int rc;
/* Strangely, the device-tree says address is 0xd2, but darwin
* accesses 0xd0 ...
*/
pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
0xd4 | pmac_low_i2c_read,
pmac_tb_pulsar_addr | pmac_low_i2c_read,
0x2e, &data, 1);
if (rc != 0)
goto bail;
@ -120,7 +118,7 @@ static void smp_core99_pulsar_tb_freeze(int freeze)
pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
0xd4 | pmac_low_i2c_write,
pmac_tb_pulsar_addr | pmac_low_i2c_write,
0x2e, &data, 1);
bail:
if (rc != 0) {
@ -185,6 +183,12 @@ static int __init smp_core99_probe(void)
if (ncpus <= 1)
return 1;
/* HW sync only on these platforms */
if (!machine_is_compatible("PowerMac7,2") &&
!machine_is_compatible("PowerMac7,3") &&
!machine_is_compatible("RackMac3,1"))
goto nohwsync;
/* Look for the clock chip */
for (cc = NULL; (cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL;) {
struct device_node *p = of_get_parent(cc);
@ -198,11 +202,18 @@ static int __init smp_core99_probe(void)
goto next;
switch (*reg) {
case 0xd2:
pmac_tb_freeze = smp_core99_cypress_tb_freeze;
printk(KERN_INFO "Timebase clock is Cypress chip\n");
if (device_is_compatible(cc, "pulsar-legacy-slewing")) {
pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
pmac_tb_pulsar_addr = 0xd2;
printk(KERN_INFO "Timebase clock is Pulsar chip\n");
} else if (device_is_compatible(cc, "cy28508")) {
pmac_tb_freeze = smp_core99_cypress_tb_freeze;
printk(KERN_INFO "Timebase clock is Cypress chip\n");
}
break;
case 0xd4:
pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
pmac_tb_pulsar_addr = 0xd4;
printk(KERN_INFO "Timebase clock is Pulsar chip\n");
break;
}
@ -210,12 +221,15 @@ static int __init smp_core99_probe(void)
pmac_tb_clock_chip_host = p;
smp_ops->give_timebase = smp_core99_give_timebase;
smp_ops->take_timebase = smp_core99_take_timebase;
of_node_put(cc);
of_node_put(p);
break;
}
next:
of_node_put(p);
}
nohwsync:
mpic_request_ipis();
return ncpus;

View File

@ -1750,7 +1750,44 @@ static void __init flatten_device_tree(void)
prom_printf("Device tree struct 0x%x -> 0x%x\n",
RELOC(dt_struct_start), RELOC(dt_struct_end));
}
}
static void __init fixup_device_tree(void)
{
unsigned long offset = reloc_offset();
phandle u3, i2c, mpic;
u32 u3_rev;
u32 interrupts[2];
u32 parent;
/* Some G5s have a missing interrupt definition, fix it up here */
u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
if ((long)u3 <= 0)
return;
i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
if ((long)i2c <= 0)
return;
mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
if ((long)mpic <= 0)
return;
/* check if proper rev of u3 */
if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) <= 0)
return;
if (u3_rev != 0x35)
return;
/* does it need fixup ? */
if (prom_getproplen(i2c, "interrupts") > 0)
return;
/* interrupt on this revision of u3 is number 0 and level */
interrupts[0] = 0;
interrupts[1] = 1;
prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts));
parent = (u32)mpic;
prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent));
}
static void __init prom_find_boot_cpu(void)
{
@ -1919,6 +1956,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
PTRRELOC(&prom_tce_alloc_end), sizeof(RELOC(prom_tce_alloc_end)));
}
/*
* Fixup any known bugs in the device-tree
*/
fixup_device_tree();
/*
* Now finally create the flattened device-tree
*/

View File

@ -292,47 +292,10 @@ int iSeries_set_rtc_time(struct rtc_time *tm)
void iSeries_get_boot_time(struct rtc_time *tm)
{
unsigned long time;
static unsigned long lastsec = 1;
u32 dataWord1 = *((u32 *)(&xSpCommArea.xBcdTimeAtIplStart));
u32 dataWord2 = *(((u32 *)&(xSpCommArea.xBcdTimeAtIplStart)) + 1);
int year = 1970;
int year1 = ( dataWord1 >> 24 ) & 0x000000FF;
int year2 = ( dataWord1 >> 16 ) & 0x000000FF;
int sec = ( dataWord1 >> 8 ) & 0x000000FF;
int min = dataWord1 & 0x000000FF;
int hour = ( dataWord2 >> 24 ) & 0x000000FF;
int day = ( dataWord2 >> 8 ) & 0x000000FF;
int mon = dataWord2 & 0x000000FF;
if ( piranha_simulator )
return;
BCD_TO_BIN(sec);
BCD_TO_BIN(min);
BCD_TO_BIN(hour);
BCD_TO_BIN(day);
BCD_TO_BIN(mon);
BCD_TO_BIN(year1);
BCD_TO_BIN(year2);
year = year1 * 100 + year2;
time = mktime(year, mon, day, hour, min, sec);
time += ( jiffies / HZ );
/* Now THIS is a nasty hack!
* It ensures that the first two calls get different answers.
* That way the loop in init_time (time.c) will not think
* the clock is stuck.
*/
if ( lastsec ) {
time -= lastsec;
--lastsec;
}
to_tm(time, tm);
tm->tm_year -= 1900;
mf_get_boot_rtc(tm);
tm->tm_mon -= 1;
}
#endif

View File

@ -515,6 +515,7 @@ void __init time_init(void)
do_gtod.varp = &do_gtod.vars[0];
do_gtod.var_idx = 0;
do_gtod.varp->tb_orig_stamp = tb_last_stamp;
get_paca()->next_jiffy_update_tb = tb_last_stamp + tb_ticks_per_jiffy;
do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
do_gtod.varp->tb_to_xs = tb_to_xs;

View File

@ -432,6 +432,7 @@ void xics_cause_IPI(int cpu)
{
ops->qirr_info(cpu, IPI_PRIORITY);
}
#endif /* CONFIG_SMP */
void xics_setup_cpu(void)
{
@ -439,9 +440,17 @@ void xics_setup_cpu(void)
ops->cppr_info(cpu, 0xff);
iosync();
}
#endif /* CONFIG_SMP */
/*
* Put the calling processor into the GIQ. This is really only
* necessary from a secondary thread as the OF start-cpu interface
* performs this function for us on primary threads.
*
* XXX: undo of teardown on kexec needs this too, as may hotplug
*/
rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
(1UL << interrupt_server_size) - 1 - default_distrib_server, 1);
}
void xics_init_IRQ(void)
{
@ -563,8 +572,7 @@ void xics_init_IRQ(void)
for (; i < NR_IRQS; ++i)
get_irq_desc(i)->handler = &xics_pic;
ops->cppr_info(boot_cpuid, 0xff);
iosync();
xics_setup_cpu();
ppc64_boot_msg(0x21, "XICS Done");
}

View File

@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <asm/pbm.h>
@ -379,6 +380,56 @@ dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direct
return PCI_DMA_ERROR_CODE;
}
static void pci_strbuf_flush(struct pci_strbuf *strbuf, struct pci_iommu *iommu, u32 vaddr, unsigned long ctx, unsigned long npages)
{
int limit;
PCI_STC_FLUSHFLAG_INIT(strbuf);
if (strbuf->strbuf_ctxflush &&
iommu->iommu_ctxflush) {
unsigned long matchreg, flushreg;
flushreg = strbuf->strbuf_ctxflush;
matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
limit = 100000;
pci_iommu_write(flushreg, ctx);
for(;;) {
if (((long)pci_iommu_read(matchreg)) >= 0L)
break;
limit--;
if (!limit)
break;
udelay(1);
}
if (!limit)
printk(KERN_WARNING "pci_strbuf_flush: ctx flush "
"timeout vaddr[%08x] ctx[%lx]\n",
vaddr, ctx);
} else {
unsigned long i;
for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
pci_iommu_write(strbuf->strbuf_pflush, vaddr);
}
pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
(void) pci_iommu_read(iommu->write_complete_reg);
limit = 100000;
while (!PCI_STC_FLUSHFLAG_SET(strbuf)) {
limit--;
if (!limit)
break;
udelay(1);
membar("#LoadLoad");
}
if (!limit)
printk(KERN_WARNING "pci_strbuf_flush: flushflag timeout "
"vaddr[%08x] ctx[%lx] npages[%ld]\n",
vaddr, ctx, npages);
}
/* Unmap a single streaming mode DMA translation. */
void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction)
{
@ -386,7 +437,7 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
struct pci_iommu *iommu;
struct pci_strbuf *strbuf;
iopte_t *base;
unsigned long flags, npages, i, ctx;
unsigned long flags, npages, ctx;
if (direction == PCI_DMA_NONE)
BUG();
@ -414,29 +465,8 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL;
/* Step 1: Kick data out of streaming buffers if necessary. */
if (strbuf->strbuf_enabled) {
u32 vaddr = bus_addr;
PCI_STC_FLUSHFLAG_INIT(strbuf);
if (strbuf->strbuf_ctxflush &&
iommu->iommu_ctxflush) {
unsigned long matchreg, flushreg;
flushreg = strbuf->strbuf_ctxflush;
matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
do {
pci_iommu_write(flushreg, ctx);
} while(((long)pci_iommu_read(matchreg)) < 0L);
} else {
for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
pci_iommu_write(strbuf->strbuf_pflush, vaddr);
}
pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
(void) pci_iommu_read(iommu->write_complete_reg);
while (!PCI_STC_FLUSHFLAG_SET(strbuf))
membar("#LoadLoad");
}
if (strbuf->strbuf_enabled)
pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages);
/* Step 2: Clear out first TSB entry. */
iopte_make_dummy(iommu, base);
@ -647,29 +677,8 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems,
ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL;
/* Step 1: Kick data out of streaming buffers if necessary. */
if (strbuf->strbuf_enabled) {
u32 vaddr = (u32) bus_addr;
PCI_STC_FLUSHFLAG_INIT(strbuf);
if (strbuf->strbuf_ctxflush &&
iommu->iommu_ctxflush) {
unsigned long matchreg, flushreg;
flushreg = strbuf->strbuf_ctxflush;
matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
do {
pci_iommu_write(flushreg, ctx);
} while(((long)pci_iommu_read(matchreg)) < 0L);
} else {
for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
pci_iommu_write(strbuf->strbuf_pflush, vaddr);
}
pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
(void) pci_iommu_read(iommu->write_complete_reg);
while (!PCI_STC_FLUSHFLAG_SET(strbuf))
membar("#LoadLoad");
}
if (strbuf->strbuf_enabled)
pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages);
/* Step 2: Clear out first TSB entry. */
iopte_make_dummy(iommu, base);
@ -715,28 +724,7 @@ void pci_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size
}
/* Step 2: Kick data out of streaming buffers. */
PCI_STC_FLUSHFLAG_INIT(strbuf);
if (iommu->iommu_ctxflush &&
strbuf->strbuf_ctxflush) {
unsigned long matchreg, flushreg;
flushreg = strbuf->strbuf_ctxflush;
matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
do {
pci_iommu_write(flushreg, ctx);
} while(((long)pci_iommu_read(matchreg)) < 0L);
} else {
unsigned long i;
for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE)
pci_iommu_write(strbuf->strbuf_pflush, bus_addr);
}
/* Step 3: Perform flush synchronization sequence. */
pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
(void) pci_iommu_read(iommu->write_complete_reg);
while (!PCI_STC_FLUSHFLAG_SET(strbuf))
membar("#LoadLoad");
pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages);
spin_unlock_irqrestore(&iommu->lock, flags);
}
@ -749,7 +737,8 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i
struct pcidev_cookie *pcp;
struct pci_iommu *iommu;
struct pci_strbuf *strbuf;
unsigned long flags, ctx;
unsigned long flags, ctx, npages, i;
u32 bus_addr;
pcp = pdev->sysdata;
iommu = pcp->pbm->iommu;
@ -772,36 +761,14 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i
}
/* Step 2: Kick data out of streaming buffers. */
PCI_STC_FLUSHFLAG_INIT(strbuf);
if (iommu->iommu_ctxflush &&
strbuf->strbuf_ctxflush) {
unsigned long matchreg, flushreg;
flushreg = strbuf->strbuf_ctxflush;
matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
do {
pci_iommu_write(flushreg, ctx);
} while (((long)pci_iommu_read(matchreg)) < 0L);
} else {
unsigned long i, npages;
u32 bus_addr;
bus_addr = sglist[0].dma_address & IO_PAGE_MASK;
for(i = 1; i < nelems; i++)
if (!sglist[i].dma_length)
break;
i--;
npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - bus_addr) >> IO_PAGE_SHIFT;
for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE)
pci_iommu_write(strbuf->strbuf_pflush, bus_addr);
}
/* Step 3: Perform flush synchronization sequence. */
pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
(void) pci_iommu_read(iommu->write_complete_reg);
while (!PCI_STC_FLUSHFLAG_SET(strbuf))
membar("#LoadLoad");
bus_addr = sglist[0].dma_address & IO_PAGE_MASK;
for(i = 1; i < nelems; i++)
if (!sglist[i].dma_length)
break;
i--;
npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length)
- bus_addr) >> IO_PAGE_SHIFT;
pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages);
spin_unlock_irqrestore(&iommu->lock, flags);
}

View File

@ -117,19 +117,34 @@ static void iommu_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages
#define STRBUF_TAG_VALID 0x02UL
static void strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages)
static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages)
{
unsigned long n;
int limit;
iommu->strbuf_flushflag = 0UL;
while (npages--)
upa_writeq(base + (npages << IO_PAGE_SHIFT),
n = npages;
while (n--)
upa_writeq(base + (n << IO_PAGE_SHIFT),
iommu->strbuf_regs + STRBUF_PFLUSH);
/* Whoopee cushion! */
upa_writeq(__pa(&iommu->strbuf_flushflag),
iommu->strbuf_regs + STRBUF_FSYNC);
upa_readq(iommu->sbus_control_reg);
while (iommu->strbuf_flushflag == 0UL)
limit = 100000;
while (iommu->strbuf_flushflag == 0UL) {
limit--;
if (!limit)
break;
udelay(1);
membar("#LoadLoad");
}
if (!limit)
printk(KERN_WARNING "sbus_strbuf_flush: flushflag timeout "
"vaddr[%08x] npages[%ld]\n",
base, npages);
}
static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages)
@ -406,7 +421,7 @@ void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size,
spin_lock_irqsave(&iommu->lock, flags);
free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT);
strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT);
sbus_strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT);
spin_unlock_irqrestore(&iommu->lock, flags);
}
@ -569,7 +584,7 @@ void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int
iommu = sdev->bus->iommu;
spin_lock_irqsave(&iommu->lock, flags);
free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT);
strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT);
sbus_strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT);
spin_unlock_irqrestore(&iommu->lock, flags);
}
@ -581,7 +596,7 @@ void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t base, size_t
size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK));
spin_lock_irqsave(&iommu->lock, flags);
strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT);
sbus_strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT);
spin_unlock_irqrestore(&iommu->lock, flags);
}
@ -605,7 +620,7 @@ void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int
size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base;
spin_lock_irqsave(&iommu->lock, flags);
strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT);
sbus_strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT);
spin_unlock_irqrestore(&iommu->lock, flags);
}

View File

@ -383,6 +383,17 @@ static void __init process_switch(char c)
/* Use PROM debug console. */
register_console(&prom_debug_console);
break;
case 'P':
/* Force UltraSPARC-III P-Cache on. */
if (tlb_type != cheetah) {
printk("BOOT: Ignoring P-Cache force option.\n");
break;
}
cheetah_pcache_forced_on = 1;
add_taint(TAINT_MACHINE_CHECK);
cheetah_enable_pcache();
break;
default:
printk("Unknown boot switch (-%c)\n", c);
break;

View File

@ -123,6 +123,9 @@ void __init smp_callin(void)
smp_setup_percpu_timer();
if (cheetah_pcache_forced_on)
cheetah_enable_pcache();
local_irq_enable();
calibrate_delay();

View File

@ -421,6 +421,25 @@ asmlinkage void cee_log(unsigned long ce_status,
}
}
int cheetah_pcache_forced_on;
void cheetah_enable_pcache(void)
{
unsigned long dcr;
printk("CHEETAH: Enabling P-Cache on cpu %d.\n",
smp_processor_id());
__asm__ __volatile__("ldxa [%%g0] %1, %0"
: "=r" (dcr)
: "i" (ASI_DCU_CONTROL_REG));
dcr |= (DCU_PE | DCU_HPE | DCU_SPE | DCU_SL);
__asm__ __volatile__("stxa %0, [%%g0] %1\n\t"
"membar #Sync"
: /* no outputs */
: "r" (dcr), "i" (ASI_DCU_CONTROL_REG));
}
/* Cheetah error trap handling. */
static unsigned long ecache_flush_physbase;
static unsigned long ecache_flush_linesize;

View File

@ -6,6 +6,10 @@ config 64BIT
bool
default y
config TOP_ADDR
hex
default 0x80000000
config 3_LEVEL_PGTABLES
bool
default y

View File

@ -20,9 +20,17 @@
#include "os.h"
#ifdef CONFIG_NOCONFIG_CHAN
/* The printk's here are wrong because we are complaining that there is no
* output device, but printk is printing to that output device. The user will
* never see the error. printf would be better, except it can't run on a
* kernel stack because it will overflow it.
* Use printk for now since that will avoid crashing.
*/
static void *not_configged_init(char *str, int device, struct chan_opts *opts)
{
printf(KERN_ERR "Using a channel type which is configured out of "
printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(NULL);
}
@ -30,27 +38,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts)
static int not_configged_open(int input, int output, int primary, void *data,
char **dev_out)
{
printf(KERN_ERR "Using a channel type which is configured out of "
printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-ENODEV);
}
static void not_configged_close(int fd, void *data)
{
printf(KERN_ERR "Using a channel type which is configured out of "
printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
}
static int not_configged_read(int fd, char *c_out, void *data)
{
printf(KERN_ERR "Using a channel type which is configured out of "
printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-EIO);
}
static int not_configged_write(int fd, const char *buf, int len, void *data)
{
printf(KERN_ERR "Using a channel type which is configured out of "
printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-EIO);
}
@ -58,7 +66,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data)
static int not_configged_console_write(int fd, const char *buf, int len,
void *data)
{
printf(KERN_ERR "Using a channel type which is configured out of "
printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-EIO);
}
@ -66,7 +74,7 @@ static int not_configged_console_write(int fd, const char *buf, int len,
static int not_configged_window_size(int fd, void *data, unsigned short *rows,
unsigned short *cols)
{
printf(KERN_ERR "Using a channel type which is configured out of "
printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-ENODEV);
}

View File

@ -73,7 +73,6 @@ int mcast_setup(char *str, char **mac_out, void *data)
struct mcast_init *init = data;
char *port_str = NULL, *ttl_str = NULL, *remain;
char *last;
int n;
*init = ((struct mcast_init)
{ .addr = "239.192.168.1",
@ -89,13 +88,12 @@ int mcast_setup(char *str, char **mac_out, void *data)
}
if(port_str != NULL){
n = simple_strtoul(port_str, &last, 10);
init->port = simple_strtoul(port_str, &last, 10);
if((*last != '\0') || (last == port_str)){
printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
port_str);
return(0);
}
init->port = htons(n);
}
if(ttl_str != NULL){

View File

@ -38,7 +38,7 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port)
}
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = in_aton(addr);
sin->sin_port = port;
sin->sin_port = htons(port);
return(sin);
}
@ -55,28 +55,25 @@ static int mcast_open(void *data)
struct mcast_data *pri = data;
struct sockaddr_in *sin = pri->mcast_addr;
struct ip_mreq mreq;
int fd, yes = 1;
int fd = -EINVAL, yes = 1, err = -EINVAL;;
if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) {
fd = -EINVAL;
if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0))
goto out;
}
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0){
printk("mcast_open : data socket failed, errno = %d\n",
errno);
fd = -ENOMEM;
fd = -errno;
goto out;
}
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
errno);
os_close_file(fd);
fd = -EINVAL;
goto out;
goto out_close;
}
/* set ttl according to config */
@ -84,26 +81,20 @@ static int mcast_open(void *data)
sizeof(pri->ttl)) < 0) {
printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
errno);
os_close_file(fd);
fd = -EINVAL;
goto out;
goto out_close;
}
/* set LOOP, so data does get fed back to local sockets */
if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
errno);
os_close_file(fd);
fd = -EINVAL;
goto out;
goto out_close;
}
/* bind socket to mcast address */
if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
printk("mcast_open : data bind failed, errno = %d\n", errno);
os_close_file(fd);
fd = -EINVAL;
goto out;
goto out_close;
}
/* subscribe to the multicast group */
@ -117,12 +108,15 @@ static int mcast_open(void *data)
"interface on the host.\n");
printk("eth0 should be configured in order to use the "
"multicast transport.\n");
os_close_file(fd);
fd = -EINVAL;
goto out_close;
}
out:
return(fd);
return fd;
out_close:
os_close_file(fd);
return err;
}
static void mcast_close(int fd, void *data)
@ -164,14 +158,3 @@ struct net_user_info mcast_user_info = {
.delete_address = NULL,
.max_packet = MAX_PACKET - ETH_HEADER_OTHER
};
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/

View File

@ -55,7 +55,7 @@
#include "mem_kern.h"
#include "cow.h"
enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
enum ubd_req { UBD_READ, UBD_WRITE };
struct io_thread_req {
enum ubd_req op;
@ -68,8 +68,6 @@ struct io_thread_req {
unsigned long sector_mask;
unsigned long long cow_offset;
unsigned long bitmap_words[2];
int map_fd;
unsigned long long map_offset;
int error;
};
@ -122,10 +120,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
#define MAX_DEV (8)
/* Changed in early boot */
static int ubd_do_mmap = 0;
#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE
static struct block_device_operations ubd_blops = {
.owner = THIS_MODULE,
.open = ubd_open,
@ -175,12 +169,6 @@ struct ubd {
int no_cow;
struct cow cow;
struct platform_device pdev;
int map_writes;
int map_reads;
int nomap_writes;
int nomap_reads;
int write_maps;
};
#define DEFAULT_COW { \
@ -200,11 +188,6 @@ struct ubd {
.openflags = OPEN_FLAGS, \
.no_cow = 0, \
.cow = DEFAULT_COW, \
.map_writes = 0, \
.map_reads = 0, \
.nomap_writes = 0, \
.nomap_reads = 0, \
.write_maps = 0, \
}
struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
@ -314,13 +297,6 @@ static int ubd_setup_common(char *str, int *index_out)
int major;
str++;
if(!strcmp(str, "mmap")){
CHOOSE_MODE(printk("mmap not supported by the ubd "
"driver in tt mode\n"),
ubd_do_mmap = 1);
return(0);
}
if(!strcmp(str, "sync")){
global_openflags = of_sync(global_openflags);
return(0);
@ -524,7 +500,7 @@ static void ubd_handler(void)
{
struct io_thread_req req;
struct request *rq = elv_next_request(ubd_queue);
int n, err;
int n;
do_ubd = NULL;
intr_count++;
@ -538,19 +514,6 @@ static void ubd_handler(void)
return;
}
if((req.op != UBD_MMAP) &&
((req.offset != ((__u64) (rq->sector)) << 9) ||
(req.length != (rq->current_nr_sectors) << 9)))
panic("I/O op mismatch");
if(req.map_fd != -1){
err = physmem_subst_mapping(req.buffer, req.map_fd,
req.map_offset, 1);
if(err)
printk("ubd_handler - physmem_subst_mapping failed, "
"err = %d\n", -err);
}
ubd_finish(rq, req.error);
reactivate_fd(thread_fd, UBD_IRQ);
do_ubd_request(ubd_queue);
@ -583,14 +546,10 @@ static int ubd_file_size(struct ubd *dev, __u64 *size_out)
static void ubd_close(struct ubd *dev)
{
if(ubd_do_mmap)
physmem_forget_descriptor(dev->fd);
os_close_file(dev->fd);
if(dev->cow.file == NULL)
return;
if(ubd_do_mmap)
physmem_forget_descriptor(dev->cow.fd);
os_close_file(dev->cow.fd);
vfree(dev->cow.bitmap);
dev->cow.bitmap = NULL;
@ -1010,94 +969,13 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
req->bitmap_words, bitmap_len);
}
static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset)
{
__u64 sector;
unsigned char *bitmap;
int bit, i;
/* mmap must have been requested on the command line */
if(!ubd_do_mmap)
return(-1);
/* The buffer must be page aligned */
if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0)
return(-1);
/* The request must be a page long */
if((req->current_nr_sectors << 9) != PAGE_SIZE)
return(-1);
if(dev->cow.file == NULL)
return(dev->fd);
sector = offset >> 9;
bitmap = (unsigned char *) dev->cow.bitmap;
bit = ubd_test_bit(sector, bitmap);
for(i = 1; i < req->current_nr_sectors; i++){
if(ubd_test_bit(sector + i, bitmap) != bit)
return(-1);
}
if(bit || (rq_data_dir(req) == WRITE))
offset += dev->cow.data_offset;
/* The data on disk must be page aligned */
if((offset % UBD_MMAP_BLOCK_SIZE) != 0)
return(-1);
return(bit ? dev->fd : dev->cow.fd);
}
static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset,
struct request *req,
struct io_thread_req *io_req)
{
int err;
if(rq_data_dir(req) == WRITE){
/* Writes are almost no-ops since the new data is already in the
* host page cache
*/
dev->map_writes++;
if(dev->cow.file != NULL)
cowify_bitmap(io_req->offset, io_req->length,
&io_req->sector_mask, &io_req->cow_offset,
dev->cow.bitmap, dev->cow.bitmap_offset,
io_req->bitmap_words,
dev->cow.bitmap_len);
}
else {
int w;
if((dev->cow.file != NULL) && (fd == dev->cow.fd))
w = 0;
else w = dev->openflags.w;
if((dev->cow.file != NULL) && (fd == dev->fd))
offset += dev->cow.data_offset;
err = physmem_subst_mapping(req->buffer, fd, offset, w);
if(err){
printk("physmem_subst_mapping failed, err = %d\n",
-err);
return(1);
}
dev->map_reads++;
}
io_req->op = UBD_MMAP;
io_req->buffer = req->buffer;
return(0);
}
/* Called with ubd_io_lock held */
static int prepare_request(struct request *req, struct io_thread_req *io_req)
{
struct gendisk *disk = req->rq_disk;
struct ubd *dev = disk->private_data;
__u64 offset;
int len, fd;
int len;
if(req->rq_status == RQ_INACTIVE) return(1);
@ -1114,34 +992,12 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
io_req->fds[1] = dev->fd;
io_req->map_fd = -1;
io_req->cow_offset = -1;
io_req->offset = offset;
io_req->length = len;
io_req->error = 0;
io_req->sector_mask = 0;
fd = mmap_fd(req, dev, io_req->offset);
if(fd > 0){
/* If mmapping is otherwise OK, but the first access to the
* page is a write, then it's not mapped in yet. So we have
* to write the data to disk first, then we can map the disk
* page in and continue normally from there.
*/
if((rq_data_dir(req) == WRITE) && !is_remapped(req->buffer)){
io_req->map_fd = dev->fd;
io_req->map_offset = io_req->offset +
dev->cow.data_offset;
dev->write_maps++;
}
else return(prepare_mmap_request(dev, fd, io_req->offset, req,
io_req));
}
if(rq_data_dir(req) == READ)
dev->nomap_reads++;
else dev->nomap_writes++;
io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
io_req->offsets[0] = 0;
io_req->offsets[1] = dev->cow.data_offset;
@ -1229,143 +1085,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
return(-EINVAL);
}
static int ubd_check_remapped(int fd, unsigned long address, int is_write,
__u64 offset)
{
__u64 bitmap_offset;
unsigned long new_bitmap[2];
int i, err, n;
/* If it's not a write access, we can't do anything about it */
if(!is_write)
return(0);
/* We have a write */
for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){
struct ubd *dev = &ubd_dev[i];
if((dev->fd != fd) && (dev->cow.fd != fd))
continue;
/* It's a write to a ubd device */
/* This should be impossible now */
if(!dev->openflags.w){
/* It's a write access on a read-only device - probably
* shouldn't happen. If the kernel is trying to change
* something with no intention of writing it back out,
* then this message will clue us in that this needs
* fixing
*/
printk("Write access to mapped page from readonly ubd "
"device %d\n", i);
return(0);
}
/* It's a write to a writeable ubd device - it must be COWed
* because, otherwise, the page would have been mapped in
* writeable
*/
if(!dev->cow.file)
panic("Write fault on writeable non-COW ubd device %d",
i);
/* It should also be an access to the backing file since the
* COW pages should be mapped in read-write
*/
if(fd == dev->fd)
panic("Write fault on a backing page of ubd "
"device %d\n", i);
/* So, we do the write, copying the backing data to the COW
* file...
*/
err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
if(err < 0)
panic("Couldn't seek to %lld in COW file of ubd "
"device %d, err = %d",
offset + dev->cow.data_offset, i, -err);
n = os_write_file(dev->fd, (void *) address, PAGE_SIZE);
if(n != PAGE_SIZE)
panic("Couldn't copy data to COW file of ubd "
"device %d, err = %d", i, -n);
/* ... updating the COW bitmap... */
cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset,
dev->cow.bitmap, dev->cow.bitmap_offset,
new_bitmap, dev->cow.bitmap_len);
err = os_seek_file(dev->fd, bitmap_offset);
if(err < 0)
panic("Couldn't seek to %lld in COW file of ubd "
"device %d, err = %d", bitmap_offset, i, -err);
n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap));
if(n != sizeof(new_bitmap))
panic("Couldn't update bitmap of ubd device %d, "
"err = %d", i, -n);
/* Maybe we can map the COW page in, and maybe we can't. If
* it is a pre-V3 COW file, we can't, since the alignment will
* be wrong. If it is a V3 or later COW file which has been
* moved to a system with a larger page size, then maybe we
* can't, depending on the exact location of the page.
*/
offset += dev->cow.data_offset;
/* Remove the remapping, putting the original anonymous page
* back. If the COW file can be mapped in, that is done.
* Otherwise, the COW page is read in.
*/
if(!physmem_remove_mapping((void *) address))
panic("Address 0x%lx not remapped by ubd device %d",
address, i);
if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
physmem_subst_mapping((void *) address, dev->fd,
offset, 1);
else {
err = os_seek_file(dev->fd, offset);
if(err < 0)
panic("Couldn't seek to %lld in COW file of "
"ubd device %d, err = %d", offset, i,
-err);
n = os_read_file(dev->fd, (void *) address, PAGE_SIZE);
if(n != PAGE_SIZE)
panic("Failed to read page from offset %llx of "
"COW file of ubd device %d, err = %d",
offset, i, -n);
}
return(1);
}
/* It's not a write on a ubd device */
return(0);
}
static struct remapper ubd_remapper = {
.list = LIST_HEAD_INIT(ubd_remapper.list),
.proc = ubd_check_remapped,
};
static int ubd_remapper_setup(void)
{
if(ubd_do_mmap)
register_remapper(&ubd_remapper);
return(0);
}
__initcall(ubd_remapper_setup);
static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
{
struct uml_stat buf1, buf2;
@ -1568,15 +1287,6 @@ void do_io(struct io_thread_req *req)
int err;
__u64 off;
if(req->op == UBD_MMAP){
/* Touch the page to force the host to do any necessary IO to
* get it into memory
*/
n = *((volatile int *) req->buffer);
req->error = update_bitmap(req);
return;
}
nsectors = req->length / req->sectorsize;
start = 0;
do {

View File

@ -31,7 +31,6 @@ extern int sysemu_supported;
#ifdef UML_CONFIG_MODE_SKAS
#include "skas_ptregs.h"
#include "sysdep/faultinfo.h"
#define REGS_IP(r) ((r)[HOST_IP])
#define REGS_SP(r) ((r)[HOST_SP])
@ -59,6 +58,7 @@ extern int sysemu_supported;
#define PTRACE_SYSEMU_SINGLESTEP 32
#endif
#include "sysdep/faultinfo.h"
#include "choose-mode.h"
union uml_pt_regs {

View File

@ -9,8 +9,6 @@
#include "linux/in6.h"
#include "asm/uaccess.h"
extern unsigned int csum_partial_copy_from(const unsigned char *src, unsigned char *dst, int len,
int sum, int *err_ptr);
extern unsigned csum_partial(const unsigned char *buff, unsigned len,
unsigned sum);
@ -31,10 +29,15 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *
}
static __inline__
unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
int len, int sum, int *err_ptr)
unsigned int csum_partial_copy_from_user(const unsigned char *src,
unsigned char *dst, int len, int sum,
int *err_ptr)
{
return csum_partial_copy_from(src, dst, len, sum, err_ptr);
if(copy_from_user(dst, src, len)){
*err_ptr = -EFAULT;
return(-1);
}
return csum_partial(dst, len, sum);
}
/**
@ -137,15 +140,6 @@ static inline unsigned add32_with_carry(unsigned a, unsigned b)
return a;
}
#endif
extern unsigned short ip_compute_csum(unsigned char * buff, int len);
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
#endif

View File

@ -135,6 +135,7 @@ extern int mode_tt;
__CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
#define UPT_SC(r) ((r)->tt.sc)
#define UPT_SYSCALL_NR(r) __CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
#define UPT_SYSCALL_RET(r) UPT_RAX(r)
extern int user_context(unsigned long sp);
@ -196,32 +197,32 @@ struct syscall_args {
#define UPT_SET(regs, reg, val) \
({ unsigned long val; \
({ unsigned long __upt_val = val; \
switch(reg){ \
case R8: UPT_R8(regs) = val; break; \
case R9: UPT_R9(regs) = val; break; \
case R10: UPT_R10(regs) = val; break; \
case R11: UPT_R11(regs) = val; break; \
case R12: UPT_R12(regs) = val; break; \
case R13: UPT_R13(regs) = val; break; \
case R14: UPT_R14(regs) = val; break; \
case R15: UPT_R15(regs) = val; break; \
case RIP: UPT_IP(regs) = val; break; \
case RSP: UPT_SP(regs) = val; break; \
case RAX: UPT_RAX(regs) = val; break; \
case RBX: UPT_RBX(regs) = val; break; \
case RCX: UPT_RCX(regs) = val; break; \
case RDX: UPT_RDX(regs) = val; break; \
case RSI: UPT_RSI(regs) = val; break; \
case RDI: UPT_RDI(regs) = val; break; \
case RBP: UPT_RBP(regs) = val; break; \
case ORIG_RAX: UPT_ORIG_RAX(regs) = val; break; \
case CS: UPT_CS(regs) = val; break; \
case DS: UPT_DS(regs) = val; break; \
case ES: UPT_ES(regs) = val; break; \
case FS: UPT_FS(regs) = val; break; \
case GS: UPT_GS(regs) = val; break; \
case EFLAGS: UPT_EFLAGS(regs) = val; break; \
case R8: UPT_R8(regs) = __upt_val; break; \
case R9: UPT_R9(regs) = __upt_val; break; \
case R10: UPT_R10(regs) = __upt_val; break; \
case R11: UPT_R11(regs) = __upt_val; break; \
case R12: UPT_R12(regs) = __upt_val; break; \
case R13: UPT_R13(regs) = __upt_val; break; \
case R14: UPT_R14(regs) = __upt_val; break; \
case R15: UPT_R15(regs) = __upt_val; break; \
case RIP: UPT_IP(regs) = __upt_val; break; \
case RSP: UPT_SP(regs) = __upt_val; break; \
case RAX: UPT_RAX(regs) = __upt_val; break; \
case RBX: UPT_RBX(regs) = __upt_val; break; \
case RCX: UPT_RCX(regs) = __upt_val; break; \
case RDX: UPT_RDX(regs) = __upt_val; break; \
case RSI: UPT_RSI(regs) = __upt_val; break; \
case RDI: UPT_RDI(regs) = __upt_val; break; \
case RBP: UPT_RBP(regs) = __upt_val; break; \
case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \
case CS: UPT_CS(regs) = __upt_val; break; \
case DS: UPT_DS(regs) = __upt_val; break; \
case ES: UPT_ES(regs) = __upt_val; break; \
case FS: UPT_FS(regs) = __upt_val; break; \
case GS: UPT_GS(regs) = __upt_val; break; \
case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \
default : \
panic("Bad register in UPT_SET : %d\n", reg); \
break; \
@ -245,14 +246,3 @@ struct syscall_args {
CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo))
#endif
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/

View File

@ -67,7 +67,6 @@ extern void *um_kmalloc(int size);
extern int switcheroo(int fd, int prot, void *from, void *to, int size);
extern void setup_machinename(char *machine_out);
extern void setup_hostinfo(void);
extern void add_arg(char *arg);
extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
extern void init_new_thread_signals(int altstack);
extern void do_exec(int old_pid, int new_pid);

View File

@ -14,7 +14,7 @@ obj-y = config.o exec_kern.o exitcode.o \
tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \
user_util.o
obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
obj-$(CONFIG_GPROF) += gprof_syms.o
obj-$(CONFIG_GCOV) += gmon_syms.o
obj-$(CONFIG_TTY_LOG) += tty_log.o
@ -23,14 +23,10 @@ obj-$(CONFIG_SYSCALL_DEBUG) += syscall_user.o
obj-$(CONFIG_MODE_TT) += tt/
obj-$(CONFIG_MODE_SKAS) += skas/
# This needs be compiled with frame pointers regardless of how the rest of the
# kernel is built.
CFLAGS_frame.o := -fno-omit-frame-pointer
user-objs-$(CONFIG_TTY_LOG) += tty_log.o
USER_OBJS := $(user-objs-y) config.o helper.o main.o process.o tempfile.o \
time.o tty_log.o umid.o user_util.o frame.o
time.o tty_log.o umid.o user_util.o
include arch/um/scripts/Makefile.rules

78
arch/um/kernel/initrd.c Normal file
View File

@ -0,0 +1,78 @@
/*
* Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#include "linux/init.h"
#include "linux/bootmem.h"
#include "linux/initrd.h"
#include "asm/types.h"
#include "user_util.h"
#include "kern_util.h"
#include "initrd.h"
#include "init.h"
#include "os.h"
/* Changed by uml_initrd_setup, which is a setup */
static char *initrd __initdata = NULL;
static int __init read_initrd(void)
{
void *area;
long long size;
int err;
if(initrd == NULL) return 0;
err = os_file_size(initrd, &size);
if(err) return 0;
area = alloc_bootmem(size);
if(area == NULL) return 0;
if(load_initrd(initrd, area, size) == -1) return 0;
initrd_start = (unsigned long) area;
initrd_end = initrd_start + size;
return 0;
}
__uml_postsetup(read_initrd);
static int __init uml_initrd_setup(char *line, int *add)
{
initrd = line;
return 0;
}
__uml_setup("initrd=", uml_initrd_setup,
"initrd=<initrd image>\n"
" This is used to boot UML from an initrd image. The argument is the\n"
" name of the file containing the image.\n\n"
);
int load_initrd(char *filename, void *buf, int size)
{
int fd, n;
fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
if(fd < 0){
printk("Opening '%s' failed - err = %d\n", filename, -fd);
return(-1);
}
n = os_read_file(fd, buf, size);
if(n != size){
printk("Read of %d bytes from '%s' failed, err = %d\n", size,
filename, -n);
return(-1);
}
os_close_file(fd);
return(0);
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/

View File

@ -236,9 +236,15 @@ static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
(*prev)->fd, pollfds[i].fd);
goto out;
}
memcpy(&pollfds[i], &pollfds[i + 1],
(pollfds_num - i - 1) * sizeof(pollfds[0]));
pollfds_num--;
/* This moves the *whole* array after pollfds[i] (though
* it doesn't spot as such)! */
memmove(&pollfds[i], &pollfds[i + 1],
(pollfds_num - i) * sizeof(pollfds[0]));
if(last_irq_ptr == &old_fd->next)
last_irq_ptr = prev;
*prev = (*prev)->next;

View File

@ -57,6 +57,7 @@ EXPORT_SYMBOL(copy_to_user_tt);
EXPORT_SYMBOL(strncpy_from_user_skas);
EXPORT_SYMBOL(copy_to_user_skas);
EXPORT_SYMBOL(copy_from_user_skas);
EXPORT_SYMBOL(clear_user_skas);
#endif
EXPORT_SYMBOL(uml_strdup);

View File

@ -100,12 +100,37 @@ void mem_init(void)
#endif
}
/*
* Create a page table and place a pointer to it in a middle page
* directory entry.
*/
static void __init one_page_table_init(pmd_t *pmd)
{
if (pmd_none(*pmd)) {
pte_t *pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
set_pmd(pmd, __pmd(_KERNPG_TABLE +
(unsigned long) __pa(pte)));
if (pte != pte_offset_kernel(pmd, 0))
BUG();
}
}
static void __init one_md_table_init(pud_t *pud)
{
#ifdef CONFIG_3_LEVEL_PGTABLES
pmd_t *pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
set_pud(pud, __pud(_KERNPG_TABLE + (unsigned long) __pa(pmd_table)));
if (pmd_table != pmd_offset(pud, 0))
BUG();
#endif
}
static void __init fixrange_init(unsigned long start, unsigned long end,
pgd_t *pgd_base)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
int i, j;
unsigned long vaddr;
@ -115,15 +140,12 @@ static void __init fixrange_init(unsigned long start, unsigned long end,
pgd = pgd_base + i;
for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) {
pmd = (pmd_t *)pgd;
pud = pud_offset(pgd, vaddr);
if (pud_none(*pud))
one_md_table_init(pud);
pmd = pmd_offset(pud, vaddr);
for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
if (pmd_none(*pmd)) {
pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
set_pmd(pmd, __pmd(_KERNPG_TABLE +
(unsigned long) __pa(pte)));
if (pte != pte_offset_kernel(pmd, 0))
BUG();
}
one_page_table_init(pmd);
vaddr += PMD_SIZE;
}
j = 0;

View File

@ -115,16 +115,6 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
return(pid);
}
void switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk)
{
int cpu = smp_processor_id();
if (prev != next)
cpu_clear(cpu, prev->cpu_vm_mask);
cpu_set(cpu, next->cpu_vm_mask);
}
void set_current(void *t)
{
struct task_struct *task = t;
@ -152,7 +142,6 @@ void release_thread(struct task_struct *task)
void exit_thread(void)
{
CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
unprotect_stack((unsigned long) current_thread);
}
@ -476,12 +465,21 @@ int singlestepping(void * t)
return 2;
}
/*
* Only x86 and x86_64 have an arch_align_stack().
* All other arches have "#define arch_align_stack(x) (x)"
* in their asm/system.h
* As this is included in UML from asm-um/system-generic.h,
* we can use it to behave as the subarch does.
*/
#ifndef arch_align_stack
unsigned long arch_align_stack(unsigned long sp)
{
if (randomize_va_space)
sp -= get_random_int() % 8192;
return sp & ~0xf;
}
#endif
/*

View File

@ -19,15 +19,30 @@
#include "skas_ptrace.h"
#include "sysdep/ptrace.h"
static inline void set_singlestepping(struct task_struct *child, int on)
{
if (on)
child->ptrace |= PT_DTRACE;
else
child->ptrace &= ~PT_DTRACE;
child->thread.singlestep_syscall = 0;
#ifdef SUBARCH_SET_SINGLESTEPPING
SUBARCH_SET_SINGLESTEPPING(child, on);
#endif
}
/*
* Called by kernel/ptrace.c when detaching..
*/
void ptrace_disable(struct task_struct *child)
{
child->ptrace &= ~PT_DTRACE;
child->thread.singlestep_syscall = 0;
set_singlestepping(child,0);
}
extern int peek_user(struct task_struct * child, long addr, long data);
extern int poke_user(struct task_struct * child, long addr, long data);
long sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
@ -67,6 +82,10 @@ long sys_ptrace(long request, long pid, long addr, long data)
goto out_tsk;
}
#ifdef SUBACH_PTRACE_SPECIAL
SUBARCH_PTRACE_SPECIAL(child,request,addr,data);
#endif
ret = ptrace_check_attach(child, request == PTRACE_KILL);
if (ret < 0)
goto out_tsk;
@ -87,28 +106,9 @@ long sys_ptrace(long request, long pid, long addr, long data)
}
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
unsigned long tmp;
ret = -EIO;
if ((addr & 3) || addr < 0)
break;
tmp = 0; /* Default return condition */
if(addr < MAX_REG_OFFSET){
tmp = getreg(child, addr);
}
#if defined(CONFIG_UML_X86) && !defined(CONFIG_64BIT)
else if((addr >= offsetof(struct user, u_debugreg[0])) &&
(addr <= offsetof(struct user, u_debugreg[7]))){
addr -= offsetof(struct user, u_debugreg[0]);
addr = addr >> 2;
tmp = child->thread.arch.debugregs[addr];
}
#endif
ret = put_user(tmp, (unsigned long __user *) data);
break;
}
case PTRACE_PEEKUSR:
ret = peek_user(child, addr, data);
break;
/* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */
@ -121,26 +121,8 @@ long sys_ptrace(long request, long pid, long addr, long data)
break;
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
ret = -EIO;
if ((addr & 3) || addr < 0)
break;
if (addr < MAX_REG_OFFSET) {
ret = putreg(child, addr, data);
break;
}
#if defined(CONFIG_UML_X86) && !defined(CONFIG_64BIT)
else if((addr >= offsetof(struct user, u_debugreg[0])) &&
(addr <= offsetof(struct user, u_debugreg[7]))){
addr -= offsetof(struct user, u_debugreg[0]);
addr = addr >> 2;
if((addr == 4) || (addr == 5)) break;
child->thread.arch.debugregs[addr] = data;
ret = 0;
}
#endif
break;
ret = poke_user(child, addr, data);
break;
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
@ -148,8 +130,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
if (!valid_signal(data))
break;
child->ptrace &= ~PT_DTRACE;
child->thread.singlestep_syscall = 0;
set_singlestepping(child, 0);
if (request == PTRACE_SYSCALL) {
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
}
@ -172,8 +153,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
child->ptrace &= ~PT_DTRACE;
child->thread.singlestep_syscall = 0;
set_singlestepping(child, 0);
child->exit_code = SIGKILL;
wake_up_process(child);
break;
@ -184,8 +164,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
if (!valid_signal(data))
break;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->ptrace |= PT_DTRACE;
child->thread.singlestep_syscall = 0;
set_singlestepping(child, 1);
child->exit_code = data;
/* give it a chance to run. */
wake_up_process(child);

View File

@ -18,7 +18,6 @@ extern int copy_thread_skas(int nr, unsigned long clone_flags,
unsigned long sp, unsigned long stack_top,
struct task_struct *p, struct pt_regs *regs);
extern void release_thread_skas(struct task_struct *task);
extern void exit_thread_skas(void);
extern void initial_thread_cb_skas(void (*proc)(void *), void *arg);
extern void init_idle_skas(void);
extern void flush_tlb_kernel_range_skas(unsigned long start,

View File

@ -18,8 +18,8 @@
((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
static inline int __deprecated verify_area_skas(int type, const void * addr,
unsigned long size)
static inline int verify_area_skas(int type, const void * addr,
unsigned long size)
{
return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
}

View File

@ -201,6 +201,11 @@ void userspace(union uml_pt_regs *regs)
}
}
}
#define INIT_JMP_NEW_THREAD 0
#define INIT_JMP_REMOVE_SIGSTACK 1
#define INIT_JMP_CALLBACK 2
#define INIT_JMP_HALT 3
#define INIT_JMP_REBOOT 4
void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
void (*handler)(int))
@ -236,7 +241,7 @@ void thread_wait(void *sw, void *fb)
*switch_buf = &buf;
fork_buf = fb;
if(sigsetjmp(buf, 1) == 0)
siglongjmp(*fork_buf, 1);
siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK);
}
void switch_threads(void *me, void *next)
@ -266,21 +271,25 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
*fork_buf_ptr = &initial_jmpbuf;
n = sigsetjmp(initial_jmpbuf, 1);
if(n == 0)
new_thread_proc((void *) stack, new_thread_handler);
else if(n == 1)
remove_sigstack();
else if(n == 2){
switch(n){
case INIT_JMP_NEW_THREAD:
new_thread_proc((void *) stack, new_thread_handler);
break;
case INIT_JMP_REMOVE_SIGSTACK:
remove_sigstack();
break;
case INIT_JMP_CALLBACK:
(*cb_proc)(cb_arg);
siglongjmp(*cb_back, 1);
}
else if(n == 3){
break;
case INIT_JMP_HALT:
kmalloc_ok = 0;
return(0);
}
else if(n == 4){
case INIT_JMP_REBOOT:
kmalloc_ok = 0;
return(1);
default:
panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
}
siglongjmp(**switch_buf, 1);
}
@ -305,7 +314,7 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
block_signals();
if(sigsetjmp(here, 1) == 0)
siglongjmp(initial_jmpbuf, 2);
siglongjmp(initial_jmpbuf, INIT_JMP_CALLBACK);
unblock_signals();
cb_proc = NULL;
@ -316,13 +325,13 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
void halt_skas(void)
{
block_signals();
siglongjmp(initial_jmpbuf, 3);
siglongjmp(initial_jmpbuf, INIT_JMP_HALT);
}
void reboot_skas(void)
{
block_signals();
siglongjmp(initial_jmpbuf, 4);
siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT);
}
void switch_mm_skas(int mm_fd)

View File

@ -83,10 +83,6 @@ void release_thread_skas(struct task_struct *task)
{
}
void exit_thread_skas(void)
{
}
void fork_handler(int sig)
{
change_sig(SIGUSR1, 1);

View File

@ -29,9 +29,12 @@ static unsigned long maybe_map(unsigned long virt, int is_write)
if(IS_ERR(phys) || (is_write && !pte_write(pte))){
err = handle_page_fault(virt, 0, is_write, 1, &dummy_code);
if(err)
return(0);
return(-1UL);
phys = um_virt_to_phys(current, virt, NULL);
}
if(IS_ERR(phys))
phys = (void *) -1;
return((unsigned long) phys);
}
@ -42,7 +45,7 @@ static int do_op(unsigned long addr, int len, int is_write,
int n;
addr = maybe_map(addr, is_write);
if(addr == -1)
if(addr == -1UL)
return(-1);
page = phys_to_page(addr);

View File

@ -17,7 +17,6 @@
#include "linux/utime.h"
#include "asm/mman.h"
#include "asm/uaccess.h"
#include "asm/ipc.h"
#include "kern_util.h"
#include "user_util.h"
#include "sysdep/syscalls.h"

View File

@ -48,7 +48,7 @@ int handle_page_fault(unsigned long address, unsigned long ip,
goto good_area;
else if(!(vma->vm_flags & VM_GROWSDOWN))
goto out;
else if(!ARCH_IS_STACKGROW(address))
else if(is_user && !ARCH_IS_STACKGROW(address))
goto out;
else if(expand_stack(vma, address))
goto out;
@ -57,10 +57,11 @@ int handle_page_fault(unsigned long address, unsigned long ip,
*code_out = SEGV_ACCERR;
if(is_write && !(vma->vm_flags & VM_WRITE))
goto out;
if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto out;
page = address & PAGE_MASK;
pgd = pgd_offset(mm, page);
pud = pud_offset(pgd, page);
pmd = pmd_offset(pud, page);
do {
survive:
switch (handle_mm_fault(mm, vma, address, is_write)){
@ -106,33 +107,6 @@ int handle_page_fault(unsigned long address, unsigned long ip,
goto out;
}
LIST_HEAD(physmem_remappers);
void register_remapper(struct remapper *info)
{
list_add(&info->list, &physmem_remappers);
}
static int check_remapped_addr(unsigned long address, int is_write)
{
struct remapper *remapper;
struct list_head *ele;
__u64 offset;
int fd;
fd = phys_mapping(__pa(address), &offset);
if(fd == -1)
return(0);
list_for_each(ele, &physmem_remappers){
remapper = list_entry(ele, struct remapper, list);
if((*remapper->proc)(fd, address, is_write, offset))
return(1);
}
return(0);
}
/*
* We give a *copy* of the faultinfo in the regs to segv.
* This must be done, since nesting SEGVs could overwrite
@ -151,8 +125,6 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
flush_tlb_kernel_vm();
return(0);
}
else if(check_remapped_addr(address & PAGE_MASK, is_write))
return(0);
else if(current->mm == NULL)
panic("Segfault with no mm");
err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);

View File

@ -19,7 +19,6 @@ extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
unsigned long stack_top, struct task_struct *p,
struct pt_regs *regs);
extern void release_thread_tt(struct task_struct *task);
extern void exit_thread_tt(void);
extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
extern void init_idle_tt(void);
extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end);

View File

@ -33,8 +33,8 @@ extern unsigned long uml_physmem;
(((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
(under_task_size(addr, size) || is_stack(addr, size))))
static inline int __deprecated verify_area_tt(int type, const void * addr,
unsigned long size)
static inline int verify_area_tt(int type, const void * addr,
unsigned long size)
{
return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
}

View File

@ -12,6 +12,7 @@ EXPORT_SYMBOL(__do_copy_to_user);
EXPORT_SYMBOL(__do_strncpy_from_user);
EXPORT_SYMBOL(__do_strnlen_user);
EXPORT_SYMBOL(__do_clear_user);
EXPORT_SYMBOL(clear_user_tt);
EXPORT_SYMBOL(tracing_pid);
EXPORT_SYMBOL(honeypot);

View File

@ -21,14 +21,8 @@ void before_mem_tt(unsigned long brk_start)
remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1);
}
#ifdef CONFIG_HOST_2G_2G
#define TOP 0x80000000
#else
#define TOP 0xc0000000
#endif
#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
#define START (TOP - SIZE)
#define START (CONFIG_TOP_ADDR - SIZE)
unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
unsigned long *task_size_out)

View File

@ -65,8 +65,7 @@ void *switch_to_tt(void *prev, void *next, void *last)
panic("write of switch_pipe failed, err = %d", -err);
reading = 1;
if((from->exit_state == EXIT_ZOMBIE) ||
(from->exit_state == EXIT_DEAD))
if(from->thread.mode.tt.switch_pipe[0] == -1)
os_kill_process(os_getpid(), 0);
err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c));
@ -81,8 +80,7 @@ void *switch_to_tt(void *prev, void *next, void *last)
* in case it has not already killed itself.
*/
prev_sched = current->thread.prev_sched;
if((prev_sched->exit_state == EXIT_ZOMBIE) ||
(prev_sched->exit_state == EXIT_DEAD))
if(prev_sched->thread.mode.tt.switch_pipe[0] == -1)
os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1);
change_sig(SIGVTALRM, vtalrm);
@ -101,14 +99,18 @@ void release_thread_tt(struct task_struct *task)
{
int pid = task->thread.mode.tt.extern_pid;
/*
* We first have to kill the other process, before
* closing its switch_pipe. Else it might wake up
* and receive "EOF" before we could kill it.
*/
if(os_getpid() != pid)
os_kill_process(pid, 0);
}
void exit_thread_tt(void)
{
os_close_file(current->thread.mode.tt.switch_pipe[0]);
os_close_file(current->thread.mode.tt.switch_pipe[1]);
os_close_file(task->thread.mode.tt.switch_pipe[0]);
os_close_file(task->thread.mode.tt.switch_pipe[1]);
/* use switch_pipe as flag: thread is released */
task->thread.mode.tt.switch_pipe[0] = -1;
}
void suspend_new_thread(int fd)

View File

@ -63,6 +63,10 @@ void do_syscall(void *task, int pid, int local_using_sysemu)
UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs);
#ifdef UPT_ORIGGPR2
UPT_ORIGGPR2(TASK_REGS(task)) = REGS_ORIGGPR2(proc_regs);
#endif
if(((unsigned long *) PT_IP(proc_regs) >= &_stext) &&
((unsigned long *) PT_IP(proc_regs) <= &_etext))
tracer_panic("I'm tracing myself and I can't get out");

View File

@ -23,6 +23,7 @@
#include "asm/ptrace.h"
#include "asm/elf.h"
#include "asm/user.h"
#include "asm/setup.h"
#include "ubd_user.h"
#include "asm/current.h"
#include "asm/setup.h"
@ -42,9 +43,9 @@
#define DEFAULT_COMMAND_LINE "root=98:0"
/* Changed in linux_main and setup_arch, which run before SMP is started */
char command_line[COMMAND_LINE_SIZE] = { 0 };
static char command_line[COMMAND_LINE_SIZE] = { 0 };
void add_arg(char *arg)
static void add_arg(char *arg)
{
if (strlen(command_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) {
printf("add_arg: Too many command line arguments!\n");
@ -449,7 +450,7 @@ void __init setup_arch(char **cmdline_p)
{
notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
paging_init();
strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
*cmdline_p = command_line;
setup_hostinfo();
}

View File

@ -73,6 +73,8 @@ SECTIONS
.got : { *(.got.plt) *(.got) }
.dynamic : { *(.dynamic) }
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */

View File

@ -9,11 +9,11 @@ USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
SYMLINKS = bitops.c semaphore.c highmem.c module.c
include arch/um/scripts/Makefile.rules
bitops.c-dir = lib
semaphore.c-dir = kernel
highmem.c-dir = mm
module.c-dir = kernel
subdir- := util
include arch/um/scripts/Makefile.rules

View File

@ -1,5 +1,7 @@
#include "linux/delay.h"
#include "asm/param.h"
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <asm/param.h>
void __delay(unsigned long time)
{
@ -20,13 +22,19 @@ void __udelay(unsigned long usecs)
int i, n;
n = (loops_per_jiffy * HZ * usecs) / MILLION;
for(i=0;i<n;i++) ;
for(i=0;i<n;i++)
cpu_relax();
}
EXPORT_SYMBOL(__udelay);
void __const_udelay(unsigned long usecs)
{
int i, n;
n = (loops_per_jiffy * HZ * usecs) / MILLION;
for(i=0;i<n;i++) ;
for(i=0;i<n;i++)
cpu_relax();
}
EXPORT_SYMBOL(__const_udelay);

View File

@ -73,6 +73,25 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
return 0;
}
int poke_user(struct task_struct *child, long addr, long data)
{
if ((addr & 3) || addr < 0)
return -EIO;
if (addr < MAX_REG_OFFSET)
return putreg(child, addr, data);
else if((addr >= offsetof(struct user, u_debugreg[0])) &&
(addr <= offsetof(struct user, u_debugreg[7]))){
addr -= offsetof(struct user, u_debugreg[0]);
addr = addr >> 2;
if((addr == 4) || (addr == 5)) return -EIO;
child->thread.arch.debugregs[addr] = data;
return 0;
}
return -EIO;
}
unsigned long getreg(struct task_struct *child, int regno)
{
unsigned long retval = ~0UL;
@ -93,6 +112,27 @@ unsigned long getreg(struct task_struct *child, int regno)
return retval;
}
int peek_user(struct task_struct *child, long addr, long data)
{
/* read the word at location addr in the USER area. */
unsigned long tmp;
if ((addr & 3) || addr < 0)
return -EIO;
tmp = 0; /* Default return condition */
if(addr < MAX_REG_OFFSET){
tmp = getreg(child, addr);
}
else if((addr >= offsetof(struct user, u_debugreg[0])) &&
(addr <= offsetof(struct user, u_debugreg[7]))){
addr -= offsetof(struct user, u_debugreg[0]);
addr = addr >> 2;
tmp = child->thread.arch.debugregs[addr];
}
return put_user(tmp, (unsigned long *) data);
}
struct i387_fxsave_struct {
unsigned short cwd;
unsigned short swd;

View File

@ -8,6 +8,25 @@ int putreg(struct task_struct *child, unsigned long regno,
return 0;
}
int poke_user(struct task_struct *child, long addr, long data)
{
if ((addr & 3) || addr < 0)
return -EIO;
if (addr < MAX_REG_OFFSET)
return putreg(child, addr, data);
else if((addr >= offsetof(struct user, u_debugreg[0])) &&
(addr <= offsetof(struct user, u_debugreg[7]))){
addr -= offsetof(struct user, u_debugreg[0]);
addr = addr >> 2;
if((addr == 4) || (addr == 5)) return -EIO;
child->thread.arch.debugregs[addr] = data;
return 0;
}
return -EIO;
}
unsigned long getreg(struct task_struct *child, unsigned long regno)
{
unsigned long retval = ~0UL;
@ -16,6 +35,27 @@ unsigned long getreg(struct task_struct *child, unsigned long regno)
return retval;
}
int peek_user(struct task_struct *child, long addr, long data)
{
/* read the word at location addr in the USER area. */
unsigned long tmp;
if ((addr & 3) || addr < 0)
return -EIO;
tmp = 0; /* Default return condition */
if(addr < MAX_REG_OFFSET){
tmp = getreg(child, addr);
}
else if((addr >= offsetof(struct user, u_debugreg[0])) &&
(addr <= offsetof(struct user, u_debugreg[7]))){
addr -= offsetof(struct user, u_debugreg[0]);
addr = addr >> 2;
tmp = child->thread.arch.debugregs[addr];
}
return put_user(tmp, (unsigned long *) data);
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically

View File

@ -14,11 +14,11 @@ obj-$(CONFIG_MODULES) += module.o um_module.o
USER_OBJS := ptrace_user.o sigcontext.o
include arch/um/scripts/Makefile.rules
SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \
semaphore.c thunk.S module.c
include arch/um/scripts/Makefile.rules
bitops.c-dir = lib
csum-copy.S-dir = lib
csum-partial.c-dir = lib
@ -28,6 +28,4 @@ semaphore.c-dir = kernel
thunk.S-dir = lib
module.c-dir = kernel
CFLAGS_csum-partial.o := -Dcsum_partial=arch_csum_partial
subdir- := util

View File

@ -5,40 +5,37 @@
* Licensed under the GPL
*/
#include "linux/delay.h"
#include "asm/processor.h"
#include "asm/param.h"
#include <linux/module.h>
#include <linux/delay.h>
#include <asm/processor.h>
#include <asm/param.h>
void __delay(unsigned long loops)
{
unsigned long i;
for(i = 0; i < loops; i++) ;
for(i = 0; i < loops; i++)
cpu_relax();
}
void __udelay(unsigned long usecs)
{
int i, n;
unsigned long i, n;
n = (loops_per_jiffy * HZ * usecs) / MILLION;
for(i=0;i<n;i++) ;
for(i=0;i<n;i++)
cpu_relax();
}
EXPORT_SYMBOL(__udelay);
void __const_udelay(unsigned long usecs)
{
int i, n;
unsigned long i, n;
n = (loops_per_jiffy * HZ * usecs) / MILLION;
for(i=0;i<n;i++) ;
for(i=0;i<n;i++)
cpu_relax();
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
EXPORT_SYMBOL(__const_udelay);

View File

@ -16,5 +16,4 @@ EXPORT_SYMBOL(__up_wakeup);
EXPORT_SYMBOL(__memcpy);
/* Networking helper routines. */
/*EXPORT_SYMBOL(csum_partial_copy_from);
EXPORT_SYMBOL(csum_partial_copy_to);*/
EXPORT_SYMBOL(ip_compute_csum);

View File

@ -5,10 +5,11 @@
*/
#define __FRAME_OFFSETS
#include "asm/ptrace.h"
#include "linux/sched.h"
#include "linux/errno.h"
#include "asm/elf.h"
#include <asm/ptrace.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
#include <asm/elf.h>
/* XXX x86_64 */
unsigned long not_ss;
@ -62,6 +63,27 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
return 0;
}
int poke_user(struct task_struct *child, long addr, long data)
{
if ((addr & 3) || addr < 0)
return -EIO;
if (addr < MAX_REG_OFFSET)
return putreg(child, addr, data);
#if 0 /* Need x86_64 debugregs handling */
else if((addr >= offsetof(struct user, u_debugreg[0])) &&
(addr <= offsetof(struct user, u_debugreg[7]))){
addr -= offsetof(struct user, u_debugreg[0]);
addr = addr >> 2;
if((addr == 4) || (addr == 5)) return -EIO;
child->thread.arch.debugregs[addr] = data;
return 0;
}
#endif
return -EIO;
}
unsigned long getreg(struct task_struct *child, int regno)
{
unsigned long retval = ~0UL;
@ -84,6 +106,29 @@ unsigned long getreg(struct task_struct *child, int regno)
return retval;
}
int peek_user(struct task_struct *child, long addr, long data)
{
/* read the word at location addr in the USER area. */
unsigned long tmp;
if ((addr & 3) || addr < 0)
return -EIO;
tmp = 0; /* Default return condition */
if(addr < MAX_REG_OFFSET){
tmp = getreg(child, addr);
}
#if 0 /* Need x86_64 debugregs handling */
else if((addr >= offsetof(struct user, u_debugreg[0])) &&
(addr <= offsetof(struct user, u_debugreg[7]))){
addr -= offsetof(struct user, u_debugreg[0]);
addr = addr >> 2;
tmp = child->thread.arch.debugregs[addr];
}
#endif
return put_user(tmp, (unsigned long *) data);
}
void arch_switch(void)
{
/* XXX

View File

@ -168,7 +168,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
frame = (struct rt_sigframe __user *)
round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8;
frame -= 128;
((unsigned char *) frame) -= 128;
if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
goto out;

View File

@ -15,6 +15,7 @@
#include "asm/unistd.h"
#include "asm/prctl.h" /* XXX This should get the constants from libc */
#include "choose-mode.h"
#include "kern.h"
asmlinkage long sys_uname64(struct new_utsname __user * name)
{
@ -44,6 +45,8 @@ long sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
#ifdef CONFIG_MODE_SKAS
extern int userspace_pid[];
#include "skas_ptrace.h"
long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
{
struct ptrace_ldt ldt;

View File

@ -3,6 +3,14 @@
#include <signal.h>
#define __FRAME_OFFSETS
#include <asm/ptrace.h>
#include <asm/types.h>
/* For some reason, x86_64 defines u64 and u32 only in <pci/types.h>, which I
* refuse to include here, even though they're used throughout the headers.
* These are used in asm/user.h, and that include can't be avoided because of
* the sizeof(struct user_regs_struct) below.
*/
typedef __u64 u64;
typedef __u32 u32;
#include <asm/user.h>
#define DEFINE(sym, val) \

View File

@ -303,6 +303,20 @@ config HPET_TIMER
as it is off-chip. You can find the HPET spec at
<http://www.intel.com/labs/platcomp/hpet/hpetspec.htm>.
config X86_PM_TIMER
bool "PM timer"
default y
help
Support the ACPI PM timer for time keeping. This is slow,
but is useful on some chipsets without HPET on systems with more
than one CPU. On a single processor or single socket multi core
system it is normally not required.
When the PM timer is active 64bit vsyscalls are disabled
and should not be enabled (/proc/sys/kernel/vsyscall64 should
not be changed).
The kernel selects the PM timer only as a last resort, so it is
useful to enable just in case.
config HPET_EMULATE_RTC
bool "Provide RTC interrupt"
depends on HPET_TIMER && RTC=y

View File

@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.11-bk7
# Sat Mar 12 23:43:44 2005
# Linux kernel version: 2.6.12-rc4
# Fri May 13 06:39:11 2005
#
CONFIG_X86_64=y
CONFIG_64BIT=y
@ -11,8 +11,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_X86_CMPXCHG=y
CONFIG_EARLY_PRINTK=y
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_IOMAP=y
@ -22,6 +20,7 @@ CONFIG_GENERIC_IOMAP=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
@ -33,7 +32,6 @@ CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
CONFIG_LOG_BUF_SHIFT=18
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
@ -43,10 +41,11 @@ CONFIG_IKCONFIG_PROC=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
CONFIG_CC_ALIGN_FUNCTIONS=0
CONFIG_CC_ALIGN_LABELS=0
@ -93,6 +92,9 @@ CONFIG_DISCONTIGMEM=y
CONFIG_NUMA=y
CONFIG_HAVE_DEC_LOCK=y
CONFIG_NR_CPUS=8
CONFIG_HPET_TIMER=y
CONFIG_X86_PM_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
CONFIG_GART_IOMMU=y
CONFIG_SWIOTLB=y
CONFIG_X86_MCE=y
@ -100,6 +102,7 @@ CONFIG_X86_MCE_INTEL=y
CONFIG_SECCOMP=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_ISA_DMA_API=y
#
# Power management options
@ -129,7 +132,7 @@ CONFIG_ACPI_NUMA=y
# CONFIG_ACPI_IBM is not set
CONFIG_ACPI_TOSHIBA=y
CONFIG_ACPI_BLACKLIST_YEAR=2001
CONFIG_ACPI_DEBUG=y
# CONFIG_ACPI_DEBUG is not set
CONFIG_ACPI_BUS=y
CONFIG_ACPI_EC=y
CONFIG_ACPI_POWER=y
@ -141,6 +144,7 @@ CONFIG_ACPI_SYSTEM=y
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=y
# CONFIG_CPU_FREQ_DEBUG is not set
CONFIG_CPU_FREQ_STAT=y
# CONFIG_CPU_FREQ_STAT_DETAILS is not set
@ -150,7 +154,6 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_TABLE=y
#
# CPUFreq processor drivers
@ -164,6 +167,7 @@ CONFIG_X86_ACPI_CPUFREQ=y
# shared options
#
CONFIG_X86_ACPI_CPUFREQ_PROC_INTF=y
# CONFIG_X86_SPEEDSTEP_LIB is not set
#
# Bus options (PCI etc.)
@ -172,19 +176,17 @@ CONFIG_PCI=y
CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
CONFIG_UNORDERED_IO=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_PCI_MSI=y
# CONFIG_PCI_LEGACY_PROC is not set
# CONFIG_PCI_NAMES is not set
# CONFIG_PCI_DEBUG is not set
#
# PCCARD (PCMCIA/CardBus) support
#
# CONFIG_PCCARD is not set
#
# PC-card bridges
#
#
# PCI Hotplug Support
#
@ -254,7 +256,7 @@ CONFIG_LBD=y
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
# CONFIG_IOSCHED_AS is not set
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
# CONFIG_ATA_OVER_ETH is not set
@ -308,7 +310,8 @@ CONFIG_BLK_DEV_AMD74XX=y
CONFIG_BLK_DEV_PIIX=y
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
CONFIG_BLK_DEV_PDC202XX_NEW=y
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIIMAGE is not set
# CONFIG_BLK_DEV_SIS5513 is not set
@ -353,7 +356,7 @@ CONFIG_BLK_DEV_SD=y
#
# SCSI low-level drivers
#
CONFIG_BLK_DEV_3W_XXXX_RAID=y
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AACRAID is not set
@ -384,7 +387,6 @@ CONFIG_SCSI_SATA_VIA=y
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
@ -392,7 +394,6 @@ CONFIG_SCSI_SATA_VIA=y
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_QLOGIC_ISP is not set
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
CONFIG_SCSI_QLA2XXX=y
@ -401,6 +402,7 @@ CONFIG_SCSI_QLA2XXX=y
# CONFIG_SCSI_QLA2300 is not set
# CONFIG_SCSI_QLA2322 is not set
# CONFIG_SCSI_QLA6312 is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_DEBUG is not set
@ -437,7 +439,6 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
# CONFIG_NETLINK_DEV is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
@ -502,7 +503,7 @@ CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
CONFIG_TUN=y
#
# ARCnet devices
@ -525,8 +526,7 @@ CONFIG_MII=y
# CONFIG_HP100 is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
CONFIG_AMD8111_ETH=y
# CONFIG_AMD8111E_NAPI is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_B44 is not set
CONFIG_FORCEDETH=y
@ -536,7 +536,7 @@ CONFIG_FORCEDETH=y
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
CONFIG_8139CP=m
CONFIG_8139CP=y
CONFIG_8139TOO=y
# CONFIG_8139TOO_PIO is not set
# CONFIG_8139TOO_TUNE_TWISTER is not set
@ -671,6 +671,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@ -696,6 +697,7 @@ CONFIG_RTC=y
#
CONFIG_AGP=y
CONFIG_AGP_AMD64=y
CONFIG_AGP_INTEL=y
# CONFIG_DRM is not set
# CONFIG_MWAVE is not set
CONFIG_RAW_DRIVER=y
@ -703,7 +705,7 @@ CONFIG_HPET=y
# CONFIG_HPET_RTC_IRQ is not set
CONFIG_HPET_MMAP=y
CONFIG_MAX_RAW_DEVS=256
CONFIG_HANGCHECK_TIMER=y
# CONFIG_HANGCHECK_TIMER is not set
#
# TPM devices
@ -786,6 +788,8 @@ CONFIG_SOUND_ICH=y
#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
@ -797,8 +801,6 @@ CONFIG_USB_DEVICEFS=y
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_SUSPEND is not set
# CONFIG_USB_OTG is not set
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
#
# USB Host Controller Drivers
@ -826,7 +828,6 @@ CONFIG_USB_PRINTER=y
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_RW_DETECT is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
@ -965,7 +966,7 @@ CONFIG_AUTOFS_FS=y
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
CONFIG_JOLIET=y
# CONFIG_ZISOFS is not set
# CONFIG_UDF_FS is not set
@ -1092,9 +1093,10 @@ CONFIG_OPROFILE=y
#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_PRINTK_TIME is not set
CONFIG_LOG_BUF_SHIFT=18
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set

View File

@ -28,6 +28,7 @@ obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o
obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o
obj-$(CONFIG_SWIOTLB) += swiotlb.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o
obj-$(CONFIG_MODULES) += module.o

View File

@ -33,6 +33,7 @@
#include <asm/mpspec.h>
#include <asm/pgalloc.h>
#include <asm/mach_apic.h>
#include <asm/nmi.h>
int apic_verbosity;
@ -925,7 +926,7 @@ __init int oem_force_hpet_timer(void)
unsigned id;
DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS);
bitmap_empty(clustermap, NUM_APIC_CLUSTERS);
bitmap_zero(clustermap, NUM_APIC_CLUSTERS);
for (i = 0; i < NR_CPUS; i++) {
id = bios_cpu_apicid[i];
@ -1056,7 +1057,7 @@ int __init APIC_init_uniprocessor (void)
nr_ioapics = 0;
#endif
setup_boot_APIC_clock();
check_nmi_watchdog();
return 0;
}

View File

@ -220,13 +220,18 @@ sysret_careful:
jmp sysret_check
/* Handle a signal */
/* edx: work flags (arg3) */
sysret_signal:
sti
testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
jz 1f
/* Really a signal */
/* edx: work flags (arg3) */
leaq do_notify_resume(%rip),%rax
leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1
xorl %esi,%esi # oldset -> arg2
call ptregscall_common
1: movl $_TIF_NEED_RESCHED,%edi
jmp sysret_check
/* Do syscall tracing */
@ -484,6 +489,8 @@ retint_careful:
jmp retint_check
retint_signal:
testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
jz retint_swapgs
sti
SAVE_REST
movq $-1,ORIG_RAX(%rsp)
@ -492,8 +499,8 @@ retint_signal:
call do_notify_resume
RESTORE_REST
cli
movl $_TIF_NEED_RESCHED,%edi
GET_THREAD_INFO(%rcx)
movl $_TIF_WORK_MASK,%edi
jmp retint_check
#ifdef CONFIG_PREEMPT

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